Skip to content

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

PropertyValue
Environmentsynkrato-stg
Resource Groupgg-sy-stg-console
Locationcentralus
Console URLhttps://console-stg.synkrato.com
Zitadel Issuerhttps://id-stg.synkrato.com
PostgreSQL Serverconsole-synkrato-stg-pg
Container Apps Envconsole-synkrato-stg-env
Managed Identityconsole-synkrato-stg-id
Front Door Profileconsole-synkrato-stg-fd
Storage Account (SPA)synkratoconsolewebstg
ACRgaeadev.azurecr.io
Log Leveldebug
Development Modetrue
BrandSynkrato Console

Scaling (Low)

ServiceMinMaxNotes
Console API12Single replica is fine
Console Worker11Fixed
Zitadel11Fixed

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 template

2. 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-latest

3. Deploy infrastructure

bash
./infra/deploy.sh synkrato-stg --phase infra

4. 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;
\q
bash
# Remove firewall rule
az postgres flexible-server firewall-rule delete \
  --resource-group gg-sy-stg-console \
  --name console-synkrato-stg-pg \
  --rule-name AllowMyIP --yes

5. Zitadel init (local Docker)

See Phase 4 in azure-deployment.md for the full Docker command. Use these staging-specific values:

VariableStaging Value
ZITADEL_EXTERNALDOMAINid-stg.synkrato.com
ZITADEL_DATABASE_POSTGRES_HOSTconsole-synkrato-stg-pg.postgres.database.azure.com
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_EMAIL_ADDRESSadmin@synkrato.com
ZITADEL_DEFAULTINSTANCE_SMTPCONFIGURATION_FROMconsole@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_frontdoor

7. 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:

TypeNameValue
TXTasuid.id-stg.synkrato.com<customDomainVerificationId>
TXT_dnsauth.id-stg.synkrato.com<validationToken>
CNAMEid-stg.synkrato.com<id-endpoint>.azurefd.net
TXTasuid.console-stg.synkrato.com<customDomainVerificationId>

Verify:

bash
curl -s https://id-stg.synkrato.com/debug/ready
# Expected: ok

8. 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-stg

10. 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)
TypeNameValue
CNAMEconsole-stg.synkrato.com<console-endpoint>.azurefd.net
TXT_dnsauth.console-stg.synkrato.com<validationToken>
bash
curl -s https://console-stg.synkrato.com/api/healthz

11. Deploy Web SPA

bash
cd web && npm run build && cd ..
./infra/deploy.sh synkrato-stg --deploy-web-only

12. Re-run bootstrap (webhook)

bash
go run ./scripts/bootstrap/
./infra/deploy.sh synkrato-stg   # pick up webhook secret if changed

Day-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-stg

SPA-only update

bash
cd web && npm run build && cd ..
./infra/deploy.sh synkrato-stg --deploy-web-only

Deploy specific image tag

bash
./infra/deploy.sh synkrato-stg --image-tag git-abc1234

Preview changes

bash
./infra/deploy.sh synkrato-stg --what-if