Part 7: CI/CD
In this last part you’ll deploy both sites from GitHub Actions on every push to main, reaching each console through ui.com.
Create the GitHub environments
Section titled “Create the GitHub environments”CI has no Alchemy profiles, so it uses environment variables instead. In your repository’s Settings → Environments, create home and office, each with these secrets:
| Secret | Value |
|---|---|
UNIFI_CONSOLE_ID |
The console’s ID: run npx alchemy profile show with its profile |
UNIFI_API_KEY |
A Site Manager API key from unifi.ui.com |
LAB_WIFI_PASSPHRASE |
The lab’s Wi-Fi passphrase |
Add the workflow
Section titled “Add the workflow”Create .github/workflows/deploy.yml:
name: Deploy
on: push: branches: [main]
jobs: deploy: strategy: matrix: site: [home, office] runs-on: ubuntu-latest environment: ${{ matrix.site }} concurrency: deploy-${{ matrix.site }} steps: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: node-version: 24 - run: npm ci - run: npx alchemy deploy --stage ${{ matrix.site }} --yes env: UNIFI_CONSOLE_ID: ${{ secrets.UNIFI_CONSOLE_ID }} UNIFI_API_KEY: ${{ secrets.UNIFI_API_KEY }} LAB_WIFI_PASSPHRASE: ${{ secrets.LAB_WIFI_PASSPHRASE }}Each site deploys in its own job, with its own environment’s secrets. concurrency queues deploys of one site, since the state store locks each stage while it runs.
Commit and push to main. The workflow deploys both sites, and the job logs show each plan.
Clean up
Section titled “Clean up”When you’re done with the lab, destroy each site’s Stack:
npx alchemy destroy --stage homenpx alchemy destroy --stage office --profile officeThe lab network, Wi-Fi, zone, policies, list and DNS records are deleted. The default networks stay, because they’re retained.
Where next
Section titled “Where next”- Networks, Firewall and DNS cover each resource in more depth.
- State on the console explains the state store and its locks.
- home-network is a real two-site config, with a full firewall matrix.