Deploy by framework

WordPress

Deploy WordPress with a managed PHP container, an external database, and object-storage uploads.

Nitroship detects WordPress when the deployment root contains wp-includes/ and a wp-config*.php file. The managed preset packages your existing WordPress installation in a FrankenPHP container. It does not install WordPress, create a database, or configure your site for you.

Deploy

Install the CLI

curl -fsSL https://nitroship.co/install.sh | bash
ntro login

Already installed? Skip ahead. Full options, PATH setup, and updates: Install the CLI.

Prepare your WordPress configuration, external database, and production secrets. Set a compute region and optionally select the preset explicitly:

nitroship.json
{
  "build": {"framework": "wordpress"},
  "compute": {"regions": ["kr-icn"]}
}
ntro apps create my-wordpress-site
ntro deploy . --prod

The managed WordPress preset requires the hosted builder. Remove --local if you have added it. A compute region is required for WordPress's PHP requests.

Database, secrets, and site URL

Use an external MySQL-compatible database. Configure the database connection in your own wp-config.php and keep credentials in Environment variables.

Environment variables are not automatically mapped to WordPress constants. DB_HOST, DB_NAME, DB_USER, and DB_PASSWORD only work as environment variables if your wp-config.php explicitly reads them. For example, a configuration you maintain can contain:

wp-config.php (excerpt)
define('DB_HOST', getenv('DB_HOST'));
define('DB_NAME', getenv('DB_NAME'));
define('DB_USER', getenv('DB_USER'));
define('DB_PASSWORD', getenv('DB_PASSWORD'));

This is an excerpt, not a complete configuration file. Preserve the rest of your WordPress configuration. The preset does not rewrite it or apply a Docker image's environment-variable conventions.

Also configure:

  • Authentication keys and salts: provide stable, securely generated values for WordPress's authentication keys and salts in your configuration. If you read them from environment variables, set those exact variable names. Do not regenerate them on every startup.
  • Public URL: set the correct HTTPS site and home URL in the database or through WP_HOME and WP_SITEURL constants in your configuration. An environment variable only takes effect if your configuration reads it.
  • Production behavior: disable debugging and make sure plugins use external services for state that must survive instance replacement.

Build, runtime, and CDN

FrankenPHP, a PHP application server, uses the WordPress root as the document root. It listens on 0.0.0.0:$PORT, defaulting to 3000. If present, Composer dependencies are installed with composer install --no-dev; a package.json build script triggers a frontend build with Node 22.

Files with allowed browser-asset extensions under the WordPress document root are copied into /nitroship/static in the generated image and automatically extracted to the CDN. The CDN serves those files first; WordPress page rendering, admin requests, and APIs continue to run on compute. No build.outputDirectory setting is needed.

The extension allowlist is .css, .js, .mjs, .html, .txt, .webmanifest, .png, .jpg, .jpeg, .gif, .webp, .avif, .ico, .svg, .woff, .woff2, .ttf, .otf, .eot, .mp4, .webm, and .pdf. PHP files, symlinks, hidden paths, and the document root's vendor/ and node_modules/ are not copied.

The filter also skips directories named app, bootstrap, config, resources, routes, storage, src, templates, tests, test, bin, parts, or patterns; JS/MJS filenames containing config or server; *.blade.html and *.twig.html; and filenames beginning with readme, license, or changelog. Because WordPress uses the root document directory, JS/MJS extraction is further limited to assets/, js/, static/, wp-includes/js/, wp-admin/js/, and wp-content/.

Extraction filters paths and extensions, not file contents. Do not assume that every template, configuration file, or server-source file is recognized: a nonpublic file with an allowed extension can otherwise be published to the CDN. Review your themes, plugins, and project layout and keep private files outside the public document root.

The preset first reads PHP require.php in composer.json, then a PHP declaration in .tool-versions. It selects the nearest supported PHP version in the declared major version, using pinned FrankenPHP bases for PHP 8.2, 8.3, 8.4, or 8.5. Missing or unsupported declarations use the current default, PHP 8.5. Check that your WordPress version and plugins support the selected PHP version; use your own Dockerfile for different runtime requirements.

Uploads and operational limits

The generated container runs as a non-root user. Its instance filesystem is ephemeral, and writable uploads are placed under /tmp/nitroship/uploads. Neither that directory nor other instance files are durable or shared between instances. Configure an S3 or other object-storage offload plugin for uploads; deploying again is not a backup strategy. Build-time CDN extraction does not publish new uploads created at runtime.

Treat plugin and theme code as deployment inputs: include updates in your source and redeploy rather than depending on in-dashboard writes to the running container. The preset does not provide durable local storage for plugin caches or file-based sessions; use an external backend when your plugins require shared state.

Nitroship does not automatically run migrations, queue workers, or schedulers. Run database changes and required upgrades from CI or your local machine with the appropriate production credentials. Background workers must run separately. For reliable scheduled work, see Cron jobs. The preset does not create a scheduler; WordPress's own request-triggered WP-Cron is application behavior, not a managed scheduling service.

Use your own Dockerfile

Without build.framework, the builder prefers the configured build.dockerfile, then Dockerfile.nitroship, then Dockerfile. It then tries Next.js, the highest-priority detected managed preset, and finally generic static output.

build.framework: "wordpress" explicitly selects this preset, overriding an automatically discovered Dockerfile. It cannot coexist with build.dockerfile. Remove build.framework when choosing your own image; see the Dockerfile guide for custom PHP extensions, startup commands, or runtime layouts.

Environment variables · Cron jobs · Dockerfile deployments

On this page