Groundfloor Docs

Example: run WordPress

Run an off-the-shelf application — WordPress — as a Coderunner Service.

This example runs WordPress, an application you didn't write, as a Service. Nothing here is specific to WordPress: any application that ships as a container and serves HTTP runs the same way. Swap in your own image and settings.

What to know first

  • Storage is temporary. Anything WordPress writes to local disk, such as uploads, is lost when the Service restarts or you redeploy. A production site should store media elsewhere.
  • WordPress needs MySQL. Groundfloor's managed databases are PostgreSQL, so this example uses a MySQL database you already run elsewhere. If your own application can use PostgreSQL, use a Groundfloor managed database instead.

Before you start

  • The gf CLI, signed in: gf login, then gf workspaces use <workspace-id>.
  • A MySQL database and user for WordPress, reachable from the internet.
  • An M2M client with Read secrets turned on.

1. Store the database password

gf secrets set WORDPRESS_DB_PASSWORD -   # paste the password, then press Ctrl+D

2. Read the password at startup

WordPress can't call the Secrets API itself, so a small script does it before starting WordPress. It uses the M2M credentials that Coderunner puts in the container's environment (see Configuration and secrets). It passes environment_id to read the password stored for the Coderunner's own environment; without it, a production site would get the dev one. environment_id only chooses which environment's secrets to read: an M2M client with Read secrets can still read every environment's. The script removes the M2M credentials before starting WordPress, so WordPress never sees them, and stops if it can't read the password.

start.sh
#!/bin/sh
set -eu
API="$CONTROLPLANE_URL/v1/workspaces/$GROUNDFLOOR_WORKSPACE_ID"

# The credentials go to curl on stdin, never as command-line arguments.
TOKEN=$(jq -n '{client_id: env.GROUNDFLOOR_M2M_CLIENT_ID, client_secret: env.GROUNDFLOOR_M2M_CLIENT_SECRET}' \
  | curl -sf -X POST "$API/m2m/token" -H "Content-Type: application/json" -d @- \
  | jq -r '.access_token // empty')
[ -n "$TOKEN" ] || { echo "start.sh: couldn't get an M2M token" >&2; exit 1; }

WORDPRESS_DB_PASSWORD=$(printf 'Authorization: Bearer %s\n' "$TOKEN" \
  | curl -sf -H @- "$API/secrets/WORDPRESS_DB_PASSWORD?environment_id=${GROUNDFLOOR_ENVIRONMENT_ID:-}" \
  | jq -r '.value // empty')
[ -n "$WORDPRESS_DB_PASSWORD" ] || { echo "start.sh: couldn't read WORDPRESS_DB_PASSWORD" >&2; exit 1; }
export WORDPRESS_DB_PASSWORD

unset GROUNDFLOOR_M2M_CLIENT_ID GROUNDFLOOR_M2M_CLIENT_SECRET TOKEN
exec docker-entrypoint.sh apache2-foreground

3. Write the Dockerfile

The official image listens on port 80; a Service must listen on 8080. The database settings that aren't secret go in the image as ENV lines, so every deploy has them; Groundfloor doesn't keep deploy-time variables between deploys.

Dockerfile
FROM wordpress:latest
RUN apt-get update && apt-get install -y --no-install-recommends jq && rm -rf /var/lib/apt/lists/* \
 && sed -i 's/Listen 80/Listen 8080/' /etc/apache2/ports.conf \
 && sed -i 's/:80>/:8080>/' /etc/apache2/sites-available/000-default.conf
COPY start.sh /usr/local/bin/start.sh
RUN chmod +x /usr/local/bin/start.sh
ENV WORDPRESS_DB_HOST=your-mysql-host:3306 \
    WORDPRESS_DB_USER=wordpress \
    WORDPRESS_DB_NAME=wordpress
EXPOSE 8080
ENV PORT=8080
CMD ["start.sh"]

4. Deploy

From the folder with Dockerfile and start.sh:

gf deploy --name wordpress --workload-type service --runtime node --cpu 500m --memory 512Mi

Then, in the Client Portal, attach your M2M client to the wordpress Coderunner and deploy again, so the container gets its credentials. In the same deploy dialog, set the minimum number of instances to 1, so the site doesn't have to start up on its first visit.

5. Check that it worked

gf coderunner status -c wordpress

Open the Deployment URL it prints: the first visit runs the WordPress installer. Complete the installer as soon as the first deploy finishes. Until you do, anyone who opens the URL can set up the site and make themselves its admin. If the deployment shows Failed, read the log:

gf coderunner logs -c wordpress

The usual causes are WordPress not listening on 8080, or start.sh failing to read the secret; the log shows which.

Change it later

  • CPU or memory: deploy again with new --cpu and --memory values, or use the deploy dialog.
  • Number of instances: the Client Portal's deploy dialog or the API. The CLI has no flag for this yet.

Next steps

On this page