From arcane
Use this skill when the user asks about Arcane GitOps, deploying docker-compose stacks from a git repo, GitOps for self-hosted services, managing docker-compose stacks declaratively, or setting up automated deployments with Arcane and GitHub Actions. Also recall when the user asks about deploying cloudflared, Nextcloud, n8n, or any docker-compose stack via GitOps. For Cloudflare Tunnel setup details, also recall the cloudflare plugin's cloudflare-tunnels skill. For LXC host setup, recall the proxmox plugin's proxmox-lxc skill.
npx claudepluginhub nsheaps/ai-mktpl --plugin arcaneThis skill uses the workspace's default tool permissions.
Arcane is a GitOps tool that syncs docker-compose stacks from a git repository to remote hosts. Push to `main`, and Arcane deploys. It provides a Portainer-like experience driven entirely by code in your repo.
Provides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
Builds 3-5 year financial models for startups with cohort revenue projections, cost structures, cash flow, headcount plans, burn rate, runway, and scenario analysis.
Arcane is a GitOps tool that syncs docker-compose stacks from a git repository to remote hosts. Push to main, and Arcane deploys. It provides a Portainer-like experience driven entirely by code in your repo.
Git Push → GitHub Actions → Arcane API → Host Agent → docker compose up
hosts/<hostname>/<stack>/docker compose up -d to apply changesiac/
├── hosts/
│ ├── README.md
│ ├── _example/ # Template for new stacks
│ └── <hostname>/ # One directory per host
│ ├── cloudflared/
│ │ └── docker-compose.yaml
│ ├── postgresql/
│ │ └── docker-compose.yaml
│ ├── redis/
│ │ └── docker-compose.yaml
│ ├── nextcloud/
│ │ └── docker-compose.yaml
│ └── n8n/
│ └── docker-compose.yaml
├── arcane/
│ └── hosts/
│ └── <hostname>/
│ └── arcane.json # Host-level Arcane config
├── apps/ # Reusable compose modules (optional)
│ └── README.md
└── .github/
└── workflows/
└── arcane-deploy.yaml # GitOps deployment workflow
hosts/<hostname>/ — match the actual hostnamehosts/<hostname>/<stack-name>/ — descriptive service name-compose.yaml or -compose.ymlarcane/hosts/<hostname>/arcane.jsonarcane.json){
"environment_id": "0"
}
The environment_id ties the host to an Arcane deployment environment.
Every stack that needs secrets follows the init-secrets pattern: a sidecar container fetches secrets from 1Password before the main service starts.
name: my-app
services:
init-secrets:
image: 1password/op:2
user: "0:0"
environment:
- OP_SERVICE_ACCOUNT_TOKEN=${OP_SERVICE_ACCOUNT_TOKEN}
volumes:
- app-secrets:/run/secrets:rw
command:
- /bin/bash
- -c
- |
op read "op://Infrastructure/my-app/db-password" > /run/secrets/db_password &
op read "op://Infrastructure/my-app/api-key" > /run/secrets/api_key &
wait
chmod 444 /run/secrets/*
my-app:
image: my-app:latest
restart: always
volumes:
- app-secrets:/run/secrets:ro
depends_on:
init-secrets:
condition: service_completed_successfully
networks:
- cloudflared
volumes:
app-secrets:
driver: local
networks:
cloudflared:
external: true
Key points:
OP_SERVICE_ACCOUNT_TOKEN is injected by Arcane as a global variable& + wait) for speed:rw for init, :ro for appchmod 444 makes secrets read-only after creationdepends_on with service_completed_successfully ensures secrets exist before app startsop://<vault>/<item>/<field>
# Examples:
op://Infrastructure/my-server--my-app/password
op://Infrastructure/my-server--postgres--root-user/username
op://Infrastructure/my-server--postgres--root-user/password
Convention: <host>--<service>--<component>/<field>
Stacks share named networks for inter-service communication:
# In the cloudflared stack (creates the network):
networks:
cloudflared:
driver: bridge
name: cloudflared
# In any stack that needs tunnel access (joins the network):
networks:
cloudflared:
external: true
Common shared networks:
cloudflared — services exposed via Cloudflare Tunnelpostgresql — services needing database accessredis — services needing cache/queue accessStacks that need a database include an init container:
services:
init-database:
image: postgres:17
depends_on:
init-secrets:
condition: service_completed_successfully
volumes:
- app-secrets:/run/secrets:ro
networks:
- postgresql
entrypoint: ["/bin/bash", "-c"]
command:
- |
export PGPASSWORD=$$(cat /run/secrets/root_password)
# Create user and database if they don't exist
psql -h postgresql -U postgres -tc "SELECT 1 FROM pg_roles WHERE rolname='myapp'" | grep -q 1 || \
psql -h postgresql -U postgres -c "CREATE USER myapp WITH PASSWORD '$$(cat /run/secrets/db_password)';"
psql -h postgresql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname='myapp'" | grep -q 1 || \
psql -h postgresql -U postgres -c "CREATE DATABASE myapp OWNER myapp;"
The apps/ directory holds shared compose configurations included via the include directive:
# In a host-specific compose file:
include:
- ../../../apps/monitoring/docker-compose.yaml
Constraint: Included apps must have identical configuration across all hosts. No parameterization — if values differ, copy the compose file instead.
Pin images by digest for reproducibility:
services:
cloudflared:
image: cloudflare/cloudflared:2026.3.0@sha256:6b599ca3e974...
Use Renovate to auto-update pinned digests.
The arcane-deploy.yaml workflow has four stages:
arcane/hosts/ for changed projects using floating git tagsOP_SERVICE_ACCOUNT_TOKEN in Arcanedeployed/arcane/heapsnas/cloudflared)Uses floating git tags to track last deployment:
Tag: deployed/arcane/<host>/<project>
On each deploy, the tag moves to the current commit. Next run compares HEAD against the tag to detect changes. Force deploy (via workflow input) ignores tags and redeploys everything.
Create the directory:
mkdir -p hosts/<hostname>/<stack-name>
Add docker-compose.yaml following the patterns above
If secrets are needed, add them to 1Password under Infrastructure/<hostname>--<stack-name>
If the service needs external access, join the cloudflared network and configure the tunnel hostname in Cloudflare dashboard (or via Pulumi)
Commit and push to main:
git add hosts/<hostname>/<stack-name>/
git commit -m "feat(<hostname>): add <stack-name> stack"
git push
The GitHub Actions workflow deploys automatically
arcane-deploy workflow runsdocker compose -f /path/to/stack/docker-compose.yaml ps