Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

いまさら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

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

teradonburi
気管支喘息を患って死にかけです。 いつ死ぬかわかりません。 成人喘息は誰でもなりえるものだし、 咳喘息から気管支喘息に進行すると慢性的な死の危険があるものです。 自身や周りで数週間咳が続いてる人がいたら気をつけて・・・ Twitterフォローいただけたらフォロバします。 https://twitter.com/teradonburi
meetsmore
プロを探せる見積りプラットフォーム「ミツモア」の開発・運営
https://meetsmore.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした