MySQL
nginx
OSX
docker

【初心者向け】Docker for Macで開発環境を作る(アプリサーバとDBサーバのコンテナ間連携まで)

いまさらDockerをはじめてみました。

コマンドを忘れやすいし、古かったり断片的にしか欲しい情報がなかったりして

どのように動作しているのか把握に苦しんだので備忘録含めてまとめておきます。

(この記事だけで一通りの使い方はわかるようにしたつもりです。)

Dockerを使うことのメリットは次のようなものがあります。


  • Dockerコンテナ上に仮想環境(OS+ミドルウェア)を構築するため、実環境が汚れない

  • 作成したDockerコンテナはイメージファイル化(Dockerイメージ)できる

  • DockerイメージはDocker Hubでプライベートもしくはパブリックリポジトリにバージョン管理&公開できる

  • Dockerイメージを持ってきてコンテナ起動するだけなので環境移行が楽

  • Dockerfileと呼ばれる環境作成ファイルからDockerイメージの作成もできる

DBサーバの各コンテナを用意し、

アプリサーバのコンテナから別コンテナのDBサーバにアクセスし

コンテナ外からはNginXにアクセスできるような構成にします。

image.png

その中で今回は開発でよく使うであろう、

NginxコンテナからMySQLコンテナにアクセスができる構成をDockerで作成してみます。

(一つのコンテナにNginXとMySQLを乗せることもできるのですが、その構成だとコンテナを増やした時にDBの共有に不都合が起きるため、コンテナを分けます。)

Docker自体の概念、Dockerfileの作り方、docker-composeについては次の記事が参考になります。

いまさらDockerに入門したので分かりやすくまとめます

Dockerコンテナが立ち上がらなくなった場合のトラブルシュートは次の記事が参考になります。

dockerでコンテナが立ち上がらないときやってみること


インストール

OSX前提で以下をインストールします。

Docker for Mac

boot2dockerは非推奨となっています。

あとこちらのほうが仮想化にVirtual Boxを使ってなくて早いらしいです。

インストールするとデスクトップにランチャーが追加されます。

Docker1.png

Docker is runningのステートになるとターミナルからdockerコマンドが使えるようになります。

$docker


よく使うコマンド

詳しくはこちらを参考にしてください

Docker ハンズオン - 基本コマンド編

さらにこの中でも特に使うと思ったコマンドを抜粋します。


  • docker pull:Docker Hubからイメージのダウンロード

  • docker build:Dockerfileからイメージの作成

  • docker images:Dockerイメージの一覧取得

  • docker rmi:Dockerイメージの削除

  • docker ps:Dockerコンテナの起動確認

  • docker run:DockerイメージからDockerコンテナの作成(と起動)

  • docker start:Dockerコンテナの起動

  • docker exec:Dockerコンテナ上の環境に対しコマンド実行

  • docker cp:Dockerコンテナへファイルコピー

  • docker stop:Dockerコンテナの停止

  • docker rm:Dockerコンテナの削除

  • docker commit:DockerコンテナのDockerイメージ化

  • docker push:DockerイメージをDocker Hubにアップロード


Dockerイメージのダウンロード

各種DBのDockerイメージをダウンロードします。(今回使うのはmysqlのみですが)


  • MySQL

  • PostgresSQL

  • Redis

  • MongoDB

Docker Hubと呼ばれるイメージファイルのGitみたいな公開リポジトリからダウンロードします。

イメージファイルのダウンロードにはdocker pullコマンドを使います。

# Mysql

$docker pull mysql
# PostgresSQL
$docker pull postgres
# Redis
$docker pull redis
# MongoDB
$docker pull mongo

次にNginXをのせるアプリサーバ用のイメージを作成します。

今回はCentOS6のイメージをとってきてその上に構築します。

$docker pull centos:6

インストール済みイメージの確認には

docker imagesコマンドでイメージ一覧を表示します。

$docker images

REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 b7dc06006192 9 days ago 385.6 MB
mysql 5.7.15 b7dc06006192 9 days ago 385.6 MB
mysql latest b7dc06006192 9 days ago 385.6 MB
centos 6 f07f6ca555a5 10 days ago 194.6 MB
mongo latest 48b8b08dca4d 2 weeks ago 366.4 MB
redis latest 0d1cbfaa41da 2 weeks ago 185 MB
postgres latest 6f86882e145d 2 weeks ago 265.9 MB


DBサーバコンテナ作成とDB作成


コンテナの作成と起動

次のコマンドでMySQLコンテナの作成と起動を行います。

$docker run -it --name mysql -e MYSQL_ROOT_PASSWORD=password -d mysql:latest

-itは-iオプションと-tオプションの併用です。(interactive+tty)このオプションがないと起動後、一瞬で終了してしまいます。

--nameオプションはDockerコンテナの起動コンテナ名を指定します。

-eオプションで環境変数の設定行います。MYSQL_ROOT_PASSWORDにはrootのパスワードを指定します。

-dオプションはバックグラウンド起動を行います。(イメージ名):(バージョン)を指定します。

起動に成功したかはdocker psコマンドで確認できます。

$docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
550c25522be8 mysql:5.7 "docker-entrypoint.sh" 3 days ago Up 4 seconds 3306/tcp mysql

ちなみに-aオプションをつけると全ての作成済みdockerコンテナが確認できます。(停止中のコンテナ含めて表示されます。)

$docker ps -a


コンテナの起動と停止(2回目以降)

2回目以降はdocker startでコンテナ起動、docker stopでコンテナ停止を行います。

# コンテナ起動

$docker start (コンテナ名)
# コンテナ停止
$docker stop (コンテナ名)


コンテナにログイン

docker execコマンドでmysqlコンテナにログインします。

$docker exec -it mysql bash

docker exec -it (コンテナ名) bash

とすることで指定のコンテナのbash(シェル)を起動する(ログインする)ことができます。

ログイン後、DBの作成を行います。(ここではdbというデータベースを作成します。)

#mysql -u root -p

Enter password:password
mysql>create database db;
mysql>show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.01 sec)
mysql>exit;
#exit


アプリサーバコンテナにNginXとDBクライアントをインストール

CentOSのmycentosコンテナを作成と起動し、ログインします。

$docker run -it --name mycentos -d centos:6

ログイン後、NginXと各種DBクライアントをインストールします。

# NginX

$rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
$yum install -y nginx
# MySQL
$yum install -y mysql
# PostgresSQL
$yum install -y postgresql
# Redis
$rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
$yum --enablerepo=epel install -y redis
# MongoDB
$echo -e "[mongodb]" > /etc/yum.repos.d/mongodb.repo
$echo -e "name=MongoDB Repository" >> /etc/yum.repos.d/mongodb.repo
$echo -e "baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64" >> /etc/yum.repos.d/mongodb.repo
$echo -e "gpgcheck=0" >> /etc/yum.repos.d/mongodb.repo
$echo -e "enabled=1" >> /etc/yum.repos.d/mongodb.repo
$yum install -y mongodb-org
$exit


コンテナを保存する


コンテナのDockerイメージ化

docker psコマンドにて起動コンテナのmycentosのCONTAINER IDを確認します。

$docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8be3061220cc centos:6 "/bin/bash" 8 seconds ago Up 6 seconds mycentos
550c25522be8 mysql:5.7 "docker-entrypoint.sh" 3 days ago Up 33 minutes 3306/tcp mysql

docker commitにて指定のコンテナをDockerイメージ化します。

次のようなフォーマットで保存します。

docker commit (コンテナID) (ユーザ名)/(イメージ名):(バージョン)

$docker commit 8be3061220cc myuser/centos:1.0

保存後、docker imagesで確認すると追加されています。

daikiterai$ docker images

REPOSITORY TAG IMAGE ID CREATED SIZE
myuser/centos 1.0 ccfb04ce118d 7 hours ago 656.1 MB
(略)

このようにdocker commitでイメージを作る他にDockerfileというファイルに

OSやミドルウェアのインストール手順を記載することも可能です。

詳細は効率的に安全な Dockerfile を作るにはが参考になります。

Dockerfileからイメージを作成するにはdocker buildコマンドを使います。


Dockerイメージの削除

余力があったら次の例のようにMySQLのコンテナの方も定期的にイメージ化してバックアップを取ると良いでしょう。(イメージ化することでデータ丸ごとバックアップが取れます。)

古いバージョンのイメージはdocker rmiコマンドで消せます。

$docker commit 550c25522be8 myuser/mysql:1.0

# バージョンアップ時
$docker commit 550c25522be8 myuser/mysql:2.0
# 古いやつは消す
$docker rmi myuser/mysql:1.0


コンテナの削除

無事イメージ化したので一旦コンテナを削除します。

$docker rm -f 8be3061220cc

もしくは
$docker rm -f mycentos

-fオプションは強制的に行うオプションです。

docker psコマンドで確認すると指定のコンテナが削除されます。

$ docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
550c25522be8 mysql:5.7 "docker-entrypoint.sh" 3 days ago Up About an hour 3306/tcp mysql


DockerイメージをDocker Hubにアップロードする

まず先にDocker Hubのアカウントを作成しておいてください。

アカウント作成後、docker loginコマンドにてログインします。

$docker login

Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: (ユーザ名)
Password: (パスワード)

Login Succeeded

ログイン成功したらdocker pushコマンドでイメージのアップロードができるようになります。

$docker push (イメージ名)

成功するとDocker Hubのリポジトリにアップロードされます。

dockerhub.png

イメージのダウンロードは他のイメージ同様

docker pullコマンドでダウンロードできます。

$docker pull (イメージ名)


アプリサーバコンテナからDBサーバコンテナにアクセスする


コンテナ結合&ポートフォワーディング指定でコンテナ作成

先ほど作ったイメージでtestappコンテナを作成し起動させます。

$docker run -it --name testapp --link mysql:mysql -d -p 8080:80 myuser/centos:1.0 

--linkオプションは結合するコンテナの指定です。(リンクしたいコンテナ名):(エイリアス)で指定します。エイリアスは環境変数にマッピングされるプレフィックスとなります。

-pオプションはポートフォワーディングの指定です。外部から指定したポートをコンテナ内部のポートに転送する指定を行います。(転送元ポート):(転送先ポート)

複数のポートフォワーディングをしたい場合は複数指定します。

-p 80:80 -p 443:443

testappコンテナにログインします。

$docker exec -it testapp bash

envコマンドで確認するとMySQLコンテナの環境変数(エイリアス名:MYSQL_*)が追加されます。

#env

(中略)
MYSQL_NAME=/centos/mysql
MYSQL_PORT_3306_TCP_PROTO=tcp
MYSQL_PORT_3306_TCP_ADDR=172.17.0.2
LESSOPEN=||/usr/bin/lesspipe.sh %s
MYSQL_ENV_MYSQL_MAJOR=5.7
MYSQL_PORT=tcp://172.17.0.2:3306

mysqlクライアントでDBサーバコンテナ側のMySQLにアクセスできれば成功です。

# mysql -u root -p -h $MYSQL_PORT_3306_TCP_ADDR

Enter password:password
mysql>


外部からアプリサーバ(NginX)へのアクセスを確認する

testappコンテナ内のNginXを起動します。

$nginx

ブラウザから下記URLを指定

http://localhost:8080

コンテナ内のNginXの80ポートに転送されていれば成功です。

nginx.png

コンテナのネットワークに関してもっと知りたい場合は下記を参考に

Docker の基本学習 ~ コンテナ間のリンク

参考訳:Docker コンテナ・ネットワークの理解


Dockerコンテナへのファイルコピー

Dockerコンテナ間のファイル転送にはdocker cpコマンドを使います。

ファイル数が多い時はSSHポート(25番ポート)をフォワーディングして

sshfsでマウント(共有フォルダ化)してしまったほうが早いかもしれません


ローカルからDockerコンテナへファイルコピー

次のようなフォーマットになっています、

docker cp (ローカルのコピー元パス) (コンテナ名):(コンテナのコピー先パス)

test.txtをtestappコンテナにコピーしたい場合

$docker cp ~/Desktop/test.txt testapp:test.txt


Dockerコンテナからローカルへファイルコピー

Dockerコンテナへのコピーと逆です。

docker cp (コンテナ名):(コンテナのコピー元パス) (ローカルのコピー先パス)

$docker cp testapp:test.txt ~/Desktop/test2.txt

ちなみにコンテナ同士のコピーは直接はできないようです。