Project Configuration (.pilum.yml)
.pilum.yml holds settings that apply to the whole project rather than one service. It is optional.
Don’t confuse the two files:
| File | Scope | Location |
|---|---|---|
pilum.yaml | One service | In each service directory, found by discovery |
.pilum.yml | Whole project | The directory you run Pilum from |
Pilum reads .pilum.yml from the current working directory only. It does not search parent directories, so run Pilum from the directory that holds it (normally the project root).
Pilum reads two sections:
webhooks: - url: https://hooks.slack.com/services/T000/B000/XXXX events: [success, failure]
compose: dependencies: - type: postgres secrets: [DATABASE_URL] - type: redis secrets: [REDIS_URL]Webhooks
webhooks is a list of HTTP endpoints that receive a JSON POST when a pipeline starts and when it finishes.
webhooks: - url: https://hooks.slack.com/services/T000/B000/XXXX events: [success, failure] - url: https://ci-events.example.com/pilum # no events: receives start, success and failure| Field | Type | Default | Description |
|---|---|---|---|
url | string | - | Endpoint to POST to. Entries without a url are skipped |
events | list | all events | Any of start, success, failure |
When webhooks fire
Webhooks fire for pilum deploy, build, publish, push and dry-run (including --dry-run). start is sent after services are discovered and the lock is taken, before the first step. success or failure is sent when the pipeline ends. rollback, status, logs and the other commands don’t send webhooks.
Payload
{ "event": "success", "command": "deploy", "tag": "v1.0.0", "services": ["api", "worker"], "duration": "1m23s", "success": true, "text": "deploy completed for 2 service(s) in 1m23s"}| Field | Description |
|---|---|
event | start, success or failure |
command | deploy, build, publish, push or dry-run |
tag | The --tag value; empty when no tag was passed |
services | Names of the services in the run (a multi-region service appears once per region) |
duration | Run time rounded to the second, e.g. 41s. Omitted on start |
success | true for start and success, false for failure |
error | Error message. Present only on failure |
text | One-line human-readable summary |
The text field means Slack-style incoming webhooks display a readable message without extra configuration.
Delivery
- Requests use
Content-Type: application/jsonandUser-Agent: pilum-webhook, with a 10-second timeout. httpsis required. Plainhttpis allowed only forlocalhost,127.0.0.1and::1.- Private and link-local addresses (
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,169.254.0.0/16,127.0.0.0/8,fc00::/7,fe80::/10) are refused, including hostnames that resolve to them. Redirects are not followed. - A failed or rejected webhook prints a warning. It never fails the run.
For GitHub commit statuses, use --github-status instead; see Environments & CI.
Compose Dependencies
compose.dependencies declares the infrastructure (databases, caches) that pilum compose adds to the generated docker-compose.yml alongside your services.
compose: dependencies: - type: postgres name: db database: payments secrets: [DATABASE_URL] - type: redis secrets: [REDIS_URL] - type: custom name: nats image: nats:2.10 port: 4222 healthcheck: "wget -qO- http://localhost:8222/healthz"| Field | Type | Default | Description |
|---|---|---|---|
type | string | - | Required. postgres, mysql, mariadb, redis, mongo or custom |
name | string | type | Compose service and container name |
image | string | preset image | Image to run. Required for custom |
port | int | preset port | Published as <port>:<port> |
user | string | appuser | Database user (not used by redis) |
password | string | apppassword | Database password (not used by redis) |
database | string | appdb | Database name (not used by redis) |
healthcheck | string | preset command | Health check command (CMD-SHELL) |
environment | map | - | Extra environment variables for the container |
secrets | list | - | Service secret names this dependency satisfies |
Presets
type | Image | Port | Connection string injected |
|---|---|---|---|
postgres | postgres:15-alpine | 5432 | postgresql://user:password@name:port/database?sslmode=disable |
mysql | mysql:8.0 | 3306 | mysql://user:password@name:port/database |
mariadb | mariadb:11 | 3306 | mysql://user:password@name:port/database |
redis | redis:7-alpine | 6379 | redis://name:port |
mongo | mongo:7 | 27017 | mongodb://user:password@name:port/database |
custom | your image | your port | none |
Each preset gets a named data volume and a health check; postgres also mounts ./init-scripts into /docker-entrypoint-initdb.d.
Wiring services to dependencies
secrets connects dependencies to services by secret name. When a service’s pilum.yaml declares a secret listed under a dependency’s secrets, the generated compose file:
- sets that environment variable to the dependency’s connection string, and
- adds a
depends_onon the dependency withcondition: service_healthy.
secrets: DATABASE_URL: database-url:latest # becomes postgresql://appuser:apppassword@db:5432/payments?sslmode=disableA malformed entry (missing type, unknown type, custom without image) makes pilum compose fail with the entry’s index. See Local Development for the rest of pilum compose.
Flag Defaults and Environment Variables
Flag names with a hyphen (only-tags, max-workers, dry-run) can’t be set from a shell variable, but they can be set as .pilum.yml keys. Other keys in .pilum.yml are ignored.
Next Steps
- Local Development — Generate and run
docker-compose.ymlwithpilum compose - Environments & CI —
--env, GitHub statuses and CI setup - Service Configuration — Per-service
pilum.yamlreference - CLI Reference — All commands and flags