Never.
Category: Technology / Software
Debugging is the Art of Asking Good Questions
~19 minutes
Migrating WordPress from Pagely
Pagely is an expensive and robust solution for WordPress hosting. With the right caching setup wordpress can be performant, so let’s slap it in a docker container behind nginx.
To get off of Pagely, the most critical thing you’ll need to do with your exported backups is to make sure to either remove or rename or remove the mu-plugins
folder.
- Rename or delete
mu-plugins/
from the folder export. - Import the database and wp-content directories.
What’s easier than physically moving your wp-content directory is using the Updraft Plus plugin to create a backup of your wordpress install.
Redirect Hell
Setting the siteurl
and home
settings in the database shoots me into redirect hell.
Setting as localhost
instead of localhost/blog
yields a somewhat more functional site, but all the links are broken and nothing tends to work. I must need PHP 5. (This was definitely not the solution)
So it all works after disbabling the pagely plugins but this reverse proxying to a docker container from a subfolder thing, wordpress really doesn’t appear to like it very much. Everything worked for a second but now it doesnt again, just stuck in a 301 redirect loop to itself. The wp-admin functions fine as long as you remember to add the trailing slash on the URL.
Endless redirect loops later, we’re still stuck in a redirect loop.
Hopefully you won’t need to spend that much time dickerin with it.
wp-config.php
define('FORCE_SSL_ADMIN', true);
define('WP_HOME', 'http://example.com/newblog/');
define('WP_SITEURL', 'http://example/newblog/');
$_SERVER['REQUEST_URI'] = '/newblog' . $_SERVER['REQUEST_URI'];
This $_SERVER['REQUEST_URI']
line was the most helpful fix I came across. I had previously been using $_SERVER['REQUEST_URI'] = str_replace("/wp-admin/", "/blog/wp-admin/", $_SERVER['REQUEST_URI']);
as recommended by several resources in place for the wp-admin but rewriting the whole URI with $_SERVER['REQUEST_URI'] = '/newblog' . $_SERVER['REQUEST_URI'];
stopped redirect hell.
/etc/nginx/sites-enabled/default
We’ll add a section for nginx to proxy to the wordpress container.
location /newblog/ {
access_log off;
auth_basic off;
rewrite /newblog/wp-admin$ $scheme://$host$uri/ permanent; # This line redirects /newblog/wp-admin to /newblog/wp-admin/ which is nice to have.
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_http_version 1.1;
proxy_buffering off;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Proxy "";
proxy_redirect off;
proxy_pass http://wordpress/;
}
.htaccess
The .htaccess file that wordpress creates will attempt to make the RewriteBase and RewriteRule include the newblog/
part of the URL, which we don’t want, and will cause a redirect loop.
# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
The deploy
So it all works after destroying and rebuilding containers. What are the steps to do it live?
- ✅ Install Updraft Plus and create a backup, stuff it in dropbox.
- ✅ Deploy the containers, on the
/newblog/
URL. - ✅ Run our install script via wp_cli:
#!/bin/bash
docker-compose run wp_cli core install --url='http://example.com/newblog/' --title=temp --admin_user=temp [email protected] --admin_password="password"
docker-compose run wp_cli plugin install updraftplus --activate
- ✅ Connect dropbox in the updraft plus plugin. Click rescan remote storage, select the backup to install, and restore that backup.
- ✅ Reset the siteurl and home options in the
wp_options
table.
mysql -uroot -psecret -h 0.0.0.0 wp_database -e 'update wp_options set option_value = "http://example.com/newblog" where option_name = "siteurl" or option_name = "home"'
- 💣 Make sure it all works!
- ✅ Remove the old nginx redirect for the
/blog
url and replace it with the/newblog
directive. Update the wp-config.php and the database to remove the references to /newblog. - ✅ Shut down pagely. Keep your money.
HTTPS Support.
We didn’t test SSL support locally before deployment, and it’s easy to bang your head against the wall chasing down a fix for a problem that’s the result of something else.
Turns out that Jeff’s Application Load Balancers handle SSL termination and thus pass http_x_forwarded_proto
. We set that right in the nginx config and suddenly there is no more redirect hell, and everything’s running on https.
The line in the nginx config proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
must use x_forwarded_proto
instead of $scheme
since we’re behind an ALB on AWS. This is only needed if you’re using nginx behind an application load balancer on aws, otherwise using $scheme
should allegedly work.
Resources
github ↗ a5hleyrich/wordpress-nginx
docs.j7k6.org ↗ Basically looks to be exactly what we are looking for, but not quite.
stackoverflow ↗ nginx subpath to redirect to wordpress docker container
serverfault ↗ hosting a wordpress blog using nginx as a sub directory
stackoverflow ↗ wordpress nginx proxy and subdirectory wp login php redirects to domain
stackexchange ↗ wordpress wp admin https redirect loop
stackexchange ↗ https leads to sorry you are not allowed to access this page
stackexchange ↗ setting server https on prevents access to wp-admin
Use the Right Tool for the Job
Don’t try to cut down a tree with a butter knife, and don’t think that a chainsaw will help you at breakfast time.
Generating ERD for Django Applications
Generating an ERD (Entity Relationship Diagram) can be helpful to understand what your database looks like, and is also really easy to generate if you’re running a Python/Django Application.
Step 1: Install django-extensions and graphviz
pip install django-extensions && pip install graphviz
Step 2: Add django_extensions to settings.py
INSTALLED_APPS = [ ... 'django_extensions', ... ]
Step 3: Create the .dot output and convert to .png
Run manage.py graph_models
from the environment you may normally use:
python manage.py graph_models -a > output.dot
From your mac, change the format to png using graphviz
brew install graphviz dot -Tpng output.dot -o output.png
Note You can also output to pdf
by changing the type:
dot -Tpdf output.dot -o output.pdf
References
Django Extensions graph_models docs
Django Extensions Commands Unavailable?
Opening .dot files on mac