在arm64架构上搭wordpress的血泪之路

前段时间朋友见我建博客,心痒痒也想整一个,不过不知为何始终无法成功注册 Oracle,薅羊毛失败。夸下海口许诺帮忙搞定博客的我当然要尽力而为,然而自己的账号上已经部署了两个博客,把 amd free instance 的限额用完了。一无所知的我发现免费账号还可以开 arm 架构的免费 VM,于是初生牛犊不怕虎地马上搞了一个。未曾想前面等着我的正是一个血泪大坑

Follow 的还是之前 Digital Ocean 的傻瓜教程,但是到安装 docker 的那一步出问题了:

sudo apt-get install docker-ce
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Package docker-ce is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
  docker-ce-cli:amd64

于是我查找docker-ce-cli:amd64的版本信息(此时的我还没意识到根本问题是架构不同)

apt-cache policy docker-ce-cli:amd64

版本列表倒是拉取成功了,然而依然不能安装。搜索后找到 stackexchange 上的大佬说建议检查是否为64位版本。我一检查:我是64位啊!挠头,百思不得其解。此后搜索时看到 docker 的 官方手册,在设置 repository 的时候看到三个 tag:x86_64 / amd64,armhf 和 arm64。觉得有点眼熟,这才想起自己选的是 arm64 架构。找到一些使用apt-get的教程,不知为何验证签名一直有问题,最后跟着 这个教程 用curl终于安装成功。

装完 docker,下一步自然是 docker-compose,果然跟着教程又出了问题:看似安装成功,实际使用docker-compose up -d时才发现根本没装上。又是一通搜索如何在 arm64 上安装 docker compose,又是很多方法都不行,最后在 github页面 上看到“不支持的平台可以使用 pip 下载”,遂使用 pip。记得先安装 python 3:

sudo apt install python3-pip
sudo pip install docker-compose

两分钟安装成功。

接下来我使用了原本的配置文件

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: on-failure
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes:
      - dbdata:/var/lib/mysql
      - ./mysqlconfig.cnf:/home/username/mysqlconfig.cnf
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

  wordpress:
    depends_on:
      - db
    image: wordpress:5.6.0-fpm-alpine
    container_name: wordpress
    restart: on-failure
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

  webserver:
    depends_on:
      - wordpress
    image: nginx:1.19.6-alpine
    container_name: webserver
    restart: on-failure
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email example@email.com --agree-tos --no-eff-email --force-renewal -d domain.com -d www.domain.com

volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

如果以为不会出任何问题,那你就太天真了

Creating network "wordpress_app-network" with driver "bridge"
Creating network "wordpress_default" with the default driver
Creating volume "wordpress_certbot-etc" with default driver
Creating volume "wordpress_wordpress" with default driver
Creating volume "wordpress_dbdata" with default driver
Pulling db (mysql:8.0)...
8.0: Pulling from library/mysql
ERROR: no matching manifest for linux/arm64/v8 in the manifest list entries

毫不意外地因为架构又出了问题。搜索后根据 这位大佬 的建议,把配置文件改成了

services:
  db:
    platform: linux/x86_64
    image: mysql:8.0
    ...

Pullup倒是成功了,然而运行后dbcertbot不是正常的状态,于是查看 log:

db           | standard_init_linux.go:228: exec user process caused: exec format error
certbot      | standard_init_linux.go:228: exec user process caused: exec format error

此时我并没有意识到这位大佬给的第二个方法是好用的,于是 fine,下一个 solution!随后找到 docker library 的这个 issue,一看过了三年还是 open 状态我的心已经哇凉哇凉的了。仔细看了几十楼,发现不止一人提到 mariadb 作为替代,这个镜像 支持 amd64,arm64v8 和 ppc64le 架构。把配置文件一改:

services:
  db:
    image: mariadb:10.5
    ...

这回dbup了,webserver又出问题了(哭)看看 log,是 nginx 在搞我,于是根据 arm64v8版本 的界面:

  webserver:
    depends_on:
      - wordpress
    image: arm64v8/nginx:1.21         
    ...

仍然无法正常运行,再看,是因为

webserver    | 2021/06/10 14:51:15 [emerg] 1#1: cannot load certificate "/etc/letsencrypt/live/domain.com/fullchain.pem": BIO_new_file() failed (SSL: error:02001002:system library:fopen:No such file or directory:fopen('/etc/letsencrypt/live/domain.com/fullchain.pem','r') error:2006D080:BIO routines:BIO_new_file:no such file)
webserver    | nginx: [emerg] cannot load certificate "/etc/letsencrypt/live/domain.com/fullchain.pem": BIO_new_file() failed (SSL: error:02001002:system library:fopen:No such file or directory:fopen('/etc/letsencrypt/live/domain.com/fullchain.pem','r') error:2006D080:BIO routines:BIO_new_file:no such file)

certbot没有成功申请证书,自然是因为前述问题:文件格式不对(不适用于 arm64 架构)。接下来又是漫漫搜索路,天知道我花了两个小时居然都没搜到解决方法,docker hub 的 certbot 镜像也只有一个,没有写有没有 arm64 版本(主要就是不知道镜像版本该怎么写)。官方手册 只提到可以通过 snap 下载,于是小白如我就去下载了 standalone 版本,自然是无法和 docker compose 协调的(也许可以但我真的不会(捂脸)此时已经凌晨,实在撑不住就睡了。

第二天起来搜索换了个方向,在 Let’s Encrypt 的官网不抱希望地搜了一下,竟然在 这个帖子 里找到了一个版本:certbot/certbot:arm32v6-v1.15.0于是我自己魔改了一下变成certbot/certbot:arm64v8-v1.15.0,运行成功了,我老泪纵横啊(哭)

然而 bug 之下的 bug 此时才暴露出来:http-01 challenge 失败了,无法取得证书。折腾一通通过 网络检测 和 psping 才发现80端口没开,我以为我开了,又是百思不得其解。不管用什么方法都死活卡在这一步过不去……叹气,最终只好放弃。

此次的尝试最后也没有成功,现在的我知识还是过于浅薄,也许有一天我真的转码了(有可能吗)再来看看吧

留下评论