Docker 開発・本番環境分け

<h2>はじめに</h2>
RailsアプリをDockerで環境を分けてbuildしようとしたときに詰まったことがありました。同じように詰まっている人の一助になればと思っています。

<h2>環境</h2>
macOS Big Sur 11.6.6<br />
rails 6.1.6<br />
Docker 20.10.7<br />
docker-compose 1.29.2<br />

<h2>原因</h2>

+ 開発・本番ともにDocker環境で構築
+ 開発・本番でシステム構成が異なるのでDockerfile、docker-composeの中身が違う
+ 開発から本番に移行する際に、Dockerfile、docker-composeの中身を本番に合うように変えた
+ 以降、開発環境でDockerが使えなくなった

<h2>解決</h2>

+ 開発環境用のファイルと本番環境用のファイルをそれぞれ用意する（自分的に一番簡単な方法だった）

<h3>システム構成</h3>
<b>開発環境</b>（本番との違い: Nginxを使っていない、PostgreSQLのDockerイメージ使用）

```.tsx:Dockerfile.dev
FROM ruby:2.7.6
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 build-essential libpq-dev nodejs yarn postgresql-client
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install

ENV PATH $PATH:/usr/local/src/bin

# コンテナー起動時に毎回実行されるスクリプトを追加
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"]
```
```.tsx:docker-compose.dev.yml
version: "3.9"
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password
  web:
    build:
      context: .
      dockerfile: Dockerfile.dev
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
    tty: true
    stdin_open: true
```
<b>本番環境</b>（開発との違い: NginxのDockerイメージを使用、かつ開発で使ったPostgreSQLのDockerイメージを使っていない→AWSのRDSを使用）
※scouterはアプリ名

```.tsx:Dockerfile
FROM ruby:2.7.6
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 build-essential libpq-dev nodejs yarn postgresql-client

WORKDIR /scouter

COPY Gemfile /scouter/Gemfile
COPY Gemfile.lock /scouter/Gemfile.lock

RUN gem install bundler
RUN bundle install

RUN bundle config set with production
RUN bundle config set without test development

RUN mkdir -p tmp/sockets

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


```.tsx:docker-compose.yml
version: '3'
services:
  app:
    build:
      context: .
    command: bundle exec puma -C config/puma.rb -e production

    volumes:
      - .:/scouter
      - public-data:/scouter/public
      - tmp-data:/scouter/tmp
      - log-data:/scouter/log
    networks:
      - scouter-network

  web:
    build:
      context: ./nginx_docker
    volumes:
      - public-data:/scouter/public
      - tmp-data:/scouter/tmp
    ports:
      - 80:80
    depends_on:
      - app
    networks:
      - scouter-network
    stdin_open: true
    tty: true

volumes:
  public-data:
  tmp-data:
  log-data:
  db-data:


networks:
  scouter-network:
    external: true
```
<h3>ファイルの置き場所</h3>

本番用のDockerfile、docker-compose.ymlが置いてある同じディレクトリに開発用のDockerfile.dev、docker-compose.dev.ymlを配置した場合、docker-compose.dev.ymlは以下のようなパスで開発用のDockerfile.devを呼び出すようにする（開発用のファイルを違うディレクトリにした場合、それに合わせてパスを変える）。

```.tsx:docker-compose.dev.yml
web:
    build:
      context: .
      dockerfile: Dockerfile.dev
```


<h3>DockerのBuild方法</h3>

<h4>開発環境</h4>

Dockerをビルドする
```.tsx:ターミナル
$ docker-compose -f docker-compose.dev.yml build
```

Dockerをアップする
```.tsx:ターミナル
$ docker-compose -f docker-compose.dev.yml up -d
```
<h4>本番環境</h4>

Dockerをビルドする(通常通り)
```.tsx:ターミナル
$ docker-compose build
```

Dockerをアップする(通常通り)
```.tsx:ターミナル
$ docker-compose up -d
```

:::note warn
警告
上記コマンドでビルドすると２つのファイルがマージされてビルドされてしまいます！
開発と環境で構成を完全に分けた場合はうまくビルドされません。
docker-compose -f docker-compose.yml -f docker-compose.dev.yml build 
:::

※記事内容で間違いなどあれば、ご指摘ください。

<h2>参考記事</h2>
<a href="https://techtechmedia.com/docker-compose-dev-prod/">https://techtechmedia.com/docker-compose-dev-prod/</a><br />
<a href="https://techracho.bpsinc.jp/gengen/2020_05_01/91520">https://techracho.bpsinc.jp/gengen/2020_05_01/91520</a>