12
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

NIJIBOXAdvent Calendar 2018

Day 20

docker-composeでローカル環境を作った備忘録と直面した問題など

Last updated at Posted at 2018-12-19

今までvagrantでローカル環境を作成していたシステムで、dockerローカル環境を入れてみました!という備忘録です。
docker-composeを使います。

ローカル環境で用意するもの

php5.6
laravel5.1
mysql5.7
apache
phpmyadmin
workspace

バージョン古くね?という声は胸の中にしまっておいてください。

構築に必要な諸々のファイル


├── apache
│   ├── Dockerfile
│   └── php.ini
├── docker-compose.yml
├── .env
└── workspace
    ├── Dockerfile
    └── php.ini

docker-compose.yml

docker-compose.yml
version: '3'

services:

  # ローカルでartisanコマンド打ったりする時用のworkspace
  workspace:
    build: workspace
    container_name: project_workspace
    volumes:
      - ${BASE_DIR}
    command: bash
    environment:
      - STAGE=docker
    depends_on:
      - mysql
      - cache

  # webサーバー。phpもここでインストールして動かす
  apache:
    build: apache
    container_name: project_apache
    volumes:
      - ${BASE_DIR}
    ports:
      - 8080:80
    environment:
      - STAGE=docker

  # ローカルで使うDB
  mysql:
    image: mysql:5.7
    container_name: project_mysql
    ports:
      - '3307:3306'
    environment:
      - MYSQL_DATABASE=db
      - MYSQL_USER=dbuser
      - MYSQL_PASSWORD=password
      - MYSQL_ROOT_PASSWORD=root
    volumes:
      - project_mysql:/var/lib/mysql

  # GUIでDB見る時用のPhpMyadmin(MySQLworkbenchとか使うなら必要ない)
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: project_phpmyadmin
    environment:
      - PMA_HOST=project_mysql
      - PMA_USER=dbuser
      - PMA_PASSWORD=password
    ports:
      - "3333:80"

  # キャッシュサーバー
  cache:
    image: memcached
    container_name: project_cache

volumes:
    project_mysql:
        driver: "local"

.env


COMPOSE_PROJECT_NAME=project

BASE_DIR=../:/var/www/html

apache/Dockerfile


FROM php:5-apache

RUN apt-get update && apt-get install -y unzip libmemcached-dev zlib1g-dev
RUN docker-php-ext-install mysqli pdo_mysql
RUN pecl install memcached-2.2.0 && docker-php-ext-enable memcached
RUN cp /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/
ENV APACHE_DOCUMENT_ROOT /var/www/html/public

RUN sed -ri -e 's!/var/www/html!/var/www/html/public!g' /etc/apache2/sites-enabled/*.conf
RUN sed -ri -e 's!/var/www/!/var/www/html/public!g' /etc/apache2/apache2.conf /etc/apache2/conf-enabled/*.conf
COPY php.ini /usr/local/etc/php/
RUN echo "date.timezone = Asia/Tokyo" >> /usr/local/etc/php/php.ini

workspace/Dockerfile


FROM php:5

RUN apt-get update && apt-get install -y unzip libmemcached-dev zlib1g-dev
RUN docker-php-ext-install mysqli pdo_mysql
RUN pecl install memcached-2.2.0 && docker-php-ext-enable memcached
RUN curl -sS https://getcomposer.org/installer | php; mv composer.phar /usr/local/bin/composer ; mkdir /var/dev

RUN mkdir /var/www && mkdir /var/www/html
COPY php.ini /usr/local/etc/php/
RUN echo "date.timezone = Asia/Tokyo" >> /usr/local/etc/php/php.ini

WORKDIR /var/www/html

CMD ["bash"]

構築手順

docker、docker-composeを使えるようにする

参考:https://qiita.com/zembutsu/items/dd2209a663cae37dfa81

composeディレクトリの中でコンテナを立ち上げる

cd (docker-compose.ymlが入ってるディレクトリ名)
docker-compose up -d apache mysql phpmyadmin cache

ローカル環境でartisanコマンドを使うとき

以下のコマンドでworkspaceに入りその中で行う

docker-compose run workspace

構築途中で直面した問題

php.iniのtimezone設定漏れによるエラー

php.iniのtimezoneを指定しないと、以下のようなエラーが表示され、ページが表示されません。

Error - date_default_timezone_get(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in COREPATH/classes/fuel.php on line 161

そこで、apacheのDockerfileと同じ階層にデフォルトのphp.iniを置き、Dockerfileに以下を追記しました。


COPY php.ini /usr/local/etc/php/
RUN echo "date.timezone = Asia/Tokyo" >> /usr/local/etc/php/php.ini

これで実行時点で動作させる対象となるイメージが存在する場合は
docker-compose up -d --build を、
存在しない場合は
docker-compose up -d を実行すると、
apacheコンテナ(サーバー)作成時にphp.iniが作成されtimezoneも追記されます。
ちなみにイメージの確認は docker images で可能です。

php.iniを直接書き換えてtimezoneを設定すれば
RUN echo "date.timezone = Asia/Tokyo" >> /usr/local/etc/php/php.ini する必要もないですが、
私はめんどくさかったのでこっちを採用しましたー。

ホスト名指定によるローカル環境判断ができない

vagrantでローカル環境を用意していた際はホスト名を gethostname() で指定して今動いてるシステムがローカル環境上のものかどうか判断する、といった処理をしていたのですが、
dockerで環境構築すると同じようなことができませんでした。
そこでdocker-compose.ymlのファイルを変え、apacheコンテナ(サーバー)のイメージ作成時に環境変数を指定し、この環境変数があればローカル環境、といった判断ができるようにしました。

docker-compose.yml
  apache:
    build: apache
    container_name: project_apache
    volumes:
      - ${BASE_DIR}
    ports:
      - 8080:80
    environment:
      - STAGE=docker

environmentのところで設定しています。

ちなみにPHP側で判別するときは以下みたいな感じです。

app.php
if (env("STAGE") == "docker") {
  echo 'ローカル環境で動いています!';
}

php-apacheコンテナからmemcachedコンテナ、mysqlコンテナに繋げられない

laravelプロジェクト上の .env でmemcachedコンテナ、mysqlコンテナに繋ぎたくても DB_HOST やら MEMCACHED_HOST やらに何を記載したらいいのかよくわからず…

と路頭に迷っていたところ、

docker-compose.ymlで宣言したサービスは、docker-compose upなどでコンテナ起動すると、同一のネットワークに所属することになる(Dockerネットワークと呼ぶ)。そして、それぞれホスト名が割り当てられる。そのホスト名はサービス名、もしくはdocker-compose.ymlで指定したコンテナ名となる。

docker-composeとネットワーク、コンテナのホスト名の割り当てなどを理解するより引用)

とのこと!
つまり、ここで立てられた apache , mysql , cache などのコンテナは全て同じネットワーク上に存在していることになり、
ホスト名(=コンテナ名)とポートで指定することで同ネットワーク上の別コンテナに接続ができるそうです。

コンテナ名は docker-compose.yml 内で container_name として指定したもののことです。
docker psNAMES として出てきます。
また、指定しない場合でも、サービス名を指定することで接続できます。

今回のケースでは .env に以下のように設定することでmemcachedコンテナ、mysqlコンテナへ繋がります。


DB_CONNECTION=mysql
DB_HOST=project_mysql
DB_PORT=3307
DB_DATABASE=db
DB_USERNAME=dbuser
DB_PASSWORD=password

MEMCACHED_HOST=project_cache
MEMCACHED_PORT=11211

PhpStorm/MySQLworkbenchがMySQLコンテナに繋がらない

docker ps で出てきた情報を元に、以下で接続しようとしても繋がりません。。

hostname: 127.0.0.1
port: 3306
username: dbuser
password: password

というのも、 docker-compose.ymlmysql 部分でportを指定していなかったのが原因でした。
以下みたいに設定してみることで繋がりました。

docker-compose.yml
  mysql:
    image: mysql:5.7
    container_name: project_mysql
    ports:
      - '3307:3306'
    environment:
      - MYSQL_DATABASE=db
      - MYSQL_USER=dbuser
      - MYSQL_PASSWORD=password
      - MYSQL_ROOT_PASSWORD=root
    volumes:
      - project_mysql:/var/lib/mysql
      
volumes:
    project_mysql:
        driver: "local"

他のシステムのローカル環境等でMySQLのportを3306にすることが多いので、3307にしてみました。
これで以下の情報で繋がるはずです。

hostname: 127.0.0.1
port: 3307
username: dbuser
password: password

ports の右側はコンテナ側のportで、左側はホストマシン側(ローカル)のポートだそうです。
ちなみに、volumesを設定しないとコンテナをdownすると同時に中身のデータまで吹っ飛びます。
忘れずに設定してローカルのディレクトリとMySQLコンテナのデータ領域をマウントしましょう。

導入してみて

やっぱりvagrantと比べてずっと容量も軽いし、開発もしやすくなりましたー。
面倒でも古い環境からモダンな環境に移行してみることが大事ですね。
dockerは勉強すればするほどこんなにシンプルで簡単なの!?と思わされることばかりですね。

勉強中の身なので、おかしい部分などあればご指摘いただけると幸いです!

12
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?