引言
一直在windows中开发,为了便捷开发,不用搭建虚拟机等,可以使用桌面版docker解决这个问题。下面是多项目开发使用的LNMP环境。
正文
条件准备
正常从 Docker https://www.docker.com/ 官网下载安装即可。
修改为国内源加速,在docker desktop的设置中setting配置即可,Docker Engine中写入下面内容,然后Apply应用并重启Docker Desktop:
{
"builder": {
"gc": {
"defaultKeepStorage": "20GB",
"enabled": true
}
},
"experimental": false,
"registry-mirrors": [
"https://docker.1ms.run",
"https://dockerproxy.com",
"https://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn"
]
}
需要说明 docker config set --global registry-mirrors命令无效,不可用。
项目的目录结构如下:
D:\develop
├── DockerEnv
├── docker-multi-web
├── dockerfile # PHP+Nginx基础镜像构建文件
├── nginx
├── nginx.conf # Nginx主配置
└── vhost # 多站点虚拟主机配置目录
├── site1.conf # 站点1配置
└── site2.conf # 站点2配置
├── mysql-server
├── mysql-data # MySQL持久化数据
├── www
├── site1 # 项目1:test1.local
│ └── index.php
└── site2 # 项目2:test2.local
└── index.php
搭建网桥docker network create web-net,如:
D:\develop\DockerEnv>docker network create web-net
2b27ad41e8489e7765f93e2fec27eb9321cf88e0d65969f438f7d3ea844d8de6
D:\develop\DockerEnv>
安装MySQL:
MySQL 不要放进自定义 Image。如果把 MySQL 打包进镜像,删除容器会丢失数据库数据,无法持久化;分离容器更灵活,可单独重启、备份、更换 MySQL 版本。
Docker Hub 官方已经提供好现成的 mysql:8.0 官方镜像,直接 docker run 拉取启动即可,不需要自己打包 MySQL。
启动MySQL容器:
docker run -d --name mysql8 --network web-net -v D:/develop/DockerEnv/mysql-server/mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=testdb -e MYSQL_ROOT_HOST=% -p 3306:3306 mysql:8.0
加上 MYSQL_ROOT_HOST=%,否则外部 Windows、PHP 容器无法连接数据库。-e MYSQL_ROOT_HOST=% 允许 PHP 容器、本机 Navicat 全部访问,本地开发必备。
运行完成后在Docker Desktop中查看MySQL容器是否启动成功,Container、Image等。
外部连接时,连接地址不要使用 127.0.0.1,而要使用 mysql8 。
Nginx 配置
nginx.conf 内容:
user www-data;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
# 加载所有站点虚拟主机配置
include /etc/nginx/conf.d/*.conf;
}
项目配置
下面看几个项目的配置。
项目一
site1.conf 内容:
server {
listen 80;
server_name test1.local www.test1.local;
root /usr/share/nginx/www/site1;
index index.html index.htm index.php;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
www/site1/index.php 内容:
<?php
echo "<h2>站点1 test1.local</h2>";
phpinfo();
项目二
site2.conf 内容:
server {
listen 80;
server_name test2.local www.test2.local;
root /usr/share/nginx/www/site2;
index index.html index.htm index.php;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
www/site2/index.php 内容:
<?php
echo "<h2>站点2 test2.local</h2>";
// 测试mysql连接
$dsn = 'mysql:host=mysql8;dbname=testdb;charset=utf8';
try {
$db = new PDO($dsn, 'root', '123456');
echo "<p>MySQL连接成功</p>";
}catch (PDOException $e){
echo "<p>数据库连接失败:".$e->getMessage()."</p>";
}
www/site2/index.php 内容:
<?php
echo "hello world";
?>
hosts 配置
在宿主机的 C:\Windows\System32\drivers\etc\hosts 文件中添加:
127.0.0.1 test1.local
127.0.0.1 test2.local
如果提示无权限修改,可以用管理员权限打开记事本,然后用记事本打开该文件进行修改并保存。
安装 Nginx + PHP
接下来安装Nginx+PHP。
dockerfile 内容:
FROM quay.io/centos/centos:stream9-minimal
# 1. 替换 CentOS 基础源为阿里云
RUN sed -e 's|mirror.centos.org|mirrors.aliyun.com|g' \
-e 's|mirror.stream.centos.org|mirrors.aliyun.com|g' \
-i /etc/yum.repos.d/centos*.repo && \
microdnf clean all && microdnf makecache
# 2. 强制移除 curl-minimal,再安装 dnf 和 curl
RUN rpm -e --nodeps curl-minimal && \
microdnf install -y dnf curl && \
microdnf clean all
# 3. 安装 epel-release 并替换为阿里云 EPEL 镜像
RUN dnf install -y epel-release && \
sed -e 's|https://download.fedoraproject.org/pub|https://mirrors.aliyun.com/fedora-epel|g' \
-i /etc/yum.repos.d/epel*.repo && \
dnf clean all && dnf makecache
# 4. 安装 Remi 源并替换为清华镜像(国内唯一完整同步Remi)
RUN dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm && \
sed -e 's|https://rpms.remirepo.net|https://mirrors.tuna.tsinghua.edu.cn/remi|g' \
-i /etc/yum.repos.d/remi*.repo && \
dnf clean all && dnf makecache
# 5. 安装 Nginx + 启用 php:remi-7.4 模块并安装全部组件 + 系统底层时区库
RUN dnf module enable -y php:remi-7.4 && \
dnf install -y \
nginx \
php-fpm \
php-cli \
php-mysqlnd \
php-pdo \
php-gd \
php-zip \
php-curl \
php-mbstring \
php-opcache \
php-xml \
vim unzip && \
dnf clean all
# 6.安装 tzdata 并重装确保时区数据文件存在
RUN dnf install -y tzdata && \
dnf reinstall -y tzdata
# 7. 修改 php-fpm 运行用户为 nginx,解决页面403权限
RUN sed -i 's/^user = apache/user = nginx/' /etc/php-fpm.d/www.conf && \
sed -i 's/^group = apache/group = nginx/' /etc/php-fpm.d/www.conf && \
sed -i 's/^listen = .*/listen = 127.0.0.1:9000/' /etc/php-fpm.d/www.conf
# 8. 统一设置系统时区+PHP时区配置,彻底消除时区报错
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo 'date.timezone = Asia/Shanghai' > /etc/php.d/99-timezone.ini
# 9. 安装 Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# 10. 手动创建 Composer 全局配置文件(阿里云镜像)
RUN mkdir -p /root/.composer && \
echo '{"config": {"repositories": {"packagist": {"type": "composer", "url": "https://mirrors.aliyun.com/composer/"}}}}' > /root/.composer/config.json
# 11. 复制本地Nginx主配置 + 多站点虚拟主机目录
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
# 12. 创建站点根目录并授权nginx读写权限
RUN mkdir -p /usr/share/nginx/www && \
chown -R nginx:nginx /usr/share/nginx/www
EXPOSE 80
# 启动php-fpm + 前台运行nginx,防止容器自动退出
CMD ["sh", "-c", "mkdir -p /run/php-fpm && chown nginx:nginx /run/php-fpm && php-fpm -F & nginx -g 'daemon off;'"]
这一块用了好长时间,说一下里面的注意点。基础镜像用的是centos:stream9精简版,为了国内加速,CentOS 基础源换为了阿里云。里面多处安装用到了dnf,但基础镜像 quay.io/centos/centos:stream9-minimal 默认的仓库配置中,没有可用的 dnf 包(尽管 microdnf 是内置的,但microdnf 本身是轻量级包管理器,好多包的安装还是要用到dnf),有些地方也要用到curl(尽管 curl-minimal 是内置的,但有些下载是要用到curl的,而curl 包与 curl-minimal 冲突),我们需要强制移除 curl-minimal,再安装 dnf 和 curl。还有centos:stream9精简版底层是缺少系统底层时区库,安装Composer会用到。Composer 全局配置文件改为阿里云,命令行总是无法执行,无奈改为手动创建。php-fpm 一般是用socket实现,绑定地址 /run/php-fpm/www.sock,这是一个临时目录,在容器启动时需要创建该目录;但这里改下来有问题,最后改为了 127.0.0.1:9000 端口监听。php-fpm -F前台运行会阻塞后面nginx -g 'daemon off;'的执行,所以不能用&&,而是改为&。
centos:stream9-minimal 为精简镜像,有意删除了 /usr/share/zoneinfo,导致tzdata安装不完整,需要重新安装dnf reinstall -y tzdata。之后 第10步 可以修改看一下能否正常安装:
# 10. 设置 Composer 全局为阿里云镜像
php -d date.timezone=Asia/Shanghai composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
生成镜像:
docker build -t centos9-nginx-php74 .
创建容器:
docker run -d --name centos9-nginx-php74 --network web-net -v D:/develop/www:/usr/share/nginx/www -v D:/develop/DockerEnv/docker-multi-web/nginx/vhost:/etc/nginx/conf.d -p 8080:80 centos9-nginx-php74
浏览器访问,查看效果:
- 站点 1:http://test1.local:8080
- 站点 2:http://test2.local:8080
新项目配置
和第二个项目一样,除了项目文件,另外需要写site3.conf配置,修改hosts文件。
重启容器:
docker restart centos9-nginx-php74
PHP8.3 安装
dockerfile 内容:
FROM quay.io/centos/centos:stream9
# 1. 替换 CentOS 基础源为阿里云
RUN sed -e 's|mirror.centos.org|mirrors.aliyun.com|g' \
-e 's|mirror.stream.centos.org|mirrors.aliyun.com|g' \
-i /etc/yum.repos.d/centos*.repo && \
microdnf clean all && microdnf makecache
# 2. 强制移除 curl-minimal,再安装 dnf 和 curl
RUN rpm -e --nodeps curl-minimal && \
microdnf install -y dnf curl && \
microdnf clean all
# 3. 安装 epel-release 并替换为阿里云 EPEL 镜像
RUN dnf install -y epel-release && \
sed -e 's|https://download.fedoraproject.org/pub|https://mirrors.aliyun.com/fedora-epel|g' \
-i /etc/yum.repos.d/epel*.repo && \
dnf clean all && dnf makecache
# 4. 安装 Remi 源并替换为清华镜像(国内唯一完整同步Remi)
RUN dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm && \
sed -e 's|https://rpms.remirepo.net|https://mirrors.tuna.tsinghua.edu.cn/remi|g' \
-i /etc/yum.repos.d/remi*.repo && \
dnf clean all && dnf makecache
# 5. 安装 Nginx + 启用 php:remi-7.4 模块并安装全部组件 + 系统底层时区库
RUN dnf module enable -y php:remi-7.4 && \
dnf install -y \
nginx \
git \
php-fpm \
php-cli \
php-mysqlnd \
php-pdo \
php-gd \
php-zip \
php-curl \
php-mbstring \
php-opcache \
php-xml \
vim unzip && \
dnf clean all
# 6.安装 tzdata 并重装确保时区数据文件存在
RUN dnf install -y tzdata && \
dnf reinstall -y tzdata
# 7. 修改 php-fpm 运行用户为 nginx,解决页面403权限
RUN sed -i 's/^user = apache/user = nginx/' /etc/php-fpm.d/www.conf && \
sed -i 's/^group = apache/group = nginx/' /etc/php-fpm.d/www.conf && \
sed -i 's/^listen = .*/listen = 127.0.0.1:9000/' /etc/php-fpm.d/www.conf
# 8. 统一设置系统时区+PHP时区配置,彻底消除时区报错
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo 'date.timezone = Asia/Shanghai' > /etc/php.d/99-timezone.ini
# 9. 安装 Composer
RUN curl -sS https://mirrors.aliyun.com/composer/composer.phar | php -- --install-dir=/usr/local/bin --filename=composer
# 10. 手动创建 Composer 全局配置文件(阿里云镜像)
RUN mkdir -p /root/.composer && \
echo '{"config": {"repositories": {"packagist": {"type": "composer", "url": "https://mirrors.aliyun.com/composer/"}}}}' > /root/.composer/config.json
# 11. 复制本地Nginx主配置 + 多站点虚拟主机目录
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
# 12. 创建站点根目录并授权nginx读写权限
RUN mkdir -p /usr/share/nginx/www && \
chown -R nginx:nginx /usr/share/nginx/www
EXPOSE 80
# 启动php-fpm + 前台运行nginx,防止容器自动退出
CMD ["sh", "-c", "mkdir -p /run/php-fpm && chown nginx:nginx /run/php-fpm && php-fpm -F & nginx -g 'daemon off;'"]
centos:stream9-minimal 为精简镜像,缺少好多东西,我们直接用centos:stream9,需要时我们也可以把git安装上。
生成镜像:
docker build -t centos9-nginx-php83 .
创建容器:
docker run -d --name centos9-nginx-php83 --network web-net -v D:/develop/www:/usr/share/nginx/www -v D:/develop/DockerEnv/docker-multi-web/nginx/vhost:/etc/nginx/conf.d -p 8081:80 centos9-nginx-php83