总算把 WordPress 装到 Docker Compose 里面去了

当前这个网站,好久没维护了。之前是部署在一台比较老旧的 TencentOS 系统上,并且是比较老旧的 apache 版本,整台服务器都很难维护,迁移就比较麻烦,然后就一直放着没动它。原本部署的这台服务器配置也低,虽然一年几十元,但不打算续费了,今年年底就要到期了,就花了点时间捣鼓一下,先将它所有环境从宿主机迁入到 Docker Compose 中,然后整个 Docker Compose 项目打包迁移。当看到这篇文章的时候,是已经迁移成功了,目前部署在 RackNerd 的美国VPS服务器上,我买的是这款配置(超划算RackNerd服务器),非常不错(还拿来搭建了VPN服务器🚀),配置如下:

$29.89 /年 💰 (29.89 美元/年)

  • 🖥️ 3 vCPU 核心 (3 vCPU Cores)
  • 💾 60 GB SSD 存储 (60 GB SSD Storage)
  • 🧠 3.5 GB 内存 (3.5 GB RAM)
  • 📡 5 TB 月流量 (5 TB Monthly Transfer)
  • 🌐 1Gbps 网络端口 (1Gbps Network Port)
  • 🔑 完全根访问权限 (Full Root Access)
  • 🌍 1 个 IPv4 地址 (1 IPv4 Address)
  • ⚙️ KVM/SolusVM

如果购买的话,尽可能选择 DC3 机房,DC3 机房在中国访问的速度比较友好。在中国访问的速度与国际出入口带宽有关。

目前网站运行状况良好,除了昨天迁移时反复修改了几次 DNS 导致缓存产生而出现 SSL 安全提示之外,今早起来发现也恢复正常了。

现在来回顾一下昨天的迁移过程,怎样把 WordPress 装到 Docker Compose 里面来。主要工作分为三个部分:

 

第一部分,从宿主机导出 Mysql 数据库。

 

这个网站使用的是 Mysql 8.0.28 版本,服务器中还有其他网站的数据库,现在需要单独把 WordPress 博客的数据库导出来,也非常简单,只需要在命令行执行以下命令:

“`

mysqldump -u root -p –databases <数据库名称> –routines –events –triggers –single-transaction > <导出保存的名称>.sql
“`

执行之后会提示输出 root 密码,稍等几秒就导出完成了。

此时还需要把原来的 WordPress 网站目录整个复制到 Docker compose 项目根目录下(website)。

需要去 `wp-config.php` 修改 `DB_HOST` 为 `mysql` 。

 

第二部分,编写 docker-compose.yml 以及 Dockerfile。

 

为了把 WordPress 装到容器里,我给它准备了 Dockerfile 和 docker-compose.yml ,服务器本身就有 docker compose 环境,这里就不把环境准备展开赘述了。

Dockerfile:

“`

FROM php:8.3.24-fpm
# 接收构建时代理参数
# ARG http_proxy
# ARG https_proxy
# 安装 mysqli, pdo, pdo_mysql 模块
RUN docker-php-ext-install mysqli pdo pdo_mysql
# 设置 PHP 配置(例如:max_execution_time)
RUN echo ‘max_execution_time = 90’ >> /usr/local/etc/php/conf.d/my-php.ini
# 安装 gd 模块
RUN apt-get update && apt-get install -y \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libpng-dev \
    && docker-php-ext-configure gd –with-freetype –with-jpeg \
    && docker-php-ext-install gd
# 安装 exif 模块
RUN docker-php-ext-install exif
# 安装 imagick 模块
RUN apt-get install -y libmagickwand-dev –no-install-recommends \
    && (pecl install imagick || true) \
    && docker-php-ext-enable imagick
# 安装 zip 模块
RUN apt-get install -y \
        libzip-dev \
        zip \
  && docker-php-ext-install zip
# 安装 intl 模块
RUN apt-get install -y libicu-dev \
    && docker-php-ext-install intl
# 清理安装后的文件
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

“`

这份 Dockerfile 主要是构建了 php 环境的容器,并且把一些必须的扩展都打包进去了,有了这个环境就能跑 WordPress 或者其他 php 项目。
docker-compose.yml:
“`
services:
  nginx:
    image: nginx:1.25.3
    restart: always
    ports:
      – “127.0.0.1:8001:80”
    volumes:
      – ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      – ./website:/var/www/website
      – /etc/letsencrypt:/etc/letsencrypt:ro
      – ./ssl:/etc/ssl
      – ./nginxlog:/var/log/nginx
    depends_on:
      – php
    networks:
      – app-network
  php:
    build:
      context: .
      dockerfile: Dockerfile
    image: php:8.3.24-fpm
    restart: always
    volumes:
      – ./website:/var/www/website
      – ./php/php.ini:/usr/local/etc/php/php.ini
    networks:
      – app-network
  mysql:
    image:  mysql:8.0.28
    container_name: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: mysqlrootpassword
    volumes:
      – ./data:/var/lib/mysql
    networks:
      – app-network
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    restart: always
    ports:
      – “127.0.0.1:8002:80”
    environment:
      PMA_HOST: mysql
      MYSQL_ROOT_PASSWORD: mysqlrootpassword
    depends_on:
      – mysql
    networks:
      – app-network
networks:
  app-network:
    driver: bridge

“`
有了这两个文件,Docker Compose 就可以跑起来了。但还需要补充一下 php.ini 和 nginx.conf,因为我让这个 Docker Compose 同时提供了 php 和 nginx 的服务。

php/php.ini:
“`
[PHP]
engine = On
short_open_tag = Off
precision = 14
output_buffering = 4096
zlib.output_compression = Off
implicit_flush = Off
unserialize_callback_func =
serialize_precision = -1
disable_functions =
disable_classes =
zend.enable_gc = On
zend.exception_ignore_args = Off
expose_php = On
max_execution_time = 30
max_input_time = 60
memory_limit = 128M
error_reporting = E_ALL
display_errors = On
display_startup_errors = On
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
variables_order = “GPCS”
request_order = “GP”
register_argc_argv = Off
auto_globals_jit = On
post_max_size = 200M
auto_prepend_file =
auto_append_file =
default_mimetype = “text/html”
default_charset = “UTF-8”
doc_root =
user_dir =
enable_dl = Off
file_uploads = On
upload_max_filesize = 60M
max_file_uploads = 20
allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60
[CLI Server]
cli_server.color = On
[Date]
[filter]
[iconv]
[imap]
[intl]
[sqlite3]
[Pcre]
[Pdo]
pdo_mysql.default_socket=
[Phar]
[mail function]
SMTP = localhost
smtp_port = 25
mail.add_x_header = Off
[ODBC]
odbc.allow_persistent = On
odbc.check_persistent = On
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096
odbc.defaultbinmode = 1
[MySQLi]
mysqli.max_persistent = -1
mysqli.allow_persistent = On
mysqli.max_links = -1
mysqli.default_port = 3306
mysqli.default_socket =
mysqli.default_host =
mysqli.default_user =
mysqli.default_pw =
mysqli.reconnect = Off
[mysqlnd]
mysqlnd.collect_statistics = On
mysqlnd.collect_memory_statistics = On
[OCI8]
[PostgreSQL]
pgsql.allow_persistent = On
pgsql.auto_reset_persistent = Off
pgsql.max_persistent = -1
pgsql.max_links = -1
pgsql.ignore_notice = 0
pgsql.log_notice = 0
[bcmath]
bcmath.scale = 0
[browscap]
[Session]
session.save_handler = files
session.use_strict_mode = 0
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.cookie_samesite =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.referer_check =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.sid_length = 26
session.trans_sid_tags = “a=href,area=href,frame=src,form=”
session.sid_bits_per_character = 5
[Assertion]
zend.assertions = 1
[COM]
[mbstring]
[gd]
[exif]
[Tidy]
tidy.clean_output = Off
[soap]
soap.wsdl_cache_enabled=1
soap.wsdl_cache_dir=”/tmp”
soap.wsdl_cache_ttl=86400
soap.wsdl_cache_limit = 5
[sysvshm]
[ldap]
ldap.max_links = -1
[dba]
[opcache]
[curl]
[openssl]
[ffi]
“`
nginx/nginx.conf

 

“`

events {
    worker_connections 1024;
}
http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    # 映射 HTTPS 状态(用于 fastcgi_param)
    map $http_x_forwarded_proto $fastcgi_https {
        default off;
        https on;
    }
    server {
        listen 80;
        listen [::]:80;
        server_name localhost;
        error_log /var/log/nginx/error.log debug;
        access_log /var/log/nginx/access.log;
        root /var/www/website;
        index index.html index.htm index.php;
        client_max_body_size 1000M;
        # 处理静态文件请求
        location ~* \.(ico|gif|jpg|jpeg|png|js|css)$ {
            try_files $uri =404;
        }
        # 防止访问特定文件类型
        location ~* \.(bak|inc|lib|sh|tpl|lbi|dwt)$ {
            deny all;
            return 404;
        }
        # 处理 PHP 文件
        location ~ \.php$ {
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param HTTPS $fastcgi_https;  # 识别 HTTPS
            fastcgi_pass php:9000;
            fastcgi_index index.php;
        }
        # URL 重写规则
        location / {
            try_files $uri $uri/ @rewrite;
        }
        location @rewrite {
            rewrite ^/(.*)$ /index.php?route=$1 last;
        }
    }
}

“`

至此,第二部分就完成了,使用 docker compose build --no-cache && docker compose up -d 启动容器。
第三部分,数据库导入。
在第二部分中,docker-compose.yml 首次启动时创建的是空的数据库,我们需要把原来备份的数据库文件复制到容器内,并且在容器内恢复数据库以及创建用户和权限。
复制数据库文件到容器:
`docker cp <导出保存的名称>.sql.sql mysql:/<导出保存的名称>.sql`
进入容器内导入原备份的 .sql 数据到数据库中
“`
docker exec -it mysql bash
ls -lt /<导出保存的名称>.sql
mysql -u root -p < /<导出保存的名称>.sql
SHOW DATABASES;
“`
通过以下三条命令创建用户和权限:
用户名、数据库名、用户密码都必须与 wordpress 一致,并且使用 % 可以从任意 IP 登录。
“`
CREATE USER ‘wwwbg7iaecom’@’%’ IDENTIFIED BY ‘Web3900,.’;
GRANT ALL PRIVILEGES ON wwwbg7iaecom.* TO ‘wwwbg7iaecom’@’%’;
FLUSH PRIVILEGES;
SELECT user, host FROM mysql.user;
“`
完成以上操作之后,退出容器。重启一次 Docker Compose: docker compose down && docker compose up -d
至此,就完成了整个项目的迁移了,现在可以通过  http://127.0.0.1:8001 访问 WordPress 博客了。
还不够,对不对?用户怎么通过 http://127.0.0.1:8001 访问嘛?没错,还需要宿主机的 nginx 反代一下到 http://127.0.0.1:8001 ,或者使用 Cloudflare Tunnel 反代也可以。做完就个动作,整个项目才算真正迁移完毕。
现在你看到的这篇文章,就是已经迁移完的结果了。
(这篇文章发完,才发现这个网站还没支持代码块功能,后面抽个时间给它加上。)
 

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部