Skip to content
English
  • There are no suggestions because the search field is empty.

01.03 Installing via Docker

SimpleRisk's official Docker images live in the separate simplerisk/docker repository. Here's how to deploy with the published images, the docker-compose pattern, the volume conventions, and the considerations specific to containerized deployments.

Why this matters

The Docker deployment shape is the most common SimpleRisk deployment for organizations that already operate containerized infrastructure. The image is self-contained (PHP, the SimpleRisk source, the supervised entry point all packaged together), the deployment artifacts are version-controlled, and the cattle-not-pets lifecycle matches the rest of the organization's workload model. For organizations new to containers, the Docker path adds learning overhead that a native Linux install avoids; for organizations already running everything containerized, the Docker path is the obvious fit.

The honest scope to know: the Docker artifacts are NOT in the SimpleRisk application repository (the one this Admin Guide ships in). The Docker support (Dockerfiles, image-build pipeline, docker-compose templates) lives in the separate simplerisk/docker repository on GitHub. This article describes the deployment pattern based on the published images; for the canonical Docker-side reference (image tags available, build instructions, image internals), the simplerisk/docker repository is the source of truth.

The other thing worth knowing: containerized SimpleRisk runs the same application as native-Linux SimpleRisk. The 6-step initial wizard, the Extras model, the v2 API surface, the operational mechanics — all identical. The Docker-specific concerns are the deployment shape (containers vs. processes), the data persistence (volume mounts), the configuration injection (environment variables, mounted config files), and the upgrade workflow (image pulls vs. file replacement). Those are the operationally distinctive bits documented here.

Before you start

Have these in hand:

  • A Docker-capable host (or a container orchestration platform like Kubernetes that can run the image). Docker Engine, Docker Desktop, or any compatible runtime works.
  • Docker Compose (or docker compose plugin for newer Docker versions). Most SimpleRisk Docker deployments use Compose for the multi-container pattern (SimpleRisk image + MySQL image).
  • Persistent storage for the SimpleRisk database and the application's writable directories. Docker volumes (managed) or host bind mounts (operator-managed) both work; pick the pattern your operations team prefers.
  • A reverse proxy or load balancer for production HTTPS termination. SimpleRisk's container typically listens on HTTP internally; the production deployment puts a reverse proxy in front (Nginx, HAProxy, AWS ALB, etc.) to handle TLS, redirect HTTP to HTTPS, and add HSTS headers.
  • A read on the System Requirements — the underlying application has the same requirements regardless of deployment shape, so the prerequisites still apply.
  • The image tag you want to deploy. The published images are tagged by SimpleRisk version; the simplerisk/docker repository documents which tag corresponds to which SimpleRisk release. Pin to a specific version rather than latest for production.

Step-by-step

1. Get the Docker artifacts

Clone the simplerisk/docker repository or download a release tarball. The repository contains:

  • Dockerfile(s) — the image build definitions. Useful for reading the image's internals or for building custom variants.
  • docker-compose.yml templates — reference Compose configurations for common deployment shapes.
  • Volume conventions documented in the README — which paths in the container correspond to which SimpleRisk concerns (web root, logs, configuration, uploads).

Read the simplerisk/docker README for the current canonical guidance; this article describes the general pattern, but the specific image names, tags, and Compose files in that repository are authoritative for any given release.

2. Pick a deployment shape

Three common Docker deployment patterns:

  • Single-container with embedded MySQL — the SimpleRisk image runs Apache, PHP, and MySQL all together. Simplest to deploy; appropriate for evaluation, demo, and small single-team installations. Not recommended for production — when you upgrade SimpleRisk, the database upgrade is bundled, and database backups have to extract through the same container.
  • Multi-container with separate MySQL container — the SimpleRisk image runs Apache + PHP, an official MySQL image runs the database, the two containers communicate over a Docker network. The standard production-grade pattern; documented in the simplerisk/docker repository's reference Compose file. Recommended for most deployments.
  • Multi-container with external managed database — the SimpleRisk image runs Apache + PHP, the database lives on managed RDS/Aurora/CloudSQL/Azure Database/etc. The right pattern for organizations with existing managed-database operational practice. The SimpleRisk container connects to the external database over network; configure the database credentials via environment variables or a mounted config file.

The choice affects the docker-compose configuration but not the SimpleRisk-side install steps.

3. Configure the environment

The SimpleRisk Docker image accepts configuration through:

  • Environment variables for the database credentials and other install-time settings.
  • Mounted volumes for persistent data (database files if using the embedded MySQL pattern, the SimpleRisk writable directories for logs and uploads, the config.php file once it's been generated).
  • Mounted configuration files for advanced customizations (custom php.ini directives, custom Apache vhost overrides, etc.).

The simplerisk/docker repository's reference Compose file documents the specific environment variables and volume paths the published image expects. The general pattern looks like:

services:
  simplerisk:
    image: simplerisk/simplerisk:
  
    ports: - "80:80" environment: - DB_HOST=mysql - DB_PORT=3306 - DB_NAME=simplerisk - DB_USER=simplerisk - DB_PASSWORD=
   
     volumes: - simplerisk-config:/var/www/simplerisk/includes/config.php - simplerisk-logs:/var/www/simplerisk/logs - simplerisk-uploads:/var/www/simplerisk/uploads depends_on: - mysql restart: unless-stopped mysql: image: mysql:8.0 environment: - MYSQL_ROOT_PASSWORD=
    
      - MYSQL_DATABASE=simplerisk - MYSQL_USER=simplerisk - MYSQL_PASSWORD=
     
       command: - --sql-mode= volumes: - mysql-data:/var/lib/mysql restart: unless-stopped volumes: simplerisk-config: simplerisk-logs: simplerisk-uploads: mysql-data: 
     
    
   
  

Note the MySQL container's --sql-mode= argument — this disables the strict modes (STRICT_TRANS_TABLES, NO_ZERO_DATE, ONLY_FULL_GROUP_BY) that block SimpleRisk. See System Requirements for the SQL mode discussion.

(The above Compose file is illustrative; the canonical version with current image names and environment-variable conventions lives in the simplerisk/docker repository.)

4. Bring up the containers

docker compose up -d

Verify both containers are running:

docker compose ps

Both simplerisk and mysql services should show as healthy. If either is restarting or stopped, check the logs:

docker compose logs simplerisk
docker compose logs mysql

5. Run the SimpleRisk installer

Open http:// / in a browser. The SimpleRisk container's entry point detects the uninstalled state and redirects to the 6-step initial wizard, the same wizard as the native Linux install. See The Initial Configuration Wizard for the per-step walk-through.

The Docker-specific notes for the wizard:

  • Step 3 (Database Credentials): provide the MySQL admin credentials. If you used the Compose file above, that's root and the MYSQL_ROOT_PASSWORD you set. The hostname is the container name of the MySQL service (in the example, mysql), not localhost.
  • Step 4 (SimpleRisk Configuration): the SimpleRisk username and database name can match what the Compose file pre-created via the MYSQL_USER / MYSQL_DATABASE environment variables, or the installer can create them itself. If you used MYSQL_USER/MYSQL_DATABASE, the installer's "user already exists" check will surface; pick a different username/database, or pre-create them out-of-band.
  • Step 6 (Installation Execution): the installer fetches the schema from raw.githubusercontent.com. The container needs outbound HTTPS to GitHub; if your environment blocks this, configure a proxy at the Docker level (typically via HTTPS_PROXY environment variable) or pre-stage the schema in the image.

After Step 6 completes, the installer writes config.php to the mounted volume, and the application is operational.

6. Configure the reverse proxy for HTTPS

The Docker image typically listens on HTTP internally (port 80 in the container). For production, put a reverse proxy in front:

  • Nginx in a separate container — add an Nginx service to the Compose file, terminate TLS there, proxy to the SimpleRisk container.
  • Traefik or Caddy — both auto-issue Let's Encrypt certificates and proxy to backend services. Useful for development clusters and many small deployments.
  • Cloud-provider load balancer — AWS ALB, Azure Application Gateway, GCP Load Balancer. The cloud LB handles TLS; the container behind it speaks HTTP.

The reverse proxy should:

  • Terminate TLS with a valid certificate.
  • Add an HTTP-to-HTTPS redirect for inbound HTTP requests.
  • Pass the X-Forwarded-Proto and X-Forwarded-For headers so SimpleRisk knows the request was originally HTTPS (the simplerisk_base_url setting and cookie-secure-flag detection depend on this).
  • Optionally add HSTS, CSP, and other security headers (SimpleRisk doesn't add these itself).

See HTTPS and TLS Configuration for the SimpleRisk-side considerations.

7. Set up cron jobs

The SimpleRisk image's behavior on cron varies by image variant. Some bundled images run cron internally (a supervisord process invokes the cron scripts on the container's own schedule); others expect the host or an external scheduler to invoke cron via docker exec or via the v2 API.

Confirm in the simplerisk/docker README which pattern your image uses. If the image doesn't run cron internally, set up a host-side cron entry that runs:

docker exec simplerisk php /var/www/simplerisk/cron/cron_notification.php

(And similar for the other cron scripts — see The Cron Jobs for the full inventory.)

8. Plan for upgrades

Container upgrades use a different pattern than native Linux upgrades:

  • Pull the new image tag.
  • Stop the current container.
  • Start a new container from the new image, with the same volume mounts.
  • The application picks up the new code; any database migrations run on the next page load (driven by the same upgrade_database() mechanism documented in The Upgrade Process).

The volume-based persistence (database, config, logs, uploads) survives the container replacement; the application code comes from the new image.

For zero-downtime upgrades on production deployments, run the new container alongside the old, drain the load balancer to the new container, and then stop the old. Standard blue-green container deployment patterns apply.

The upgrade-specific Docker workflow is in Upgrading via Docker.

Common pitfalls

A handful of patterns recur with Docker deployments.

  • Using latest tag in production. The latest tag floats; production deployments should pin to a specific version tag so upgrades happen deliberately. Pin in the Compose file (image: simplerisk/simplerisk:20260422-001 rather than image: simplerisk/simplerisk:latest). Schedule the upgrade explicitly when the next version is available.

  • Forgetting the --sql-mode= MySQL argument. The MySQL official images default to strict modes that SimpleRisk's installer rejects. The command: --sql-mode= argument in the Compose file disables them; without this, the installer fails at Step 3 with the SQL mode error.

  • Volume mount points wrong for the image variant. Different variants of the SimpleRisk Docker image expect mounts at different paths. The Compose file in this article uses /var/www/simplerisk/... paths; some image variants use /srv/simplerisk/... or other paths. Check the simplerisk/docker README for your image variant's specific paths.

  • Container can't reach GitHub for the schema fetch. During Step 6, the installer needs outbound HTTPS to raw.githubusercontent.com. Container networking that blocks outbound HTTPS produces a Step 6 hang. Configure proxy settings if needed (HTTPS_PROXY environment variable in the Compose service).

  • Forgetting to mount config.php as a volume. The installer writes config.php during Step 6. If simplerisk/includes/config.php isn't mounted as a volume, the file lives only inside the container's writable layer and is lost when the container is replaced (e.g., during an upgrade). Always mount config.php to a persistent volume.

  • Running cron from inside a stateless container without external scheduling. Some operators stand up the SimpleRisk image and assume cron just works. If the image variant doesn't run cron internally, the cron jobs don't run, and notifications/syncs/maintenance go silent. Verify the cron pattern for your image variant; configure host-side cron if the image doesn't handle it.

  • Sharing volumes across multiple SimpleRisk containers without coordination. A scaled-out deployment with two SimpleRisk containers behind a load balancer needs to share the database (which is fine; both containers connect to the same MySQL), the uploads volume (so a file uploaded to container A is visible to container B), and the config (both containers need the same config.php). The cron, however, should run on one container only — running cron on both produces duplicate notifications and concurrent sync attempts. Designate one container (or a separate cron-only container) as the cron runner.

  • Treating volume snapshots as backups. A Docker volume snapshot captures the volume's bytes at a moment in time, but a MySQL data volume snapshotted while the database is running can be inconsistent (mid-transaction state). For real backups, use the database's native backup tools (mysqldump, xtrabackup) inside the container; volume snapshots alone aren't a backup strategy. See Database Backup and Restore.

  • Running outdated MySQL or PHP versions because the SimpleRisk image is pinned. The SimpleRisk container has its own pinned PHP version; the MySQL container has its own MySQL version. Both should be updated as part of the security-patch cadence. The SimpleRisk version-tag pinning doesn't pin the MySQL container — those upgrade independently.

  • Not pulling images through a private registry mirror. Production deployments that pull from Docker Hub directly are subject to Docker Hub's rate limits and any availability incidents. For production, mirror the SimpleRisk images through your organization's private container registry; pull from the mirror in production deployments.

Related

Reference

  • Permission required: Server-side: Docker access. SimpleRisk-side: not applicable (pre-installation).
  • Implementing files: Docker images and Compose templates: separate repository at https://github.com/simplerisk/docker. SimpleRisk application code (mounted into the container): simplerisk/index.php, simplerisk/install.php, simplerisk/includes/install.php, simplerisk/includes/config.php.
  • Database tables: Created during Step 6 from the SQL schema fetched at https://raw.githubusercontent.com/simplerisk/database/{branch}/simplerisk-{language}-{version}.sql — same as native install.
  • config_settings keys: Set during Step 6: simplerisk_base_url, ssl_certificate_check_simplerisk, default_language, instance_id, schedule_cron_ping.
  • Volume mounts: simplerisk/includes/config.php (configuration); simplerisk/logs/ (operational logs); simplerisk/uploads/ (file uploads); MySQL data directory if using embedded MySQL.
  • Environment variables: Image-variant-dependent; consult simplerisk/docker README. Typical: DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD for SimpleRisk; MYSQL_ROOT_PASSWORD, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD for MySQL.
  • External dependencies: Docker engine, MySQL container (or external managed database); outbound HTTPS to raw.githubusercontent.com during install; outbound HTTPS for Extras after install.