こんにちイワンコフ。
奥さん、おたくの旦那さん朝の9時ごろに公園のベンチで黄昏てるとこ見ましたよ。
今回は以前にも少し触れたDockerを勉強したいと思います。
今まではXAMPPで開発環境を構築していましたが、時代の波がやっと僕にも押し寄せてきたのでDockerを使って開発環境を構築していこうと思います。
Dockerをインストール
まずはDocker for Windowsのインストールから。
必要条件があるので注意してください。
また、Dockerのアカウントも作成する必要があります。
- Window10 pro 64bit
- VirtualBoxなどの仮想化環境をインストールしていない(調べたらVirtualBox6.0からHyper-vと共存が可能らしいです)
- Hyper-vを有効にしている
- メモリ4GB以上
満たしてない時はDocker Toolboxというものがあるのでそちらをインストールしてください。
インストールできたらデスクトップにクジラのアイコンができていると思うのでそれを起動しましょう。
そしてPowerShellを開いてちゃんとインストールできるか確認してみます。
PS C:\Users\ユーザー名> docker --version
Docker version 18.09.2, build 6247962
このようになっていればインストールは完了です。
pythonを動かそう
DockerにはまずDockerイメージというものがあってそのDockerイメージをもとにDockerコンテナというものを作成し起動します。
料理で例えるとイメージはレシピ、コンテナは完成した料理といったとこでしょうか。
なんせ流れとしてはイメージを作成してそれをもとにコンテナを作って起動するノリです(笑)
雰囲気を掴むためかるくやってみましょう
PS C:\Users\ユーザー名> docker pull python
Using default tag: latest
latest: Pulling from library/python
5ae19949497e: Pull complete
ed3d96a2798e: Pull complete
f12136850781: Pull complete
1a9ad5d5550b: Pull complete
6f18049a0455: Pull complete
ce39fa9d79d1: Pull complete
3a91ffcf88ea: Pull complete
ee82cc8e1506: Pull complete
bf0dbf90a115: Pull complete
Digest: sha256:87fd2bad3de70a5e779a91d7e2ec2bd01115dfe3faf97dacf730a7f4155d11d8
Status: Downloaded newer image for python:latest
pythonのイメージを作成してみました。
作成といってもDocker Hubという公式イメージ集からプルしてきただけです。(実はこのプル作業ですこしハマってます。最後に解決策をのせときます)
PS C:\Users\ユーザー名> docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
python latest 42d620af35be 39 hours ago 918MB
無事イメージが作成されていることを確認できました。
次にコンテナの作成と起動をしてpythonを使ってみます。
PS C:\Users\ユーザー名> docker container run -it --name spam python /bin/bash
root@aec5013cf366:/# python --version
Python 3.7.4
root@aec5013cf366:/# python3
Python 3.7.4 (default, Jul 13 2019, 14:04:11)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
おなじみの対話モードです。
雰囲気はこんな感じです。イメージを作ってコンテナを作り起動するイメージはつかめました。(ここでイメージとか言うとややこいぞ)
コマンドの意味は
docker container run
がコンテナの作成と起動--it
は-i
がコンテナの標準出力を開く、-t
が端末デバイスを確保するという意味だそうです。とりあえずおまじないとして覚えておきます。--name spam
は作成するコンテナ名python
はイメージ名\bin\bash
はコンテナ内で実行するコマンド
イメージ名を元にspam
という名前のコンテナを作り、そのコンテナ内でbash
で実行することでLinuxサーバのようにコマンド操作ができる感じ?
PS C:\Users\ユーザー名> docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d7084f15ef19 python "python3" About a minute ago Exited (0) About a minute ago spam
上記のコマンドでコンテナが作成されていることがわかります。
Webサーバを動かそう
次にwebサーバを動かしてみましょう。今回はNginxというサーバを動かしてみたいと思います。
まずはイメージをダウンロードします。
PS C:\Users\ユーザー名> docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
fc7181108d40: Pull complete
d2e987ca2267: Pull complete
0b760b431b11: Pull complete
Digest: sha256:48cbeee0cb0a3b5e885e36222f969e0a2f41819a68e07aeb6631ca7cb356fed1
Status: Downloaded newer image for nginx:latest
docker image ls
でイメージが作成されていることを確認した後、サーバを起動します。
PS C:\Users\ユーザー名> docker container run --name webserver -d -p 5000:80 nginx
978a80eda6e32f1ddbb52fcf4a7f4874df8c7573103a666bc38b962e3295cb61
--name
はコンテナ名-d
はバックグラウンドでの実行-p
はポート転送で、ポート番号5000でアクセスしたときコンテナの80番ポートへ転送する仕組みになっています。
localhost:5000
でアクセスして下記のような画面が表示されたら成功です。
laravelを動かそう
では実践的にDockerでLaravelの環境を作ってみたいと思います。Laravel学べるゆうてやっていきましょう!
こちらとこちらを参考にしています
まず適当なディレクトリを作り、イメージのレシピとなるDockerfileを作ります。
構成は下記のようになります。
FROM php:7.2-fpm
# install composer
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer
RUN apt-get update \
&& apt-get install -y \
git \
zip \
unzip \
vim
RUN apt-get update \
&& apt-get install -y libpq-dev \
&& docker-php-ext-install pdo_mysql pdo_pgsql
WORKDIR /var/www/html
いきまり出てきましたDockerfileですが、これがイメージの全貌となります。先ほどはDocker Hubより直接イメージを取得していましたが、今回はイメージファイルを自前で作成しました。拡張子もなしに単にDockerfileという名前でOKです。
これはPHPのイメージなのですがLaravelを使えるように公式のPHPのイメージをベースにカスタマイズしたものです。(Composerを使えるようにしただけです)
その他Webサーバ(Nginx)やDBサーバ(MySql)も用意しますがそれらは公式のイメージからダウンロードしていきます。
公式のイメージはさておき自作したイメージは先ほどのノリでrun
しても、そんなイメージはないぜ。ブラザー!と怒られてしまいます。
そこでイメージを作成する必要があるのですが、
docker build -t bro-town ./docker/php/Dockerfile
で作成できます。
ここではbro-town
が作成されるイメージ名でその後ろがイメージファイルの指定となっています。
次にphp.ini
とNginxの設定ファイルを用意します。
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"
server {
listen 80;
index index.php index.html;
root /var/www/html/laravel-manavel-app/public;
location / {
root /var/www/html/laravel-manavel-app/public;
index index.html index.php;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
あとは作成したPHPとWebサーバとDBサーバのイメージをひとつずつrun
してコンテナを作成したら無事環境構築完了となります。
では、やっていましょう!
普通そんなことやらないぜ。ブラザー
なんかまたブロコップがでてきましたね。
どうゆうことでしょう?
実はDockerにはdocker-compose
というコマンドがあり、これは作成したイメージのビルド、公式のイメージのダウンロードやコンテナ名の定義などを一発でやってくれる代物です。
ディレクトリ構成をみると`docker-compose.yml`というymlファイルがありますがこれがdocker-compose
するための指示書のようなものです。
version: '3'
services:
php:
container_name: php
build: ./docker/php
volumes:
- ./server:/var/www/html
nginx:
image: nginx
container_name: nginx
ports:
- 5000:80
volumes:
- ./server:/var/www/html
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
db:
image: mysql:5.7
container_name: db-host
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: database
MYSQL_USER: docker
MYSQL_PASSWORD: docker
TZ: 'Asia/Tokyo'
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
volumes:
- ./docker/db/data:/var/lib/mysql
- ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
- ./docker/db/sql:/docker-entrypoint-initdb.d
ports:
- 13306:3306
volumes
というオプションがありますが、これは:を基準に左がローカル、右が仮想環境でファイルを共有するという意味です。
これにより./server
配下にソースを保存すればそこでの変更が仮想環境にも反映されというわけです。(逆もしかり)
ちなみにDBのvolumes
の方ですが、1行目はデータ永続化のためでここでマウントしてないとコンテナを停止したときにDBに保存したデータがなくなってしまいます。
2行目は設定ファイルの共有で、3行はmysqlの公式イメージの機能で./docker/db/sql
配下に保存したsqlやシェルスクリプトがコンテナ起動時に実行されると仕組みなっています。ここにDDLなどを保存するのがよさそうですね。
さてここでdocker-compose up -d
コマンドを実行します。この時docker-compose.yml
があるディレクトリに移動して実行しましょう。
するとイメージ作成が始まります。
コンテナ内を確認しましょう。
PS C:\Users\ユーザー名> docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9bf5afcf468f nginx "nginx -g 'daemon of…" 19 seconds ago Up 15 seconds 0.0.0.0:5000->80/tcp nginx
cefccfce2c96 mysql:5.7 "docker-entrypoint.s…" 19 seconds ago Up 16 seconds 33060/tcp, 0.0.0.0:13306->3306/tcp db-host
6969d42907ce laravel-manavel_php "docker-php-entrypoi…" 5 minutes ago Up 5 minutes 9000/tcp php
php, nginx, db-host 指定した名前のコンテナができています。
次にphp
のコンテナ内に入り、Laravelをインストールしていきます。
プロジェクト名は、ここではlaravel-manavel-appとしましたがなんでも構いません。ただしそれに合わしてdefault.conf
のルートディレクトリも変更してください。
PS C:\Users\ユーザー名\laravel-manevel> docker container exec -it php bash
root@7a36feb581de:/var/www/html# composer create-project --prefer-dist laravel/laravel laravel-manavel-app
ではlocalhost:5000
でアクセスしてみましょう
laravelのデフォルト画面が表示されれば成功です。
あとはDB設定を行えば開発環境が整います。
感想
こいつは便利!
おまけ
プルしたとこでハマった内容
PS C:\Users\ユーザー名> docker pull python
Using default tag: latest
Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
これはDockerの設定画面の下記のDNS Serverを8.8.8.8に設定してDockerを再起動すると直りました。
その次に、
PS C:\Users\ユーザー名> docker pull python
Using default tag: latest
Error response from daemon: Get https://registry-1.docker.io/v2/library/python/manifests/latest: unauthorized: incorrect username or password
といった内容のエラー。これはDockerにログインすることで解決しました。
PS C:\Users\ユーザー名> docker login
Authenticating with existing credentials...
Stored credentials invalid or expired
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