Payroll Engine Container Setup
This document describes how to set up and run the Payroll Engine stack using Docker.
Setup Variants
The repository includes two Docker Compose files for different use cases:
| File | Use case | Requirement |
|---|---|---|
docker-compose.ghcr.yml |
End users — pulls pre-built images from ghcr.io |
Docker + GitHub PAT |
docker-compose.yml |
Developers — builds images from local source code | All source repositories present |
The Payroll Console can be run as a Docker container for automation and testing (see Running the Payroll Console below).
Prerequisites
- Docker (includes Docker Compose)
- A GitHub account with a Personal Access Token (PAT)
GitHub Container Registry Login
The Docker images are hosted on the GitHub Container Registry (ghcr.io) and require authentication. Create a GitHub PAT with the read:packages scope at github.com/settings/tokens, then log in:
echo "<your-pat>" | docker login ghcr.io -u <github-username> --password-stdin
This is a one-time step per machine. Without login, docker compose up and docker run will fail with an unauthorized error.
Getting Started
The stack runs five services: SQL Server, a one-time db-init container (creates or migrates the database), Backend API, Web Application, and optionally the Payroll Console for automation and testing.
1. Clone the Repository
The repository includes both a developer compose file (docker-compose.yml) and a ready-to-use file for pre-built images:
git clone https://github.com/Payroll-Engine/PayrollEngine.git
cd PayrollEngine
2. Environment Configuration
Create a file named .env in the repository root to set the database password:
# PayrollEngine Docker Stack Configuration
DB_PASSWORD=PayrollStrongPass789
Use alphanumeric characters only — special characters like
!,@,#can cause authentication failures that appear as misleading "sqlcmd not found" errors.The
.envfile is excluded from version control (.gitignore) and must be created manually — this is intentional to avoid storing passwords in the repository.
3. Docker Compose File
The repository includes docker-compose.ghcr.yml — a ready-to-use compose file that pulls pre-built images from ghcr.io. The docker-compose.yml is for local development builds and requires all source repositories to be present.
The
sql-copyservice extracts the database scripts from the Backend image into a shared volume. Thedb-initservice then decides automatically: - New installation: Creates the database and runsModelCreate.sql- Existing database: RunsModelUpdate.sql(idempotent — skips if already at target version)As a safety net, the Backend also verifies the database schema version on startup and refuses to start if the version does not match.
4. Start the Stack
That's it. Steps 1–2 are all that's needed before starting the stack.
docker compose -f docker-compose.ghcr.yml up -d
This will pull the pre-built images from ghcr.io and start all services. On the first run, the database initialization takes approximately 30 seconds.
5. Accessing the Applications
Once the stack is running:
| Service | URL |
|---|---|
| Web Application | http://localhost:8081 |
| Backend API | http://localhost:5001 |
| Swagger UI | http://localhost:5001/swagger |
| SQL Server | localhost:1433 (user: sa, password: from .env) |
Verify the SQL Server connection:
docker exec payroll-db /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P "YourPassword" -C -Q "SELECT @@VERSION"
Use the Payroll Console container to install examples and execute tests against the running Backend.
6. Stopping the Stack
Stop and remove the containers:
docker compose -f docker-compose.ghcr.yml down
Stop and also remove the database volume (all data):
docker compose -f docker-compose.ghcr.yml down -v
Using a Specific Version
By default, the docker-compose.yml uses the :latest tag. To pin a specific release version, replace the image tags:
backend-api:
image: ghcr.io/payroll-engine/payrollengine.backend:2.1.0
# ...
webapp:
image: ghcr.io/payroll-engine/payrollengine.webapp:3.0.0
# ...
Available image tags are listed on the Releases page.
Updating to a New Version
- Update the image tags in
docker-compose.ghcr.yml(or use:latest) - Pull the new images and restart:
docker compose -f docker-compose.ghcr.yml pull docker compose -f docker-compose.ghcr.yml up -d
The db-init service handles database migrations automatically. If the new Backend image includes a schema update, ModelUpdate.sql is executed before the Backend starts. If the database is already at the target version, the script does nothing.
If the Backend detects a version mismatch on startup, it will log an error and stop. Check the Release Notes for breaking changes.
Running the Payroll Console
The Payroll Console is available as a Docker image for automation, testing, and data import tasks:
docker run --rm --network payroll-engine_default \
-e PayrollApiConnection="BaseUrl=http://backend-api:8080; Port=8080;" \
ghcr.io/payroll-engine/payrollengine.payrollconsole:latest \
PayrollTest --testFile Tests/Test.All.pecmd
Next Steps
- Basic Payroll example
- Examples — payroll examples and demos
- Articles — blog posts and technical articles