Laradock DNMP 环境搭建
Laradock 是什么?
Laradock.io 是一堆 Dockfile
和 docker-compose.yml
的文件集合,用于一键构建 DNMP
环境。
Laradock 封装了一个 Workspace
工作区镜像作为开发环境,里面包含了丰富且实用的工具集:PHP-CLI、Composer、Git、Linuxbrew、Node、V8JS、Gulp、SQLite、xDebug、Envoy、Deployer、Vim、Yarn、SOAP、Drush 等等。
CentOS 中 Laradock 的使用
1. 安装 Docker
http://www.runoob.com/docker/centos-docker-install.html
2. 安装 Docker-Compose
1 | # 注意 URL 里的版本号 |
3. 下载 Laradock
A. 单应用
cd /home/wwwroot/ai_gmall_server
git submodule add https://github.com/Laradock/laradock.git
目录结构:
- ai_gmall_server
- laradock
- app
- public
- ...
B. 多应用
cd /home/wwwroot/
git clone https://github.com/Laradock/laradock.git
目录结构:
- wwwroot
- laradock
- ai_gmall_server
- ai_stadium_server
注:多应用时,需要配置
nginx vhost
才能访问到,配置文件在laradock/nginx/sites/*.conf
4. Laradock 环境配置
初始化 laradock/.env
配置:
cd laradock
cp env-example .env
vim .env
注意修改其中的以下关键选项:
# 应用持久化数据保存目录(映射在宿主机的数据卷)
# 用于保存 MySQL 产生的数据、Redis 快照文件等
DATA_PATH_HOST=~/.laradock/ai_gmall/data
# 定义容器前缀
# 当一台宿主机有多个 laradock 单应用时,需要设置前缀进行区分
COMPOSE_PROJECT_NAME=laradock_ai_gmall
# 端口修改(按需)
NGINX_HOST_HTTP_PORT=1322
NGINX_HOST_HTTPS_PORT=13443
# 关闭 PHPRedis 扩展,我们用 Predis
WORKSPACE_INSTALL_PHPREDIS=false
PHP_FPM_INSTALL_PHPREDIS=false
# MySQL 版本
# 注意默认 latest 为 8.0,这里改为 5.7
MYSQL_VERSION=5.7
MYSQL_DATABASE=ai_gmall
MYSQL_USER=gmall
MYSQL_PASSWORD=gmall.1322
MYSQL_PORT=3306
MYSQL_ROOT_PASSWORD=gmall.1322
# 设置中国镜像源
CHANGE_SOURCE=true
WORKSPACE_NPM_REGISTRY=https://registry.npm.taobao.org
WORKSPACE_COMPOSER_REPO_PACKAGIST=https://packagist.phpcomposer.com
# 设置中国时区
WORKSPACE_TIMEZONE=Asia/Shanghai
# 安装 NodeJS
WORKSPACE_INSTALL_NODE=true
# 启用 PHP OPCache
PHP_FPM_INSTALL_OPCACHE=true
以下可选配置:
# 安装 Swoole
WORKSPACE_INSTALL_SWOOLE=true
PHP_FPM_INSTALL_SWOOLE=true
# phpMyAdmin
PMA_USER=default
PMA_PASSWORD=secret
PMA_ROOT_PASSWORD=secret
PMA_PORT=8080
# phpRedisAdmin
REDIS_WEBUI_USERNAME=laradock
REDIS_WEBUI_PASSWORD=laradock
REDIS_WEBUI_CONNECT_HOST=redis
REDIS_WEBUI_CONNECT_PORT=6379
REDIS_WEBUI_PORT=9987
5. Nginx 虚机配置
打开 laradock/nginx/sites/default.conf
,修改 server_name
为实际域名,去除 default_server
指定。
如需启用 HTTPS
,则把证书放到 laradock/nginx/ssl/
目录里,并在对应的配置中引入。
如果一套环境包含多应用,那么还需要给 Nginx
增加 vhost
配置:
1 | # 里面可以添加 server 段 |
6. PHP-FPM 设置
(1) 修改 laradock/php-fpm/phpX.X.ini
(X.X 为 PHP 版本号) 设置 disable_functions
等参数。
(2) 修改 laradock/php-fpm/laravel.ini
设置 memory_limit
等参数。
(3) 修改 laradock/php-fpm/opcache.ini
确保参数按如下设置:
1 | opcache.enable="1" |
强烈建议:生产环境 validate_timestamps=0
,每次 PHP 文件变更都应平滑重启 PHP-FPM。
1 | # 平滑重启 |
7. Laravel 应用内配置
修改项目里的 ai_gmall_server/.env
文件,将其中的 DB_HOST
和 REDIS_HOST
改为以下值:
DB_HOST=mysql
REDIS_HOST=redis
QUEUE_HOST=beanstalkd
然后进行应用初始化(必做步骤):
1 | cd /home/wwwroot/ai_gmall_server |
7. Redis 配置
配置文件 laradock/redis/redis.conf
,修改以下项并重启 Redis
:
# 设置密码
requirepass 密码
# 绑定 IP
# 也可以注释掉
bind 0.0.0.0
# 修改持久化频率
save 900 1
save 300 10
save 60 50000
重启 Redis
的命令是:
1 | docker-compose restart redis |
8. MySQL 配置
配置文件 laradock/mysql/my.cnf
,增加或修改以下项并重启 MySQL
:
1 | # @see http://dev.mysql.com/doc/mysql/en/server-system-variables.html |
重启 MySQL
的命令是:
1 | docker-compose restart mysql |
在目录 laradock/mysql/docker-entrypoint-initdb.d/
里的 *.sql
文件,会在MySQL 容器初次创建时自动执行。
我们可以把应用初始化所需的 SQL 放在里面。
容器初次创建:指
$DATA_PATH_HOST/data/mysql
文件夹第一次创建时,如果该文件夹已存在,则不会执行。
如果就是需要手动执行一些 SQL,那么可以进入 MySQL 容器:
1 | docker-compose exec mysql bash |
MySQL 默认安装的版本是 latest
,即 8.0
,如想更换,可以修改 laradock/.env
中的 MYSQL_VERSION
常量,例如改为 MYSQL_VERSION=5.7
。
更换 MySQL 版本的坑
如果之前已装了 latest
版本,现在换成 5.7
,那么在重新构建新的 MySQL 镜像前,必须先清空旧的数据卷:$DATA_PATH_HOST/data/mysql
,否则新的 MySQL 会启动失败。
或者一并删除旧容器及其数据卷,命令如下:
1 | # 把旧容器和数据卷一并删除 |
9. Laravel WebSocket Echo Server
修改 laradock/laravel-echo-server/laravel-echo-server.json
文件:
1 | { |
每次修改完都需重启该容器:
1 | docker-compose restart laravel-echo-server |
另外,容器版的 laravel-echo-server
无需 Supervisord
来守护,因为:
- 容器的主进程只要发生中断,容器也会自动终止。
- 在
docker-compose.yml
中laravel-echo-server
的『退出后的重启策略』是始终重启:restart: always
以上就可以确保 laravel-echo-server
服务会一直保持,达到了和 Supervisord
一样的目的。
10. Supervisord + Laravel Horizon
Laradock 并没有单独的 Supervisord 容器,而是顺便夹带在 laravel-horizon
或 php-worker
两个容器里,这样会导致无法监听其他进程(例如 PHP iNotify
),这并不是一个好的设计。解决办法是把 Supervisord
以及待监听的进程都装到 Workspace
容器里。
在目录 laradock/workspace/supervisor.d/
里新建 *.conf
文件,格式如下:
1 | [program:AI_GMall_Server_Horizon] |
重启 Supervisord
的命令是:
1 | docker-compose exec workspace bash -c 'supervisorctl reload' |
重启 Laravel Horizon
的命令是:
1 | docker-compose exec workspace bash -c 'php artisan horizon:terminate' |
11. 计划任务
Laradock 的计划任务有两种实现方式:
A. 通过系统 Crond
实现
打开文件 laradock/workspace/crontab/laradock
,确保里面每条命令的 执行者
和项目文件的拥有者一样,否则会导致无权执行:
1 | # 以下执行者为 root 用户 |
原理:在 Workspace
容器创建时,会把 laradock/workspace/crontab/
里的所有文件(文件名随意)都复制到容器的 /etc/cron.d/
目录里(注:Linux 系统里,/etc/cron.d/
是 /etc/crontab
的扩展目录,都是系统级计划任务),系统会每分钟都会扫描这些文件并按策略执行。
扩展阅读:Linux Crontab 计划任务拾遗
B. 通过 Supervisord
实现
新增文件 laradock/workspace/supervisord.d/laravel-scheduler.conf
:
1 | [program:laravel-scheduler] |
疑问待验证:这种单进程阻塞的写法,假设一个任务执行超过10分钟,那么期间本该执行的其他任务是否会被遗漏?
99. 正式启动 Laradock
1 | docker-compose up -d \ |
注:
php-fpm
是nginx
的depends_on
依赖项,Workspace
是php-fpm
的依赖项,所以这两个容器会自动创建并启动,不需要写出来。
100. 应用初始化
在项目目录先执行:
1 | cd /home/wwwroot/ai_gmall_server |
经验:如果访问出现 500 错误,那大多数情况是没有执行
composer install
导致。
相关访问 URL 入口:
- WebServer:
http://localhost:80
- WebSocketServer
http://localhost:6001
- phpMyAdmin:
http://localhost:8080
- phpRedisAdmin:
http://localhost:9987
日常使用手册
1. 执行 Compose 命令的位置
执行 docker-compose
命令默认会在当前目录查找 docker-compose.yml
,如果找不到就会报执行失败,否则请用 -f
参数指定位置,例如:
1 | docker-compose -f docker-compose-XXXX.yml up -d ... |
2. 如何执行 php artisan
命令?
先进入 Workspace 工作区容器:
1 | docker-compose exec [--user=laradock] workspace bash |
缺省是以 root
身份进入容器,用 --user=laradock
可以指定为其他用户。要求项目工作区文件的拥有者必须与进入者身份一致,否则会导致一些文件读写权限的问题。
进入 Workspace
容器后,就可自由运行 php artisan
命令了。
3. 如何更新 PHP 代码?
应用代码仍然是放在宿主机的 /home/wwroot
目录里,是以数据卷形式挂载在容器里的,所以对文件的操作还是和之前一样。
例如应用初始化时,我们可以直接在宿主机的 /home/wwwroot/ai_gmall_server
目录里执行:
1 | chmod -R 777 storage bootstrap/cache |
更新脚本 ~/sh/update_ai_gmall_server.sh
如下:
1 |
|
4. 什么时候必须重新构建镜像?
如果修改了 laradock/docker-compose.yml
或 laradock/.env
或相关组件的 Dockerfile
文件,那么就需要重建指定的镜像和容器使之生效。
假设我们修改了 laradock/workspace/Dockerfile
,然后重建并重启:
1 | docker-compose build workspace |
注意:重建会一并重建 depends_on
依赖镜像,加上参数 --no-deps
表示只需重建指定镜像,不要牵连依赖镜像。如果重建时想忽略缓存,也可以加上 --no-cache
参数。
此时切忌用 docker-compose down
,因为 down
会停止并删除所有 up
启动的容器,即使这些容器没有修改过。
5. 如何安装更多 PHP 扩展?
安装 PHP 扩展需要同时修改 PHP-FPM
和 PHP-CLI
两个容器,并重建镜像:
- PHP-FPM :
php-fpm/Dockerfile-XX
(XX 是 PHP 版本号) - PHP-CLI :
workspace/Dockerfile
6. 备份和导出 MySQL 数据库
1 | cd laradock |
7. 生产环境的注意事项
生产环境应该用另一份 docker-compose-prod.yml
,移除 docker-compose.yml
中的相关 ports
选项,保证的 MySQL/Redis 端口不暴露在公网。
查看文档:多个 docker-compose.yml
文件共享配置
参考资料
- https://laradock.io/documentation
- https://gitee.com/anviod/laradock/blob/master/.github/README-zh.md