说明
本文不是Docker入门教程, 而是Laradock的入门教程, 使用Laradock可以方便高效地搭建兼容各平台的PHP开发环境.
上手Laradock需要一些Docker基础, 得知道Dockerfile
文件和docker-compsoe.yml
文件是干嘛用的
要解决的问题
- Laradock中启动Nginx、MySQL、PHP、Redis服务运行一个全新的Laravel项目
- 一个Laradock运行多个项目
- 后期切换MySQL、PHP版本
- 添加PHP扩展
操作环境
- 主机: macOS 10.15
- Docker Desktop community: 2.2.0 (Engin: 19.03) (已配置阿里的docker镜像加速)
- Composer: 1.9
- Git: 2.23
一些约定
- 下文用到的主机命令别名:
alias dr="docker "
、alias ds="docker-compose "
, 即docker
简写成dr
- 下面演示中的Laradock和Laravel代码都放置在
~/_code/
目录下
安装
Laradock默认是给单一项目搭建环境的, 但也可以设置成支持多项目的, 区别在于Laradock目录与项目目录的相对位置.
例如我的全部项目代码都是放置在~/_code/
目录下的, 项目1的目录是~/_code/project_1/
, 项目2的目录是~/_code/project_2/
如此类推.
那多项目模式的Laradock目录结构如下:
~/_code/
laradock/
project_1/
project_2/
单项目模式(也就是将laradock作为一个项目的子项目):
~/_code/
project_3/
laradock/
项目3的其它目录/
多项目模式对于运行多个对环境无特别要求的项目的情况比较方便; 单项目模式对于专门给个别项目适配特定的服务比较有针对性, 同时还可以把laradock作为子项目一并提交到版本管理, 当需要在别处部署项目的时候代码和执行环境可以一步到位, 特别方便.
因此, 我个人建议是这两种模式可以根据面临的情况选择使用, 先搭一套多项目模式的, 一般情况就这个就够了, 然后其它情况特殊的就用单项目模式的. 下面我以多项目模式来演示.
下载
cd ~/_code/
git clone https://github.com/Laradock/laradock.git
配置
# 演示的Laradock目录在 `~/_code/laradock/`
cd laradock/
cp env-example .env
修改.env
如下:
# 下面开始的是重点!
# 指定要挂载进容器的目录,也就是项目代码在主机的目录
APP_CODE_PATH_HOST=../
# 将`APP_CODE_PATH_HOST`指定的目录挂载进到容器(如workspack、php-fpm容器)内相应哪个位置
APP_CODE_PATH_CONTAINER=/var/www
# MySQL,Redis等数据持久化保存在主机的什么位置,可以自定义目录的
DATA_PATH_HOST=~/.laradock/general_data
# 给这个laralock(docker-compose)项目取个名字,这个名字将会作为未来启动的容器的命名前缀,不能与其它laradock重名.默认是`laradock`,当然也可以设置成`aaa`
COMPOSE_PROJECT_NAME=general
# php-cli和php-fpm的版本,目前可选填: 7.4 - 7.3 - 7.2 - 7.1 - 7.0 - 5.6
PHP_VERSION=7.3
# MySQL的版本,latest是最新版8.0.x,写5.7会给你安装5.7.x的最新版
MYSQL_VERSION=5.7
# 在国内网络环境下加快容器内的一些下载,默认采用阿里的镜像
CHANGE_SOURCE=true
# 设置时区,会影响到所有运行的容器,PRC是指中国
WORKSPACE_TIMEZONE=PRC
# 下面开始的是看情况有选择地操作:
# 设置composer镜像
WORKSPACE_COMPOSER_REPO_PACKAGIST=https://mirrors.aliyun.com/composer/
# Node镜像
WORKSPACE_NVM_NODEJS_ORG_MIRROR=https://npm.taobao.org/mirrors/node
# NPM镜像
WORKSPACE_NPM_REGISTRY=https://registry.npm.taobao.org/
# 修改映射端口,是为了避免与其它laradock或是主机端口冲突, 如果确定没有冲突的可以不用更改
# workspace相关端口
WORKSPACE_SSH_PORT=12222
WORKSPACE_VUE_CLI_SERVE_HOST_PORT=18080
WORKSPACE_VUE_CLI_UI_HOST_PORT=18001
# Nginx服务相关端口
NGINX_HOST_HTTP_PORT=10080
NGINX_HOST_HTTPS_PORT=10443
VARNISH_BACKEND_PORT=10081
# MySQL端口
MYSQL_PORT=13306
# Reids端口
REDIS_PORT=16379
# phpMyAdmin端口
PMA_PORT=18888
# phpRedisAdmin端口
REDIS_WEBUI_PORT=19987
选装PHP扩展
PHP扩展在laradock里是分成 PHP-CLI扩展和PHP-FPM扩展的, 因为它们分别位于两个容器中(PHP-CLI在workspace容器内, PHP-FPM单独一个容器), 可以根据情况只装一边或两边都装.
PHP-CLI默认扩展:
[PHP Modules]
ast
bcmath
calendar
Core
ctype
curl
date
dom
exif
fileinfo
filter
ftp
gd
gettext
hash
iconv
igbinary
intl
json
libxml
mbstring
memcached
msgpack
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
pdo_mysql
pdo_pgsql
pdo_sqlite
pgsql
Phar
posix
readline
redis
Reflection
session
shmop
SimpleXML
sockets
sodium
SPL
sqlite3
standard
sysvmsg
sysvsem
sysvshm
tokenizer
wddx
xml
xmlreader
xmlwriter
xsl
Zend OPcache
zip
zlib
[Zend Modules]
Zend OPcache
PHP-FPM默认扩展:
[PHP Modules]
bcmath
Core
ctype
curl
date
dom
fileinfo
filter
ftp
gd
hash
iconv
imagick
intl
json
libxml
mbstring
mysqli
mysqlnd
openssl
pcre
PDO
pdo_mysql
pdo_pgsql
pdo_sqlite
Phar
posix
readline
redis
Reflection
session
SimpleXML
sodium
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
Zend OPcache
zip
zlib
[Zend Modules]
Zend OPcache
同时给PHP-CLI和PHP-FPM安装swoole扩展的配置
编辑.env
# PHP-CLI
WORKSPACE_INSTALL_SWOOLE=true
# PHP-FPM
PHP_FPM_INSTALL_SWOOLE=true
可选的PHP扩展都是WORKSPACE_INSTALL_*
和PHP_FPM_INSTALL_*
这种格式的, 类似的扩展选项还有很多, 可以自行选用.
不安装Node的情况
如果你在容器中安装Node时因为网络问题出错(如图示), 或是在主机已经安装了Node, 不需要在容器中执行Node命令, 那可以不安装Node.
# 都设为false就不安装了
WORKSPACE_INSTALL_NODE=false
WORKSPACE_INSTALL_YARN=false
# 不安装的时候也不要有填写镜像地址,否则报错
WORKSPACE_NVM_NODEJS_ORG_MIRROR=
WORKSPACE_NPM_REGISTRY=
安装中可能的网络错误:
(像上图这种情况, 如果还是坚持要Node的话可以采用全局科学上网的方式安装)
运行
启动服务
注意: 每次执行docker-compose
命令时, 需要确保当前命令行所在的目录有docker-compose.yml
文件, 在当前的演示中即为~/_code/laradock/
目录
# 进入laradock根目录
cd ~/_code/laradock/
# 一次性启动 Nginx MySQL Redis phpMyAdmin phpRedisAdmin PHP-FPM workspace
# laradock在启动Nginx容器时会自动连带启动PHP-FPM和workspace容器,因此在启动命令中可以省略不写这两个
# `-d`参数指以守护进程方式运行,redis-webui是phpRedisAdmin的服务名
# 可以逐个启动, 如: `ds up -d mysql`
ds up -d nginx mysql redis phpmyadmin redis-webui
# 列出当前docker-compose项目下的所有容器
ds ps
# 关闭当前项目的所有容器并移除: `ds down`
如果是第一次启动, 那么laradock会根据配置生成各个docker镜像, 然后再启动这些镜像, 所需时间取决于所处环境的网速和要安装的东西的量的多少, 例如不装Node、Yarn和额外的PHP扩展就比装的时间短.
成功启动后会有如下的提示
可以看到之前在.env
中设置的项目名general
已经成为了容器名的前缀
另外还可以通过命令docker exec -it [container-name] bash
进入容器
默认情况下workspace容器会装有Composer、Node、Yarn、Git等工具
更改PHP版本
例如要将php从之前设置的7.3更改为7.4
先修改.env
的php版本参数
PHP_VERSION=7.4
然后重新生成PHP-FPM和workspace容器的镜像, 再重新启动即可
ds build php-fpm workspace
ds up -d php-fpm workspace
# 进入 workspace 服务在当前项目下的容器 general_workspace_1 查看PHP-CLI版本
dr exec -it general_workspace_1 bash
# 类似地, 查看PHP-FPM版本
dr exec -it general_php-fpm_1 bash
更改MySQL版本
例如要将MySQL从之前设置的5.7更改为8.0
先修改Laradock.env
的php版本参数
PHP_VERSION=8.0
更改数据库涉及持久化的数据文件问题, 需要专门另外处理
# 大版本之间的MySQL数据库文件存在不兼容的问题,所以要迁移旧或删除旧数据库文件
# 停止mysql容器, 防止操作还生成数据库文件
ds stop mysql
# 迁移旧数据库文件
mv ~/.laradock/general_data/mysql ~/.laradock/general_data/mysql_5.7
# 重新生成镜像
ds build mysql
# 按镜像启动
ds up -d mysql
# 可参考更改php版本一节查看mysql版本
使用
跑一个laravel项目
在主机使用composer创建一个6.x版本的laravel新项目, 取名为lv6_2
, 使用本地域名lv6_2.test
运行
下载Laravel并修改配置
cd ~/_code/
composer create-project --prefer-dist laravel/laravel:^6 lv6_2
cp .env.example .env
此时lv6_2
目录已经出现在容器的挂载目录中
修改Laravel的.env
文件
# 代码是在容器内运行的,容器之间的通信地址就是服务名,所以这里的数据库地址写`mysql`
DB_HOST=mysql
# 容器内用的是默认的端口
DB_PORT=3306
DB_DATABASE=default
DB_USERNAME=root
DB_PASSWORD=root
REDIS_HOST=redis
REDIS_PORT=6379
之前在Laradock的.env
文件中给MySQL设置的端口13306
是映射到物理主机的端口, 即在主机连接容器中的MySQL时都用13306
, 容器之间还是3306
, Redis也是一样的道理.
修改主机hosts文件
# 要确保主机当前用户有修改hosts的权限
echo '127.0.0.1 lv6_2.test' >> /etc/hosts
添加nginx站点配置文件并重启
复制默认配置文件
cd ~/_code/laradock/nginx/sites
cp laravel.conf.example lv6_2.test.conf
修改lv6_2.test.conf
关键参数
# 就改这两个就可以
server_name lv6_2.test;
root /var/www/lv6_2/public;
重启nginx容器
cd ~/_code/laradock/
ds restart nginx
运行项目
编辑~/_code/lv6_2/routes/web.php
路由文件, 加入MySQL和Redis的测试代码
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
Route::prefix('t')->group(function () {
Route::get('db', function () {
dump(DB::select('select version()'));
dump(Redis::incr('incr_key'));
dd('db end');
});
});
浏览器访问 http://lv6_2.test:10080/t/db
正常显示则说明MySQL和Redis的连接没有问题
主机命令行连接MySQL和Redis
此前已经将MySQL和Redis的端口映射成13306
和16379
,要如下连接
# redis
redis-cli -p 16379
# mysql 划重点! 注意参数`-h127.0.0.1` 不能用默认值不能不写
mysql -u root -proot -h127.0.0.1 -P 13306
MySQL的host参数不能用localhost是因为它默认是通过sock文件与mysql通信,而容器与主机文件系统已经隔离,所以需要通过TCP方式连接,所以需要指定IP。
phpMyAdmin
浏览器访问http://127.0.0.1:18888
, 要注意服务器这一个参数, 这是容器之间访问数据库, 要写成数据库容器的服务名mysql
phpRedisAdmin
浏览器访问http://127.0.0.1:19987
, 这个账号和密码在laradock的.env
文件有, 分别是REDIS_WEBUI_USERNAME
和REDIS_WEBUI_PASSWORD
结语
从Docker到Laradock, 学习成本是有的, 但也是绝对值得的. 使用Laradock搭建环境是跨平台的, 高效的, 而且还相当的酷!
本文对Laradock的介绍只是很基础的一部分, 其实它里面还集合了好多好多有用的工具, 如netdata、protainer和rabbitmq等等, 这将是接下来要探索的东西
以上是本人的一些实践经验, 欢迎留言交流