docker-composeを利用してdockerコンテナを作成する方法メモ(複数コンテナ対応)
はじめに
本記事の目的
dockerコンテナを立ち上げる。 また、今回はdocker-composeというツールも利用する。
基礎知識として、docker-composeツールを使わずにDockerを立ち上げる方法は以下の記事に記載している。
いかの記事ではAWSのEC2上で実施しているが、もちろんEC2を使わずローカルで実施も可能。
EC2サーバ(Linux)上でdockerコンテナを起動する方法メモ(nginxベース) - エンジニアを目指す日常ブログ
前提
- Linux環境とする。
今回はWindows上にVagrantで仮想環境を用意している。 tomiko0404.hatenablog.com
- はじめに
- dockerインストール
- Dockerfileの作成
- docker-compose.ymlファイルの作成
- イメージをビルドし、コンテナを作成する
- 【補足】コンテナ上でアプリを実行してみる
- おわりに
dockerインストール
以下サイトを参考に実施した。
Vagrantの上にDockerを載せて開発環境を作成する(おそらくこちらを見ながらやったはず)
Ubuntuにdockerをインストールする - Qiita
docker-composeもインストールが必要。
Docker Compose のインストール | Docker ドキュメント
Dockerfileの作成
Dockerfileとは、dockerイメージファイルを作るときに元ネタとなる設定値を記載するファイル。 dockerイメージはdockerコンテナの設計図のようなもので、基本的にdockerは、
- Dockerfileに従ってdockerイメージをビルド
- dockerイメージに従ってコンテナを作成
という流れでコンテナを作成する必要がある。
今回はDockerfileを以下のように記述した。
FROM node:14.15.4-slim RUN apt-get update && apt-get install -y locales \ && locale-gen en_US.UTF-8 \ && localedef -i en_US -f UTF-8 en_US.UTF-8 \ && echo "export LC_ALL=en_US.UTF-8" >> ~/.bashrc \ && ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime RUN apt-get install -y \ wget \ curl \ && apt-get clean \ && rm -rf /var/lib/apt/lists/*
一番上の
FROM node:14.15.4-slim
は、dockerhubという、コンテナイメージの倉庫のようなところから既存のイメージを持ってくるための記載。
今回はNode.jsを利用してアプリを作りたいので、Node.jsのイメージを持ってくる。
■docker hubの node ページ。 hub.docker.com ■nodeのReadmeページ。Dockerfileの書き方例なども載っている。 github.com
docker-compose.ymlファイルの作成
docker-composeは、一言でいえば「Docker構築を楽にするためのツール」である。
docker-composeツールを使うと、コマンド docker-compose up
一つで「Dockerfileに従ってdockerイメージをビルド」⇒「dockerイメージに従ってコンテナを作成」を実行してくれる。
その際の設定値を規定するのがdocker-compose.yml
である。
dockerの各種コマンド(イメージをビルドするコマンドや、コンテナ起動するコマンド)の引数をdocker-compose.yml
で事前に定義しておくイメージ。
今回作成したdocker-compose.ymlファイル
今回は、「画面サーバ」と「Webサーバ」を用意したいので、2つのコンテナを立ち上げたい。 記載内容は以下となる。
docker-compose.yml
# このファイルはversion3の書き方仕様で書いてますよという宣言。おまじない扱いで良い。 version: '3' # networkを作成する。複数のコンテナどうしでネットワークを構成したいときに # 作成する。基本はbridgeを利用する。「react_net」は自分で設定したネットワーク名。 networks: react_net: driver: bridge # 作りたいサービスを規定する。 # 今回は「frontend」と「backend」の2つのサービスを作成。 services: frontend: # サービス名 build: ./ # Dockerfileを利用してイメージをbuildする。Dockerfileの場所を記載する。 image: react_front # buildしたイメージの名前を決める。 container_name: frontend # 起動するコンテナの名前を決める。 tty: true # 調査中 volumes: - ../front:/app # ローカルの ../front フォルダを、コンテナ上の/appフォルダにマウントする working_dir: "/app" # コンテナが立ち上がったときに最初にいるフォルダの場所を決める ports: - 8000:8000 # ローカルの8000ポートとコンテナの8000ポートをポートフォワーディング networks: - react_net # 上で定義したreact_netネットワークに接続する backend: build: ./ image: node_back container_name: backend # コンテナ名は別名を設定する tty: true volumes: - ../back:/app working_dir: "/app" ports: - 3000:3000 # ポートフォワーディングもかぶらないよう設定 networks: - react_net
コンテナ1つで良い場合
コンテナ1つで良い場合は、以下の記載とする。
version: '3' networks: react_net: driver: bridge services: frontend: build: ./ image: react_front container_name: frontend tty: true volumes: - ../:/app working_dir: "/app" ports: - 8000:8000 networks: - react_net
docker-compose.ymlの記載内容について
各種設定の中身は以下記事が参考になる。 【Docker】初心者のための Docker Compose まとめ - AI can fly !!
参考:Dockerfileを利用しない方法
上記参考記事のimage
オプションの解説を見ると以下の記載がある。
前述の build が指定されている場合は、 build で指定された Dockerfile から Docker イメージが構築され、そのイメージ名が image で指定した名前になります。 build を指定しない (Dockerfile からイメージを構築しない) 場合、ここで指定された Docker イメージからコンテナを作成しますが、指定した Docker イメージがローカルに存在しない場合は、 Docker Hub から Pull (取得) した上でコンテナが作成されます。
今回はbuild
コマンドで自作のDockerfileを指定しているが、単純に
image: node:14.15.4-slim
と記載しても問題ない。この場合Dockerfileが不要になる。
イメージをビルドし、コンテナを作成する
(事前確認)dockerイメージの存在確認
今あるdockerイメージを確認する。
dockerイメージを確認するコマンド:docker images
$ sudo docker images
過去に作ったものが残っていた。node
は公式イメージ。
REPOSITORY TAG IMAGE ID CREATED SIZE react-practice-6 latest d4a0b79d2c36 3 weeks ago 473MB node 14.15.4-slim 2f75d89d8162 8 months ago 167MB
イメージ作成とコンテナ起動
以下のコマンドを実行する。
$ sudo docker-compose up -d
イメージが作られたことの確認
docker-compose.ymlで指定した名前のdockerイメージが作成された。
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE node_back latest e6e824760f03 About a minute ago 216MB react_front latest e6e824760f03 About a minute ago 216MB react-practice-6 latest d4a0b79d2c36 3 weeks ago 473MB node 14.15.4-slim 2f75d89d8162 8 months ago 167MB
コンテナが起動したことの確認
- 起動中のコンテナを確認するコマンド:
docker ps
- 起動中に限らずコンテナを確認するコマンド:
docker ps -a
frontendコンテナとbackendコンテナが起動された。
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fce6328cdc9f react_front "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp frontend 3eb02504a2a0 node_back "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp backend
コンテナの中に入って操作する
コンテナの操作は基本的に'docker exec'で実施することができる。 毎回書くのは大変なので以下コマンドでターミナルを立ち上げることができる。
$ sudo docker exec -u node -it frontend /bin/bash -l
docker exec
の構文は以下の通りである。
$ docker exec [オプション] [コンテナ名] [コマンド] [引数...]
-u node
はユーザ名を指定している。今回は公式のnode
イメージのデフォルトユーザ名node
を指定。
-it
は対話型を指定するオプション。
frontend
はコンテナ名。
/bin/bash -l
が実行したいコマンドとなる。
コンテナから抜ける
コンテナから抜けたいときはexit
コマンドで抜けられる。
コンテナを停止する
コンテナを停止したいときは
$docker-compose down
【補足】コンテナ上でアプリを実行してみる
Node.jsで簡単なHTTPサーバが動くか確認。
コンテナと共有しているフォルダにapp.js
を作成する。
ローカルのフォルダ構成
ローカルのフォルダ構成は以下のようになっている。
. ├── back ※backendのdockerにマウント │ └── app.js ├── docker │ ├── Dockerfile │ └── docker-compose.yml └── front ※frontendのdockerにマウント(今は空)
app.jsの作成
app.js
const portNumber = 8000; const http = require("http"); http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "text/plain" }); res.end("Hello World"); }).listen(portNumber); console.log(`PortNumber is ${portNumber}`);
app.jsを実行
コンテナに入った状態で以下を実行する。
node@fce6328cdc9f:/app$ node app.js
ブラウザからlocalhost:8000
にアクセスすると応答が返ってくる。
今回は、Node.jsのみで実行できるアプリのため、app.js
を作成するだけで実行できる。追加モジュールが必要な場合は、npm install
などで追加する必要がある。
おわりに
docker-composeを利用してコンテナを立ち上げる方法をメモした。
以前にも同じような記事を書いたが、この理解度で複数のコンテナを立ち上げようとしたら行き詰ってしまったので、docker-composeについて勉強しました。 結果、理解が深まったので整理がてら書き直したのが本記事です。
以前の記事
vagrant上にdockerコンテナを立ち上げる方法メモ(docker-compose利用) - エンジニアを目指す日常ブログ
関連記事
つづき:WebAPIサーバの開発
上記のapp.js
の続きで、Node.jsでWebAPIサーバを作成した。
つづき:フロントエンドの開発
dockerコンテナ上にReactアプリ作成した。
参考資料
dockerコマンドが豊富な記事。