{"id":3353,"date":"2026-01-29T20:16:05","date_gmt":"2026-01-30T01:16:05","guid":{"rendered":"https:\/\/blog.lufamily.ca\/kang\/?p=3353"},"modified":"2026-02-28T16:55:20","modified_gmt":"2026-02-28T21:55:20","slug":"moving-my-blog","status":"publish","type":"post","link":"https:\/\/blog.lufamily.ca\/kang\/2026\/01\/29\/moving-my-blog\/","title":{"rendered":"Moving My Blog"},"content":{"rendered":"\n<p>Since I had difficulties in upgrading my NAS, as I detailed here on this <a href=\"https:\/\/blog.lufamily.ca\/kang\/2026\/01\/13\/ubuntu-22-04-lts-to-24-04-lts-upgrade-fail\/\" data-type=\"post\" data-id=\"3327\" target=\"_blank\" rel=\"noreferrer noopener\">post<\/a>. I decided that I need to move my NAS services to another server called, <code>workervm<\/code>. The first service that I decided to move is this web site, my blog, which is a WordPress site hosted by an Apache2 instance with a MySQL database backend.<\/p>\n\n\n\n<p>I decided that instead of installing all the required components on <code>workervm<\/code>, I will use run WordPress inside a <code>podman<\/code> container. I already have <code>podman<\/code> installed and configured for rootless quadlet deployment.<\/p>\n\n\n\n<p>The first step is to backup my entire WordPress document root directory and moved the contents to the target server. I placed the contents on <code>\/mnt\/hdd\/backup<\/code> on <code>workervm<\/code>. I also need to perform a dump of the SQL database. On the old blog server, I had to do the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mysqldump -u wordpressuser -p wordpress &gt; ..\/..\/wordpress.bk.sql<\/code><\/pre>\n\n\n\n<p>I then proceeded to create the following network, volume, and container files on <code>workervm<\/code> in <code>${HOME}\/.config\/containers\/systemd<\/code>:<\/p>\n\n\n\n<p>I wanted a private network for all WordPress related containers to share and also ensure that DNS requests are resolved properly. Contents of <code>wordpress.network<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Unit]\nDescription=Network for WordPress and MariaDB\nAfter=podman-user-wait-network-online.service\n\n&#91;Network]\nLabel=app=wordpress\nNetworkName=wordpress\nSubnet=10.100.0.0\/16\nGateway=10.100.0.1\nDNS=192.168.168.198\n\n&#91;Install]\nWantedBy=default.target<\/code><\/pre>\n\n\n\n<p>I also create three podman volumes. The first is where the database contents will be stored. Contents of <code>wordpress-db.volume<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Unit]\nDescription=Volume for WordPress Database\n\n&#91;Volume]\nLabel=app=wordpress<\/code><\/pre>\n\n\n\n<p>Contents of <code>wordpress.volume<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Unit]\nDescription=Volume for WordPress Site itself\n\n&#91;Volume]\nLabel=app=wordpress<\/code><\/pre>\n\n\n\n<p>We also needed a volume to store Apache2 related configurations for WordPress. Contents of <code>wordpress-config.volume<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Unit]\nDescription=Volume for WordPress configurations\n\n&#91;Volume]\nLabel=app=wordpress<\/code><\/pre>\n\n\n\n<p>Now with the network and volumes configured, lets create our database container with <code>wordpress-db.container<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Unit]\nDescription=MariaDB for WordPress\n\n&#91;Container]\nImage=docker.io\/library\/mariadb:10\nContainerName=wordpress-db\nNetwork=wordpress.network\nVolume=wordpress-db.volume:\/var\/lib\/mysql:U\n# Customize configuration via environment\nEnvironment=MARIADB_DATABASE=wordpress\nEnvironment=MARIADB_USER=wordpressuser\nEnvironment=MARIADB_PASSWORD=################\nEnvironment=MARIADB_RANDOM_ROOT_PASSWORD=1\n\n&#91;Install]\nWantedBy=default.target<\/code><\/pre>\n\n\n\n<p>Note that the above container refers database volume that we configured earlier as well as the network. We are also using the community forked version of MySQL (MariaDB).<\/p>\n\n\n\n<p>Finally we come to the configuration of the WordPress container, <code>wordpress.container<\/code>: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Unit]\nDescription=WordPress Application\n# Ensures the DB starts first\nRequires=wordpress-db.service\nAfter=wordpress-db.service\n\n&#91;Container]\nImage=docker.io\/library\/wordpress:latest\nContainerName=wordpress-app\nNetwork=wordpress.network\nPublishPort=8168:80\nVolume=wordpress.volume:\/var\/www\/html:z\nVolume=wordpress-config.volume:\/etc\/apache2:Z\n# Customize via Environment\nEnvironment=WORDPRESS_DB_HOST=wordpress-db\nEnvironment=WORDPRESS_DB_USER=wordpressuser\nEnvironment=WORDPRESS_DB_PASSWORD=################\nEnvironment=WORDPRESS_DB_NAME=wordpress\n\n&#91;Install]\nWantedBy=default.target<\/code><\/pre>\n\n\n\n<p>Notice the requirement for the database container to be started first, and this container also uses the same network but the two volumes are different.<\/p>\n\n\n\n<p>We have to refresh the system since we changed the container configurations.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl --user daemon-reload<\/code><\/pre>\n\n\n\n<p>We can then start the WordPress container with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl --user start wordpress<\/code><\/pre>\n\n\n\n<p>Once the container is started, we can check both the WordPress and its database container status with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl --user status wordpress wordpress-db<\/code><\/pre>\n\n\n\n<p>And track its log with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>journalctl --user -xefu wordpress<\/code><\/pre>\n\n\n\n<p>It is now time to restore our old content with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>podman cp \/mnt\/hdd\/backup\/. wordpress-app:\/var\/www\/html\/\n\npodman unshare chmod -R go-w ${HOME}\/.local\/share\/containers\/storage\/volumes\/systemd-wordpress\/_data\n\npodman unshare chown -R 33:33 ${HOME}\/.local\/share\/containers\/storage\/volumes\/systemd-wordpress\/_data<\/code><\/pre>\n\n\n\n<p>The copy will take some time, and once it is completed, we have to fix the permissions and ownerships. Note that both of these have to be performed with <code>podman unshare<\/code> command so that proper <code>uid<\/code> and <code>gid<\/code> mapping can be performed.<\/p>\n\n\n\n<p>I also had to restore the database contents with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat wordpress.bk.sql | podman exec -i wordpress-db \/usr\/bin\/mariadb -u wordpressuser --password=############# wordpress<\/code><\/pre>\n\n\n\n<p>Lastly I needed to modify my main\/old Apache server where the port forwarding is directed to so that blog.lufamily.ca requests are forwarded to this new server and port.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Define BlogHostName blog.lufamily.ca\nDefine DestBlogHostName workervm.localdomain:8168\n\n&lt;VirtualHost *:443&gt;\n    ServerName ${BlogHostName}\n    ServerAdmin kangclu@gmail.com\n    DocumentRoot \/mnt\/airvideo\/Sites\/blogFallback\n    Include \/home\/kang\/gitwork\/apache2config\/ssl.lufamily.ca\n\n    SSLProxyEngine  on\n\n    ProxyPreserveHost On\n    ProxyRequests Off\n\n    ProxyPass \/ http:\/\/${DestBlogHostName}\/\n    ProxyPassReverse \/ http:\/\/${DestBlogHostName}\/\n\n    # Specifically map the vaultAuth.php to avoid reverse proxy\n    RewriteEngine On\n    RewriteRule \/vaultAuth.php(.*)$ \/vaultAuth.php$1 &#91;L]\n\n    ErrorLog ${APACHE_LOG_DIR}\/blog-error.log\n    CustomLog ${APACHE_LOG_DIR}\/blog-access.log combined\n&lt;\/VirtualHost&gt;<\/code><\/pre>\n\n\n\n<p>Note that on the old server I still have the document root pointed to a fallback directory. In this fallback directory I have <code>php<\/code> files that I needed to be served directly without being passed to WordPress but the requested path shares the same domain name as my WordPress site. The rewrite rule performs this short circuit processing. When <code>vaultAuth.php<\/code> is requested, we skip the reverse proxy all together.<\/p>\n\n\n\n<p>This is working quite well. I am actually using the new location of this blog site to write this post. I plan to migrate the other services on my NAS in a similar manner with <code>podman<\/code>.<\/p>\n\n\n\n<p>The idea is that once the majority of the services have been ported to <code>workervm<\/code>, then I can reinstall my NAS with a fresh install of Ubuntu 24.04 LTS without doing a migration.<\/p>\n\n\n\n<p><strong>Update 2026-02-28<\/strong>:<\/p>\n\n\n\n<p>I had to move my blog to a different virtual machine because the current one had a network stack corruption. What I found was that the <code>podman<\/code> volume concept was super handy. I was able to use <code>podman import\/export<\/code> commands to easily move my blog storage and database without having to worry about permissions and other file system nuances.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Since I had difficulties in upgrading my NAS, as I detailed here on this post. I decided that I need to move my NAS services to another server called, workervm. The first service that I decided to move is this web site, my blog, which is a WordPress site hosted by an Apache2 instance with &hellip; <a href=\"https:\/\/blog.lufamily.ca\/kang\/2026\/01\/29\/moving-my-blog\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Moving My Blog&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[111],"tags":[201,97,5,200,6,199],"class_list":["post-3353","post","type-post","status-publish","format-standard","hentry","category-tech","tag-containers","tag-linux","tag-nas","tag-podman","tag-ubuntu","tag-wordpress"],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p7V6i8-S5","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blog.lufamily.ca\/kang\/wp-json\/wp\/v2\/posts\/3353","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.lufamily.ca\/kang\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.lufamily.ca\/kang\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.lufamily.ca\/kang\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.lufamily.ca\/kang\/wp-json\/wp\/v2\/comments?post=3353"}],"version-history":[{"count":7,"href":"https:\/\/blog.lufamily.ca\/kang\/wp-json\/wp\/v2\/posts\/3353\/revisions"}],"predecessor-version":[{"id":3372,"href":"https:\/\/blog.lufamily.ca\/kang\/wp-json\/wp\/v2\/posts\/3353\/revisions\/3372"}],"wp:attachment":[{"href":"https:\/\/blog.lufamily.ca\/kang\/wp-json\/wp\/v2\/media?parent=3353"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.lufamily.ca\/kang\/wp-json\/wp\/v2\/categories?post=3353"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.lufamily.ca\/kang\/wp-json\/wp\/v2\/tags?post=3353"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}