一键导入
system-administration
Guide for server management, system APIs, backups, and maintenance operations.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Guide for server management, system APIs, backups, and maintenance operations.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Guide for developing features in the Vite + React Router frontend.
Guide to Docklift's automated release pipeline using semantic-release.
Guide for setting up, running, and developing the Docklift project.
Guide for setting up and managing Docklift's GitHub App integration.
Coolify/Dokploy-style managed databases with Dokku-style app linking.
Security patterns, guards, and best practices enforced across the Docklift codebase.
| name | System Administration |
| description | Guide for server management, system APIs, backups, and maintenance operations. |
Docklift includes built-in system management features accessible through the UI and API.
/system)The system page shows real-time server health metrics:
/proc/meminfo for accuracy)nsenter to read host processes)| API | Purpose |
|---|---|
GET /api/system/stats | Full system metrics (3s cache) |
GET /api/system/quick | CPU + memory only (for header widget) |
GET /api/system/ip | Server's public IP (5-min cache) |
API: POST /api/system/purge
DockLift-scoped only. Requires password step-up (requireStepUpPassword / body password).
What it does today:
What it must never do from the panel:
docker image prune / docker system prune (shared-host: may delete foreign dangling layers)drop_caches, journal vacuum, apt clean, /tmp wipeUI copy must stay honest (not “isolated host wipe”). Post-deploy cleanup is also a no-op for images.
Load averages on /api/system/stats come from real os.loadavg() — never fabricated load5/load15.
| API | Purpose | Notes |
|---|---|---|
POST /api/system/reboot | Reboot the host server | Uses reboot -f, simulated on Windows/Mac |
POST /api/system/reset | Restart all Docklift containers | docker restart on CORE_CONTAINERS (all 5) |
POST /api/system/update-system | Run apt update && upgrade on host | Via nsenter, 15-min timeout |
POST /api/system/upgrade | Run Docklift upgrade script | Executes /opt/docklift/upgrade.sh on host |
Route: /terminal
WebSocket: ws://host:8000/ws/terminal (proxied via Nginx /ws/)
A full-featured xterm.js-based interactive terminal providing direct root access to the host.
ws server + child_process.spawn('script', ...)script command for TTY emulation (zero native dependencies)docklift-backend (Alpine) but has host access via Docker privileged mode & PID host./root with full host privileges.TerminalView): quiet text actions above the shell — update packages, upgrade Docklift, purge dangling images, reset stack, reboot. No rainbow action cards; shell chrome follows light/dark theme./terminal?confirm=upgrade (does not POST from the rail). Legacy ?action=upgrade opens the same confirm, not a fake in-progress state.The backend handles SIGTERM/SIGINT signals for clean exit:
cleanupAllSessions().index.ts.API: GET /api/system/logs/:service (SSE stream)
Mapping lives in LOG_SERVICE_CONTAINERS (backend/src/routes/system.ts):
| Service | Container | UI label |
|---|---|---|
backend | docklift-backend | Backend |
frontend | docklift-frontend | Frontend |
nginx | docklift-nginx | Dashboard Gateway (:8080) |
proxy | docklift-nginx-proxy | Public Proxy (:80/:443) |
certbot | docklift-certbot | Certbot |
API: GET /api/system/version
package.json version against GitHub releases/latest{ current, latest, updateAvailable, githubOk, checkedAt }?refresh=1 revalidates
only if the cache is older than 30s (not an unconditional bypass).refresh=1All backup/restore routes are in backend/src/routes/backup.ts, mounted at /api/backup.
BACKUP_PATH defaults to <DATA_PATH>/backups (not a hardcoded /data/backups).BACKUP_PATH=/data/backups with a ./backups mount.DEPLOYMENTS_PATH, NGINX_CONF_PATH, DOCKER_NETWORK, DATA_PATH (not DOCKLIFT_* for those).| API | Purpose |
|---|---|
POST /api/backup/create | Create a full backup (DB, deployments, Nginx configs, GitHub key) |
GET /api/backup/list | List available backups |
GET /api/backup/download/:filename | Download a backup file |
DELETE /api/backup/:filename | Delete a backup |
SQLite integrity: create uses VACUUM INTO a temp snapshot, then archives that file — never a live
raw copy of docklift.db. Missing DB aborts with [ERROR] (UI must not toast success).
Frontend streams use frontend/src/lib/streamProgress.ts: require res.ok and fail on [ERROR] lines.
| API | Purpose |
|---|---|
POST /api/backup/restore/:filename | Restore from a server-side backup |
POST /api/backup/restore-upload | Upload and immediately restore |
POST /api/backup/restore-from-upload/:filename | Restore from a previously uploaded file |
Safety:
tryAcquireRestoreLock() before Multer (lib/restoreLock.ts) — concurrent restore → 409.
Upload filenames are server-chosen (restore-<ts>-<random>.zip), never trusted client names.
Password step-up for authenticated restores; setup-token path for fresh install (no users yet)
via setupTokenAuth.
All three restore routes track dbReplaced and call rollbackDatabaseFromPreRestore on later failure.
Commit gate (finishRestoreCommit / decideRestoreCommit): consume setup secrets only when
reconcile succeeds and restored DB has role: 'admin'. Setup-token + incomplete reconcile →
abort + roll DB back. If rollback itself fails → critical seal:
data/.restore-critical, hold restore lock, keep maintenanceloadRestoreCriticalOnBoot)/api/backup/restore* until POST /api/backup/clear-critical-restore (password step-up)enterMaintenance() blocks all API traffic except /api/health and the active restore stream
(not just mutating methods).
Files/certs/proxy directory swaps are still not fully transactional with the DB.
Directory restores use lib/fsCopy.ts (fs.promises.cp + content-level replace inside
the target) — never shell cp, and never rename bind-mount roots (/deployments,
/nginx-conf, /etc/letsencrypt). Staging/prev live under the mount as
.docklift-restore-staging-* / .docklift-restore-prev-*. Failed promote or partial
move-aside restores from prev; orphaned prev dirs are folded in on the next successful replace.
Restore does not wipe other backup ZIPs.
After restoring files, the system automatically:
reconnectPrisma() then read projectsPersistentVolume row is re-created as an external
labelled Docker volume before the project starts, so mounts resolvedocker compose -f <runtime-compose> -p <composeProject> up -d,
where the compose file is deployments/.docklift/<projectId>/compose.yml and the project name comes
from composeProjectName(). Older backups without generated runtime state fall back to a
docker-compose.yml at the source root; if neither exists the project is skipped and must be
deployed manuallydocker exec docklift-nginx-proxy nginx -s reloadprocess.exit(0) triggers Docker's restart: unless-stopped policyAny per-project or nginx failure emits [ERROR]; the stream ends with RESTORE INCOMPLETE so the
UI does not toast success. Backend still restarts so the restored DB is loaded.
The
-pname must match deploy-time naming, or restore creates a second set of containers and images alongside the originals.
| Item | Path | Description |
|---|---|---|
| Database | /app/data/docklift.db | SQLite database |
| Deployments | /deployments/ | Project source + generated runtime compose |
| Nginx configs | /nginx-conf/ | Generated proxy configurations |
| Certificates | /etc/letsencrypt/ | Let's Encrypt certs (backend mounts this RW for restore) |
| GitHub key | github-app.pem | GitHub App private key |
Named volume contents are not archived — the volumes are re-created empty if missing. Snapshot application data separately if it matters.
| Script | Purpose |
|---|---|
install.sh | Production install into /opt/docklift (default latest release). Pin with bash -s -- v=2.0.2 or DOCKLIFT_VERSION=2.0.2. Resolves/validates the tag before compose down; fails closed if latest API/tag missing (no master fallback). |
install-dev.sh | Same, but from master (unreleased code) |
upgrade.sh | Stop backend → SQLite snapshot (.backup / copy) → tag *:pre-upgrade images → rebuild; rollback uses tagged images + DB restore with backend stopped; health-checks /api/health |
install.sh | Prints Dashboard: http://SERVER_IP:8080 + Setup code from .bootstrap-secret |
uninstall.sh | Remove DockLift containers, images, volumes, network, build cache and /opt/docklift |
uninstall.sh targets DockLift-owned resources only (core names, dl_* / dl-*,
dl-net-*, com.docklift.* labels). Never host-wide docker system prune / builder prune, and
never remove Docker Engine/git.
The backend container needs these host-level permissions (defined in docker-compose.yml):
privileged: true — required for nsenter into host PID 1 (system update / reboot)pid: host — For host process visibility (reboot, system info)/var/run/docker.sock/etc/hostname, /etc/os-release, /proc (read-only)./nginx-proxy/certbot/conf:/etc/letsencrypt — read-write, so restores can put certificates back
(the proxy mounts the same path read-only)Panel purge must not use privileged host maintenance (drop_caches, journal, apt, swap, /tmp).