Recipe: Set up External Deployment from scratch
When to use this
Section titled “When to use this”Use this recipe when:
- The repository has no
reoclo/run,reoclo/checkout, orreoclo/deploy-syncsteps in any workflow. - The user wants to add Reoclo route sync to a workflow that deploys via
docker compose upordocker run. - The user already has a Reoclo account (tenant exists).
If the repo already has Reoclo workflow steps, use Enhance an existing GitHub workflow instead.
Detection
Section titled “Detection”Step 1 — Confirm no existing Reoclo integration:
grep -rl "reoclo/" .github/workflows/ 2>/dev/null || echo "no reoclo steps found"If any file contains a reoclo/ action reference, switch to the enhance recipe.
Step 2 — Confirm a Docker deploy step exists:
grep -rl "docker" .github/workflows/ 2>/dev/nullIf no Docker commands are found in any workflow, ask the user to confirm how containers are deployed before proceeding.
Step 3 — Confirm Reoclo account exists:
The agent cannot verify account existence programmatically without a key. Ask the user:
“Do you have a Reoclo account at app.reoclo.com and at least one Application configured with a Linked Container Name?”
If the user says no, stop. External Deployments require an existing Reoclo tenant and Application.
The change
Section titled “The change”Step A — User must do: generate an API key
Section titled “Step A — User must do: generate an API key”The agent cannot create API keys on the user’s behalf. Instruct the user to complete this step manually in the dashboard.
Tell the user:
- Go to https://app.reoclo.com and navigate to API Keys > Automation Keys.
- Click Create Automation Key.
- Name it something like
github-deploy-sync-prod. - Under Allowed Operations, enable
external_deploy. - Optionally restrict to a specific server and set an IP allowlist.
- Click Create and copy the key — it starts with
rca_and is shown only once.
Wait for the user to confirm they have the key before proceeding to Step B.
Step B — Wire the GitHub secret
Section titled “Step B — Wire the GitHub secret”Tell the user:
- In the GitHub repository, go to Settings > Secrets and variables > Actions.
- Click New repository secret.
- Name:
REOCLO_API_KEY - Value: the
rca_key from Step A. - Click Add secret.
Step C — Add the sync step to the workflow
Section titled “Step C — Add the sync step to the workflow”Find the workflow file that contains the docker compose up or docker run command. Add reoclo/deploy-sync@v2 as the next step after the deploy command.
If the workflow uses Docker Compose:
- name: Sync Reoclo proxy routes uses: reoclo/deploy-sync@v2 with: api_key: ${{ secrets.REOCLO_API_KEY }} compose_file: ./docker-compose.prod.ymlReplace ./docker-compose.prod.yml with the actual path to the Compose file used in the deploy step.
If the workflow uses bare docker run:
- name: Sync Reoclo proxy routes uses: reoclo/deploy-sync@v2 with: api_key: ${{ secrets.REOCLO_API_KEY }} services: "container-name:3000"Replace container-name with the value passed to --name in the docker run command, and 3000 with the container port the app listens on.
Step D — Ensure the service is on the reoclo-proxy network
Section titled “Step D — Ensure the service is on the reoclo-proxy network”Check the Compose file (or docker run command) for network configuration. For Compose:
services: myapp-web: # ... existing config ... networks: - reoclo-proxy # add this
networks: reoclo-proxy: external: true # add this block if absentFor docker run, add --network reoclo-proxy to the run command.
If the service is not on the reoclo-proxy network, Caddy cannot route to it and the site will return 502 after sync.
Verification
Section titled “Verification”Check 1 — YAML is valid:
python3 -c "import yaml, sys; yaml.safe_load(open(sys.argv[1]))" .github/workflows/deploy.ymlecho "YAML OK"Check 2 — API key has correct scope:
There is no public key-introspection endpoint. Probe the session endpoint and read the HTTP status — 201 means the key has external_deploy, 403 means it does not:
curl -s -o /dev/null -w "%{http_code}\n" -X POST https://api.reoclo.com/external-deploy/session \ -H "Authorization: Bearer $REOCLO_API_KEY" \ -H "Content-Type: application/json" \ -d '{"container_names": ["YOUR_CONTAINER_NAME"]}'A 403 means external_deploy is missing from the key’s allowed operations — add it in the dashboard under API Keys > Automation Keys.
Check 3 — Container name resolves to an Application:
curl -s -X POST https://api.reoclo.com/external-deploy/session \ -H "Authorization: Bearer $REOCLO_API_KEY" \ -H "Content-Type: application/json" \ -d '{"container_names": ["YOUR_CONTAINER_NAME"]}' \ | jq '{applications: [.applications[].linked_container_name], unmatched}'Expected: applications contains your container name, unmatched is empty.
If unmatched contains the container name, the Application’s linked_container_name field does not match. Ask the user to correct it in the dashboard under the Application’s settings.
Clean up the test session:
SESSION_ID=$(curl -s -X POST https://api.reoclo.com/external-deploy/session \ -H "Authorization: Bearer $REOCLO_API_KEY" \ -H "Content-Type: application/json" \ -d '{"container_names": ["YOUR_CONTAINER_NAME"]}' \ | jq -r '.session_id')
curl -s -X DELETE "https://api.reoclo.com/external-deploy/session/$SESSION_ID" \ -H "Authorization: Bearer $REOCLO_API_KEY" \ -o /dev/null -w "%{http_code}"Expected: 204
Pitfalls
Section titled “Pitfalls”- Agent cannot create API keys or GitHub secrets. These are manual steps that require browser access. Always wait for user confirmation before proceeding to the workflow edit.
linked_container_namemust match exactly. The service name in the Compose file is the container name Docker assigns by default (prefixed with the project name in some configurations). If the Application was linked with a full container name likemyapp-web-1, the Compose service namewebwill not match. Ask the user to verify the exact value in the dashboard.- Do not add
server_idto the action inputs. It is not a valid input forreoclo/deploy-sync@v2. - Pin to
@v2for moving tags or to an exact tag (e.g.@v2.0.0) for reproducible builds. The action is published on the GitHub Marketplace.