Skip to content

Installation

TruePPM ships as pre-built Docker images and a Python package on PyPI. Through 0.3 (alpha) the images live on the internal GitLab Container Registry; starting with the 0.4 beta they will also publish to the GitHub Container Registry (GHCR) as a public pull path — ghcr.io/trueppm/{api,web} for the images and oci://ghcr.io/trueppm/charts for the chart — with every published artifact Trivy-scanned, CycloneDX SBOM-attested, and Cosign-signed (keyless). See Deployment for how to verify a signed artifact once 0.4 ships.

Docker Compose is the fastest path to a running instance — every service starts from one command, and it is the right path for evaluation, development, and contributors. Pick a different path if you’re deploying for production:

PathBest for
Docker Compose (below)Evaluation, development, contributors
Helm / KubernetesProduction, horizontal scaling
Single server with systemdProduction without Kubernetes
Scheduler libraryEmbedding the CPM engine in your own app

Before you put a real program on it, read the tested scale envelope — the scale ceilings measured against the 0.4 beta build, which dimensions are still untested, and the issue behind each ceiling. The short version: plan on the Schedule view staying comfortable up to roughly 1,000 tasks.


The fastest way to run TruePPM locally. All six services start from a single command.

ToolMinimum version
Docker + Docker Compose24+
Gitany recent
Terminal window
git clone https://gitlab.com/trueppm/trueppm.git
cd trueppm
docker compose up -d

Wait for all services to be healthy (usually 15–20 seconds), then open the web UI at http://localhost:5173.

Services started:

ServicePortPurpose
db5432PostgreSQL 16
valkey6379Celery broker + Django Channels layer (BSD-licensed Redis fork; wire-compatible)
api8000Django ASGI (uvicorn)
celeryCPM auto-scheduling worker
celery-beatPeriodic task runner
web5173React frontend

Migrations run automatically on first startup. The create_admin management command generates a secure random password and writes it to /tmp/trueppm_admin_password:

Terminal window
docker compose exec api cat /tmp/trueppm_admin_password
docker compose exec api rm /tmp/trueppm_admin_password # delete after retrieval

The quickest way to see TruePPM with realistic data is the in-app Load demo data button on the Programs page. It imports the Atlas Platform Launch sample — a hybrid program with a live sprint-to-milestone bridge, anchor-relative dates, and replayed history, so the demo always reads as current rather than aging into a fixed-date snapshot. If more than one sample is bundled, the button opens a picker.

Prefer the command line, or want the six persona logins used in the per-persona walkthrough? Seed the “Platform Migration” demo instead:

Terminal window
docker compose exec api python manage.py seed_demo_project --with-personas

Creates a “Platform Migration” project with eight closed sprints, an active sprint, baselines, resources, a retro, and six persona logins. The persona password is demo only when the API runs with DEBUG=True; on a production install (DEBUG=False) the command prints a one-time random password at the end of its output unless you set TRUEPPM_DEMO_PASSWORD — see seed_demo_project. The bundled samples can also be loaded from the CLI with load_sample_project --sample atlas-platform-launch (see management commands).

Terminal window
curl http://localhost:8000/api/v1/health/
# → {"status": "ok"}

The OpenAPI schema is at http://localhost:8000/api/schema/swagger-ui/.

For a production deployment — Kubernetes with Helm, a single server with systemd, or verifying image/chart signatures — see Deployment.


If you only need the CPM scheduling engine in your own Python application:

Terminal window
pip install trueppm-scheduler
from datetime import date, timedelta
from trueppm_scheduler import schedule, Calendar, Project, Task, Dependency, DependencyType
calendar = Calendar() # Mon–Fri working days
project = Project(
id="p-1", name="My Project", start_date=date(2026, 1, 5),
tasks=[
Task(id="t-1", name="Design", duration=timedelta(days=5)),
Task(id="t-2", name="Build", duration=timedelta(days=10)),
],
dependencies=[
Dependency(predecessor_id="t-1", successor_id="t-2", dep_type=DependencyType.FS),
],
calendar=calendar,
)
result = schedule(project)
print(result.tasks[1].early_finish) # 2026-01-23

See the Scheduler integration guide for full API reference.


VariableRequiredDescription
SECRET_KEYYesDjango secret key — 50+ character random string
DATABASE_URLYespostgres://user:password@host:5432/dbname
REDIS_URLYesredis://:password@host:6379 (Valkey accepts the redis:// scheme)
DJANGO_SETTINGS_MODULEYes (prod)trueppm_api.settings.prod
ALLOWED_HOSTSYesComma-separated list of allowed hostnames

The single-server path (systemd) adds a couple more — see Single server with systemd. For all configuration options, see Configuration.