docker
dockerfile
docker-compose

docker-compose コマンドまとめ

More than 1 year has passed since last update.

開発環境としてDockerを使ってるのですが、なんとなくコマンドを打っていて、あまりちゃんとコマンドを理解していないので、覚え書きとしてまとめてみようと思います。
dockerコマンドというよりdocker-composeを紹介します。

今回は以下のようなdocker-compose.ymlを参考にします。

docker-compose.yml
web:
  build: .
  environment:
    DISABLE_SPRING: "1" 
    DB_USERNAME: "root"
    DB_PASSWORD: "root"
    DB_HOST: "db"
  ports:
    - "3000:3000"
  volumes:
    - ".:/var/local/rails5_product"
  links:
    - "db"

db:
  image: mysql:5.6
  environment:
    MYSQL_ROOT_PASSWORD: "root"                                

Dockerfileも

Dokerfile
# rails5_product
FROM ruby:2.3.0
ENV LANG C.UTF-8

# Install Packages
RUN apt-get update -y && apt-get upgrade -y
RUN apt-get install -y \
      sudo \
      nodejs \
      build-essential \
      mysql-client 

# Application
ENV app     rails5_product
ENV deploy  /var/local/$app
ENV user    prod_dev

# User
RUN useradd -d /home/$user -m -s /bin/bash $user
RUN echo "$user:$user" | chpasswd
RUN echo "$user ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/$user
USER $user
ENV HOME /home/$user

# Work Directory
RUN sudo mkdir -p $deploy
RUN sudo chown -R $user:$user $deploy
WORKDIR $deploy

# Bundle Install
RUN sudo gem install bundler
ADD Gemfile $deploy/
ADD Gemfile.lock $deploy/
RUN sudo chown $user:$user Gemfile
RUN sudo chown $user:$user Gemfile.lock
RUN bundle install

EXPOSE 3000
CMD ["./bin/rails", "server", "-b", "0.0.0.0"]

環境

・ Ruby 2.3.0 (ベースとなるDockerイメージを使用しております。)
・ Ruby on Rails 5.0.0
・ Mac OS X El Capitan 10.11.5
・ Docker 1.12.0-rc4
・ docker-compose version 1.8.0-rc2
(Docker for Mac Beta を使用しております。)

build

サービスのビルドを実行します。
サービスとは「web」や「db」のことを指します。ymlファイルにimage:が書かれている場合はそのイメージ名がローカルになければ、リモートからプルしてきます。imageが書かれていない場合、buildに書かれているパスの(デフォルトは)Dockerfileを参考にしてイメージを構築します。

$ docker-compose build
db uses an image, skipping
Building web ......

また引数にサービス名を指定して、特定のサービスだけビルドすることも可能です。

bundle

DAB(Distributed Application Bundles)というのを作成します。これは事前に作成したイメージをdockerのregistryにpushしておく必要があります(ローカルにpushでも可)。

$ docker-compose bundle
WARNING: Unsupported key 'links' in services.web - ignoring
WARNING: Unsupported key 'volumes' in services.web - ignoring
Wrote bundle to rails5product.dab

作成されたファイルは以下のような内容です。

{
  "Services": {
    "db": {
      "Env": [
        "MYSQL_ROOT_PASSWORD=root"
      ], 
      "Image": "mysql@sha256:2897982d4c086b03586a1423d0cbf33688960ef7534b7bb51b9bcfdb6c3597e7", 
      "Networks": [
        "default"
      ]
    }, 
    "web": {
      "Args": [
        "bash", 
        "-c", 
        "rm -f tmp/pids/server.pid; ./bin/rails server -b 0.0.0.0"
      ], 
      "Env": [
        "DB_PASSWORD=root", 
        "DB_HOST=db", 
        "DB_USERNAME=root", 
        "DISABLE_SPRING=1"
      ], 
      "Image": "wataru0225/rails5_product@sha256:3fb6321b2c8edb2a3f74ca85574182802359a8d4106a9350406a6d5252a71a00", 
      "Networks": [
        "default"
      ], 
      "Ports": [
        {
          "Port": 3000, 
          "Protocol": "tcp"
        }
      ]
    }
  }, 
  "Version": "0.1"
}

config

docker-compose.ymlで書かれてる内容が表示されます。今回は、networksやvolumesは書いてないので空で表示されてます。

$ docker-compose config
networks: {}
services:
  db:
    environment:
      MYSQL_ROOT_PASSWORD: root
    image: mysql:5.6
    network_mode: bridge
  web:
    build:
      context: ~/rails5_product
    environment:
      DB_HOST: db
      DB_PASSWORD: root
      DB_USERNAME: root
      DISABLE_SPRING: '1'
    links:
    - db
    network_mode: bridge
    ports:
    - 3000:3000
    volumes:
    - ~/rails5_product:/var/local/rails5_product:rw
version: '2.0'
volumes: {}

create

構築されたサービスを参考にそのコンテナを作ります。ここで作られたコンテナは起動している状態ではありません。

$ docker-compose create
Creating rails5product_db_1
Creating rails5product_web_1

これもまた引数にサービス名を指定して、特定のサービスだけのコンテナを作ることも可能です。

down

docker-compose.ymlに書かれているサービスを参考にコンテナを停止し、そのコンテナとネットワークを削除します。
オプションで--rmi allをつけることでイメージも削除してくれます。

$ docker-compose down
Stopping rails5product_web_1 ... done
Stopping rails5product_db_1 ... done
Removing rails5product_web_1 ... done
Removing rails5product_db_1 ... done

events

コンテナからのイベントを受信します。コマンドを打つと、受信状態に入り特に動きはありません。別のタブでdockerコマンドを試すと動きが分かります。

$ docker-compose events

$ docker exec -it rails5product_web_1 /bin/bash
root@21896a731d87:/var/local/rails5_product#                                                               
$ docker-compose events
container exec_start: /bin/bash  21896a731d87e65c0725df989b8c2828d14850ece829897e057caa514e435f7f (image=rails5product_web, name=rails5product_web_1) 

exec

docker execコマンドと同等のことができます。引数にサービス名と実行するコマンドを指定して、実行します。

$ docker-compose exec web /bin/bash
root@3a0319c17621:/var/local/rails5_product# 

help

コマンドの一覧を表示します。基本はこちらを参考にすると良いでしょう。

images

対象のイメージの情報を表示します。

$ docker-compose images
     Container           Repository        Tag       Image Id      Size   
-------------------------------------------------------------------------
rails5product_db_1    mysql               5.6      cdfa8cc50c33   284 MB  
rails5product_web_1   rails5product_web   latest   42427affdec4   1.17 GB 

kill

コンテナを強制停止します。

$ docker-compose kill
Killing rails5product_web_1 ... done
Killing rails5product_db_1 ... done

logs

サービスのログを出力します。

$ docker-compose logs
Attaching to rails5product_web_1, rails5product_db_1
.....

また引数でサービス名を指定できるので、そうするとサービスごとにログを出力してくれます。

pause

サービスを一旦停止します。(一時停止したサービスは強制削除、強制開始ができずunpauseをしてからでないと作業ができなくなるので注意してください。)

$ docker-compose pause
Pausing rails5product_db_1 ... done
Pausing rails5product_web_1 ... done

port

割り当てているポートを表示します。引数でサービス名とポート番号が必要になります。

$ docker-compose port web 3000
0.0.0.0:3000

ps

コンテナの一覧を表示します。

$ docker-compose ps
       Name                      Command              State            Ports          
-------------------------------------------------------------------------------------
rails5product_db_1    docker-entrypoint.sh mysqld     Paused   3306/tcp               
rails5product_web_1   ./bin/rails server -b 0.0.0.0   Paused   0.0.0.0:3000->3000/tcp 

ちなみにdocker psでもコンテナ一覧表示ができます。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
430a9252b5ef        rails5product_web   "./bin/rails server -"   4 seconds ago       Up 2 seconds        0.0.0.0:3000->3000/tcp   rails5product_web_1
ace14a21fdca        mysql:5.6           "docker-entrypoint.sh"   4 seconds ago       Up 4 seconds        3306/tcp                 rails5product_db_1

pull

サービスのイメージをプルしてきます。今回書かれている内容だと、mysqlにしかimageが記載されてないので、mysqlのイメージのみpullしてきます。

$ docker-compose pull
Pulling db (mysql:5.6)...
5.6: Pulling from library/mysql

push

サービスのイメージをプッシュします。サービス名がwebの方ならpushができます。(dockerのregistryなどにpushする場合、事前に docker loginをしておく必要があります。)

$ docker-compose push web
Pushing web (wataru0225/rails5_product:latest)...
The push refers to a repository [docker.io/wataru0225/rails5_product]
dd109e1c2002: Preparing
9fb4d117f6f2: Preparing
17e7a11e646d: Preparing
d1223c4f56c0: Preparing
73b7de3ce7c8: Preparing
6e3fe9a92a13: Waiting
251e05a2e324: Waiting
1ad3dbeb7233: Waiting
..........

restart

コンテナを再起動します。

$ docker-compose restart
Restarting rails5product_web_1 ... done
Restarting rails5product_db_1 ... done

rm

停止中のコンテナを削除します。デフォルトだと[y/N]の確認があるのですが、-fオプションをつけることで、確認なしでコンテナを削除します。

$ docker-compose rm 
Removing rails5product_web_1 ... done
Removing rails5product_db_1 ... done

run

引数で指定したサービスのコンテナ内でコマンドを実行します。

$ docker-compose run web rails s
=> Booting Puma
=> Rails 5.0.0 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
..........

scale

サービスを実行するコンテナ数を指定します。サーバーの台数を増やしたりする時に使用します。
portsが被ると正常に実行できないので注意してください。

$ docker-compose scale web=2
Creating and starting rails5product_web_1 ... done
Creating and starting rails5product_web_2 ... done

start

サービスを開始します。これは既にコンテナがある状態でなければなりません。

$ docker-compose start
Starting db ... done
Starting web ... done

stop

サービスを停止します。

$ docker-compose stop
Stopping rails5product_web_1 ... done
Stopping rails5product_db_1 ... done

top

各コンテナのプロセス情報を表示します。

$ docker-compose top
rails5product_db_1
 PID    USER   TIME   COMMAND 
-----------------------------
26399   999    0:00   mysqld  

rails5product_web_1
 PID      USER     TIME                               COMMAND                              
------------------------------------------------------------------------------------------
26690   dockrema   0:00   bash -c rm -f tmp/pids/server.pid; ./bin/rails server -b 0.0.0.0 
26713   dockrema   0:03   {ruby} puma 3.4.0 (tcp://0.0.0.0:3000) [rails5_product]    

unpause

サービスの再開をします。pauseしている状態から復帰するのですが、pauseしている状態から復帰するにはこのコマンドが必要です。

$ docker-compose unpause
Unpausing rails5product_web_1 ... done
Unpausing rails5product_db_1 ... done

up

コンテナを作成して、起動します。オプションで-dをつけることでバックグラウンドで実行することができます。
またオプションで--buildをつけることで起動前にイメージも構築します。

$ docker-compose up
Creating rails5product_db_1
Creating rails5product_web_1
Attaching to rails5product_db_1, rails5product_web_1
.........

version

docker-composeのバージョンを表示します。

$ docker-compose version
docker-compose version 1.8.0-rc2, build c72c966
docker-py version: 1.9.0-rc2
CPython version: 2.7.9
OpenSSL version: OpenSSL 1.0.2h  3 May 2016

(※これは 2016年7月16日現在のバージョンになります。)

その他

up -d --buildをすれば、サービスのコンテナが立ち上がりサービスを開始してくれます。
またdocker-composeとコマンドを打つのが面倒な方は、エイリアスでfigとするのもお勧めします。
元はfigというツールだったようなので。(2014年7月にDocker社は、figを買収したようです。)

alias fig='docker-compose'

docker-composeはイメージ名とコンテナ名を自動で生成してくれます。ですが、railsとかだとGemとかを管理する時、ブランチを切ってbundleを実行したりしてしまうと、イメージ名に差はないのでまた新しくイメージをbuildしようとしてしまいます。差分を管理したいとかの運用法になると、自動生成はかえって便利でなくなってしまう恐れがありますね。(ベストプラクティスが思いついてはいません。。。)

参考リンク

https://docs.docker.com/compose/reference/
http://qiita.com/skyriser/items/2cf98b747ed6577cc5ee