Files
teamai-global/skills/deploy-docker-service/SKILL.md
T

4.5 KiB

name, description
name description
deploy-docker-service Stand up a self-hosted service (BBS/web app/tool) in this restricted-network cluster: research via web_fetch GitHub API, then docker pull the published image and run it.

Deploy a self-hosted service via Docker image

Triggered when you need to get a self-hosted service running (a BBS, web app, utility) that isn't already packaged, and you must obtain its software — but this cluster's direct outbound network to upstream sources is slow or blocked.

Why: direct source access is unreliable here

  • exec/curl/git clone direct to GitHub and to gitlab.synchro.net is slow or blocked from 襄阳2c4g. Observed: gitlab tarball ~23 KB/s (597 KB in 25 s), git clone --depth 1 stalled at ~1.5 MB after 2 minutes, node fetch to those hosts timed out.
  • GitHub acceleration mirrors are NOT reliable: gh-proxy.com returned a username/auth error and timed out; ghfast.top and ghproxy.net returned 404 for a repo path. A 404 there most likely means the repo path is wrong (mirror up, repo name wrong), not the mirror down.
  • web_fetch (gateway egress) DOES reach api.github.com, raw.githubusercontent.com, and gitlab.synchro.net fast (api.github.com ~1.7 s). Use it to research even when raw exec can't.

Steps

  1. Research the project over web_fetch, not exec. Find the repo via the GitHub search API: https://api.github.com/search/repositories?q=<topic>&per_page=5 — returns JSON; items[].full_name names the repo. Read the repo README (the image name is usually there): https://api.github.com/repos/<owner>/<repo>/readme — content is base64; decode it. Note the GitHub org name may differ from the Docker Hub namespace (observed: org bbs-io → Docker Hub image bbsio/synchronet).

  2. Prefer a published Docker image over compiling from source. If the README names a Docker Hub image, use it. Don't git-clone + build unless no image exists.

  3. Pull it. docker pull <image>:<tag> — direct pull of the public image succeeds from this host. If it returns not found, re-check the exact namespace/image name from the README — a wrong name gives not found, not a network error (so not found confirms the name is the problem, not the network).

  4. Inspect the real entrypoint/ports/volume before running. docker inspect <image> --format '{{.Config.Entrypoint}} {{.Config.Cmd}} {{.Config.ExposedPorts}} {{.Config.Volumes}}'. Use what it reports for the run command. Many images set Cmd to the service launcher, so a bare docker run starts it.

  5. Run the container. docker run -d --name <name> --restart unless-stopped -p <hostPort>:<imgPort> -v <hostdata>:/<imgvolume> <image>. Pick host ports above 1024 for plaintext protocols (e.g. container 23 → host 2323) so edge/ISP doesn't interfere; reserve 22/80/443 semantics for HTTPS/SSH.

  6. Verify in-container and locally. docker ps --filter name=<name> (Up + port map), then confirm the port answers. Prefer nc over bash /dev/tcp for the port check:

    • Port-open check (no I/O): nc -vz -w 3 <host> <port> → exit 0 = open.
    • Banner read: timeout 6 nc -w 3 <host> <port> prints the server's welcome banner. First-run logs often show harmless init errors (missing mail base, failed external sync/QNET) — not blockers for local use.

    ⚠️ bash -c exec 3<>/dev/tcp/... trips EDR reverse-shell detection. A command like bash -c 'exec 3<>/dev/tcp/<ip>/<port>; sleep 2; head -c 120 <&3' matches ATT&CK T1059.004 "reverse shell" and fires a spurious alert on any host with host-security/EDR (observed on aliyun). Reading a banner on your own localhost is harmless, but on a monitored host (or over SSH to one) use nc so you don't generate alert noise the operator has to answer.

  7. Expose it publicly (if needed) via the expose-service-subdomain skill.

Worked example (Synchronet BBS, 2026-09-09)

  • README image bbsio/synchronet:latest; docker inspect → Cmd=[/sbbs/scripts/sbbs], Volume /sbbs-data.
  • Run: docker run -d --name sbbs --restart unless-stopped -p 2323:23 -p 2222:2222 -v /root/docker/sbbs-data:/sbbs-data bbsio/synchronet:latest
  • Verified: telnet 127.0.0.1 2323 returned "Synchronet BBS for Linux Version 3.19" welcome screen.

Distinct from K3s image pulls

For pods (K3s/containerd), use crictl pull / Deployment imagePullPolicy: IfNotPresent and the CRI mirror config. This skill is for a plain host docker run service (like searxng / the BBS), where docker pull + docker run is the path.