Groundfloor Docs

Deploy a container image

Worked example — deploy an off-the-shelf application (WordPress) as a Coderunner service, with CPU/memory limits and autoscaling replicas.

This walks through deploying WordPress — an application you didn't write, with no Groundfloor-specific code in it — as a Coderunner service. The point isn't WordPress specifically; it's that any application that ships as a container and listens on a port can run the same way. Swap the Dockerfile and env vars for your own image and the rest of this walkthrough still applies.

If you're deploying your own code (not a pre-built image), see Coderunner for the function/job/schedule types instead — those are a better fit for request/response handlers and batch jobs than service.

What you get

  • A long-running container, always reachable at a Deployment URL, running behind the Front Door edge proxy
  • CPU and memory limits you set
  • A min/max replica band the platform autoscales within (this is what "autoscaling" means here — see Resources you control)
  • Automatic redeploy-on-failure detection: if your container never becomes ready on its port, the deployment is marked Failed and traffic isn't routed to it

What you don't get (yet)

  • No customer-attachable persistent volume. The container's filesystem is ephemeral — anything WordPress writes to local disk (uploads, etc.) is lost on redeploy or a pod restart. Point file storage at Files or an S3-compatible bucket if your image supports it; this walkthrough accepts the limitation for simplicity.
  • No managed MySQL/MariaDB. Groundfloor's Managed Databases catalog today is Postgres, Redis, ClickHouse, and Qdrant — no MySQL-family engine. WordPress needs MySQL-compatible storage, so this example points at an external MySQL instance (RDS, Cloud SQL, or one you already run) rather than a Groundfloor-managed one. If your application can use Postgres instead, use a Groundfloor Managed Database and skip this caveat entirely.

Prerequisites

gf login --stage          # or --dev / production
gf workspaces use <uuid>

An external MySQL-compatible database reachable from your cluster's egress, with a database and user already created for WordPress.

1. Write the Dockerfile

Zip root must contain the Dockerfile — Kaniko builds with --dockerfile=Dockerfile, and language bootstrap does not apply to service workloads.

FROM wordpress:latest
EXPOSE 8080
ENV PORT=8080
# The official image listens on 80 by default; Coderunner requires 8080 (or $PORT).
RUN sed -i 's/Listen 80/Listen 8080/' /etc/apache2/ports.conf \
 && sed -i 's/:80>/:8080>/' /etc/apache2/sites-available/000-default.conf

2. Put credentials in Secrets, not the image

Never bake WORDPRESS_DB_PASSWORD into the Dockerfile or the ZIP.

gf secrets set WORDPRESS_DB_PASSWORD

3. Deploy

gf deploy --workload-type service \
  --runtime node \
  --cpu 500m --memory 512Mi \
  -e WORDPRESS_DB_HOST=your-mysql-host:3306 \
  -e WORDPRESS_DB_USER=wordpress \
  -e WORDPRESS_DB_NAME=wordpress \
  --secret WORDPRESS_DB_PASSWORD
  • --runtime must still be one of Code Runner's existing language slugs (node, python, go, dotnet, dotnet-script) even though it has no effect on a service build — the build always uses your Dockerfile. Pick any valid slug; node is a reasonable default. There's no docker or generic "container" runtime slug today.
  • gf deploy fails fast if the ZIP has no root Dockerfile for a service workload.

gf deploy does not set replicas. The CLI has --cpu and --memory, but no --min-replicas/--max-replicas flag — the autoscaling band is set from the Customer Portal's deploy dialog (Databases → your coderunner → Deploy), or by calling POST /v1/workspaces/{workspace_id}/coderunners/{id}/deploy directly with minReplicas/maxReplicas in the body (see Coderunners API). After gf deploy finishes the first deploy, set minReplicas: 1 there so the site doesn't cold-start on first load — a fresh coderunner otherwise deploys with the platform default replica count.

4. Verify

gf coderunner status -c <slug>

Open the printed Deployment URL — first load runs the WordPress installer. If the deployment shows Failed (status 4), check that your container is actually listening on 8080/PORT and bound to 0.0.0.0, not 127.0.0.1:

gf coderunner logs -c <slug>

5. Scale or update later

CPU/memory changes: redeploy with new --cpu/--memory values (CLI), or from the Portal deploy dialog. Replica/autoscaling-band changes: Portal deploy dialog or the deploy API only (see the callout above) — you don't need a new coderunner for either, only for a workload-type change (e.g. service → function).

On this page