banner
文诗inscripoem

文诗的万事屋

视、听与文字表达
bilibili
github
twitter
pixiv

WordPress Docker Migration

The migration issue of WordPress has always been a big problem for me.

Actually, it's not just for me. Although the migration process can be troublesome, it can be easily done by copying a directory and writing an SQL for the database (without changing the domain name or even writing anything). Now, there are even ready-made plugins (such as Duplicator) that can handle it with just one click. What I'm worried about is Fēnglán (for a summary, see What are we talking about when we talk about the Fēnglán official website).

For Fēnglán, a more idiot-proof and one-click (although this may not be a good thing) solution is needed. As a long-time Docker user, I naturally thought of containerization. With Docker Compose, the website and database can be packaged in one directory, moved to a new machine without modification, and can be started or stopped with a single command.

In the actual operation, I encountered many pitfalls (including those that I didn't have time to record before using Docker), and I will write them down here.

Steps#

The Compose file is from docker/awesome-compose:

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
      - MYSQL_USER=wordpress
      - MYSQL_PASSWORD=wordpress
    expose:
      - 3306
      - 33060
  wordpress:
    image: wordpress:latest
    volumes:
      - wp_data:/var/www/html
    ports:
      - 80:80
    restart: always
    environment:
      - WORDPRESS_DB_HOST=db
      - WORDPRESS_DB_USER=wordpress
      - WORDPRESS_DB_PASSWORD=wordpress
      - WORDPRESS_DB_NAME=wordpress
volumes:
  db_data:
  wp_data:

In the actual operation, I just moved the two mounted volumes, db_data and wp_data, to a local directory, and everything else remained basically unchanged.

This step will create two containers, one for the MariaDB database and one for the Nginx+WordPress web server. If the port mapped by wordpress is not installed on the host machine, it can be set to 80 directly. I prefer to map it to another port and use reverse proxy (the new version of Baota can directly create reverse proxy projects, which is highly praisedwho is still using Baota in 2024), but I won't go into details here.

After docker compose up -d, accessing the port or domain name will give you a brand new WordPress. If you need to migrate, you can use the aforementioned Duplicator to package it and put it in wp_data for installation.

Pitfalls#

Finally, it's time for my favorite partthe most torturous part, and now it seems that most of the problems are not caused by containerization, but by some troublesome features of WordPress itself, which further strengthens my belief that although WordPress is good, it should still be abandoned resolutely.

Please note that almost all of the following problems I did not dig deep into the root cause, I just made simple speculations and searched for solutions. In the end, I think that if you need to use such tricks to ensure its use in a modern environment, it is not worth wasting a lot of time on these things, as long as it works.

ERR_TOO_MANY_REDIRECTS#

This problem occurred after I changed the WordPress address and site address in the settings to https://example.com. There was no problem accessing the website itself, but when accessing the administration site, it would report ERR_TOO_MANY_REDIRECTS. After multiple restarts and waiting in vain, I found this post on StackExchange and suddenly understood.

Native WordPress does not support setting HTTPS within the site, so my SSL settings are in the Nginx at the reverse proxy position. The address settings of WordPress control the Base URL for its redirection. So when accessing the site with https, the outer Nginx will bring me to the inner WordPress, and at this time, according to the settings, WordPress will redirect me to the https site, thus entering a loop of redirection.

My solution is somewhat similar to this comment, but I know for sure that SSL is not set in the Nginx in Docker, so I just changed the address back to starting with http.

There are many ways to make this change. If you can access the database, you can modify the home and siteurl fields in the [sitename]_options table. You can also add the following lines to the wp-config.php file in the root directory:

define('WP_HOME','http://example.com');
define('WP_SITEURL','http://example.com');

After modifying the wp-config.php file, the overridden items in the site settings will become gray and cannot be modified, which means that the values in the database are useless. Please pay attention to thisI was puzzled for a long time why I couldn't change it.

Plugin Installation and Directory Permissions#

For WordPress installed directly on the host machine, plugin installation is smooth and does not require any special operations. However, Docker images have a problem, which is that the official WordPress image runs as the www-data user, and the permissions of the files copied in/automatically created are incorrect, which leads to the need to enter FTP account information when installing plugins.

The solution refers to this issue and the gist mentioned in the reply. First, as usual, add the following line to wp-config.php:

define('FS_METHOD', 'direct');

This will change the installation mode of plugins. Then, change the owner and permissions of the WordPress folder in the terminal:

docker exec -u root -it {CONTAINER_ID} /bin/bash
chown -R www-data wp-content
chmod -R 755 wp-content

Of course, instead of changing the owner, I just changed the permissions of the folder to 777. Don't follow my example, you will be scolded ( )I heard that the Fēnglán official website was taken down last time because it was hacked

Pros and Cons#

In my opinion, there are some advantages to migrating a legacy framework like WordPress to Docker:

  1. Easy migration

    This is my favorite advantage. The entire website is in one folder, so if you need to move, you don't need to backup and restore the database or change any settings. Just compress the whole directory and take it with you.

  2. Easy deployment

    The entire system can be started with just one command docker compose up -d, and stopping and restarting is also a one-liner. You can also conveniently use docker compose logs to view the logs of both containers at the same time. Although it is not recommended to put the database in a container in principle, containers are cool!

  3. More secure (?)

    In Docker Compose, both the database and WordPress itself are in a virtual network. Normally, the database is not exposed to the outside world, reducing the risk of being attacked. However, this is questionable because as long as WordPress can access the database, the cost of directly attacking WordPress's existing vulnerabilities is also very low.

Of course, there are also obvious disadvantages:

  1. More complicated database and file access

    After putting it into Docker, files and ports need to be mapped to access them, and some operations require entering the container. Database and file management have indeed become more complicated than before. Of course, you can also add a database management program like PHPMyAdmin to the Compose configuration (ready-made solution), but managing ports can be a bit tricky and I haven't successfully deployed it. You can try it yourself.

  2. Need to deal with permission issues

    As mentioned earlier, Docker means that there is a higher chance of inconsistency between owners and permissions inside and outside the container, and usually it takes some time to solve them (you may need to go back to look at the Dockerfile or enter the container).

  3. Slower access speed

    This is the most unacceptable disadvantage for me. WordPress is already notorious for its weak performance, and after entering Docker, every file access needs to go through directory mounting, and every database request needs to go through directory mounting as well. The perceived loading time of the website has even increased by more than 100%.

Conclusion and Outlook#

Overall, it was a relatively pleasant experience, but when I was tinkering with this, I found that the panel on my server suddenly couldn't read the Nginx configuration. Under the dual pressure of extremely slow access speed and occasional crashes of the host machine's Nginx, I feel that I will turn to newer technology stacks. It's already 2024, why spend so much time tinkering with a blog framework that doesn't even natively support HTTPS (but the fact proves that WordPress is still necessary, as it is currently the most customizable CMS with the highest level of community support and support for multi-author writing)? It's time to make a new choice!

Today, I saw some new optimization methods (Redis, jsDelivr). If I have the energy later, I may try to tinker with them. After all, almost all of Fēnglán's posts are on WordPress, and it would be a pity to lose them.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.