Deploying with Docker
Setyenv is published as a Docker image: WordPress with WP-PFManagement, WP-PFWorkflow and WP-PFAgent already installed and activated. It runs the Community Edition by default and switches to the Enterprise Edition the moment you give it a key.
Image: setyenv/setyenv on Docker Hub. latest is the newest suite; every image is also tagged with the three plugin versions it carries, <pfm>-<pfw>-<pfa> (for example 1.2.25-1.2.13-1.2.8).
What is in the image
- The official WordPress image (Apache, PHP 8.3) plus the PHP
imapextension the WP-PFManagement inbox needs. - The three plugins, exactly the builds you would download from the portal, activated on the first request after WordPress is installed.
- A built-in cron every 3 minutes: WordPress's own visit-driven cron is switched off and a loop inside the container runs
wp-cron.phpon schedule, so workflows' async queue, the inbox poller and the daily licence check run on time even on a site nobody visits. The cadence isSETYENV_CRON_SECONDS(seconds, minimum 60). - An embedded MariaDB, used only when no external database is given.
No demo data, no default admin: you finish the normal WordPress install on first visit.
Run it on its own
docker run -d -p 8080:80 --name setyenv setyenv/setyenv
# then open http://localhost:8080 and finish the WordPress install
Docker Desktop's Run button does the same. With no WORDPRESS_DB_HOST given, the container starts an embedded MariaDB (bound to 127.0.0.1, its files in the /var/lib/mysql volume) and WordPress uses it; the database password is generated inside the container and written to wp-config.php. Name the two volumes, /var/www/html and /var/lib/mysql, to keep the site across container re-creation.
With your own database
Pass the usual WORDPRESS_DB_* variables and the embedded database never starts. The smallest compose, with MariaDB as a second container:
services:
setyenv:
image: setyenv/setyenv:latest
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: change-me
# SETYENV_LICENSE_KEY: "PFL3.…" # Enterprise Edition (optional)
volumes:
- html:/var/www/html
depends_on:
- db
restart: unless-stopped
db:
image: mariadb:11
environment:
MARIADB_DATABASE: wordpress
MARIADB_USER: wordpress
MARIADB_PASSWORD: change-me
MARIADB_ROOT_PASSWORD: change-me-too
volumes:
- db:/var/lib/mysql
restart: unless-stopped
volumes:
html:
db:
docker compose up -d
# then open http://localhost:8080 and complete the WordPress install
Every WORDPRESS_* variable of the official image works unchanged (WORDPRESS_TABLE_PREFIX, WORDPRESS_CONFIG_EXTRA, …). Put the site behind your usual reverse proxy for TLS.
Community or Enterprise
The container starts as the Community Edition — free for personal and non-commercial use, every feature on. For commercial use, give it an Enterprise key in either of two ways:
SETYENV_LICENSE_KEYin the environment: the key is applied on the first request after WordPress is installed. Change the value to apply a new key; the container reads it once per value.- wp-admin → Setyenv → License in either plugin, like on any WordPress.
Either way both plugins switch together. See Community & Enterprise for what the key does and does not do.
Updates
The plugins update through the Setyenv update channel like on any WordPress install: the update appears under Plugins, and auto-updates work if you enable them. The plugin files live in the html volume, so an update survives container restarts and image pulls; pulling a newer image only matters for a fresh install (the image is the plugins' first copy, not their source of updates).
Persistence and backups
Everything that is yours lives in two volumes: html (WordPress, the plugins, uploads) and db. Back those up and the container itself is disposable.
What the container reports
Once a day the suite tells setyenv.com that it exists — an opaque site fingerprint, the host name, docker as its runtime, the edition and the plugin versions. That is how we count hosts and containers running the product. See Telemetry & privacy for the exact fields.