Skip to content

GitHub Actions Integration

Reoclo provides three GitHub Actions for integrating your CI/CD workflows with your servers:

  • reoclo/run - Execute commands on your servers
  • reoclo/checkout - Clone or update repositories on your servers
  • reoclo/docker-auth - Log in to a private container registry on your server using a vaulted Reoclo credential

Your GitHub Actions workflow orchestrates the steps, Reoclo dispatches commands to your servers, and every operation is fully audited.

  1. GitHub Actions runs your workflow on a GitHub-hosted runner
  2. The reoclo/run action sends commands to the Reoclo API
  3. Reoclo dispatches the command to the runner agent on your server via WebSocket
  4. The runner executes the command and returns the result
  5. Every operation is logged in Reoclo’s audit trail

This means you don’t need to run self-hosted GitHub runners on your servers. Your servers only need the Reoclo runner agent installed.

In the Reoclo dashboard:

  1. Navigate to the API Keys page, then select the Automation Keys tab
  2. Click Create Key
  3. Give it a descriptive name (e.g., github-prod-deploy)
  4. Configure the scope:
    • Servers: select which servers this key can target, or leave empty for all servers
    • Operations: select which operations are allowed (exec, deploy, restart, reboot)
  5. Optionally configure:
    • IP allowlist: restrict to GitHub-hosted runner IP ranges for extra security
    • Rate limit: requests per minute (default: 100)
    • Expiration: set an expiry date
  6. Click Create
  7. Copy the key immediately. It’s shown only once.

In your GitHub repository:

  1. Go to Settings > Secrets and variables > Actions
  2. Add two secrets:
    • REOCLO_API_KEY: the automation API key you just created
    • REOCLO_SERVER_ID: the ID of the target server (found in Servers page in the dashboard)
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to production
uses: reoclo/run@v1
with:
api_key: ${{ secrets.REOCLO_API_KEY }}
server_id: ${{ secrets.REOCLO_SERVER_ID }}
command: |
cd /opt/app && docker compose pull && docker compose up -d
timeout: 300

Execute shell commands on your servers.

InputRequiredDefaultDescription
api_keyYes-Reoclo automation API key
server_idYes-Target server ID
commandYes-Shell command to execute on the server
working_directoryNo-Working directory on the server
envNo-Environment variables (KEY=VALUE, one per line)
timeoutNo60Timeout in seconds (max 900)
OutputDescription
exit_codeCommand exit code
stdoutCommand stdout (truncated to 64KB)
stderrCommand stderr (truncated to 64KB)
operation_idReoclo operation ID for audit trail
duration_msExecution duration in milliseconds

Log in to a container registry on your server using a registry credential stored in your Reoclo tenant. The login runs on the target server, not on the GitHub runner, so subsequent reoclo/run steps can pull or push from the registry without any extra setup. When the job ends, an automatic cleanup step runs docker logout on the server.

Unlike docker/login-action@v3, this action sources the password from your Reoclo tenant instead of GitHub Secrets. You get one place to rotate credentials, per-key scoping, and a full audit trail.

InputRequiredDefaultDescription
api_keyYes-Reoclo automation API key
server_idYes-Target server ID (must be runner-connected)
credential_idYes-Reoclo registry credential UUID (from the Registry Credentials page)
cleanupNotrueRun docker logout on the server at job end
OutputDescription
operation_idReoclo operation ID for the login (cross-reference with the audit log)
registry_urlResolved registry URL (for example, ghcr.io, docker.io, or your ECR host)
registry_typeRegistry provider (docker_hub, ghcr, aws_ecr, google_artifact_registry, azure_acr, harbor, generic)
  1. Create a Registry Credential in the dashboard. Pick a provider, enter the username and password or token, then save.
  2. Create an Automation API Key (or edit an existing one). Add registry_login (and registry_logout for the cleanup step) to Allowed Operations, and include the credential’s UUID in Allowed Credentials.
  3. On the Registry Credentials page, click Use in CI on the credential row. The drawer generates a pre-filled workflow snippet you can copy straight into your repository.
name: Build and push
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Log in to GHCR on the server
uses: reoclo/docker-auth@v1
with:
api_key: ${{ secrets.REOCLO_API_KEY }}
server_id: ${{ secrets.REOCLO_SERVER_ID }}
credential_id: ${{ secrets.REOCLO_GHCR_CREDENTIAL_ID }}
- name: Checkout code on server
uses: reoclo/checkout@v1
with:
api_key: ${{ secrets.REOCLO_API_KEY }}
server_id: ${{ secrets.REOCLO_SERVER_ID }}
token: ${{ github.token }}
- name: Build and push
uses: reoclo/run@v1
with:
api_key: ${{ secrets.REOCLO_API_KEY }}
server_id: ${{ secrets.REOCLO_SERVER_ID }}
working_directory: /opt/deploy/workspace
command: |
docker build -t ghcr.io/myorg/myapp:${{ github.sha }} .
docker push ghcr.io/myorg/myapp:${{ github.sha }}
timeout: 600

Use one step per credential. Each step creates its own login and logout in the audit log, so partial failures stay scoped to a single credential.

- uses: reoclo/docker-auth@v1
with:
api_key: ${{ secrets.REOCLO_API_KEY }}
server_id: ${{ secrets.REOCLO_SERVER_ID }}
credential_id: ${{ secrets.REOCLO_GHCR_CREDENTIAL_ID }}
- uses: reoclo/docker-auth@v1
with:
api_key: ${{ secrets.REOCLO_API_KEY }}
server_id: ${{ secrets.REOCLO_SERVER_ID }}
credential_id: ${{ secrets.REOCLO_ECR_CREDENTIAL_ID }}
  • The registry password is never returned to the GitHub Actions runner. Only the resolved registry URL, the registry provider type, and a Reoclo operation ID are set as outputs.
  • Every login and logout is recorded in your Reoclo audit log with the originating repository, workflow, actor, and commit.
  • Automation API keys must explicitly allow each credential they are permitted to use. Keys cannot reference credentials outside your tenant.
  • When cleanup is enabled (the default), docker logout runs automatically on the server at job end so the credential does not stay resident on the server filesystem.

Clone or update a repository on your server. Works like actions/checkout, but the code ends up on your remote server instead of the GitHub runner.

InputRequiredDefaultDescription
api_keyYes-Reoclo automation API key
server_idYes-Target server ID
repositoryNoCurrent repoRepository to checkout (owner/repo)
refNoCurrent SHABranch, tag, or SHA to checkout
pathNo/opt/deploy/workspaceDirectory on the server to checkout into
tokenNogithub.tokenToken for repository access
cleanNotrueRemove target directory before cloning
depthNo1Clone depth (0 for full clone)
submodulesNofalseCheckout submodules (true, false, or recursive)
OutputDescription
commit_shaThe checked-out commit SHA on the server
refThe ref that was checked out
pathThe path on the server where the repo was checked out

Use Bitwarden, 1Password, or any secrets manager in GitHub Actions. Secrets are fetched in the workflow and passed to Reoclo as environment variables. They never touch Reoclo’s database.

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Fetch secrets from Bitwarden
uses: bitwarden/sm-action@v2
with:
access_token: ${{ secrets.BW_ACCESS_TOKEN }}
secrets: |
abc123 > DB_URL
- name: Deploy with secrets
uses: reoclo/run@v1
with:
api_key: ${{ secrets.REOCLO_API_KEY }}
server_id: ${{ secrets.REOCLO_SERVER_ID }}
command: docker compose up -d
working_directory: /opt/app
env: |
DB_URL=${{ env.DB_URL }}
timeout: 300

Use reoclo/checkout to clone your code onto the server, then reoclo/run to build and deploy:

steps:
- name: Checkout code on server
uses: reoclo/checkout@v1
with:
api_key: ${{ secrets.REOCLO_API_KEY }}
server_id: ${{ secrets.REOCLO_SERVER_ID }}
token: ${{ github.token }}
- name: Build and deploy
uses: reoclo/run@v1
with:
api_key: ${{ secrets.REOCLO_API_KEY }}
server_id: ${{ secrets.REOCLO_SERVER_ID }}
working_directory: /opt/deploy/workspace
command: |
docker build -t myapp:latest .
docker compose up -d
timeout: 600
- name: Checkout staging branch
uses: reoclo/checkout@v1
with:
api_key: ${{ secrets.REOCLO_API_KEY }}
server_id: ${{ secrets.REOCLO_SERVER_ID }}
ref: develop
path: /opt/staging/workspace
token: ${{ github.token }}

Use a Personal Access Token with cross-repo access:

- name: Checkout shared config
uses: reoclo/checkout@v1
with:
api_key: ${{ secrets.REOCLO_API_KEY }}
server_id: ${{ secrets.REOCLO_SERVER_ID }}
repository: myorg/shared-config
path: /opt/config
token: ${{ secrets.CROSS_REPO_TOKEN }}
on:
workflow_dispatch:
inputs:
service:
description: Service to deploy
type: choice
options: [api, web, worker]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy service
uses: reoclo/run@v1
with:
api_key: ${{ secrets.REOCLO_API_KEY }}
server_id: ${{ secrets.REOCLO_SERVER_ID }}
command: |
cd /opt/app
docker compose pull ${{ inputs.service }}
docker compose up -d ${{ inputs.service }}
timeout: 300

Combine reoclo/checkout and multiple reoclo/run steps for multi-stage deployments:

steps:
- name: Checkout latest code
uses: reoclo/checkout@v1
with:
api_key: ${{ secrets.REOCLO_API_KEY }}
server_id: ${{ secrets.REOCLO_SERVER_ID }}
path: /opt/app
token: ${{ github.token }}
- name: Run migrations
uses: reoclo/run@v1
with:
api_key: ${{ secrets.REOCLO_API_KEY }}
server_id: ${{ secrets.REOCLO_SERVER_ID }}
working_directory: /opt/app
command: docker compose exec -T api python manage.py migrate
timeout: 120
- name: Build and restart services
uses: reoclo/run@v1
with:
api_key: ${{ secrets.REOCLO_API_KEY }}
server_id: ${{ secrets.REOCLO_SERVER_ID }}
working_directory: /opt/app
command: |
docker compose build
docker compose up -d
timeout: 600

For faster deploys, skip the full clone and fetch updates instead:

- name: Update code on server
uses: reoclo/checkout@v1
with:
api_key: ${{ secrets.REOCLO_API_KEY }}
server_id: ${{ secrets.REOCLO_SERVER_ID }}
clean: false
token: ${{ github.token }}

If the repository already exists at the target path, the action runs git fetch and checks out the ref instead of re-cloning. This is faster for large repositories.

- name: Checkout with submodules
uses: reoclo/checkout@v1
with:
api_key: ${{ secrets.REOCLO_API_KEY }}
server_id: ${{ secrets.REOCLO_SERVER_ID }}
depth: 0
submodules: recursive
token: ${{ github.token }}

Every command executed via the GitHub Action is logged in Reoclo’s audit trail. Each operation records:

  • The command that was executed
  • Which server it ran on
  • The exit code, stdout, and stderr
  • Which API key was used
  • The GitHub Actions run context (repository, workflow, actor, commit SHA)

View automation operations in the dashboard by clicking the operation count on any key row to view history in Logs.

Operations from the same GitHub Actions run are grouped by run_id, so you can see all commands from a single workflow execution together.

Always scope your automation API keys to the minimum required permissions:

  • Restrict to specific servers rather than all servers
  • Limit operations to what the workflow needs (e.g., exec only)
  • Set an IP allowlist to GitHub’s runner IP ranges
  • Use separate keys for different environments (staging vs production)

Environment variables passed via the env input are:

  • Sent to the server for command execution
  • Never stored in Reoclo’s database. Only the key names appear in audit logs.
  • Transmitted over HTTPS to the Reoclo API, then over the encrypted WebSocket to the runner

Each API key has a configurable rate limit (default: 100 requests/minute). If exceeded, the action will receive a 429 Too Many Requests response.