Docker 部署博客系统

junlan
49
2025-02-19

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

image-20250214150251201

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

前台效果:http://typecho.land.com/

image-20250214150528008

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

4.2.1 Easyimage 设置

开启 API 上传

image-20250219113918163

简单图床 - EasyImage

1739936398918

4.3 兰空图床

https://www.lsky.pro/