Laravel 是一套简洁、优雅的 PHP Web 开发框架 (PHP Web Framework)。
Laravel: https://laravel.com/
Laravel GitHub: https://github.com/laravel
1. 部署环境
IP 地址(本地测试环境):192.168.0.10
操作系统:Linux CentOS 7.9
Docker 版本: 20.10.7
Docker Compose 版本: 2.6.1
Nginx 目录:/home/docker/nginx
MariaDB 目录:/home/docker/mysql
Php 目录:/home/docker/php
Laravel 目录:/home/docker/laravel
2. 创建 Dockerfile
Docker pull 下载的 PHP 镜像,缺少需要的扩展,所以编写 Dockerfile 在本地生成需要的 PHP 镜像。
$ cd /home/docker/laravel
$ vim Dockerfile
FROM php:7.4-fpm
RUN sed -i s@/deb.debian.org/@/mirrors.aliyun.com/@g /etc/apt/sources.list
RUN sed -i s@/security.debian.org/@/mirrors.aliyun.com/@g /etc/apt/sources.list
RUN apt-get update && apt-get install -y zlib1g-dev libzip-dev
RUN docker-php-ext-install pdo_mysql mysqli zip
RUN docker-php-ext-enable pdo_mysql mysqli zip
注:运行 sed 命令把 docker 容器的 apt 改成阿里源,zip 扩展依赖 zlib1g-dev 和 libzip-dev,所以 docker-php-ext-install 安装 zip 之前需要先安装这两个系统库 。
$ docker build -t php:7.4-fpm-mysqli .
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
php 7.4-fpm-mysqli fbca0f9390a3 8 seconds ago 444MB
php 7.4-fpm cf71a2f33ec4 3 minutes ago 444MB
可以通过 docker-php-ext-install 安装的常用扩展:
bcmath bz2 calendar ctype curl dba dom enchant exif fileinfo filter ftp gd gettext gmp hash iconv imap interbase intl json ldap mbstring mysqli oci8 odbc opcache pcntl pdo pdo_dblib pdo_firebird pdo_mysql pdo_oci pdo_odbc pdo_pgsql pdo_sqlite pgsql phar posix pspell readline recode reflection session shmop simplexml snmp soap sockets sodium spl standard sysvmsg sysvsem sysvshm tidy tokenizer wddx xml xmlreader xmlrpc xmlwriter xsl zend_test zip
注:大部分扩展在 docker-php-ext-install 安装之前,需要先用 yum or apt-get 安装所需要的系统依赖库,具体需要参考各扩展的文档。
3. 创建 docker-compose.yml
$ cd /home/docker/laravel
$ vim docker-compose.yml
version: "3"
services:
nginx:
image: nginx
container_name: nginx-php7.4
ports:
- "80:80"
restart: always
volumes:
- /home/docker/nginx/conf.d:/etc/nginx/conf.d
- /home/docker/nginx/html:/usr/share/nginx/html
- /home/docker/nginx/logs:/var/log/nginx
mariadb:
image: mariadb:10.4
container_name: mariadb-10.4
ports:
- "3306:3306"
restart: always
environment:
- MARIADB_ROOT_PASSWORD=123456
volumes:
- /home/docker/mysql/conf:/etc/mysql/conf.d
- /home/docker/mysql/data:/var/lib/mysql
- /home/docker/mysql/log:/var/log/mysql
php:
image: php:7.4-fpm-mysqli
container_name: php-7.4-fpm-mysqli
depends_on:
- nginx
- mariadb
build: .
ports:
- "9000:9000"
restart: always
volumes:
- /home/docker/php/conf.d:/usr/local/etc/php/conf.d
- /home/docker/nginx/html:/var/www/html
4. 配置文件
1) 创建 nginx.conf
在 /home/docker/nginx/conf.d 目录下,创建 nginx.conf 文件,内容如下:
server {
listen 80 default_server;
server_name localhost;
root /usr/share/nginx/html;
location / {
index index.php index.html index.htm;
autoindex off;
}
location ~ \.php(.*)$ {
root /var/www/html;
fastcgi_pass php-7.4-fpm-mysqli:9000;
fastcgi_index index.php;
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
include fastcgi_params;
}
}
参数说明:
(1) server.location.fastcgi_pass: php-7.4-fpm-mysqli:9000 表示 “容器名称:端口”,也可以写成 “ip:端口”,获取 ip 的方法,运行如下命令:
$ docker inspect --format='{{.NetworkSettings.IPAddress}}' php-7.4-fpm-mysqli
172.17.0.4
(2) 目录映射关系:
server.root: /usr/share/nginx/html 是 nginx 容器内的路径。静态文件 (HTML/CSS/JS/Images 等文件)对应的映射目录是 usr/share/nginx/html;
server.location.root: /var/www/html/ 是 php 容器内的路径。 php 文件(*.php)通过 location ~ \.php(.*)$ 解析,对应的映射目录是 /var/www/html/。
把 nginx 容器内的路径 /usr/share/nginx/html 和 php 容器内的路径 /var/www/html/ 都挂载到 Docker 所在主机的目录 /home/docker/nginx/html,这个目录就同时支持 php 文件和静态文件的解析。
(3) 使用虚拟域名,如 www.test.com,只需在 Docker 所在主机的 /etc/hosts 添加 127.0.0.1 www.test.com,不必在 nginx 容器或 php 容器中添加。
2) 创建 my_mariadb.cnf 文件
在 /home/docker/mysql/conf 目录下,创建 my_mariadb.cnf 文件,内容如下:
[mysqld]
server-id=1
port=3306
#basedir=/usr/local/mysql
#tmpdir=/tmp
datadir=/var/lib/mysql
# 查询日志,默认在 /var/lib/mysql 目录下
#general_log=1
#general_log_file=mysql_general.log
# 二进制日志,默认在 /var/lib/mysql 目录下
#log_bin=mysql_log_bin-1
# 慢查询日志,默认在 /var/log/mysql 目录下
#slow_query_log=1
#long_query_time=1
#slow_query_log_file=mysql_slow_query.log
# 错误日志,指定到 /var/log/mysql 目录
log_error=/var/log/mysql/mysql_err.log
注:MariaDB (MySQL) 的默认配置文件是 /etc/mysql/my.cnf 文件。如果想要自定义配置,在 /etc/mysql/conf.d 目录中创建 *.cnf 文件。新建的文件可以任意起名,只要保证后缀名是 cnf 即可。新建的文件中的配置项可以覆盖 /etc/mysql/my.cnf 中的配置项。
3) 创建 my_php.ini 文件
在 /home/docker/php/conf.d 目录下,创建 my_php.ini 文件,内容如下:
file_uploads=On
upload_max_filesize=10M
post_max_size=10M
memory_limit=20M
extension=mysqli.so
extension=pdo_mysql.so
extension=sodium
extension=zip.so
注:PHP 的配置文件在容器内 /usr/local/etc/php/conf.d 目录。如果想要自定义配置,在该 目录中创建 *.ini 文件。新建的文件可以任意起名,只要保证后缀名是 ini 即可。新建的文件中的配置项可以覆盖原来的配置项。
docker build 调用 docker-php-ext-install 命令安装 php 扩展时,会在 /usr/local/etc/php/conf.d 目录下创建扩展的配置文件,比如 docker-php-ext-pdo_mysql.ini,内容如下:
extension=pdo_mysql.so
挂载目录 “- /home/docker/php/conf.d:/usr/local/etc/php/conf.d” 时, docker-php-ext-pdo_mysql.ini 等配置文件会丢失,所以需要把这些配置文件的内容加入到 my_php.ini 文件。docker build 安装的所有 php 扩展的配置,都需要添加到 my_php.ini 文件里,否者有些 php 扩展无法正常工作。
4) 测试文件
在 /home/docker/nginx/html 目录下,创建 test.html 文件,内容如下:
<h3>Nginx/PHP7.4 - test.html</h3>
在 /home/docker/nginx/html 目录下,创建 demo.php 文件,内容如下:
<?php
echo "Nginx/PHP7.4 - PHP file demo.php";
?>
5. 启动
$ cd /home/docker/laravel # 进入 docker-compose.yml 所在目录
$ docker-compose up # 执行 docker-compose.yml
$ docker-compose up -d # 在后台运行
[+] Running 4/4
⠿ Network laravel_default Created 0.0s
⠿ Container mariadb-10.4 Started 0.5s
⠿ Container nginx-php7.4 Started 0.5s
⠿ Container php-7.4-fpm-mysqli Started 0.8s
注:本地 docker 没有所需要的镜像时,会自动下载所需的镜像。遇到无法自动下载的情况,可以使用 docker pull 命令下载所需的镜像,在运行 docker-compose up 命令。
$ docker images # 查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
php 7.4-fpm-mysqli fbca0f9390a3 21 minutes ago 444MB
php 7.4-fpm cf71a2f33ec4 24 minutes ago 444MB
nginx latest 2d389e545974 5 days ago 142MB
mariadb 10.4 801fdf0164b2 2 weeks ago 404MB
$ docker ps # 查看容器运行情况
CONTAINER ID IMAGE ... PORTS NAMES
c663e5fc3b3f php:7.4-fpm-mysqli 0.0.0.0:9000->9000/tcp,... php-7.4-fpm-mysqli
397a6488239e mariadb:10.4 0.0.0.0:3306->3306/tcp,... mariadb-10.4
7d4d9fa56ed6 nginx 0.0.0.0:80->80/tcp,... nginx-php7.4
$ docker-compose ps # 类似 docker ps 的作用
NAME COMMAND SERVICE STATUS PORTS
mariadb-10.4 ... mariadb running 0.0.0.0:3306->3306/tcp,...
nginx-php7.4 nginx running 0.0.0.0:80->80/tcp,...
php-7.4-fpm-mysqli php running 0.0.0.0:9000->9000/tcp,...
mariadb-10.4 容器内的程序要在 /home/docker/mysql/log (该目录被挂载到容器内 /var/log/mysql 目录) 目录下创建 log 文件,需要确保容器内 root/root 以外的用户也有 /home/docker/mysql/log 目录的写权限,修改该目录的权限,命令如下:
$ cd /home/docker/mysql
$ chmod a+w log
修改后需要重启 mariadb-10.4 容器,命令如下:
$ docker restart mariadb-10.4
浏览器访问 http://192.168.0.10/test.html,静态页面显示如下:
Nginx/PHP7.4 - test.html
浏览器访问 http://192.168.0.10/demo.php,动态页面显示如下:
Nginx/PHP7.4 - PHP file demo.php
6. 停止
$ docker-compose stop # 停止容器,类似 docker stop 的作用
[+] Running 3/3
⠿ Container php-7.4-fpm-mysqli Stopped 0.1s
⠿ Container mariadb-10.4 Stopped 1.8s
⠿ Container nginx-php7.4 Stopped 0.2s
$ docker-compose ps # 查看容器,类似 docker ps -a 的作用
NAME COMMAND SERVICE STATUS PORTS
mariadb-10.4 ... mariadb exited (0)
nginx-php7.4 nginx exited (0)
php-7.4-fpm-mysqli php exited (0)
$ docker-compose down # 停止并删除容
[+] Running 4/0
⠿ Container php-7.4-fpm-mysqli Removed 0.1s
⠿ Container mariadb-10.4 Removed 1.9s
⠿ Container nginx-php7.4 Removed 0.1s
⠿ Network laravel_default Removed 0.0s
类似 docker stop 和 docker rm 的复合作用。
$ docker-compose ps
NAME COMMAND SERVICE STATUS PORTS
此时容器列表为空。
$ docker images # 查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
php 7.4-fpm-mysqli fbca0f9390a3 33 minutes ago 444MB
php 7.4-fpm cf71a2f33ec4 36 minutes ago 444MB
nginx latest 2d389e545974 5 days ago 142MB
mariadb 10.4 801fdf0164b2 2 weeks ago 404MB
运行 docker-compose down 不会删除镜像,Docker 所在主机上挂载的目录里数据和文件也不会被删除,运行 docker-composer up 或 up -d 就可以恢复运行。
7. 配置 Laravel 项目
1) 项目创建环境
操作系统:Windows 10 Home 21H2
PHP 版本:7.4.25,https://www.php.net/
PHP Composer 版本:2.4.2,https://getcomposer.org/
Nginx 版本:1.20.2,http://nginx.org/en/
2) 创建 Laravel 项目
运行 Composer 命令创建项目:
C:\laravel>composer create-project laravel/laravel laravel-demo
...
C:\laravel>tar -cvzf laravel-demo.tar.gz laravel-demo
配置 Windows/Nginx 测试 laravel-demo 项目,修改 conf/nginx.conf 内容如下:
...
http {
...
server {
listen 8888;
server_name localhost;
location / {
root C:\laravel\laravel-demo\public;
index index.php index.html index.htm;
# 根据 laravel 规则进行 url 重写
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
root C:\laravel\laravel-demo\public;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
include fastcgi_params;
}
}
...
}
启动 fastcgi,运行如下命令:
C:\laravel>php-cgi.exe -b 127.0.0.1:9000
启动 nginx (假设安装目录 C:\Applications\nginx-1.20.2),双击目录下的 nginx.exe 文件或在命令行下运行如下命令:
C:\Applications\nginx-1.20.2>nginx
浏览器访问 http://localhost:8888/,显示 Laravel 空项目的默认页面。
注:Laravel 项目创建过程,可以参考 https://laravel.com/docs/9.x/installation#your-first-laravel-project 。
3) 部署 laravel-demo
把 laravel-demo.tar.gz 上传到 192.168.0.10 主机的 /home/docker/laravel 目录。
$ cd /home/docker/laravel
$ tar -vxzf laravel-demo.tar.gz
$ cd laravel-demo
$ ls
app bootstrap composer.lock database phpunit.xml README.md routes storage vendor
artisan composer.json config package.json public resources server.php tests webpack.mix.js
4) 修改 docker-compose.yml
$ cd /home/docker/laravel
$ vim docker-compose.yml
version: "3"
services:
nginx:
image: nginx
container_name: nginx-php7.4
ports:
- "80:80"
restart: always
volumes:
- /home/docker/nginx/conf.d:/etc/nginx/conf.d
- /home/docker/laravel/laravel-demo/public:/usr/share/nginx/html
- /home/docker/nginx/logs:/var/log/nginx
mariadb:
image: mariadb:10.4
container_name: mariadb-10.4
ports:
- "3306:3306"
restart: always
environment:
- MARIADB_ROOT_PASSWORD=123456
volumes:
- /home/docker/mysql/conf:/etc/mysql/conf.d
- /home/docker/mysql/data:/var/lib/mysql
- /home/docker/mysql/log:/var/log/mysql
php:
image: php:7.4-fpm-mysqli
container_name: php-7.4-fpm-mysqli
depends_on:
- nginx
- mariadb
build: .
ports:
- "9000:9000"
restart: always
volumes:
- /home/docker/php/conf.d:/usr/local/etc/php/conf.d
- /home/docker/laravel/laravel-demo/public:/var/www/html
- /home/docker/laravel/laravel-demo:/var/www
注:修改 services.nginx.volumes,挂载 /home/docker/laravel/laravel-demo/public:/usr/share/nginx/html。
修改 services.php.volumes,挂载 /home/docker/laravel/laravel-demo/public:/var/www/html 和 /home/docker/laravel/laravel-demo:/var/www。
laravel-demo 的入口文件是 laravel-demo/public/index.php,所以挂载 /home/docker/laravel/laravel-demo/public:/var/www/html 。
挂载 /home/docker/laravel/laravel-demo:/var/www,是因为 laravel-demo/public/index.php 需要用到它上级目录里的文件,所以上级目录也需要挂载。
5) 修改 nginx.conf
$ cd /home/docker/nginx/conf.d
$ vim nginx.conf
server {
listen 80 default_server;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.php index.html index.htm;
# 根据 laravel 规则进行 url 重写
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php(.*)$ {
root /var/www/html;
fastcgi_pass php-7.4-fpm-mysqli:9000;
fastcgi_index index.php;
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
include fastcgi_params;
}
}
6) 运行
$ cd /home/docker/laravel
$ docker-compose up -d
浏览器访问 http://192.168.0.10/,显示 Laravel 空项目的默认页面。
8. 配置 phpMyAdmin
1) 下载 phpMyAdmin
phpMyAdmin 官网: https://www.phpmyadmin.net/,本文使用 phpMyAdmin 4.9.3。
$ cd /home/docker/laravel
$ wget https://files.phpmyadmin.net/phpMyAdmin/4.9.3/phpMyAdmin-4.9.3-all-languages.tar.gz
$ tar -vxzf phpMyAdmin-4.9.3-all-languages.tar.gz
$ mv phpMyAdmin-4.9.3-all-languages phpmyadmin
2) 配置 MariaDB 连接
$ cd /home/docker/laravel/phpmyadmin
$ cp config.sample.inc.php config.inc.php
$ vim config.inc.php ...
/**
* First server
*/
$i++;
/* Authentication type */
$cfg['Servers'][$i]['auth_type'] = 'config';
/* Server parameters */
//$cfg['Servers'][$i]['host'] = '192.168.0.10';
$cfg['Servers'][$i]['host'] = 'mariadb-10.4';
$cfg['Servers'][$i]['user'] = 'root';
$cfg['Servers'][$i]['password'] = '123456';
$cfg['Servers'][$i]['compress'] = false;
$cfg['Servers'][$i]['AllowNoPassword'] = false;
...
/**
* Directories for saving/loading files from server
*/
$cfg['UploadDir'] = './storage/uploads/';
$cfg['SaveDir'] = './storage/downloads';
$cfg['TempDir'] = './storage/tmp';
$cfg['ZipDump'] = true;
...
注:这里的 storage 目录在 phpMyAdmin 的根目录下,把 storage 目录及其子目录的权限改成 777。
ZipDump 开启支持导入/导出 zip 文件。
auth_type 设置为 cookie 时,访问 phpMyAdmin 页面,需要输入用户名和密码。
3) 修改 docker-compose.yml
$ cd /home/docker/laravel
$ vim docker-compose.yml
version: "3"
services:
nginx:
image: nginx
container_name: nginx-php7.4
ports:
- "80:80"
restart: always
volumes:
- /home/docker/nginx/conf.d:/etc/nginx/conf.d
- /home/docker/laravel/laravel-demo/public:/usr/share/nginx/html
- /home/docker/nginx/logs:/var/log/nginx
- /home/docker/laravel/phpmyadmin:/usr/share/nginx/html/phpmyadmin
mariadb:
image: mariadb:10.4
container_name: mariadb-10.4
ports:
- "3306:3306"
restart: always
environment:
- MARIADB_ROOT_PASSWORD=123456
volumes:
- /home/docker/mysql/conf:/etc/mysql/conf.d
- /home/docker/mysql/data:/var/lib/mysql
- /home/docker/mysql/log:/var/log/mysql
php:
image: php:7.4-fpm-mysqli
container_name: php-7.4-fpm-mysqli
depends_on:
- nginx
- mariadb
build: .
ports:
- "9000:9000"
restart: always
volumes:
- /home/docker/php/conf.d:/usr/local/etc/php/conf.d
- /home/docker/laravel/laravel-demo/public:/var/www/html
- /home/docker/laravel/laravel-demo:/var/www
- /home/docker/laravel/phpmyadmin:/var/www/html/phpmyadmin
注:修改 services.nginx.volumes,挂载 /home/docker/laravel/phpmyadmin:/usr/share/nginx/html/phpmyadmin。
修改 services.php.volumes,挂载 /home/docker/laravel/phpmyadmin:/var/www/html/phpmyadmin。
也可以不挂载 phpmyadmin 目录,把整个目录复制到 /home/docker/laravel/laravel-demo/public 目录下,可以运行。为了保持项目的独立性,不建议复制整个 phpmyadmin 到 /home/docker/laravel/laravel-demo/public 目录下。
另外,在 /home/docker/laravel/laravel-demo/public 目录下建立软链接到 phpmyadmin 也不可行,因为容器内无法读取软连接下的文件资源。
4) 运行
$ cd /home/docker/laravel
$ docker-compose down
$ docker-compose up -d
浏览器访问 http://192.168.0.10/phpmyadmin,页面显示 phpMyAdmin 主页。