Appearance
Staging Deployment — Synkrato Console
Environment-specific deployment guide for Synkrato staging. Follow the phases in azure-deployment.md — this document provides staging-specific values, naming, and commands.
Environment Summary
| Property | Value |
|---|---|
| Environment | synkrato-stg |
| Resource Group | gg-sy-stg-console |
| Location | centralus |
| Console URL | https://console-stg.synkrato.com |
| Zitadel Issuer | https://id-stg.synkrato.com |
| PostgreSQL Server | console-synkrato-stg-pg |
| Container Apps Env | console-synkrato-stg-env |
| Managed Identity | console-synkrato-stg-id |
| Front Door Profile | console-synkrato-stg-fd |
| Storage Account (SPA) | synkratoconsolewebstg |
| ACR | gaeadev.azurecr.io |
| Log Level | debug |
| Development Mode | true |
| Brand | Synkrato Console |
Scaling (Low)
| Service | Min | Max | Notes |
|---|---|---|---|
| Console API | 1 | 2 | Single replica is fine |
| Console Worker | 1 | 1 | Fixed |
| Zitadel | 1 | 1 | Fixed |
No zone redundancy. No HA on PostgreSQL. GeneralPurpose SKU (Standard_D2ds_v4) with 128 GB storage.
Step-by-Step
1. Prepare secrets
bash
cp infra/.env.synkrato-stg.example infra/.env.synkrato-stg
# Fill in all values — see infra/.env.synkrato-stg.example for the template2. Build and push images
bash
make docker-all REGISTRY=gaeadev.azurecr.io TAG=dev-latest
az acr login -n gaeadev --subscription <GaeaGlobal-subscription-id>
docker push gaeadev.azurecr.io/console-api:dev-latest
docker push gaeadev.azurecr.io/console-worker:dev-latest
docker push gaeadev.azurecr.io/console-web:dev-latest3. Deploy infrastructure
bash
./infra/deploy.sh synkrato-stg --phase infra4. Database setup
bash
# Allow your IP
az postgres flexible-server firewall-rule create \
--resource-group gg-sy-stg-console \
--name console-synkrato-stg-pg \
--rule-name AllowMyIP \
--start-ip-address <YOUR_IP> \
--end-ip-address <YOUR_IP>
# Connect
psql "postgresql://consoleadmin:<POSTGRES_ADMIN_PASSWORD>@console-synkrato-stg-pg.postgres.database.azure.com:5432/postgres?sslmode=require"sql
CREATE ROLE zitadel LOGIN PASSWORD '<ZITADEL_DB_PASSWORD>';
ALTER DATABASE zitadel_auth OWNER TO zitadel;
CREATE ROLE console_app LOGIN PASSWORD '<CONSOLE_DB_PASSWORD>';
GRANT azure_pg_admin TO console_app;
CREATE DATABASE console OWNER console_app;
\c console
GRANT ALL PRIVILEGES ON SCHEMA public TO console_app;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO console_app;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO console_app;
\qbash
# Remove firewall rule
az postgres flexible-server firewall-rule delete \
--resource-group gg-sy-stg-console \
--name console-synkrato-stg-pg \
--rule-name AllowMyIP --yes5. Zitadel init (local Docker)
See Phase 4 in azure-deployment.md for the full Docker command. Use these staging-specific values:
| Variable | Staging Value |
|---|---|
ZITADEL_EXTERNALDOMAIN | id-stg.synkrato.com |
ZITADEL_DATABASE_POSTGRES_HOST | console-synkrato-stg-pg.postgres.database.azure.com |
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_EMAIL_ADDRESS | admin@synkrato.com |
ZITADEL_DEFAULTINSTANCE_SMTPCONFIGURATION_FROM | console@synkrato.com |
Extract PAT tokens from the init log and add ZITADEL_LOGIN_SERVICE_TOKEN to infra/.env.synkrato-stg.
6. Deploy Zitadel + Front Door
bash
./infra/deploy.sh synkrato-stg --phase zitadel_frontdoor7. Configure DNS
Retrieve values:
bash
ASUID=$(az containerapp env show -n console-synkrato-stg-env -g gg-sy-stg-console \
--query "properties.customDomainConfiguration.customDomainVerificationId" -o tsv)
FD_ID_HOST=$(az afd endpoint list --profile-name console-synkrato-stg-fd -g gg-sy-stg-console \
--query "[?starts_with(name,'id-')].hostName" -o tsv)
DNSAUTH_ID=$(az afd custom-domain show --profile-name console-synkrato-stg-fd -g gg-sy-stg-console \
--custom-domain-name id-stg-synkrato-com \
--query "validationProperties.validationToken" -o tsv)Create DNS records:
| Type | Name | Value |
|---|---|---|
| TXT | asuid.id-stg.synkrato.com | <customDomainVerificationId> |
| TXT | _dnsauth.id-stg.synkrato.com | <validationToken> |
| CNAME | id-stg.synkrato.com | <id-endpoint>.azurefd.net |
| TXT | asuid.console-stg.synkrato.com | <customDomainVerificationId> |
Verify:
bash
curl -s https://id-stg.synkrato.com/debug/ready
# Expected: ok8. Bootstrap
bash
cat > .bootstrap-input.env << 'EOF'
ZITADEL_URL=https://id-stg.synkrato.com
ZITADEL_PAT=<admin-human-user-pat>
CONSOLE_URL=https://console-stg.synkrato.com
DEVELOPMENT_MODE=true
EOF
go run ./scripts/bootstrap/Copy output values from .bootstrap.env to infra/.env.synkrato-stg.
9. Full stack deploy
bash
./infra/deploy.sh synkrato-stg10. Console DNS + verify
Retrieve console Front Door values:
bash
FD_CONSOLE_HOST=$(az afd endpoint list --profile-name console-synkrato-stg-fd -g gg-sy-stg-console \
--query "[?starts_with(name,'console-')].hostName" -o tsv)
DNSAUTH_CONSOLE=$(az afd custom-domain show --profile-name console-synkrato-stg-fd -g gg-sy-stg-console \
--custom-domain-name console-stg-synkrato-com \
--query "validationProperties.validationToken" -o tsv)| Type | Name | Value |
|---|---|---|
| CNAME | console-stg.synkrato.com | <console-endpoint>.azurefd.net |
| TXT | _dnsauth.console-stg.synkrato.com | <validationToken> |
bash
curl -s https://console-stg.synkrato.com/api/healthz11. Deploy Web SPA
bash
cd web && npm run build && cd ..
./infra/deploy.sh synkrato-stg --deploy-web-only12. Re-run bootstrap (webhook)
bash
go run ./scripts/bootstrap/
./infra/deploy.sh synkrato-stg # pick up webhook secret if changedDay-to-Day Operations
Redeploy after code changes
bash
make docker-all REGISTRY=gaeadev.azurecr.io TAG=dev-latest
docker push gaeadev.azurecr.io/console-api:dev-latest
docker push gaeadev.azurecr.io/console-worker:dev-latest
./infra/deploy.sh synkrato-stgSPA-only update
bash
cd web && npm run build && cd ..
./infra/deploy.sh synkrato-stg --deploy-web-onlyDeploy specific image tag
bash
./infra/deploy.sh synkrato-stg --image-tag git-abc1234Preview changes
bash
./infra/deploy.sh synkrato-stg --what-if
