| name | paperclip-coolify-deployer |
| description | Deploy and self-host Paperclip — the open-source AI agent orchestration dashboard — on Coolify v4. Use this skill immediately whenever the user mentions Paperclip, wants to install or run an AI company/org-chart management tool, deploy an agent orchestration platform, or get Paperclip working on their VPS/self-hosted server. Trigger for any combination of "Paperclip" + "Coolify" / "VPS" / "Docker" / "self-hosted" / "deploy" / "install". Also use when the user gets deployment errors like "Remote branch main not found" or "EACCES permission denied" while deploying Paperclip. This skill provides the complete step-by-step workflow: from Coolify project creation, through the critical `master` branch (not `main`) gotcha, environment variable setup, `/paperclip` persistent volume mount, permission fixes (chown 1000:1000), health check configuration, deployment, and post-deploy onboarding (CEO invite URL). |
Author: Anton Gulin · Tool: opencode-skill-creator · GitHub: @antongulin · Registry: skills.sh
Paperclip Coolify Deployer
Deploy Paperclip on a self-hosted Coolify v4 server.
Paperclip is an open-source platform for managing AI agents in an org chart, tracking tasks and budgets. This skill automates or guides every step of deploying it on Coolify — a self-hosted PaaS (Platform as a Service).
Prerequisites
- A running Coolify v4 server with a reachable Server in its sidebar (green dot)
- Docker / Buildx available on that server
- At least 2 GB RAM, 2 CPU cores, 10 GB disk
- OpenCode must have access to the Coolify MCP tools (
coolify_*)
Workflow Overview
The deployment has 8 phases. The agent should execute them sequentially, pausing for user confirmation only where indicated.
- Discover Coolify infrastructure
- Create/select a Project and Environment
- Add Paperclip Application
- Configure Environment Variables
- Configure Persistent Storage
- Preempt known issues (permissions, health check)
- Deploy
- Post-deployment onboarding
Important: This workflow is specifically for Paperclip on Coolify v4. Other PaaS (Railway, Heroku) are not covered.
Phase 1: Discover Coolify Infrastructure
First, figure out where everything goes.
-
Ask the user (or infer from context) for:
- Their Coolify server's public IP address (e.g.,
YOUR_SERVER_IP)
- Whether they use
sslip.io or a custom domain
- Whether they prefer creating a new project or using an existing one
-
If the IP is not given, try to find it:
- Use
coolify_list_servers to discover servers
- Use
coolify_server_domains or coolify_get_server to inspect them
-
Pick the FQDN for Paperclip:
- Default:
http://paperclip.<SERVER_IP>.sslip.io
- If the user has a custom domain, substitute accordingly
- Ensure the scheme (
http:// vs https://) matches what the user actually types in their browser
Phase 2: Create Project & Environment
In Coolify, every app lives in a Project inside an Environment (typically production).
If creating a new project:
- Call
coolify_projects with action: "create"
name: "AI Infrastructure" (or user preference)
- Optionally set
description
- The result contains
uuid — save this for later
If using an existing project:
- Call
coolify_projects with action: "list"
- Ask the user to pick one, or use context to infer which
- Save its
uuid
Then get the environment:
- Call
coolify_environments with action: "list" and the project UUID
- Look for the environment named
production
- Save its
uuid
Edge case: If production doesn't exist, either use another environment or create one. Ask the user.
Phase 3: Add the Paperclip Application
This is the crucial step with several known failure modes.
Step 3a: Create Application Resource
Call coolify_application with:
action: "create"
project_uuid: (from Phase 2)
environment_uuid: (from Phase 2)
name: "paperclip"
description: "Paperclip AI - Open-source orchestration for zero-human companies"
build_pack: "dockerfile"
git_repository: "https://github.com/paperclipai/paperclip"
git_branch: "master" — CRITICAL: Paperclip uses master, not main
ports_exposes: "3100"
server_uuid: (from Phase 1)
Common failure: Wrong branch
If git_branch is set to "main", deployment will fail with:
fatal: Remote branch main not found in upstream origin
If this error appears in logs later, immediately switch branch to "master" and redeploy.
Step 3b: Set FQDN
Call coolify_application with action: "update" and:
fqdn: The FQDN chosen in Phase 1 (e.g., "http://paperclip.YOUR_SERVER_IP.sslip.io")
Step 3c: Ensure non-static deployment
Make sure the app is not marked as a static site. If the Coolify UI shows a static-site toggle, ensure it is unchecked.
Phase 4: Configure Environment Variables
Paperclip requires several environment variables to start correctly.
Required variables
Call coolify_env_vars in batch or individually for these:
| Key | Value | Notes |
|---|
HOST | 0.0.0.0 | Accept connections from outside the container |
PAPERCLIP_HOME | /paperclip | Persistent data folder inside the container |
PAPERCLIP_PUBLIC_URL | http://paperclip.<IP>.sslip.io | Must match FQDN exactly, including http:// or https:// |
BETTER_AUTH_SECRET | <64-char-hex> | See below for how to generate |
PAPERCLIP_ALLOWED_HOSTNAMES | paperclip.<IP>.sslip.io | Without http:// prefix |
Generating BETTER_AUTH_SECRET
This must be a 64-character hex string. The agent should either:
- Ask the user to run
openssl rand -hex 32 on the server, or
- If there is a trusted way to execute commands on the server (e.g., Coolify terminal, local terminal with SSH access), run it and capture the output.
Why this matters: Paperclip uses this secret for authentication token encryption. A weak or missing secret prevents login.
Optional variable
| Key | Value | Notes |
|---|
PAPERCLIP_TELEMETRY_DISABLED | 1 | Disables usage telemetry if desired |
After setting all variables, call coolify_application_logs or ask the user to verify the Environment Variables tab in Coolify.
Phase 5: Configure Persistent Storage
Without persistent storage, all Paperclip data (companies, agents, tasks) is lost on container restart.
Using Coolify Storage tab
- Navigate to the app's Storage (or Volumes) tab
- Click "+ Add Volume"
- Set Mount Type to "Directory Mount"
- Configure:
- Source Directory: auto-filled host path (e.g.,
/data/coolify/applications/YOUR_APP_UUID)
- Destination Directory:
/paperclip
- Save
Why this host path matters: Coolify generates a unique UUID folder per application under /data/coolify/applications/ on the host. Accept the auto-filled path unless the user intentionally customized their Coolify data directory.
Phase 6: Preempt Known Issues
Two issues will almost certainly happen if not handled proactively.
Issue A: Permission Denied on Volume
Root cause: The host directory is owned by root, but Paperclip runs inside the container as user node (UID 1000). It tries to write to /paperclip and gets EACCES permission denied.
Proactive fix (recommended):
- Find the exact host directory for this app's volume from Coolify
- Execute (or provide to the user):
sudo chown -R 1000:1000 /data/coolify/applications/YOUR_APP_UUID
sudo chmod -R u+rwX /data/coolify/applications/YOUR_APP_UUID
Reactive fix: If the first deployment fails with the EACCES error, apply the chown commands above, redeploy, and it should work.
Issue B: Health Check Failures
Root cause: The container doesn't have curl, and Paperclip's startup takes longer than the default Coolify health-check interval.
Fix: Disable the health check.
- In Coolify, go to the app's Health Check tab
- Toggle "Health Check Enabled" to OFF
- Save
Alternatively, if the user wants to keep it on, increase:
- Retries:
10
- Start Period:
60
- Interval:
10
Recommendation: For first-time deployers, turn health check OFF to avoid the container being rolled back prematurely. Re-enable later once stable.
Phase 7: Deploy
- Call
coolify_deploy with the application tag or UUID
- Wait for deployment logs
Expected success pattern in logs
Building docker image completed.
Rolling update started.
New container started.
Attempt 3 of 10 | Healthcheck status: "healthy"
New container is healthy.
Removing old containers.
Rolling update completed.
If deployment fails
| Symptom | Cause | Fix |
|---|
Remote branch main not found | Wrong branch | Set branch to master, redeploy |
EACCES permission denied, mkdir '/paperclip/instances/default/logs' | Host volume owned by root | Run chown -R 1000:1000 /data/coolify/applications/UUID |
New container is unhealthy | Health check timing out | Turn health check OFF in Coolify, redeploy |
Build step skipped | Coolify cached stale image | Force rebuild from deployment settings |
Phase 8: Post-Deployment Onboarding
Paperclip is running, but it's not fully configured until you run two interactive commands inside the container.
Step 8a: Find the container
Use one of these approaches:
Option 1 (agent-friendly):
docker ps -q --filter "publish=3100"
Option 2 (human-friendly, on the server):
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
Look for the one with port 3100 exposed. Copy that full name or ID.
Step 8b: Onboard Paperclip
Run inside the container (replace CONTAINER_ID with actual ID or UUID):
docker exec -it --user node CONTAINER_ID pnpm paperclipai onboard
What happens:
- Corepack may ask to download
pnpm — confirm Y
- Select "Quickstart" via arrow keys
- When asked if you want to start Paperclip now, say NO (Coolify already started it)
- Look for the server info screen — this confirms configuration
- Copy the CEO invite URL immediately. Example:
Invite URL: http://paperclip.YOUR_SERVER_IP.sslip.io/invite/pcp_bootstrap_0db2f2d2bc5610d3acaa3f47c58334607cd84d9f90697532
- Exit the container (
exit or Ctrl+D)
Why "Quickstart"? It pre-configures an embedded PostgreSQL database and default company setup. Other options (like manual) are for advanced users.
Step 8c: Bootstrap CEO (if onboard didn't give an invite URL)
If onboarding did not output an invite link, run:
docker exec -it --user node CONTAINER_ID pnpm paperclipai auth bootstrap-ceo
Copy the resulting invite URL.
Step 8d: User opens invite URL
- Instruct the user to open the invite URL in their browser
- Fill in name, email, password
- They are now logged in as the CEO — top-level admin
Verification
Once complete, test with:
curl http://paperclip.<IP>.sslip.io
Expected: HTML from Paperclip's frontend.
Quick Reference: All Commands
Check containers
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
View Paperclip logs
docker logs $(docker ps -q --filter "publish=3100")
SSH into container as node user
docker exec -it --user node $(docker ps -q --filter "publish=3100") bash
Restart from Coolify CLI
coolify restart paperclip
Troubleshooting Summary
"Remote branch main not found"
- Cause: Branch set to
main
- Fix: Change to
master, redeploy
"EACCES permission denied, mkdir '/paperclip/instances/default/logs'"
- Cause: Host volume owned by root, Paperclip runs as UID 1000
- Fix:
chown -R 1000:1000 /data/coolify/applications/UUID && chmod -R u+rwX ...
"New container is unhealthy"
- Cause: Health check timing or missing curl
- Fix: Turn Health Check OFF, redeploy
Can't access URL in browser
- DNS delay: Wait 2-3 minutes for
sslip.io to propagate
- Firewall: Ensure ports 80/443 are open
- FQDN mismatch: Verify
PAPERCLIP_PUBLIC_URL exactly matches browser URL
- App crashed: Check deployment logs in Coolify
Invite URL doesn't work
- Cause:
PAPERCLIP_PUBLIC_URL or PAPERCLIP_ALLOWED_HOSTNAMES mismatched with actual browser URL
- Fix: Ensure both match exactly (including
http vs https)
Version & Compatibility
- Tested on: Coolify v4 (latest stable / 4.x beta as of 2026-04)
- Paperclip source:
https://github.com/paperclipai/paperclip (branch: master)
- Required ports: 3100 (container internal), 80/443 (host ingress)
- Required storage:
/paperclip inside container → host directory mount