Laravel 是 PHP 的一个 WEB 框架,部署操作有些复杂,且 PHP 不像 node.js 服务器和解释器在一块,而是分开的。
Composer 是包管理器,Laravel Artisan 是 Laravel 框架的工具,和数据库连接以及写入数据库初始数据等。
共需要六个容器。
首先创建一个 docker-compose
配置整个项目的运行:
version: '3.8'
services:
server:
php:
mysql:
composer:
laravel:
npm:
ngnix server
services:
server:
image: "nginx:stable-alpine"
ports:
- "7749:80"
volumes:
- "./nginx/nginx.conf:/etc/nginx/nginx.conf:ro"
使用官方的轻量镜像并开放端口以及配置 nginx,其中配置如下:
server {
listen 80;
index index.php index.html;
server_name localhost;
root /var/www/html/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:3000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
php 解释环境
官方的php镜像会默认持续运行一个解释环境,当nginx请求时会自动处理,因此不需要我们写 CMD 或者 ENTRYPOINT,创建一个 php.dockerfile
文件配置镜像:
FROM php:8.2-fpm-alpine
WORKDIR /var/www/html
RUN docker-php-ext-install pdo pdo_mysql
其中 WORKDIR
是 Nginx 中设定的网站目录,RUN
指令安装了一些 php 扩展。
然后是 docker-compose
:
services:
php:
build:
context: ./dockerfiles
dockerfile: php.dockerfile
volumes:
- ./src/:/var/www/html:delegated
这里改了dockerfile名字所以需要 配置上下文,之后使用 bind mounts 来将之后会生成的代码同步到宿主机以便进一步修改,delegated
是一个优化参数,让双方的同步操作不那么频繁。
端口的话由于是 nginx 去和 php 交互,我们宿主机并不需要访问,故不需要设置,但得修改 nginx 配置,将 php:3000
替换为 php:9000
因为官方的php镜像默认是在 9000 端口。
mysql
services:
mysql:
image: "mysql:5.7"
env_file:
- ./env/mysql.env
其中 env 文件内容:
MYSQL_DATABASE=homeset
MYSQL_USER=admin
MYSQL_PASSWORD=admin
MYSQL_ROOT_PASSWORD=admin
composer
作为 Utility Container 不仅需要被 Laravel 使用,也会用于最开始设置项目初始化架构。
首先创建对应的 dockerfile:
FROM composer:latest
WORKDIR /var/www/html
ENTRYPOINT [ "composer", "--ignore-platform-reqs" ]
以及 docker-compose:
services:
composer:
build:
context: ./dockerfiles
dockerfile: composer.dockerfile
volumes:
- ./src:/var/www/html
之后用 composer 先创建项目代码框架:
docker-compose run --rm composer create-project --prefer-dist laravel/laravel .
执行后会在本地 src 目录下生成项目文件,我们需要进一步修改 .env
文件来指定数据库:
而由于PHP代码是由 nginx 处理并交给 php 解释器处理,所以需要在项目目录中也加入代码目录:
services:
server:
image: "nginx:stable-alpine"
ports:
- "7749:80"
volumes:
- "./nginx/nginx.conf:/etc/nginx/nginx.conf:ro"
- "./src:/var/www/html"
这里不需要写 public,因为src下本身就有一个 public, 复制过去会直接替代。
至此就可以先运行服务器了,可以直接使用 docker-compose up
来全部运行,但 composer 是工具容器不是必要的,因此可以使用:
docker-compose up -d server php mysql
或者直接设定 server
依赖于 php
和 mysql
,然后只需要启动 server
即可。
不过运行之后会发现报错,Failed to open stream: Permission denied
,即 laravel 没有使用 /var/www/html
目录的权限,这是因为在 docker 管理中,每个容器程序的权限是独立的,需要在 PHP 容器中对文件夹开放:
FROM php:8.2-fpm-alpine
WORKDIR /var/www/html
RUN docker-php-ext-install pdo pdo_mysql
RUN chown -R www-data:www-data /var/www/html