Comparison

WordPress on a Container Host: Why It Is the Wrong Tool, and the Two Ways It Fits Anyway

SnapDeploy Team 2026-12-02 Updated 2026-12-02 8 min read
wordpressphpstatic-sitesdockerfree-tier

People ask whether they can run WordPress on a free container tier, and the honest answer is that you can, and you should not. WordPress assumes a persistent disk for uploads and plugins, a database that is always there, and a server that never sleeps. A free container has none of those, and buying them one by one costs more than a WordPress host that includes them. This post is the reasoning, the two ways WordPress does fit a container platform, and the exact setup if you decide to do it anyway.

Why WordPress and a free container disagree

  • Uploads live on disk. Every image in the media library, every plugin and theme installed from the admin, is written to wp-content. A container's filesystem is reset on every deploy and every wake, so a site edited through the admin loses its media the next time it sleeps.
  • It needs MySQL, all the time. WordPress cannot start without its database, and it makes dozens of queries per page. A paused or expired free database is a white screen.
  • It is a public site. The point of a WordPress site is that strangers open it. A free container sleeps after 15 minutes without traffic and takes about a minute to wake, which for a public homepage is a visitor lost.
  • PHP-FPM and a web server. The official wordpress image bundles Apache and works, but it is 600 MB and the admin is slow on a quarter of a CPU.

What it would cost to make it work here

Solving those honestly means: an Always-On container so the site never sleeps and can have a custom domain ($12/month), a MySQL Mini so the database is dedicated and backed up ($29/month), and a media-offload plugin that stores uploads in an S3-compatible bucket instead of on disk (the bucket is a few cents). That is over $40 a month for one WordPress site, and it still leaves plugin and theme files on the ephemeral disk unless you bake them into the image. A managed WordPress host at a fraction of that includes all of it, and so does a $5 VPS with a control panel. We would rather tell you that than take the $41.

Where WordPress does fit a container platform

1. As a static site

If the site is a blog or a brochure that changes a few times a month, export it to plain HTML with a static-export plugin (Simply Static and WP2Static are the known ones), and host the export. A static site is the cheapest thing on the internet: a Pages host serves it for free without ever sleeping, and an nginx container serves it if you want a password or custom rules. WordPress itself then runs only on your laptop or on a cheap host, as the editor, and no visitor ever touches it.

2. As a headless CMS behind a front end you deploy

Keep WordPress where it is well hosted, use its REST API or WPGraphQL as the content source, and deploy the front end (Next.js, Astro, Nuxt) as a container or a static site. The container tier is a good fit for that front end: it is your code, it builds from a repository, and if it is static it never sleeps on a Pages host. Our Next.js and static-site guides cover both shapes.

If you are going to do it anyway

For a staging copy, a client preview, or a site you will only edit through code, here is the setup that survives redeploys. The rule is that nothing important lives on the container's disk.

FROM wordpress:6-php8.3-apache
# themes and plugins are part of the image, not installed from the admin
COPY wp-content/themes/mytheme /usr/src/wordpress/wp-content/themes/mytheme
COPY wp-content/plugins /usr/src/wordpress/wp-content/plugins
COPY wp-config-extra.php /usr/src/wordpress/
EXPOSE 80
<?php // wp-config-extra.php, included from wp-config.php
define('WP_HOME', getenv('WP_HOME'));
define('WP_SITEURL', getenv('WP_HOME'));
define('DISALLOW_FILE_MODS', true);     // no plugin/theme installs from the admin: the disk is ephemeral
define('FORCE_SSL_ADMIN', true);
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}
  • Database: a MySQL or MariaDB Mini add-on. The official image reads WORDPRESS_DB_HOST, WORDPRESS_DB_USER, WORDPRESS_DB_PASSWORD and WORDPRESS_DB_NAME; split the injected connection string into those four variables in the container settings.
  • Uploads: install a media-offload plugin in the image and point it at an S3-compatible bucket with its access keys in environment variables. After that, the media library survives anything.
  • DISALLOW_FILE_MODS turns off installs and updates from the admin. Plugins and themes change through the repository and a redeploy, which is the only way they persist.
  • Always-On for anything public, which also unlocks the custom domain WordPress will want as WP_HOME.
  • Search engines: keep a staging copy out of the index (Settings → Reading → discourage indexing) or protect it with basic auth in front.

Test it locally before spending a deploy

docker run -d --name db -e MYSQL_ROOT_PASSWORD=dev -e MYSQL_DATABASE=wp mysql:8
docker build -t wp .
docker run --rm -p 8080:80 --link db -e WORDPRESS_DB_HOST=db -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=dev -e WORDPRESS_DB_NAME=wp -e WP_HOME=http://localhost:8080 wp

Run through the installer once, add a post, restart the container, and confirm the post is still there (it is in the database) while an uploaded image without the offload plugin is not (it was on disk). That ten-minute exercise is the whole argument of this post.

Decision in one paragraph

A public WordPress site belongs on a WordPress host or a small VPS. A blog that changes rarely belongs in a static export on a Pages host, and WordPress becomes an editor you run privately. A modern front end with WordPress as its content source belongs on a container or static host, with WordPress hosted separately. A container running WordPress itself is for staging, previews and code-managed sites, with the database and the media taken off the disk first.

Moving an existing site in

Export the database from the old host (mysqldump or the host's backup), import it into the MySQL Mini, and search-and-replace the old URL for the new WP_HOME (WP-CLI's search-replace handles serialised data correctly; a plain SQL replace does not). Copy the media library into the bucket the offload plugin uses and run its "offload existing media" step. Themes and plugins go into the repository, not the admin. Then the site works on the container the same way it did on the host, minus the ability to install things from the admin, which is the trade you made on purpose.

Numbers used: Always-On Small $12/month and MySQL or MariaDB Mini $29/month from the add-on pricing page and pricing page; free tier from the free tier docs.

Ready to Deploy?

Deploy free. 10 deploys a day, 100 hours a month, no credit card.

Run this yourself: Get a dedicated NVIDIA T4 (16 GB) for a flat $499/mo or A10G (24 GB) for $999/mo — never shared, never spot, no hourly metering. See dedicated GPU hosting →

One-click Ollama, vLLM, ComfyUI, Whisper, PyTorch & more — or deploy your own GitHub repo or Docker image. Compare plans.

FIRST OF ITS KIND

Sprint Pack — ₹99 for 24 hours

The first managed container PaaS to offer a one-time 24-hour Always-On pass under $5. Unlimited deploys + Always-On for one Small (512 MB) container — including WebSockets & real-time apps. No subscription, no auto-renewal. Stack two for 48 hours.

Need a managed database too? DB Sprint Pack — ₹99 / 12h for Postgres, MySQL, MariaDB, Mongo, Redis, or RabbitMQ.

Tip: Need 24 hours of Always-On for a demo, weekend, or quick test — or WebSockets & real-time apps? Sprint Pack is ₹99 one-time — no subscription, no auto-renewal.

Need a managed Postgres / MySQL / Mongo / Redis instead? DB Sprint Pack — ₹99 / 12h.

Take SnapDeploy with you

Deploy, monitor and wake your containers from your iPhone.

Download on the App Store

Get DevOps Tips & Updates

Container deployment guides, platform updates, and DevOps best practices. No spam.

Unsubscribe anytime. We respect your privacy.

More Articles