Docker構築メモ

iOS用のサーバ環境をDockerでローカルに構築した時のメモ。

なお、ローカルの開発用ということでセキュリティは考慮していないので注意

要件

主にAPIでサーバとやりとりするアプリの開発用なので以下の感じ

環境

構成イメージ

Mac   (192.168.0.2) == ルータ(192.168.0.1) == iPhone(192.168.0.3)  
|  
VM    (192.168.99.1)  
|  
Docker(192.168.99.100)

()内はIPアドレス

ゴールは、iPhone上からhttps://192.168.0.2へアクセスするとページが表示(APIの通信)できればOK。

Mac上(ホストOS)

Docker上(ゲストOS)

手順

Dockerのインストール

  1. 公式からDockerToolBoxをダウンロードしてインストールを実行
  2. 途中でDocker Quickstart Terminalのアイコンがでてきたら起動させる
    (忘れたらアプリケーションにもあるのでそちらから)
  3. すると勝手にVM作成やらネットワーク設定をしてくれる親切設計なのでクジラが出てくるまで待つ

DockerComposeの設定

Dockerはコンテナをパーツのように組み合わせて環境を作っていく。

そのコンテナを作成する際の基本的な流れは

  1. 使いたいもののイメージを見つける
    (無ければDockerfileを自力で書く)
  2. タグを指定してイメージをダウンロード
  3. コンテナの作成
    (もし足りない設定などあればDockerfileでカスマイズ)

となる。

イメージの検索からコンテナの取得は公式GUIのKitematic (Beta)を使うと一気にしてくれるので便利。

ただ、この方法だと引数の指定が多かったり複数のコンテナを利用する場合は大変なので、 DockerComposeを用いて管理する。

事前準備

まずは適当な場所に、コンテナ毎のDockerfileや設定ファイルなどを まとめておくディレクトリを作ってカレントディレクトリとする。 今回のディレクトリ構成は、以下のようにする。

docker
 ├─ docker-compose.yml
 ├─ mariadb              # MariaDB用のフォルダ
 |   └─ my.cnf
 ├─ php                  # PHP用のフォルダ
 |   ├─ Dockerfile
 |   └─ php.ini
 └─ www                  # Apacheのドキュメントルート
     └─ index.html       # 動作確認用のHTML

Apache+PHP

ApacheはPHPに同梱されているものを使うのが便利なので、apacheがついているタグのものを使う。 今回は公式で5系の一番新しいバージョンの5.6.18-apacheを選択。

で、php.iniの設定と追加で入れたい拡張モジュール(特にXdebug)をDockerfileでカスタムしておく。

DockerComposeの設定

php:
  build: ./php/        # php/Dockerfileからビルド
  ports:
    - "80:80"         # 80ポートを公開
  volumes:
    - ./www:/var/www/html   # ドキュメントルートを指定
  links:
    - mariadb:mysql         # DBとの接続を指定
  container_name: php

これでMac上からは、http://192.168.99.100/index.htmlへアクセスすると、 www/index.htmlが表示される。

MariaDB+phpMyAdmin

特に変更点もないのでイメージは公式の最新をそのままを使う。

DockerComposeの設定

mariadb:
  image: mariadb:latest           # 常に最新版を使う
  environment:
    MYSQL_ROOT_PASSWORD: pass     # ルートのパスワード
    MYSQL_DATABASE: docker        # DB名
    MYSQL_USER: docker            # ユーザ名
    MYSQL_PASSWORD: docker        # パスワード
  volumes:                        # my.cnfの設定
    - ./mariadb/my.cnf:/etc/mysql/conf.d/my.cnf
  container_name: mariadb

phpmyadmin:
  image: phpmyadmin/phpmyadmin:latest
  container_name: myadmin
  ports:
    - "8080:80"                   # 8080ポートを公開して80へフォワード
  links:
    - mariadb:db

これでMac上からは、http://192.168.99.100:8080へアクセスすると、 phpMyAdminのログイン画面が表示され、docker/dockerでログインが可能。

注意点としてこの状態ではDBの永続化はできていないので、コンテナを削除するとDBの内容も消える

iOS端末からのアクセス

ここまでの状態だとMacからしかアクセスできないので、Mac上でnginxをリバースプロキシとして動かし、 他のiOS端末からアクセスできるようにする。

また、iOS9のATSへ対応する為にSSLでアクセスできるようにする。ただしローカル環境なのでオレオレ証明書を利用する。

nginxのインストール

Homebrewでインストールする。

brew update
brew install nginx

インストールできたら、

nginx -t

で設定ファイルの場所を確認し、適当なエディタで開いてリバースプロキシの設定をする。 コメントにしてあるのがデフォルトの設定。

http {
  server {
    #listen       8080;
    listen       80;
    location / {
      # root   html;
      # index  index.html index.htm;
      proxy_pass http://127.0.0.1:8080;
    }
  }
}

SSLの証明書について

今回はnginx部分だけSSLに対応させる。(dockerはHTTPのまま)

オレオレ証明書作成のiOS向けの設定のポイントは、

もし、上の条件が満たせない場合は、ATSの設定を変えるとか個別に認証処理を書くなどして回避する必要がある。 (回避できないのもあるけど)

SSLの証明書の作成

openssl genrsa -out server.key 2048
openssl req -new -key server.key > server.csr
openssl x509 -days 3650 -sha256 -req -signkey server.key < server.csr > server.crt

(オレオレ証明書の各項目はCommonName以外は空白でも動作する)

生成されたserver.keyserver.crtをnginxの設定ファイルと同じディレクトリに置く。

iOS端末へはserver.crtをインストールする。 (メール添付か適当なWEB上に置いてインストール)
※環境によってうまくいかないことがあったので、より確実な構成プロファイル経由にすること (手順はATS有効の状態でオレオレ証明書を使って通信する(iOS9)を参照)

nginxの設定ファイルに以下を追加する。

server {
  listen       443 ssl;
  server_name  localhost;

  ssl_certificate      server.crt;
  ssl_certificate_key  server.key;

  location / {
    proxy_pass http://127.0.0.1:8080;
  }
}

VMの設定

DockerはVirtualBox上で動いているので、VMのポートフォワードを設定が必要となる。 設定は、

VBoxManage controlvm "default" natpf1 "nginx,tcp,127.0.0.1,8080,,80"

とする。VirtualBoxを起動して、default-設定-ネットワーク-アダプター1-ポートフォワーディングからでもOK。

起動

  1. Dockerを起動させる
  2. docker-compose.ymlを置いた場所をカレントディレクトリにする
  3. docker-compose up -dでコンテナを起動
  4. sudo nginxでnginxを起動

これでiPhone上からは、https://192.168.0.2/index.htmlへアクセスすると、 www/index.htmlが表示される。 (ただし、オレオレ証明書なので認証の警告などは出る)

追記

Docker起動時に

ERROR: Couldn't connect to Docker daemon - you might need to run `docker-machine start default`.

というエラーが出る場合は、VMの設定の

VBoxManage controlvm "default" natpf1 "nginx,tcp,127.0.0.1,8080,,80"

をしてから起動し直すと大丈夫っぽい。なお、原因は不明・・・

感想

開発環境をプラグインみたいな感じで構築していけるのと構築内容がテキストで残るのはあとあと楽。

ただ、サーバ環境とまるまる同じものを構築するならVagrantの方が良いのかも・・・ でも、Dockerはいろいろな環境を次々に試すのには便利なので、使い分けが大事そう。

ファイル一式

実際の各イメージのDockerfileや設定ファイルをまとめたものは こちら