9

说明

本文不是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=

安装中可能的网络错误:
截屏2020-03-1500.40.52.png
(像上图这种情况, 如果还是坚持要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扩展就比装的时间短.

成功启动后会有如下的提示
截屏2020-03-1600.39.36.png

可以看到之前在.env中设置的项目名general已经成为了容器名的前缀

另外还可以通过命令docker exec -it [container-name] bash进入容器

截屏2020-03-1500.45.54.jpg
默认情况下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

截屏2020-03-1601.53.29.png

更改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目录已经出现在容器的挂载目录中
截屏2020-03-1517.54.08.png
修改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
截屏2020-03-1423.22.59.png

正常显示则说明MySQL和Redis的连接没有问题

主机命令行连接MySQL和Redis

此前已经将MySQL和Redis的端口映射成1330616379,要如下连接

# redis
redis-cli -p 16379
# mysql 划重点! 注意参数`-h127.0.0.1` 不能用默认值不能不写
mysql -u root -proot -h127.0.0.1 -P 13306

截屏2020-03-1423.31.26.png

MySQL的host参数不能用localhost是因为它默认是通过sock文件与mysql通信,而容器与主机文件系统已经隔离,所以需要通过TCP方式连接,所以需要指定IP。

phpMyAdmin

浏览器访问http://127.0.0.1:18888, 要注意服务器这一个参数, 这是容器之间访问数据库, 要写成数据库容器的服务名mysql
截屏2020-03-1417.10.35.png

截屏2020-03-1417.12.37.png

phpRedisAdmin

浏览器访问http://127.0.0.1:19987, 这个账号和密码在laradock的.env文件有, 分别是REDIS_WEBUI_USERNAMEREDIS_WEBUI_PASSWORD
截屏2020-03-1501.12.41.png

截屏2020-03-1501.14.14.png

结语

从Docker到Laradock, 学习成本是有的, 但也是绝对值得的. 使用Laradock搭建环境是跨平台的, 高效的, 而且还相当的酷!

本文对Laradock的介绍只是很基础的一部分, 其实它里面还集合了好多好多有用的工具, 如netdata、protainer和rabbitmq等等, 这将是接下来要探索的东西🌏

以上是本人的一些实践经验, 欢迎留言交流😃

参考资料


Jeffid
214 声望10 粉丝

新世界的开发者;