Portainer 上搭建 Wordpress

现在搭建一个service,基本上默认都是走 Docker了,也许过几年都又会变成podman或者其他的container solution吧。现在先以container为例。假定Host上面已经搞定了docker的安装,然后假定也装好 Portainer 了。

docker-compose.yaml

WordPress的stack是相当简单的,就是一个DB和一个Wordpress的Container。下面就是 docker-compose.yaml文件的内容。也可以直接copy paste 到 Portainer 的 stack 里面。

services:
  db:
    # We use a mariadb image which supports both amd64 & arm64 architecture
    image: mariadb:10.6.4-focal
    # If you really want to use MySQL, uncomment the following line
    #image: mysql:8.0.27
    command: '--default-authentication-plugin=mysql_native_password'
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=somewordpress
      - MYSQL_DATABASE=wordpress_db
      - MYSQL_USER=wordpress_user
      - MYSQL_PASSWORD=wordpress
    expose:
      - 3306
      - 33060
  wordpress:
    image: wordpress:latest
    volumes:
      - wp_data:/var/www/html
    ports:
      - 12380:80
    restart: always
    environment:
      - WORDPRESS_DB_HOST=db
      - WORDPRESS_DB_USER=wordpress_user
      - WORDPRESS_DB_PASSWORD=wordpress
      - WORDPRESS_DB_NAME=wordpress_db
volumes:
  db_data:
  wp_data:

port我这里用的是12380. 外面肯定还是需要反向代理的,这里先采用 Nginx Proxy Manager。12380只是container映射到host的端口号,当然,host这里肯定也只是个VM,这里采用的是 Ubuntu。

至于上面高亮的那些个密码,个人觉得改一下最好,如果不改的话其实可能也问题不大,因为这个DB应该也只有host的docker网络上面能访问。

Docker compose默认给每一个 stack 起一个默认的 network,然后默认同一个docker-compose里面的 container都会在这个网络上,然后service name 直接可以做 host name用。这也就是为什么 WORDPRESS_DB_HOST=db 这里这么设置,db在这里就是上面那个 DB service的hostname,Wordpress container就用这个找到 DB service。

Create Stack

如果是 Portainer的话,就是直接复制粘贴到WebUI上面

如果是CLI的话,那就直接 docker-compose up -d 就好了。关于CLI的使用还是另外详细在写吧。平时使用的话,有个WebUI还是方便多了,虽然Portainer还是有些局限性的。

正常来说,应该就能看到看到这个 stack 里面的 Containers正常启动了

在左边侧边栏的里面,containers 页面应该也是显示 container 正常启动了。

Volumes里面有相应的两个 Volumes,一个是DB的,一个是 WordPress 自己的。注意这里 Volumes的名字是 wordpress_db_data wordpress_wp_data. 这里的前缀 wordpress 是自动添加的。因为我们的 Stack 名字是 wordpress,所以这里的名字就是 <stack_name>_<db/wordpress>_data。如果 volumes 在 docker-compose.yaml 里面有指定name,那么 docker compose 就不会自己再生成名字了,而是用指定的名字。

这个时候访问 http://<your_server_host_name_or_IP>:12380 应该就是可以直接访问了。不过没有 HTTPS 以及反代,也没有公网域名。

Reverse Proxy 反代

我这里用的是 Nginx Proxy Manager 来做的反代。相对来讲比较简单,也比较业余。长期来看的话,要不然把 Nginx玩明白,要不就是 Caddy 或者 Traefik两者里面选一个,要不就再专业一点,HAProxy。不过我现在大概也许是没有时间学些这些东西,就先用 Nginx Proxy Manager吧。

WordPress的反代没有什么需要特殊注意到地方(大概这些反代工具至少都要保证Wordpress可以很轻松的支持,甚至默认支持,毕竟Wordpress太典型了)。

  • Details 页面
    • Domain name肯定就是你外网的 domain name 了。当然如果内网使用内网有 DNS,那就内网的 domain name。
    • Scheme要用 http
    • Forward Hostname / IP 就是docker host的IP或者hostname
    • Forward port 就是 docker-compose里面 wordpress映射出来的 port,我这里就是12380
    • Cache assets/block common exploits/ websockets support 都打开了,大概没什么理由不打开
  • Custom Locations 什么都不用动
  • SSL
    • 我这里还是选择使用SSL了,因为我的域名是 .dev 结尾,所以实际上是必须要搞定SSL的。这里就用 Let’s Encrypt 搞一个新证书就好了。NPM 在这方面做的还是挺好的。
    • 这一步的一个前提条件是,你的域名映射都搞定了。也就是外网上面这个域名已经映射到你这里的服务器了。

初次登陆

初次访问会setup 一些admin 账户的东西。这里务必记住或者设置好admin的初始密码。因为这里我们没有设置SMTP邮箱服务,所以 WordPress 现在是没有办法发送密码重置邮件的,一旦密码忘了登陆不进去,就只能重新部署一次 WordPress 了。

重新部署的话,需要删除我们这里创建的两个 volumes, 来保证新的部署是全新的。

Change upload limit

最重要的Config 就是上传大小的限制。默认的upload limit是2MB,这确实有些不方便,一些照片都不能方便的传上去。

这里需要登陆到 docker 的主机上面,修改一个文件。这个文件实际上是 wordpress container的文件,同时这文件位于我们在docker-compose.yaml 里面指定的 volume里面,所以我们可以在 host 上面直接更改,然后 WP 里面的config也就相当于更改了。

# using vim here, use whatever editor you like, e.g. nano
vim /var/lib/docker/volumes/<stack_name>_wp_data/_data/.htaccess

这个文件打开应该是这样的

# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

我们需要在最后加上高亮部分:

# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

php_value upload_max_filesize 64M
php_value post_max_size 64M

如此最大上传就是 64M 了。

至于平时上传的图片需要压缩,这里还是推荐至少搞一个 image compressor的插件,参见 WordPress 图片压缩插件

Summary

  • WordPress 算是最简单的self-host service了。麻雀虽小五脏俱全,基本上涉及了 docker-compose, portainer stack, 一些关于 Docker volume的基础知识。还需要一个基本的reverse proxy来处理 HTTPS offload。
  • WordPress 搭建完一定别忘了调整 upload size limit,要不然用起来不方便。
  • WordPress 的使用方面我也还在摸索,慢慢学吧。