Skip to content

Run Docker Compose

PerfShop ships with three distinct Docker Compose files. Each targets a specific deployment scenario. This page describes which one to choose, how to start it, and how to manage the stack lifecycle.

The three compose files

File Target Image strategy
docker-compose.yml Production — Synology NAS, production VPS, image registry Uses prebuilt images published on a registry
docker-compose.desktop.yml Docker Desktop (Windows, macOS) Local image build with Docker Desktop optimizations
docker-compose.build.yml Local Linux, Unix VPS, CI Local build without Docker Desktop specific optimizations

Pick the right file

  • On Windows / macOS with Docker Desktop: use docker-compose.desktop.yml
  • On Linux locally or on a VPS: use docker-compose.build.yml
  • In NAS production: use docker-compose.yml with .env.production

First-time startup

1. Copy the environment file

cp .env.example .env

This file contains all configuration variables with sensible default values for a local deployment. You can leave it as-is for a first start, or edit the values you want to customize (passwords, language, ports, public URLs).

Points to check depending on your situation:

  • HOST_IP — keep localhost on Docker Desktop; set the host IP if you want other machines to access the stack
  • PERFSHOP_LANGfr (default) or en
  • ADMIN_PASSWORD — change it for any public exposure
  • DB_PASSWORD, DB_ROOT_PASSWORD — same
  • PERFSHOP_LICENSE_KEY — paste your PerfShop key here to start with the license already active (see License system)

See the environment variables reference for the full list.

2. Start the stack

docker compose -f docker-compose.desktop.yml up -d --build
docker compose -f docker-compose.build.yml up -d --build
cp .env.production .env
docker compose up -d

The -d flag starts in detached mode (in the background). The --build flag forces local image rebuild — required for the first start and after any code change.

The first start downloads the base images (MySQL, Grafana, Prometheus, Loki, Tempo, OpenSearch, Selenium…), which can take several minutes depending on your connection. Subsequent starts are much faster.

3. Wait for healthchecks to pass

Several services have explicit dependencies via depends_on: { condition: service_healthy }. The backend waits for MySQL, monitoring waits for the backend, and so on. Compose handles the startup order automatically.

You can follow the status with:

docker compose ps

All services should move from starting to healthy within 30 to 90 seconds depending on the machine. The slowest one is usually perfshop-app (Spring Boot with Flyway running V1-V10 against an empty database).

4. Access the welcome page

Once the stack is running, open in a browser:

http://<HOST_IP>:3011

This page lists all exposed service URLs with their default credentials. See Welcome page.

Lifecycle

Stop the stack

docker compose -f <compose-file> down

Containers are stopped and removed. The persistent volumes (database, Grafana data, provisioned dashboards, Loki logs, Tempo traces, Pyroscope profiles) are kept.

Stop and remove volumes

docker compose -f <compose-file> down -v

Add -v to also remove volumes — the entire database, custom Grafana dashboards, historical logs will be lost. Use this to start over from a clean state.

Restart a single service

docker compose restart perfshop-app

Useful after a backend configuration change without touching the other services.

View logs

# All services
docker compose logs -f

# A single service
docker compose logs -f perfshop-app

# Last 100 lines
docker compose logs --tail=100 perfshop-app

The -f flag enables continuous tailing.

Rebuild a single image

docker compose build perfshop-app
docker compose up -d perfshop-app

Useful after modifying the code of a single component without wanting to rebuild everything.

Persistent volumes

The following data is kept across restarts:

Docker volume Service Contents
mysql-data perfshop-db PerfShop database (users, products, orders, license, sessions…)
grafana-data perfshop-grafana Grafana users, personal dashboards
prometheus-data perfshop-prometheus Metric history (default retention 15 days)
loki-data perfshop-loki Log history
tempo-data perfshop-tempo Trace history
pyroscope-data perfshop-pyroscope CPU and memory profiles
squash-db-data perfshop-squash-db Squash TM database
opensearch-data perfshop-opensearch OpenSearch indexes
forgejo-data perfshop-forgejo Local Git repositories

Dependencies between services

Docker Compose starts services in the order defined by depends_on. The simplified graph:

flowchart TD
  db[perfshop-db]
  app[perfshop-app]
  front[perfshop-frontend]
  mon[perfshop-monitoring]
  chaos[perfshop-chaos-admin]
  welcome[perfshop-welcome]

  prom[perfshop-prometheus]
  graf[perfshop-grafana]
  loki[perfshop-loki]
  tempo[perfshop-tempo]
  pyro[perfshop-pyroscope]

  db --> app
  app --> front
  app --> mon
  app --> chaos
  prom --> graf
  loki --> graf
  tempo --> graf
  pyro --> graf
  app -.->|push metrics| prom
  app -.->|push logs| loki
  app -.->|push traces| tempo
  app -.->|push profiles| pyro

The QA stack services (Selenium, Squash, Forgejo, Scripts UI, JMeter UI) are largely independent of the PerfShop core and start in parallel.

Healthchecks

Every critical service exposes an HTTP healthcheck or a shell command that Docker probes every few seconds:

Service Endpoint / command
perfshop-app GET /actuator/health
perfshop-frontend curl http://localhost
perfshop-db mysqladmin ping
perfshop-grafana GET /api/health
perfshop-prometheus GET /-/healthy

The condition: service_healthy option in depends_on makes Compose wait for the healthcheck to be green before starting the dependent services.

See also