laravelを試したいために、手っ取り早い方法としてLaradockを使ってみようと思います。
下準備
work用のディレクトリ作成
% mkdir -p ~/study/laravel/laraveltest
% cd $_
% mkdir testapp
laradock
docker使ってよしなに開発サーバ用意してくれるものという理解。
redisとかsolrとかnginxとかapacheとかmysqlとかphpmyadminとか用意されていて簡単にサーバを作ることができる。
今回はAPサーバとDB使ってみる
- nginx
- mysql
まずはここらへん見ながら
http://laradock.io/getting-started/
既存のプロジェクトにlaradock導入する場合こんな感じでやるといいらしい
└── project-a
└── laradock-a
今回はイチから作ろのでこういう構成でやってみる。先にtestappディレクトリだけ作っておいた。
~/study/laravel/laraveltest
├── laradock
└── testapp
laradockセットアップ
% git clone https://github.com/laradock/laradock.git
% cd laradock
アクセスするドメインを変更したいならconfファイルに指定するとのこと。変更しないけどデフォルトの設定、server_name、root、indexらへんは確認しておこうか
nginx/sites/default.conf
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name localhost;
root /var/www/public;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_pass php-upstream;
fastcgi_index index.php;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#fixes timeouts
fastcgi_read_timeout 600;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt/;
log_not_found off;
}
}
laradockの設定
.envファイル作成。サンプルがあるのでそれを ベースに使おう。
% cp env-example .env
この.envファイルって何?どう使われているの?
docker-compose.ymlで使われているのでしばらくするとわかると思います。
アプリケーションのディレクトリを指定。APP_CODE_PATH_HOSTをtestappに変更
% vi .env
#APP_CODE_PATH_HOST=../
APP_CODE_PATH_HOST=../testapp/
workspaceコンテナの起動
composerやらnodeやらlaravelの開発に必要なものが入っているコンテナ。
% docker-compose up -d workspace
中身はどうなってるかというと、docker-compose.ymlをみてあげればなんとなくわかる。他に立ち上げることができるコンテナにどんなものがあるのかもわかる。
% cat docker-compose.yml
・・・
### Workspace Utilities ##################################
workspace:
build:
context: ./workspace
args:
- PHP_VERSION=${PHP_VERSION}
- INSTALL_XDEBUG=${WORKSPACE_INSTALL_XDEBUG}
- INSTALL_BLACKFIRE=${INSTALL_BLACKFIRE}
- INSTALL_SOAP=${WORKSPACE_INSTALL_SOAP}
- INSTALL_LDAP=${WORKSPACE_INSTALL_LDAP}
- INSTALL_IMAP=${WORKSPACE_INSTALL_IMAP}
- INSTALL_MONGO=${WORKSPACE_INSTALL_MONGO}
- INSTALL_AMQP=${WORKSPACE_INSTALL_AMQP}
- INSTALL_PHPREDIS=${WORKSPACE_INSTALL_PHPREDIS}
- INSTALL_MSSQL=${WORKSPACE_INSTALL_MSSQL}
- INSTALL_NODE=${WORKSPACE_INSTALL_NODE}
- NPM_REGISTRY=${WORKSPACE_NPM_REGISTRY}
- INSTALL_YARN=${WORKSPACE_INSTALL_YARN}
- INSTALL_DRUSH=${WORKSPACE_INSTALL_DRUSH}
- INSTALL_DRUPAL_CONSOLE=${WORKSPACE_INSTALL_DRUPAL_CONSOLE}
- INSTALL_AEROSPIKE=${WORKSPACE_INSTALL_AEROSPIKE}
- INSTALL_V8JS=${WORKSPACE_INSTALL_V8JS}
- COMPOSER_GLOBAL_INSTALL=${WORKSPACE_COMPOSER_GLOBAL_INSTALL}
- COMPOSER_REPO_PACKAGIST=${WORKSPACE_COMPOSER_REPO_PACKAGIST}
- INSTALL_WORKSPACE_SSH=${WORKSPACE_INSTALL_WORKSPACE_SSH}
- INSTALL_LARAVEL_ENVOY=${WORKSPACE_INSTALL_LARAVEL_ENVOY}
- INSTALL_LARAVEL_INSTALLER=${WORKSPACE_INSTALL_LARAVEL_INSTALLER}
- INSTALL_DEPLOYER=${WORKSPACE_INSTALL_DEPLOYER}
- INSTALL_PRESTISSIMO=${WORKSPACE_INSTALL_PRESTISSIMO}
- INSTALL_LINUXBREW=${WORKSPACE_INSTALL_LINUXBREW}
- INSTALL_MC=${WORKSPACE_INSTALL_MC}
- INSTALL_SYMFONY=${WORKSPACE_INSTALL_SYMFONY}
- INSTALL_PYTHON=${WORKSPACE_INSTALL_PYTHON}
- INSTALL_IMAGE_OPTIMIZERS=${WORKSPACE_INSTALL_IMAGE_OPTIMIZERS}
- INSTALL_IMAGEMAGICK=${WORKSPACE_INSTALL_IMAGEMAGICK}
- INSTALL_TERRAFORM=${WORKSPACE_INSTALL_TERRAFORM}
- INSTALL_DUSK_DEPS=${WORKSPACE_INSTALL_DUSK_DEPS}
- INSTALL_PG_CLIENT=${WORKSPACE_INSTALL_PG_CLIENT}
- INSTALL_SWOOLE=${WORKSPACE_INSTALL_SWOOLE}
- PUID=${WORKSPACE_PUID}
- PGID=${WORKSPACE_PGID}
- CHROME_DRIVER_VERSION=${WORKSPACE_CHROME_DRIVER_VERSION}
- NODE_VERSION=${WORKSPACE_NODE_VERSION}
- YARN_VERSION=${WORKSPACE_YARN_VERSION}
- TZ=${WORKSPACE_TIMEZONE}
- BLACKFIRE_CLIENT_ID=${BLACKFIRE_CLIENT_ID}
- BLACKFIRE_CLIENT_TOKEN=${BLACKFIRE_CLIENT_TOKEN}
- DRUSH_VERSION=${DRUSH_VERSION}
volumes:
- ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}
extra_hosts:
- "dockerhost:${DOCKER_HOST_IP}"
ports:
- "${WORKSPACE_SSH_PORT}:22"
tty: true
environment:
- PHP_IDE_CONFIG=${PHP_IDE_CONFIG}
networks:
- frontend
- backend
volumes でコンテナのディレクトリとローカルのディレクトリの紐付けが行われている。これでコンテナ内で変更したものがローカルに。ローカルで変更したものがコンテナに反映される仕組み。
${APP_CODE_PATH_HOST}
、${APP_CODE_PATH_CONTAINER}
はさっきコピーした.envファイルに設定されている。APP_CODE_PATH_HOSTは先ほどtestappに変更した。
.env
# Point to the path of your applications code on your host
APP_CODE_PATH_HOST=../testapp/
# Point to where the `APP_CODE_PATH_HOST` should be in the container. You may add flags to the path `:cached`, `:delegated`. When using Docker Sync add `:nocopy`
APP_CODE_PATH_CONTAINER=/var/www:cached
laravelプロジェクト作成
laravelの開発に必要なものがworkspaceコンテナに用意されているので、このコンテナ内で作業すればよし。
コンテナ内に入って作業
% docker-compose exec workspace bash
% composer create-project laravel/laravel . --prefer-dist
外からコンテナ上でコマンド実行でもOK
% docker-compose exec workspace composer create-project laravel/laravel . --prefer-dist
どっちでもやってることは同じ。色々やることがあれば、コンテナ内に入って作業したほうがいいけど、1コマンドだけ実行するなら、入るまでもないみたいな使いわけなのかなと。
nginx起動して動作確認
% docker-compose up -d nginx
ブラウザでアクセス
http://localhost
mysqlへの接続
DBへの接続もできるようにしておきたいと思います。
laradockのmysqlコンテナの設定を確認しておこう。workspaceの時と同じ感じ。
laradock/docer-compose.yml
### MySQL ################################################
mysql:
build:
context: ./mysql
args:
- MYSQL_VERSION=${MYSQL_VERSION}
environment:
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- TZ=${WORKSPACE_TIMEZONE}
volumes:
- ${DATA_PATH_HOST}/mysql:/var/lib/mysql
- ${MYSQL_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d
ports:
- "${MYSQL_PORT}:3306"
networks:
- backend
laradock/.env
### MYSQL #################################################
#MYSQL_VERSION=latest
MYSQL_VERSION=5.7
MYSQL_DATABASE=default
MYSQL_USER=default
MYSQL_PASSWORD=secret
MYSQL_PORT=3306
MYSQL_ROOT_PASSWORD=root
MYSQL_ENTRYPOINT_INITDB=./mysql/docker-entrypoint-initdb.d
MYSQL_VERSIONだけ変更しました。
% docker-compose up -d mysql
Starting laradock_mysql_1 ... done
うまく立ち上がればこうなって、StatusのところがUpになっているはず。Exit 2とかだと起動に失敗してる。
% docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------------------------
laradock_mysql_1 docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp
laradock_nginx_1 nginx Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
laradock_php-fpm_1 docker-php-entrypoint php-fpm Up 9000/tcp
laradock_workspace_1 /sbin/my_init Up 0.0.0.0:2222->22/tcp
DB接続確認
migrateはlaravel使ってDBに接続してるはずなのでDB接続の確認はこれで。scaffoldみたいなのあれば簡単でいいなぁと思ったけどlaravelには標準では見つからないのでまぁできてるでしょうということで。
mysqlに接続
% docker-compose exec mysql mysql -uroot -proot
mysql>
ローカルの3306ポートに紐つけられているのでこれでもよし
% mysql -uroot -proot
プロジェクトのDB接続設定
laradockのほうじゃなくて、プロジェクトのほうの.env
% vi ../testapp/.env
DB_CONNECTION=mysql
#DB_HOST=127.0.0.1
DB_HOST=mysql
DB_PORT=3306
#DB_DATABASE=homestead
DB_DATABASE=default
#DB_USERNAME=homestead
DB_USERNAME=default
DB_PASSWORD=secret
databaseは先に作っておく必要があるみたい。面倒なのでdefault使っちゃう。
% docker-compose exec workspace php artisan migrate:install
% docker-compose exec workspace php artisan migrate
% mysql -uroot -proot default
mysql> show tables;
+-------------------+
| Tables_in_default |
+-------------------+
| migrations |
| password_resets |
| users |
+-------------------+
3 rows in set (0.00 sec)
migrationされてテーブル作られているのでDB接続も問題なさそう
mysqlが起動しないトラブルシュート
ローカルのmysqlが起動していて3306ポートが使えない場合
% docker-compose up -d mysql
Starting laradock_mysql_1 ... error
ERROR: for laradock_mysql_1 Cannot start service mysql: driver failed programming external connectivity on endpoint laradock_mysql_1 (321dd76338c96fbc822eb534d47b64def13d1bcebc7899def799b0da6d7c099c): Error starting userland proxy: Bind for 0.0.0.0:3306 failed: port is already allocated
ERROR: for mysql Cannot start service mysql: driver failed programming external connectivity on endpoint laradock_mysql_1 (321dd76338c96fbc822eb534d47b64def13d1bcebc7899def799b0da6d7c099c): Error starting userland proxy: Bind for 0.0.0.0:3306 failed: port is already allocated
ERROR: Encountered errors while bringing up the project.
windowsだとPermission deniedになるらしい
ERROR: for a9e7628e2be7_laradock_mysql_1 Cannot start service mysql: driver failed programming external connectivity on endpoint laradock_mysql_1 (bd740192b9d2ade5b32f89b90dStarting laradock_nginx_1 ... done
ERROR: for mysql Cannot start service mysql: driver failed programming external connectivity on endpoint laradock_mysql_1 (bd740192b9d2ade5b32f89b90d09a94c506079a7d9aeb877aa1699e404303e7d): Error starting userland proxy: Bind for 0.0.0.0:3306: unexpected error Permission denied
ERROR: Encountered errors while bringing up the project.
MYSQL_VERSIONをlatestのままやったら
Exit 2になってこんなエラー出てました。
% docker-compose logs mysql
Attaching to laradock_mysql_1
mysql_1 |
mysql_1 | ERROR: mysqld failed while attempting to check config
mysql_1 | command was: "mysqld --verbose --help"
mysql_1 |
mysql_1 | 2018-05-03T11:08:45.963958Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release.
mysql_1 | 2018-05-03T11:08:45.964029Z 0 [ERROR] [MY-011071] [Server] /usr/sbin/mysqld: Error while setting value 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' to 'sql_mode'
mysql_1 | 2018-05-03T11:08:45.965497Z 0 [ERROR] [MY-010119] [Server] Aborting
latestのほうが意識高いよね!ってことで自分もlatest使いたがりますが、試したいだけならば5.7にするのが無難。
ちなみに、色々調べてmysqlのsql_modeが変わっててここらへんいじると動いた。
mysql/my.cnf を変更してNO_AUTO_CREATE_USER を消す。
# The MySQL Client configuration file.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html
[mysql]
[mysqld]
sql-mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
character-set-server=utf8
バージョン変えたりして色々やっているとデータが壊れてしまってうまくいかないようなので、一度まっさらにして試すとうまくいったりします。
% docker-compose down
% rm -rf ~/.laradock/data/mysql
% docker rmi laradock_mysql -f
% docker rmi mysql -f
% docker-compose build mysql
docker image ls で見てmysqlっぽいものも全部消してみる
イメージの削除どこまでやればいいかわからないけど、とりあえず全部やってやった
migrateしようとするもエラー
% docker-compose exec workspace php artisan migrate:install
Illuminate\Database\QueryException : SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client (SQL: select * from information_schema.tables where table_schema = default and table_name = migrations)
at /var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:664
660| // If an exception occurs when attempting to run a query, we'll format the error
661| // message to include the bindings with SQL, which will make this exception a
662| // lot more helpful to the developer instead of just the database's errors.
663| catch (Exception $e) {
> 664| throw new QueryException(
665| $query, $this->prepareBindings($bindings), $e
666| );
667| }
668|
Exception trace:
1 PDOException::("PDO::__construct(): The server requested authentication method unknown to the client [caching_sha2_password]")
/var/www/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:68
2 PDO::__construct("mysql:host=mysql;port=3306;dbname=default", "default", "secret", [])
/var/www/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:68
Please use the argument -v to see more details.
mysqlコンテナ作り直したらうまくいった。
そもそも、laradockでmysqlが起動しないって質問されて、ローカルでやってみたらうまくいっててdockerなのに差があるのやだなぁと思って、ちゃんとまとめておこうと思ってやりはじめたのですが、、、
ローカルでうまくいってたのは、latestが古いバージョン向いたままだったようで、latestの罠ですかね。それでもlatestをなぜか使いたくなるんですけどw
参考にしたサイト
https://qiita.com/lara_bell/items/d4bd1340a5cc7dfcfcb4
https://teratail.com/questions/122336
https://github.com/laradock/laradock/issues/1492
https://stackoverflow.com/questions/50068663/laravel-5-5-with-mysql-8-0-11-sql-mode-cant-be-set-to-the-value-of-no-auto?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
https://laravel-news.com/laravel-5-6-18
https://github.com/laradock/laradock/issues/1392