Docker触ってみた

# Dockerfile

# TODO: nodeもFROMからとってきたい
# TODO: alipineにして軽くしたい
FROM ruby:2.6.6 # 2.6.6-alpineとかにすると最低限のパッケージしか入らないのでイメージが軽くなる
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
    && apt-get update -qq \
    && apt-get install -y nodejs yarn postgresql-client \
    && mkdir /myapp # この辺は必要なパッケージを入れてる。だいたい公式の通り。https://docs.docker.com/compose/rails/
WORKDIR /myapp
RUN gem install bundler
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]

# WORKDIR

http://docs.docker.jp/engine/reference/builder.html#workdir cdみたいなものだと理解。

WORKDIR /myappで作業ディレクトリを/myappに移してるイメージ。

# COPY

ローカルからコンテナにファイルをコピー http://docs.docker.jp/engine/reference/builder.html#copy

COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock

→ Gemfileたちをコピーしてる。

COPY . /myapp

→ ローカルのRailsアプリたちをまるっとコピーしてる。

# ENTRYPOINT

http://docs.docker.jp/engine/reference/builder.html#entrypoint

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

CMDとの違いは?

→ 書いてあった。

http://docs.docker.jp/engine/reference/builder.html#cmd-entrypoint

ENTRYPOINT は、コンテナを実行モジュールとして実行する際に利用します。

→ よくわからない。 実行モジュール = 他のコンテナのベースイメージではなくそれ自体docker runで実行するコンテナのことを指すらしい。 ちょっと後回し。

# EXPOSE

http://docs.docker.jp/engine/reference/builder.html#expose

リッスンするポート番号を指定する。

# docker-compose.yml

version: '3'
services:
  db:
    image: postgres
    volumes:
      - postgres:/var/lib/postgresql/data # 公式では - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password
  web:
    build: .
    environment:
      REDIS_URL: "redis://redis:6379"
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp:cached
      - bundle:/bundle
      - node_modules:/myapp/node_modules
      - packs:/myapp/public/packs
    ports:
      - "3000:3000"
    depends_on:
      - db
      - redis
      - sidekiq
    stdin_open: true
    tty: true

  redis:
    image: redis:latest
    ports:
      - 6379:6379
    volumes:
      - redis:/data
  sidekiq:
    build: .
    environment:
      REDIS_URL: "redis://redis:6379"
    volumes:
      - .:/myapp
      - /myapp/tmp/cache # https://github.com/Shopify/bootsnap/issues/177#issuecomment-491711481
    depends_on:
      - db
      - redis
    command: bundle exec sidekiq -C config/sidekiq.yml
  webpacker:
    build: .
    command: ./bin/webpack-dev-server
    ports:
      - '3035:3035'
    volumes:
      - .:/myapp:cached
      - bundle:/bundle
      - node_modules:/myapp/node_modules
      - packs:/myapp/public/packs
volumes:
  postgres:
  redis:
  bundle:
  node_modules:
  packs:

# volumes

http://docs.docker.jp/compose/compose-file.html#volumes-volume-driver

volumes:
  - postgres:/var/lib/postgresql/data

volumes:
  postgres:

# トップレベルのvolumes

名前付きvolumeと呼ぶらしい。 複数のコンテナ間で使い回ししたいときらしいがそうしたいときってどんなケース?

この記事にあるように https://khanamoto.hatenablog.com/entry/2018/03/05/020429

名前付きvolumeを使うと、 docker-compose down や docker-compose prune とかでコンテナを削除したらDBのデータも消えるっぽい?

とのこと。確かに実際に消えた。

Docker buildとrun

docker imagesのnoneは