This guide uses the production environment and main branch. Prepare the server and environment profile following shared CI/CD instructions.
1. Create the workflow
Enable Docker and Production deployment in Deployment. Choose GitHub as CI provider. In Deployment environments, create a production profile, enter servers and domains, and choose Archive or Registry delivery. Save settings, run Generate, and commit the generated profile and custom file without secrets to Git.
The generator creates .github/workflows/admingen.yml. Push the project to GitHub, enable Actions, and protect main. The workflow uses runner ubuntu-24.04 and Docker Buildx. Put your own jobs in separate workflow files: Generate updates admingen.yml.
2. Configure builds
By default, build reads the production profile from Git. For another profile, create repository variable ADMINGEN_BUILD_ENVIRONMENT in Settings → Secrets and variables → Actions → Variables, containing its name. Commit the generated profile and custom file.
Complete JSON is unnecessary in secrets. If intentionally keeping configuration outside Git, ADMINGEN_BUILD_ENVIRONMENT_JSON in repository secrets fully overrides the build profile, and ADMINGEN_ENVIRONMENT_JSON in environment secrets overrides the operation profile. Paste the complete manual JSON contents rather than a file path. Do not create these overrides for normal UI profiles.
Add registry secrets in Settings → Secrets and variables → Actions → Repository secrets.
For Registry, add if needed:
| Secret | Contents |
|---|---|
ADMINGEN_BUILD_REGISTRY_USER |
Registry user |
ADMINGEN_BUILD_REGISTRY_PASSWORD |
Publishing token |
For GHCR, the template can use GITHUB_TOKEN if this repository has package access. For another registry, set both variables. Archive needs no registry credentials; builds still need network access for base images and dependencies.
3. Create a release environment
In Settings → Environments, create production and permit deployment from main. Configure required reviewers if available and you want release approval.
Add environment secrets:
| Secret | Contents |
|---|---|
ADMINGEN_SSH_KEY |
Deployment user's private SSH key |
ADMINGEN_KNOWN_HOSTS |
Prepared server known_hosts |
Use the files from manual server setup. Paste their full contents, preserving line breaks. PostgreSQL passwords and application signing keys do not belong here.
For Registry, add ADMINGEN_REGISTRY_USER and ADMINGEN_REGISTRY_PASSWORD with read permissions if needed. For GHCR, an available workflow token can replace this pair; other registries need your own values. This is runner access; the server uses the persistent provisioning token.
Build and release JSON must describe the same environment and delivery method. Archive needs no registry secrets.
4. Obtain a build
Push code to main and open Actions → Admingen. Wait for a successful build.
The admingen-release artifact contains release.json, plus its matching *.images.tar for Archive. Keep them together. The artifact is available for 90 days.
For first installation, download it and perform provision following Archive or Registry, using the downloaded release instead of another build. The workflow does not perform initial provision.
5. Release the chosen build
- Open the successful workflow run from a push to
main. - Copy its numeric ID from the address:
.../actions/runs/123456789means123456789. - Open Actions → Admingen → Run workflow.
- Choose branch main,
operation: deploy,environment: production. - Paste the ID from step 2 into
build_run_id. - Start the workflow, approve deployment if required, and wait for completion.
- Open the application.
The workflow checks that the selected build succeeded and belongs to this workflow and a push to main. It then downloads and releases that exact artifact. Commit SHA and pull request number are not valid build_run_id values. If the artifact is deleted, that build cannot be released through the workflow.
6. Configure maintenance
Create environment production-maintenance, allow main, and add the same environment secrets. Disable manual approval for daily runs. Maintenance uses the same production profile.
The workflow already has a schedule: daily at 02:17 UTC. It creates a backup and maintains certificates. With backup.kind: none, backup is skipped. The schedule does not release new code.
For manual maintenance, choose operation: backup or certificates, environment: production, and branch main in Run workflow. No build_run_id is needed. Explicit backup with None fails.
If the environment is named staging, create environments staging and staging-maintenance with their secrets for manual operations. ADMINGEN_BUILD_ENVIRONMENT selects the build profile; daily scheduling still maintains production. Create a separate workflow for a different schedule.
If the workflow fails
| Symptom | Check |
|---|---|
| No Run workflow | File exists on default branch; Actions enabled |
| Operate skipped | Manual run selected on main |
| Build profile not found | ADMINGEN_BUILD_ENVIRONMENT name and generated/custom files in Git |
| Empty operation secrets | Correct environment selected; backup uses -maintenance suffix |
| GHCR permission denied | Package permissions and token for the build or release step |
| Maintenance waits for approval | Reviewer rules in production-maintenance |
| Deployment interrupted | Operation recovery |