はじめに
Docker + Laravelの環境構築はQiitaに溢れているのですが、Docker + Symfonyの記事はあまり見当たらなかったので記事にしました。(と言ってもほぼLaravelと変わらないですが)。
Docker初心者なので、各種設定などを備忘録として細かく解説していこうと思います。
構成
ホスト環境
ツール | バージョン |
---|---|
Mac macOS | Catalina 10.15.5 |
docker-compose | 1.25.5 |
docker-sync | 0.5.14 |
構築環境 (ゴール)
- PHP 7.4
- mysql 5.7
- Apache
- Symfony 5
ディレクトリ構成
appディレクトリにsymfonyのソースコードを配置します。注意点としてルートにある.env
はSymfonyの.env
とは異なります。
project/
├ app/
├ docker/
│ ├ apache/
│ │ └ my_app.conf
│ ├ php/
│ │ └ php.ini
│ └ Dockerfile
├ .env
├ docker-compose.yaml
└ docker-sync.yaml
必要なツール類のインストール
Homebrewを使って、ホスト環境に必要なツール類をインストールします。
docker
$ brew install docker
$ brew cask install docker
docker-sync
>> ~/.zshrc
のところは環境に合わせて変えてください。
$ brew install ruby
$ echo 'export PATH="/usr/local/opt/ruby/bin:$PATH"' >> ~/.zshrc
$ source ~/.zshrc
$ gem install docker-sync -n /usr/local/bin
docker-composeの設定
version: '3'
services:
app:
container_name: my_app
build: ./docker
ports:
- 8880:80
volumes:
- my_app_symfony:/var/www/html
- ./docker/php/php.ini:/usr/local/etc/php/php.ini
- ./docker/apache/my_app.conf:/etc/apache2/sites-enabled/my_app.conf
depends_on:
- mysql
mysql:
image: mysql:5.7
container_name: my_app_app_mysql
environment:
MYSQL_ROOT_PASSWORD: $DB_ROOT_PASSWORD
MYSQL_DATABASE: $DB_NAME
TZ: 'Asia/Tokyo'
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
ports:
- 3306:3306
volumes:
my_app_symfony:
external: true
解説
docker-composeは複数のDockerコンテナをまとめて管理するツールです。docker-compose.yaml
のservices
の下に各種コンテナの設定を記述します。
app
には、WEBサーバーとして動作するコンテナの設定を記述してあります。container_name
のmy_appは好きな値に書き換えて大丈夫です。
build: ./docker
と記述することでdocker/Dockerfileの内容にしたがってビルドを行います。
ports
にはコンテナで立ち上げたプロセスのどのポートをローカルのどのポートにバインドするかと言う設定を記述します。ローカル:コンテナの順で記述するので、今回はローカルの8880ポートをコンテナの80ポートへバインドする、と言う意味です。http://localhost:8880 へリクエストを送ると、コンテナ内の80ポートへリクエストが転送されます。
volumes
にはローカルにあるファイルやディレクトリをコンテナと同期する場合に記述します。volumes
の2,3行目はローカルのphp.iniとmy_app.confをコンテナと同期する設定が記述してあります。1行目は、appディレクトリにあるローカルのsymfonyのプロジェクトをコンテナの/var/www/html
と言うように記述してありますが、symfonyのソースコードは量が多く普通に同期するとパフォーマンスが落ちるので後述するdocker-syncを用いて同期を行います。ここでは、一番下に記述してあるvolumes
の項目で(docker-syncで作成された)外部のボリュームを定義し、それにmy_app_symfony
と言う名前をつけています。app
コンテナのvolumes
のローカルの方にはこのmy_app_symfony
を指定します。
mysql
にはDBとして使用するmysqlコンテナの設定が記述してあります。こちらはDockerfileを用いず、あらかじめ公開されているイメージを使用します。イメージはDockerhubなどで検索することができます。Dockerhubのmysqlのページにドキュメントがあるのですが、コンテナを作成する時に特定の環境変数を渡すことで各種設定を行うことができます。環境変数はenvironment
に書くことで渡すことができ、今回はMYSQL_ROOT_PASSWORD
、MYSQL_DATABASE
、TZ
の三つを使用していますです。役割は名前から推測できると思うので割愛します。また、このファイルに変数の値をベタがきしても良いのですが、今回は柔軟性を持たせるためにローカルの環境変数から値を取得してくるようにしています(ややこしい)。ルートディレクトリにある.env
ファイルに
DB_ROOT_PASSWORD=root
DB_NAME=app_db
と言うように書いておくことで、コンテナ作成時にdocker-compose.yaml
無いの変数を書き換えてくれます。
command
にはコンテナ作成時にコンテナ内で実行されるコマンドを記述することができます。
/docker ディレクトリ
memory_limit = 2048M
date.timezone = "Asia/Tokyo"
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html/my_app/public
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
FROM php:7.4-apache
RUN a2dissite 000-default
WORKDIR /var/www/html
RUN apt-get update && apt-get install -y git zip unzip
RUN apt-get install -y wget libjpeg-dev libfreetype6-dev
RUN apt-get install -y libmagick++-dev \
libmagickwand-dev \
libpq-dev \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
libwebp-dev \
libxpm-dev
RUN docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/
RUN docker-php-ext-install -j$(nproc) gd
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && mv /usr/bin/composer.phar /usr/bin/composer
解説
php.ini
とmy_app.conf
には特殊なことは書いていません。必要に応じて編集してください。
Dockerfile
にはコンテナをどのようにビルドするかと言う手順を記述します。
1行目のFROM
にはコンテナの元となるイメージを指定します(Dockerhubで検索)。RUN xxxx
とすると、コンテナ内でxxxx
を実行します。注意点として、RUN
コマンドで実行した結果は次のRUN
コマンドへは引き継がれませんので、cd
などでディレクトリ移動したのに何故かファイルが無い!!見たいなことが起こります。結果を引継ぎたい時は&&
でコマンドを続けて指定します。
2行目以降ではApacheのデフォルトサイトを無効化し、php
のgd拡張のインストール及び、composer
のインストールを行っています。WORKDIR /var/www/html
では作業ディレクトリを/var/www/html
に設定しています。
docker-syncの設定
version: '2'
syncs:
my_app_symfony:
src: './app'
sync_host_ip: '127.0.0.1'
sync_host_port: '5000'
sync_strategy: 'native_osx'
sync_excludes: ['.git', '.gitignore', 'node_modules']
解説
syncs
の中に各種ボリュームの定義を記述します。my_app_symfony
のところはdocker-compose
のvolumes
で指定したボリューム名と一致させます。
src
には同期させるディレクトリを指定し、sync_host_ip
とsync_host_port
それぞれホストのIPトポートを指定します。sync_strategy
は、色々あるようですが、とりあえずnative_osx
で問題無いと思います(よくわかってない)。sync_excludes
には同期しないファイル、ディレクトリを指定します。node_modules
など量が多くPHPで使用しないソースコードなどは同期しない方が無難だと思います。
起動
※ 8880ポート、8888ポート、5000ポート、3306ポートを使用するので、これらを使用しているソフトがある場合は停止しておいてください。
$ docker-sync start
$ docker-compose up -d --build
この時点で各種コンテナが起動します。
続いて、コンテナへ入りcomposer
を用いてsymfonyのプロジェクトを作成します。コンテナからはexit
で抜けられます。
# appコンテナでbashを実行
$ docker-compose exec app /bin/bash
# コンテナ内
root@eb419aab1d32:/var/www/html# composer create-project symfony/skeleton my_app
ローカルのブラウザから http://localhost:8880 へアクセスするとsymfonyの画面が表示されていると思います!
各種操作
# コンテナの終了
$ docker-compose stop
# コンテナの再開
$ docker-compose start
# composer install
$ docker-compose exec app composer install
以上!