agentsclimarketplace

Docker vps deploy

Skill itsgitz/agent-skills/docker-vps-deploy

Personal Claude Code skill collection. Compatible with any AI agent that supports ~/.agents skills (Claude Code, Cursor, OpenCode, and more).

Install
npx -y skills add itsgitz/agent-skills --skill docker-vps-deploy

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use when deploying a Dockerized application to a VPS (Linux server) via SSH without a container registry, generating a GitHub Actions pipeline that uses docker save, gzip compression, and rsync to transfer images. Triggers: "deploy to VPS", "rsync docker image", "docker save and load", "VPS CI/CD", "SSH deploy pipeline", "deploy without registry", "transfer docker image via SSH".

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

6.8 KB, as published. Nobody here has run it

Docker VPS Deploy

Overview

Build Docker image in CI, compress with gzip, transfer to VPS via rsync over SSH, load and run with Docker Compose. No container registry required — the image travels as a .tar.gz file.

When to Use

  • VPS with SSH access, Docker, and Docker Compose installed
  • No container registry in the workflow (no Docker Hub, ECR, GHCR, etc.)
  • Single-server or small-fleet deployment
  • User asks to generate a GitHub Actions workflow for VPS deployment via rsync/SSH

When NOT to Use

  • Container registry already available → push/pull is simpler and faster
  • Cloud-managed deployments (ECS, Cloud Run, Fly.io, Railway, Render)
  • Multi-node orchestration (Kubernetes, Docker Swarm across nodes)
  • Non-Docker deployments (bare-metal, systemd services)

Prerequisites

On the VPS before first run:

  • Docker and Docker Compose v2 (docker compose, not docker-compose) installed
  • SSH key-based authentication configured for deploy user
  • Deploy directory exists and is writable (e.g., /opt/app)
  • docker-compose.yml present in the repository root

Required Secrets

SecretDescriptionExample
SSH_HOSTVPS IP or hostname203.0.113.10
SSH_USERSSH login userdeploy
SSH_KEYPrivate SSH key (Ed25519 PEM)Contents of ~/.ssh/id_ed25519
SSH_PORTSSH port22

Add in: GitHub repo → Settings → Secrets and variables → Actions.

Core Pipeline Pattern

name: Deploy to VPS

on:
  push:
    branches: [main]
    paths-ignore:
      - "*.md"
      - "docs/**"

env:
  IMAGE_NAME: my-app
  DEPLOY_DIR: /opt/app

jobs:
  deploy:
    runs-on: ubuntu-latest
    timeout-minutes: 20
    permissions:
      contents: read

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Build Docker image
        uses: docker/build-push-action@v6
        with:
          context: .
          file: ./Dockerfile
          load: true
          tags: ${{ env.IMAGE_NAME }}:latest
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: Save and compress image
        run: docker save ${{ env.IMAGE_NAME }}:latest | gzip > image.tar.gz

      - name: Setup SSH agent
        uses: webfactory/[email protected]
        with:
          ssh-private-key: ${{ secrets.SSH_KEY }}

      - name: Add VPS to known hosts
        run: ssh-keyscan -p ${{ secrets.SSH_PORT }} -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts

      - name: Transfer files to VPS
        run: |
          rsync -avz \
            -e "ssh -p ${{ secrets.SSH_PORT }} -o StrictHostKeyChecking=yes" \
            image.tar.gz docker-compose.yml \
            ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:${{ env.DEPLOY_DIR }}/

      - name: Deploy on VPS
        uses: appleboy/[email protected]
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USER }}
          port: ${{ secrets.SSH_PORT }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            cd ${{ env.DEPLOY_DIR }}
            gunzip -c image.tar.gz | docker load
            docker compose down
            docker compose up -d
            docker image prune -f
            rm -f image.tar.gz

Key Optimizations

  • Layer caching (type=gha, mode=max): GitHub Actions cache backend. Skips rebuild of unchanged layers. mode=max caches all intermediate layers, not just the final stage.
  • Gzip compression: docker save outputs uncompressed tar. Gzip reduces image size 60–70% before transfer. For images >2 GB, consider zstd (docker save ... | zstd) for faster compression.
  • webfactory/ssh-agent: Loads the deploy key into ssh-agent in memory — no key file written to disk. Integrates with the system SSH client, so rsync and other SSH commands work without -i flags.
  • appleboy/ssh-action: Executes remote Docker commands over SSH with a clean YAML interface. Errors and stdout are surfaced natively in the Actions log without manual heredoc handling.
  • rsync -avz: Archive mode + compression during transfer. Subsequent deploys only transfer changed bytes (docker-compose.yml updates are nearly instant).
  • load: true: Required in build-push-action when NOT pushing to a registry. Makes the built image available locally for docker save.

Security Considerations

  • Never use StrictHostKeyChecking=no. Use ssh-keyscan to populate known_hosts before connecting. Disabling host key checking enables MITM attacks.
  • SSH key never written to disk. webfactory/ssh-agent loads the key into ssh-agent in memory. appleboy/ssh-action handles its own key internally — no files, no CLI args.
  • Ed25519 keys preferred over RSA — smaller, faster, same security.
  • Dedicated deploy user on the VPS: non-root, member of docker group, write access to deploy dir only.
  • permissions: contents: read — least-privilege GITHUB_TOKEN scoping.

Common Mistakes

MistakeWhy It FailsFix
Using GHCR/Docker Hub instead of docker saveDoesn't match the no-registry requirement; adds registry credentials complexityUse docker save | gzip > image.tar.gz + rsync
StrictHostKeyChecking=noDisables MITM protectionUse ssh-keyscan + StrictHostKeyChecking=yes
Missing load: true in build stepImage not available locally for docker saveAdd load: true to build-push-action
Using docker-compose (v1 binary)Deprecated; may not exist on VPSUse docker compose (v2 plugin, no hyphen)
No timeout-minutesStuck deploy blocks runner for 6 hoursSet timeout-minutes: 20 on the job
Not cleaning up image.tar.gz on VPSDisk fills up over repeated deploysrm -f image.tar.gz after docker load
Hardcoding SSH port 22Breaks when VPS uses non-standard portParameterize via SSH_PORT secret

Cross-Reference

For GitHub Actions syntax fundamentals — workflow YAML structure, triggers, job orchestration, caching patterns, action SHA pinning, and the 13 common anti-patterns — use the github-actions skill:

npx skills add oakoss/agent-skills/github-actions

This skill focuses exclusively on the Docker + VPS rsync-based deployment pattern and delegates all GitHub Actions syntax questions to that skill.

Gives 0 of the 12 instructions most containers cloud skills give

Counted across 607 of the 657 authors here whose files we hold, read 2026-08-06

  • run containers as a non-root userin 69 of 607, across 49 files
  • use multi-stage buildsin 52 of 607, across 41 files
  • use Promise.all for independent operationsin 47 of 607, across 13 files
  • import directly instead of barrel filesin 46 of 607, across 12 files
  • use ternary instead of AND for conditionalsin 45 of 607, across 12 files
  • use Set or Map for O(1) lookupsin 42 of 607, across 10 files
  • create a .dockerignore filein 41 of 607, across 31 files
  • Read individual rule files for detailsin 39 of 607, across 9 files
  • authenticate server actions like API routesin 35 of 607, across 7 files
  • use next/dynamic for heavy componentsin 34 of 607, across 9 files
  • use React.cache for per-request deduplicationin 34 of 607, across 10 files
  • copy dependency files before source codein 34 of 607, across 21 files

Said here and by no other author read

  • compress docker image with gzip
  • transfer image via rsync over ssh
  • load and run image with docker compose
  • use load true in build step
  • prune docker images after deploy
  • delete image tarball on vps after load

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.