【Docker】docker-composeファイルをコピーして使い回す時の注意点(コンテナ起動エラーやファイルがコピーされない時の対処法)

docker-prograshi(プロぐらし)-kv Rails
記事内に広告が含まれていることがあります。
[PR]

既に作成ずみのDocker(docker-compose)環境を使って、同じベースとなる環境を作成するときに、一部の設定を変更しないと、コンテナが重複して起動しなかったりコンテナの中に展開したファイルがローカルにコピーされないということがあります。

ここでは、Docker環境を使い回す時の注意点をまとめています。

例として、docker-compose.ymlを使って構築したRails環境を複製しています。

(参考)Docker上にRails6を作成する方法(PostgrasSQL)

Docker環境を使い回すときに変更するべき点

docker-compse.ymlとDcokerfileは変更が必要です。

コンテナ内のディレクトリ名はそれぞれで共通になるので、どちらかを変更した場合は合わせる必要があります。

docker-compose.ymlで変更する点

docker-compose.ymlで変更するポイント
  • services: サービス名(※必須)
    • depends_onやlinksのサービス名も合わせて変更
  • container_name: コンテナ名(※必須)
  • ports: ホスト側のポート番号(※必須)
  • volumes: バインドするコンテナ内のディレクトリ

サービス名を変更しないと、既存のdockerイメージを使って構築するため、コンテナ内の中身がバインドされません。

サービス名を変更したときに、depends_onやlinksも合わせて変更しないと、起動するサービスがないというエラーが発生します。

コンテナ名を変更しないと、コンテナが重複して起動できません。

ポート番号を変更しないとポートが重複してページが開けません。

Dockerfileでコンテナ内のディレクトリ名を変更した場合は、バインドするコンテナ内のディレクトリ名も合わせて変更する必要があります。

docker-compose.ymlの変更例

version: '3'
services:
  db:
    image: postgres
    container_name: rails-vue-db
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_HOST_AUTH_METHOD: 'trust'

  web:
    build: .
    container_name: rails-vue-web
    command: bash -c "rm -f tmp/pids/server.pid && rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/rails-vue
    ports:
      - "3000:3000"
    depends_on:
      - db

 
 ↓次のように変更します。

version: '3'
services:
  aa-db: #変更
    image: postgres
    container_name: rails-aa-db #変更 
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_HOST_AUTH_METHOD: 'trust'

  aa-web: #変更
    build: .
    container_name: rails-aa-web #変更
    command: bash -c "rm -f tmp/pids/server.pid && rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/rails-aa #変更
    ports:
      - "3001:3000" #変更
    depends_on:
      - aa-db #変更



Dockerfileで変更する点

Dockerfileで変更が必要なのは、WORKDIR、COPYなどのディレクトリ名です。

Dockerfileで変更する点
  • コピー元になるディレクトリ名(※必須)
  • コンテナ内のディレクトリ名

コピー元になるディレクトリ名を絶対パスで記述している場合は、展開するディレクトリに合わせて変更が必要です。(ほとんどない)

Dockerfileの変更例

FROM ruby:2.7.4

#apt-keyとdevconfのエラー対策
ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
ENV DEBCONF_NOWARNINGS=yes

# node.jsと必要なライブラリのインストトール
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client \
            curl apt-transport-https wget

# yarnのインストール
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 && apt-get install -y yarn

#aptキャッシュの削除
RUN rm -rf /var/lib/apt/lists/*

# ディレクトリ・ファイルの作成
RUN mkdir /rails-vue
WORKDIR /rails-vue
COPY Gemfile /rails-vue/Gemfile
COPY Gemfile.lock /rails-vue/Gemfile.lock

# gem(Rails6)のインストール
RUN bundle install
COPY . /rails-vue

RUN yarn install --check-files
RUN bundle exec rails webpacker:compile

# コンテナ起動時に毎回実行するスクリプトを追加
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# rails起動コマンド
CMD ["rails", "server", "-b", "0.0.0.0"]

 
 ↓次のように変更します。

FROM ruby:2.7.4

#apt-keyとdevconfのエラー対策
ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
ENV DEBCONF_NOWARNINGS=yes

# node.jsと必要なライブラリのインストトール
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client \
            curl apt-transport-https wget

# yarnのインストール
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 && apt-get install -y yarn

#aptキャッシュの削除
RUN rm -rf /var/lib/apt/lists/*

# ディレクトリ・ファイルの作成 ※変更
RUN mkdir /rails-aa
WORKDIR /rails-aa
COPY Gemfile /rails-aa/Gemfile
COPY Gemfile.lock /rails-aa/Gemfile.lock

# gem(Rails6)のインストール ※変更
RUN bundle install
COPY . /rails-aa

RUN yarn install --check-files
RUN bundle exec rails webpacker:compile

# コンテナ起動時に毎回実行するスクリプトを追加
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# rails起動コマンド
CMD ["rails", "server", "-b", "0.0.0.0"]


entrypoint.sh

コンテナ起動時に実行する entrypoint.sh の中で絶対パスを使ってコンテナ内のディレクトリを指定している場合は、Dockerfileの内容に合わせて修正します。

entrypoint.shの変更例

#!/bin/bash
set -e

# 初期に作成されるPIDを削除する
rm -f /rails-aa/tmp/pids/server.pid

# DockerfileのCMDにセットしたすべての引数を実行する
exec "$@"

 
 ↓次のように変更します。

#!/bin/bash
set -e

# 初期に作成されるPIDを削除する  ※変更
rm -f /rails-vue/tmp/pids/server.pid

# DockerfileのCMDにセットしたすべての引数を実行する
exec "$@"



database.ymlの変更点

起動するDBのサービス名を変更したため、合わせて接続するDBのホスト名も変更する必要があります。

config/database.ymlに追記するhostを host: <DBのサービス名>とします。

database.ymlの変更例

default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  #####追記#####
  host: db
  username: postgres
  passowrd:
  #############

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test

production:
  <<: *default
  database: myapp_production
  username: myapp
  password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %>

 
 ↓次のように変更します。

default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  #####追記(※変更)#####
  host: aa-db
  username: postgres
  passowrd:
  #############

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test

production:
  <<: *default
  database: myapp_production
  username: myapp
  password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %>


docker-composeコマンド実行時の注意点

docker-copmose.ymlのサービス名を変更したので、docker-composeコマンドの引数でサービス名を指定する場合は合わせて変更する必要があります。

$ docker-compose run web rails new .
$ docker-compose run web rails db:create


 ↓

$ docker-compose run aa-web rails new .
$ docker-compose run aa-web rails db:create

最後に

設定を間違えた状態でコンテナを作成したり、コンテナ操作を行うと、間違った設定が認識されてしまいます。

その場合は、一度ディレクトリや、コンテナ、イメージを削除して、もう一度立ち上げる方が早かったりもします。

参考にDockerイメージやコンテナの削除コマンドを載せておきます。

コンテナの削除手順

起動中のコンテナの停止

#起動中のコンテナ一覧を表示
docker ps

#コンテナの停止
docker stop <コンテナ名>

コンテナの削除

#すべてのコンテナ一覧を表示
docker ps -a

#コンテナを削除
docker rm <コンテナ名>


停止中のコンテナをまとめて削除する便利なコマンドもあります。

docker container prune

yをクリックして削除を実行します。

イメージの削除手順

イメージの削除

#イメージ一覧を表示
docker images

#イメージを削除
docker rmi <イメージ名>


イメージをまとめて削除する便利なコマンドもあります。

docker image prune

yをクリックして削除を実行します。

タイトルとURLをコピーしました