php8.3-fpm(FastCGI Process Manager)
: php + FastCGI
php8.3-apache
: php + apache
1. Blog 整合(halo、wordpress、typecho)
1.1 nginx 配置
1.1.1 default.conf 配置文件
[root@blog blog~]# cat /blog/nginx/default.conf
server {
listen 80;
server_name wordpress.land.com;
location / {
proxy_set_header Host $host; # 将客户端请求的Host头字段转发到后端服务器
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 记录将客户端的真实IP地址(或中间代理的IP地址)转发到后端服务器
proxy_pass http://wordpress/;
}
}
[root@blog blog]# cat /blog/nginx/default.conf
server {
listen 80;
server_name land.snimay.net;
# 将 HTTP 请求重定向到 HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name land.snimay.net;
# 将该服务下的所有请求实体限制的大小
client_max_body_size 1g;
# 设置 SSL 证书和私钥
ssl_certificate /etc/nginx/conf.d/server.pem; # 证书文件
ssl_certificate_key /etc/nginx/conf.d/server.key; # 私钥文件
# 其他 SSL 配置
ssl_protocols TLSv1.2 TLSv1.3; # 启用现代的 TLS 协议
ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-RSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers on;
# 设置其他安全头(可选)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 配置反向代理到内部服务
location / {
proxy_pass http://halo:8090/; # 请求代理到halo容器(使用容器名而不不是IP地址避免ip地址变更问题)
proxy_set_header Host $host; # 设置代理请求的 Host 头为客户端原始请求的 Host 头(如,如果客户端访问 http://example.com,则 Host 头的值为 example.com)
proxy_set_header X-Real-IP $remote_addr; # 通过 X-Real-IP 头获取客户端的真实 IP 地址,而不是 Nginx 服务器的 IP 地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 用于记录客户端的原始 IP 地址和经过的所有代理服务器 IP 地址
proxy_set_header X-Forwarded-Proto $scheme; # 可以通过 X-Forwarded-Proto 头判断客户端使用了 HTTPS 还是 HTTP 协议。
}
# 访问 /resume 时显示 /etc/nginx/conf.d/resume/(宿主机/blog/nginx下的resume目录 ) 下的 index.html
location /resume {
root /etc/nginx/conf.d/; # 设置静态文件根目录
index index.html; # 默认加载的文件
}
}
1.1.2 wordpress.land.com.conf 配置文件
[root@blog blog]# cat nginx/wordpress.land.com.conf
server {
listen 80;
server_name wordpress.land.com;
location / {
proxy_set_header Host $host; # 将客户端请求的Host头字段转发到后端服务器
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 记录将客户端的真实IP地址(或中间代理的IP地址)转发到后端服务器
proxy_pass http://wordpress/;
}
}
1.1.3 typecho.land.com.conf 配置文件
[root@blog blog]# cat nginx/typecho.land.com.conf
server {
listen 80;
server_name typecho.land.com;
location / {
proxy_set_header Host $host; # 将客户端请求的Host头字段转发到后端服务器
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 记录将客户端的真实IP地址(或中间代理的IP地址)转发到后端服务器
proxy_pass http://typecho/;
}
}
1.1.4 blogimg.conf 配置文件(图床系统)
[root@blog blog]# cat <<EOF > nginx/blogimg.conf
server {
listen 80;
server_name blogimg;
location / {
proxy_set_header Host $host; # 将客户端请求的Host头字段转发到后端服务器
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 记录将客户端的真实IP地址(或中间代理的IP地址)转发到后端服务器
proxy_pass http://blogimg/;
}
}
EOF
1.1.5 compose.yanl 配置文件
[root@blog blog]# cat compose.yaml
services:
halo:
image: registry.fit2cloud.com/halo/halo:2.20.14
restart: always
depends_on:
halodb:
condition: service_healthy # 不仅要等待服务启动,还会等待服务本身报告为监控才会启动本halo服务
volumes:
- ./halo/halo2:/root/.halo2
# ports:
# - "8090:8090" # 转用 nginx 访问
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8090/actuator/health/readiness"] # curl -f 遇到错误时直接返回错误代码,不输出服务器返回的具体内容
interval: 30s # 健康检查的频率,每隔30秒执行一次
timeout: 5s
retries: 5 # 健康检查失败后重试的次数,连续5次健康检查都失败,Docker将认为容器不健康
start_period: 30s # 容器启动后30秒内不会执行健康检查。30秒的启动期过后,健康检查将会每interval的频率执行一次
environment:
# JVM 参数,默认为 -Xmx256m -Xms256m,可以根据实际情况做调整,置空表示不添加 JVM 参数
- JVM_OPTS=-Xmx256m -Xms256m # 设置JVM(Java虚拟机)的最大堆内存为256MB
command:
- --spring.r2dbc.url=r2dbc:pool:postgresql://halodb/halo
- --spring.r2dbc.username=halo
# PostgreSQL 的密码,请保证与下方 POSTGRES_PASSWORD 的变量值一致。
- --spring.r2dbc.password=openpostgresql
- --spring.sql.init.platform=postgresql
# 外部访问地址,请根据实际需要修改
- --halo.external-url=https://land.snimay.net:6900/
networks:
- blog_net
halodb:
image: postgres:15.4 # 2025.02.14 最新的版为17.3
# restart: on-failure:3
restart: always
volumes:
- ./halo/db:/var/lib/postgresql/data
healthcheck:
test: [ "CMD", "pg_isready" ]
interval: 10s
timeout: 5s
retries: 5
environment:
- POSTGRES_PASSWORD=openpostgresql
- POSTGRES_USER=halo
- POSTGRES_DB=halo
- PGUSER=halo
networks:
- blog_net
wordpress:
image: wordpress:6.7.2
volumes:
- ./wordpress/wp_data:/var/www/html
- ./wordpress/php.ini:/usr/local/etc/php/conf.d/php.ini
restart: always
environment:
- WORDPRESS_DB_HOST=wordpressdb
- WORDPRESS_DB_USER=wordpress
- WORDPRESS_DB_PASSWORD=wordpress
- WORDPRESS_DB_NAME=wordpress
networks:
blog_net:
wordpressdb:
image: mariadb:11.6.2 # 2025.02.14 docker 默认提供最新的稳定版11.6.2,官网和 github 最新为11.7.2
command: '--default-authentication-plugin=mysql_native_password'
volumes:
- ./wordpress/db_data:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=somewordpress
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=wordpress
expose:
- 3306
networks:
blog_net:
typecho:
image: joyqi/typecho:nightly-php8.2-apache
restart: always
environment:
TYPECHO_DB_HOST: typechodb #默认值是localhost,docker部署时可以用服务名充当主机名
TYPECHO_DB_USER: MYSQL_USER #数据库用户名
TYPECHO_DB_PASSWORD: MYSQL_PASSWORD #数据库密码
TYPECHO_DB_DATABASE: MYSQL_DATABASE #所用的database
volumes:
- ./typecho/typecho_data:/app/usr # /app/usr是typecho数据文件
depends_on:
- typechodb
networks:
- blog_net
typechodb:
image: mysql:9.2.0 # 2025.02.14 最新版本
restart: always
volumes:
- ./typecho/db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--silent"] # 通过 mysqladmin 工具发送一个 ping 请求检查 MySQL 容器是否响应。
interval: 3s
retries: 5
start_period: 30s
environment:
MYSQL_DATABASE: typecho
MYSQL_USER: typecho #数据库用户名
MYSQL_PASSWORD: typecho #数据库密码
MYSQL_RANDOM_ROOT_PASSWORD: 'Root@2020' # 设置MySQL root密码
networks:
- blog_net
blogimg:
image: ddsderek/easyimage:latest
restart: always
environment:
- TZ=Asia/Shanghai
- PUID=1000
- PGID=1000
- DEBUG=false
volumes:
- './easyimage/config:/app/web/config'
- './easyimage/i:/app/web/i' # 图片存放的真实位置
networks:
- blog_net
nginx:
image: nginx:1.27.4
restart: always
volumes:
- ./nginx:/etc/nginx/conf.d/
ports:
- "80:80"
- "443:443"
networks:
- blog_net
networks:
blog_net:
1.2 运行容器
[root@blog blog]# docker compose up -d
[+] Running 8/8
✔ Network blog_blog_net Created 0.3s
✔ Container blog-wordpressdb-1 Started 1.4s
✔ Container blog-typechodb-1 Started 1.3s
✔ Container blog-nginx-1 Started 1.4s
✔ Container blog-halodb-1 Healthy 11.8s
✔ Container blog-wordpress-1 Started 1.3s
✔ Container blog-halo-1 Started 12.4s
✔ Container blog-typecho-1 Started 2.1s
[root@blog blog]# docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
blog-halo-1 registry.fit2cloud.com/halo/halo:2.20.14 "sh -c 'java ${JVM_O…" halo About a minute ago Up About a minute (healthy) 8090/tcp
blog-halodb-1 postgres:15.4 "docker-entrypoint.s…" halodb About a minute ago Up About a minute (healthy) 5432/tcp
blog-nginx-1 nginx:1.27.4 "/docker-entrypoint.…" nginx About a minute ago Up About a minute 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp
blog-typecho-1 joyqi/typecho:nightly-php8.2-apache "docker-php-entrypoi…" typecho About a minute ago Up About a minute 80/tcp
blog-typechodb-1 mysql:9.2.0 "docker-entrypoint.s…" typechodb About a minute ago Up About a minute (healthy) 3306/tcp, 33060/tcp
blog-wordpress-1 wordpress:6.7.2 "docker-entrypoint.s…" wordpress About a minute ago Up About a minute 80/tcp
blog-wordpressdb-1 mariadb:11.6.2 "docker-entrypoint.s…" wordpressdb About a minute ago Up About a minute 3306/tcp
# 删除悬虚(dangling)镜像
[root@blog blog]# docker image prune
# 删除没有被任何容器使用的镜像
[root@blog blog]# docker image prune -a
[root@blog blog]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
wordpress 6.7.2 8a0d05df9d95 2 days ago 701MB
nginx 1.27.4 97662d24417b 8 days ago 192MB
registry.fit2cloud.com/halo/halo 2.20.14 e1fc683d04a6 3 weeks ago 428MB
mysql 9.2.0 c013d3763e14 3 weeks ago 797MB
joyqi/typecho nightly-php8.2-apache 3916b42de9c0 4 weeks ago 509MB
mariadb 11.6.2 027c25922bcd 2 months ago 415MB
postgres 15.4 68a92c148701 17 months ago 411MB
2. Wordpress
2.1 nginx 配置
[root@localhost nginx]# vim default.conf
server {
listen 80;
server_name wp.land.com;
location / {
proxy_set_header Host $host; # 将客户端请求的Host头字段转发到后端服务器
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 记录将客户端的真实IP地址(或中间代理的IP地址)转发到后端服务器
proxy_pass http://wordpress/;
}
}
2.2 compose 文件配置
[root@localhost nginx]# vim /blog/compose.yaml
services:
wordpress:
image: wordpress:6.7.2
volumes:
- /blog/wordpress/wp_data:/var/www/html
- /blog/wordpress/php.ini:/usr/local/etc/php/conf.d/php.ini
#ports:
#- 80:80 # 转用 nginx 访问
restart: always
environment:
- WORDPRESS_DB_HOST=wordpressdb
- WORDPRESS_DB_USER=wordpress
- WORDPRESS_DB_PASSWORD=wordpress
- WORDPRESS_DB_NAME=wordpress
networks:
blog_net:
wordpressdb:
image: mariadb:11.6.2
command: '--default-authentication-plugin=mysql_native_password'
volumes:
- /blog/wordpress/db_data:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=somewordpress
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=wordpress
expose: # 仅用于容器间通信,不对外暴露
- 3306
networks:
blog_net:
blogngx:
image: nginx:1.27.4
restart: always
volumes:
- ./nginx:/etc/nginx/conf.d/
ports:
- "80:80"
- "443:443"
networks:
- blog_net
networks:
blog_net:
2.3 访问测试
管理后台:http://wp.land.com/wp-admin/ (http://wp.land.com/admin/)
前台效果:http://wp.land.com
2.3.1 http 抓包
GET
http://192.168.110.132/
版本HTTP/1.1
传输12.44 kB(大小 57.03 kB)
Connection
Keep-Alive
Content-Encoding
gzip
Server
Apache/2.4.62 (Debian)
X-Powered-By
PHP/8.2.27
3. Typecho
3.1 nginx 配置
[root@localhost typecho]# cat ./nginx/default.conf
server {
listen 80;
server_name typecho.land.com;
location / {
proxy_set_header Host $host; # 将客户端请求的Host头字段转发到后端服务器
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 记录将客户端的真实IP地址(或中间代理的IP地址)转发到后端服务器
proxy_pass http://typecho/;
}
}
3.2 compose 文件配置
[root@localhost typecho]# vim compose.yaml
services:
typecho:
image: joyqi/typecho:nightly-php8.2-apache
restart: always
#ports:
#- 80:80 # 转用 nginx 访问
environment:
TYPECHO_DB_HOST: typechodb #默认值是localhost,docker部署时可以用服务名充当主机名
TYPECHO_DB_USER: MYSQL_USER #数据库用户名
TYPECHO_DB_PASSWORD: MYSQL_PASSWORD #数据库密码
TYPECHO_DB_DATABASE: MYSQL_DATABASE #所用的database
volumes:
- ./typecho/typecho_data:/app/usr # /app/usr是typecho数据文件
depends_on:
- typechodb
networks:
- blog_net
typechodb:
image: mysql:9.2.0
restart: always
volumes:
- ./typecho/db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--silent"] # 通过 mysqladmin 工具发送一个 ping 请求检查 MySQL 容器是否响应。
interval: 3s
retries: 5
start_period: 30s
environment:
MYSQL_DATABASE: typecho
MYSQL_USER: typecho #数据库用户名
MYSQL_PASSWORD: typecho #数据库密码
MYSQL_RANDOM_ROOT_PASSWORD: 'Root@2020' # 设置MySQL root密码
networks:
- blog_net
blogngx:
image: nginx:1.27.4
restart: always
volumes:
- ./nginx:/etc/nginx/conf.d/
ports:
- "80:80"
- "443:443"
networks:
- blog_net
networks:
blog_net:
3.3 访问测试
管理后台:http://typecho.land.com/admin
4. 图床系统
4.1 Picsur
https://github.com/CaramelFur/Picsur/issues/56
https://github.com/CaramelFur/Picsur/issues/54
http://blogimg:8080
默认账号密码:admin/picsur
# https://github.com/CaramelFur/Picsur?tab=readme-ov-file
[root@localhost picsur]# cat compose.yaml
services:
picsur:
image: ghcr.io/caramelfur/picsur:latest
container_name: picsur
ports:
- '8080:8080'
environment:
# PICSUR_HOST: '0.0.0.0'
# PICSUR_PORT: 8080
PICSUR_DB_HOST: picsur_postgres
# PICSUR_DB_PORT: 5432
# PICSUR_DB_USERNAME: picsur
# PICSUR_DB_PASSWORD: picsur
# PICSUR_DB_DATABASE: picsur
## The default username is admin, this is not modifiable
# PICSUR_ADMIN_PASSWORD: picsur
## Optional, random secret will be generated if not set
# PICSUR_JWT_SECRET: CHANGE_ME
# PICSUR_JWT_EXPIRY: 7d
## Maximum accepted size for uploads in bytes
# PICSUR_MAX_FILE_SIZE: 128000000
## No need to touch this, unless you use a custom frontend
# PICSUR_STATIC_FRONTEND_ROOT: "/picsur/frontend/dist"
## Warning: Verbose mode might log sensitive data
# PICSUR_VERBOSE: "true"
restart: unless-stopped
picsur_postgres:
image: postgres:17-alpine
container_name: picsur_postgres
environment:
POSTGRES_DB: picsur
POSTGRES_PASSWORD: picsur
POSTGRES_USER: picsur
restart: unless-stopped
volumes:
- ./picsur-data:/var/lib/postgresql/data
#volumes:
#picsur-data:
4.2 Easyimage
# https://github.com/DDS-Derek/EasyImages-Docker
# https://icret.github.io/EasyImages2.0/
[root@localhost blog]# mkdir easyimage
[root@localhost easyimage]# cat compose.yaml
services:
easyimage:
image: ddsderek/easyimage:latest
container_name: easyimage
ports:
- '8090:80'
environment:
- TZ=Asia/Shanghai
- PUID=1000
- PGID=1000
- DEBUG=false
volumes:
- './config:/app/web/config'
- './i:/app/web/i' # 图片存放的真实位置
restart: unless-stopped
services:
easyimage:
image: ddsderek/easyimage:latest
container_name: easyimage
#ports:
#- '8090:80'
environment:
- TZ=Asia/Shanghai
- PUID=1000
- PGID=1000
- DEBUG=false
volumes:
- './config:/app/web/config'
- './i:/app/web/i' # 图片存放的真实位置
restart: always