stefanpejcic/openpanel/deploy-openpanel

Claude Code and agent skill by stefanpejcic/openpanel

Trust tier 3
  • community
  • ext:[{"type":"hook","description":"Pre/post lifecycle hooks"}]
Source check pending

Checking that the SKILL.md file is still in the repository.

Build the OpenPanel Go binary and deploy it into the test server's 'openpanel' podman container, then smoke-test it live.

Install

npx vskill@latest install stefanpejcic/openpanel/deploy-openpanel

Semi-extensibleMentions customization, but needs skill-specific knowledge. Read the extensible skills standard

SKILL.md

Deploy OpenPanel to the test server

Deploys the current working tree of this repo (cmd/openpanel) to a test server by replacing the binary inside the running openpanel podman container, then verifies it actually works by logging into the live app.

Never write the server address, SSH password, or app login credentials into any file in this repo. Ask for them in the conversation each time this skill runs, use them only inline in the Bash commands that need them, and don't echo them back or persist them anywhere.

Step 0 — Get connection details for this run

Ask the user (if not already given earlier in this conversation) for:

  1. The server's IP address or hostname (call it $SERVER below).
  2. The root SSH password for that server.
  3. OpenPanel user login credentials to use for the post-deploy smoke

test (a username/password that can log into https://$SERVER:2083 — confirm the port too, in case it's not 2083 on this server; this is the end-user panel, a different app/port than OpenAdmin's 2087).

Step 1 — Build and test locally first

From the repo root:

bash
go build ./... && go test ./internal/modules/<relevant-module>/... -v 2>&1 | tail -60

Fix or flag any failures before deploying.

Then cross-compile for the server. This container is Alpine (musl libc), not glibc — a normal go build produces a dynamically-linked glibc binary that crashes on exec with missing dynamic library. Always build static with CGO_ENABLED=0:

bash
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /tmp/claude-*/scratchpad/openpanel-amd64 ./cmd/openpanel
file /tmp/claude-*/scratchpad/openpanel-amd64 # should say "statically linked", not "dynamically linked"

(Use this session's actual scratchpad path, not a literal glob.)

Step 2 — Copy the binary to the server

bash
export SSHPASS='<password from step 0>'
sshpass -e scp -o StrictHostKeyChecking=accept-new \
<scratchpad>/openpanel-amd64 \
root@<server>:/root/openpanel-amd64.new

Step 3 — Swap the binary into the running container and restart it

The binary lives at /openpanel inside the container (per its Dockerfile's CMD ["/openpanel"]), not on the host filesystem — use podman cp / podman exec, not scp directly into a host path.

bash
export SSHPASS='<password>'
sshpass -e ssh root@<server> '
set -e
podman exec openpanel cp /openpanel /openpanel.bak-$(date +%Y%m%d%H%M%S)
podman cp /root/openpanel-amd64.new openpanel:/openpanel
podman exec openpanel chmod +x /openpanel
podman restart openpanel
sleep 4
podman ps -a --filter "name=openpanel" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
podman logs --tail 15 openpanel 2>&1
'

Confirm the openpanel row shows Up ... (not Exited), and the log tail ends with a clean startup (BOOTSTRAP - listening on :2083 (tls=true) and no missing dynamic library or panic output). If it's Exited, podman logs openpanel will show why — the previous binary is at /openpanel.bak-<timestamp> inside the container and can be copied back over /openpanel followed by another podman restart openpanel to roll back.

Step 4 — Smoke-test it live (log in and check it actually works)

Prefer an actual browser check if a browser-automation tool/skill (e.g. claude-in-chrome) is available in this environment: load that skill first, open https://<server>:2083/login (or whatever port was confirmed in Step 0), log in with the user credentials from Step 0, navigate to whatever page is relevant to the change you just deployed, and take a screenshot to visually confirm it renders correctly and the feature works.

If no browser tool is available, fall back to this curl-based login flow (same gorilla/csrf setup as OpenAdmin — login form fields are username and password, field name csrf_token, and the app requires a matching Referer header on HTTPS POSTs):

bash
cd <scratchpad>
BASE="https://<server>:<port from step 0>"
login_page=$(curl -sk -c cookies.txt -e "$BASE/login" "$BASE/login")
csrf=$(echo "$login_page" | grep -oP 'name="csrf_token" value="\K[^"]+' | head -1 \
| python3 -c "import sys,html; print(html.unescape(sys.stdin.read().strip()))")
curl -sk -b cookies.txt -c cookies.txt -e "$BASE/login" -o login_resp.html \
-w "login POST status: %{http_code}\n" \
-X POST "$BASE/login" \
--data-urlencode "username=<username>" \
--data-urlencode "password=<password>" \
--data-urlencode "csrf_token=$csrf"
# Success redirects to /dashboard (302/303).
# Fetch a page relevant to what changed and check it looks right, e.g.
# for cron-related changes:
curl -sk -b cookies.txt "$BASE/cronjobs" | grep -o "No overlap"
curl -sk -b cookies.txt "$BASE/cronjobs/new" | grep -o "no_overlap"

Pick the page/grep target based on whatever was actually changed this session.

Step 5 — Report back

Summarize concisely: build/test result, deploy result (container up or not, clean logs or not), and the smoke-test result (what you actually saw on the live page). If anything failed, say exactly what and at which step — don't declare success unless the live page genuinely showed the expected content.

Security

  • Security scanPassed, 90 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
760
Repository forks
109
7-day trend score
0

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Extension points

  • hookPre/post lifecycle hooks

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/stefanpejcic/openpanel/deploy-openpanel/badge)](https://verified-skill.com/skills/stefanpejcic/openpanel/deploy-openpanel)

Something wrong with this skill or its page? Tell us.