Dockerで開発環境を作成するメモ3

docker-composeを使ってコンテナ作成を行うメモ

docker-compose.ymlファイルに記述することもできそうだけど、とりあえずコンテナ単位でDockerfileを作成して、docker-compose.ymlから読み込むような構成にしてみる。

# Dockerfile
FROM node:12.13.1-alpine

WORKDIR /home/app
USER node
ENV PORT 3000
EXPOSE 3000

ENTRYPOINT /bin/ash

次に以下のようなdocker-compose.ymlファイルを定義する。ファイルの内容としてはservices以下に複数のサービスを定義する。これがコンテナ単位になる。build.dockerfileで、カレントディレクトリのDockerfile1を読み込んでイメージ作成する。とりあえずコンテナ名と外部とのポートマッピングを指定してみた。

# docker-compose.yml
version: '3.3'
services:
  container1:
    build:
      context: .
      dockerfile: Dockerfile1
    ports:
      - 8080:3000

docker-compose buildで定義ファイルの内容からイメージを作成する。完了してもコンテナまでは作成されない。

> docker-compose build
Building container1
Step 1/6 : FROM node:12.13.1-alpine
 ---> 3fb8a14691d9
Step 2/6 : WORKDIR /home/app
 ---> Running in ada14448bb27
Removing intermediate container ada14448bb27
 ---> b7abbdc31c9c
Step 3/6 : USER node
 ---> Running in 9cf75c8dff07
Removing intermediate container 9cf75c8dff07
 ---> ee47a3a0a6e3
Step 4/6 : ENV PORT 3000
 ---> Running in 6a305a579c4d
Removing intermediate container 6a305a579c4d
 ---> 241b5aa28395
Step 5/6 : EXPOSE 3000
 ---> Running in 0443d11bd999
Removing intermediate container 0443d11bd999
 ---> beb17880d65f
Step 6/6 : ENTRYPOINT /bin/ash
 ---> Running in 7a6834baa1b4
Removing intermediate container 7a6834baa1b4
 ---> d5ecad5bd967

Successfully built d5ecad5bd967
Successfully tagged compose_test1_container1:latest

> docker images
REPOSITORY                 TAG                  IMAGE ID            CREATED             SIZE
compose_test1_container1   latest               d5ecad5bd967        30 seconds ago      80.2MB

docker-compose runでコンテナを展開してみる。引数の最後にymlファイルで定義したサービスを指定すると、そのサービスのコンテナが作成される。今回はコンテナから抜けたら自動削除されるように--rm、サービス用のポートを有効化するために--service-portsを指定。

> docker-compose run --rm --service-ports container1
Creating network "compose_test1_default" with the default driver
/home/app $ node -v
v12.13.1
/home/app $

別のターミナルを起動してコンテナのプロセスを確認してみる。ymlファイルの親フォルダ名、サービス名などからイメージやコンテナ名が自動生成されている感じ。

> docker ps
CONTAINER ID        IMAGE                     COMMAND                 CREATED             STATUS              PORTS                    NAMES
5c449f36d300        compose_test1_container1   "/bin/sh -c /bin/ash"   25 seconds ago      Up 24 seconds       0.0.0.0:8080->3000/tcp   compose_test1_container1_run_16c7049b2253

コンテナ間の連携

試しにpythonとnode.jsのコンテナを2つ起動してみる。

# docker-compose.yml
version: '3.3'
services:
  container1:
    image: python:3.8.0-slim
    container_name: cont1
  container2:
    image: node:12.13.1-slim
    container_name: cont2

すでにイメージはダウンロード済みなので、バックグラウンドで起動してみても、起動は成功するけど、すぐに終了してしまう。docker runの場合は-it -dオプションを指定すれば、稼働したままになるが、docker-composeコマンドの場合は、定義が必要になる。

> docker-compose up -d
Creating cont2 ... done
Creating cont1 ... done

> docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
1d09ea4cffe1        python:3.8.0-slim   "python3"                7 seconds ago       Exited (0) 5 seconds ago                       cont1
4e22de81b430        node:12.13.1-slim   "docker-entrypoint.s…"   7 seconds ago       Exited (0) 5 seconds ago                       cont2

> docker-compose down

この場合、各サービスの定義のところにtty: trueを追加すると、コンテナが起動しっぱなしになるので、docker execで中に入ることができるようになる。

# docker-compose.yml
version: '3.3'
services:
  container1:
    image: python:3.8.0-slim
    container_name: cont1
    tty: true
  container2:
    image: node:12.13.1-slim
    container_name: cont2
    tty: true
>  docker-compose up -d
Creating network "compose_test1_default" with the default driver
Creating cont1 ... done
Creating cont2 ... done

> docker ps
docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
c073519f9ccf        node:12.13.1-slim   "docker-entrypoint.s…"   6 seconds ago       Up 5 seconds                            cont2
0d73fdb4912a        python:3.8.0-slim   "python3"                6 seconds ago       Up 5 seconds                            cont1

無事コンテナが起動したので、pythonコンテナに侵入してちゃんと存在しているか確認する。以下のようにpythonのバージョンは確認できたものの、node.jsのバージョンは確認できないことがわかる。

つまり、docker-compose.ymlで複数のコンテナを定義しただけでは、それぞれが別の空間で稼働するだけでお互いが繋がってないことがわかる。

> docker exec -it cont1 /bin/bash
root@0d73fdb4912a:/# python --version
Python 3.8.0

root@0d73fdb4912a:/# node --version
bash: node: command not found