← 返回
未分类 中文

VPS Deploy

Deploy a full-stack app to any VPS from zero to production in one command. Handles SSH hardening, firewall, Docker, Nginx reverse proxy, SSL certificates, an...
使用一条命令将全栈应用从零部署到任意 VPS,完成 SSH 加固、防火墙、Docker、Nginx 反向代理、SSL 证书等配置。
llcsamih
未分类 clawhub v1.0.0 1 版本 100000 Key: 无需
★ 0
Stars
📥 375
下载
💾 1
安装
1
版本
#latest

概述

VPS Deploy

Deploy any application to any VPS — from bare server to production with SSL — in one session.

When to Use

  • User has a VPS (Ubuntu/Debian) and wants to deploy an application
  • User says "deploy to VPS", "set up my server", "go to production"
  • User has a running app locally and wants it live on a server
  • User needs SSL, Nginx, Docker setup on a VPS

When NOT to Use

  • Deploying to Vercel, Netlify, or other managed platforms (use their CLIs)
  • Deploying to Kubernetes (use /k8s-deploy if it exists)
  • The user just wants to push code (use git push)

Prerequisites

  • SSH access to a VPS (IP address + root or sudo credentials)
  • A domain pointed to the VPS IP (for SSL — can skip SSL if no domain)
  • The app must have a Dockerfile or be deployable via Docker

Execution Flow

Phase 1: Gather Information

Ask the user for (skip what you can detect):

  1. VPS IP address and SSH credentials (root password or key path)
  2. Domain name (optional — needed for SSL)
  3. Application type — detect from the current directory if possible:
    • Look for package.json (Node.js/Next.js)
    • Look for requirements.txt / pyproject.toml (Python)
    • Look for go.mod (Go)
    • Look for Dockerfile (any)
  4. Port the app runs on (detect from Dockerfile EXPOSE, or ask)
  5. Environment variables needed (check .env.local, .env.example)
  6. Database requirements (Postgres, MySQL, Redis, MongoDB — detect from dependencies)

Phase 2: Server Setup (SSH into VPS)

Run these via ssh root@ commands. Chain with && for safety.

2a. System Update

apt update && apt upgrade -y

2b. Create Deploy User

adduser --disabled-password --gecos "" deploy
usermod -aG sudo docker deploy
echo "deploy ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/deploy

2c. SSH Hardening

# Copy root's authorized_keys to deploy user
mkdir -p /home/deploy/.ssh
cp ~/.ssh/authorized_keys /home/deploy/.ssh/ 2>/dev/null || true
chown -R deploy:deploy /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys 2>/dev/null || true

# Harden SSH config
sed -i 's/#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/#\?PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
systemctl restart sshd

CRITICAL: Before disabling root login, verify the deploy user can SSH in. Test in a separate connection. If the user doesn't have SSH keys set up, help them first.

2d. Firewall (UFW)

apt install -y ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp   # SSH
ufw allow 80/tcp   # HTTP
ufw allow 443/tcp  # HTTPS
ufw --force enable

2e. Install Docker

curl -fsSL https://get.docker.com | sh
usermod -aG docker deploy

2f. Install Docker Compose (v2)

apt install -y docker-compose-plugin
# Verify
docker compose version

Phase 3: Application Deployment

3a. Generate Dockerfile (if none exists)

Detect the stack and generate an appropriate multi-stage Dockerfile:

Node.js / Next.js:

FROM node:22-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev

FROM node:22-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
EXPOSE 3000
CMD ["node", "server.js"]

Python (FastAPI/Flask):

FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Adapt based on what you detect in the project.

3b. Generate docker-compose.yml

Generate a production-grade compose file. Include:

services:
  app:
    build: .
    restart: unless-stopped
    ports:
      - "127.0.0.1:${APP_PORT:-3000}:${APP_PORT:-3000}"
    env_file: .env
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:${APP_PORT:-3000}/"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: '1.0'
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  # Add database services based on detection:
  # postgres:
  #   image: postgres:16-alpine
  #   restart: unless-stopped
  #   volumes:
  #     - pgdata:/var/lib/postgresql/data
  #   environment:
  #     POSTGRES_DB: ${DB_NAME:-app}
  #     POSTGRES_USER: ${DB_USER:-app}
  #     POSTGRES_PASSWORD: ${DB_PASSWORD}
  #   healthcheck:
  #     test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-app}"]
  #     interval: 10s
  #     timeout: 5s
  #     retries: 5

# volumes:
#   pgdata:

Key rules:

  • Always bind app port to 127.0.0.1 (Nginx handles external traffic)
  • Always include health checks
  • Always include resource limits
  • Always include logging limits
  • Always use restart: unless-stopped
  • Never expose database ports to the host

3c. Transfer Files to VPS

# Create app directory
ssh deploy@<IP> "mkdir -p ~/apps/<app-name>"

# Copy project files (exclude node_modules, .git, etc.)
rsync -avz --exclude='node_modules' --exclude='.git' --exclude='.next' \
  ./ deploy@<IP>:~/apps/<app-name>/

3d. Build and Start

ssh deploy@<IP> "cd ~/apps/<app-name> && docker compose up -d --build"

Phase 4: Nginx Reverse Proxy

apt install -y nginx

# Generate site config
cat > /etc/nginx/sites-available/<domain> << 'EOF'
server {
    listen 80;
    server_name <domain>;

    location / {
        proxy_pass http://127.0.0.1:<APP_PORT>;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
        proxy_read_timeout 86400;
    }
}
EOF

ln -sf /etc/nginx/sites-available/<domain> /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
nginx -t && systemctl reload nginx

Phase 5: SSL Certificate (Let's Encrypt)

Skip if no domain provided.

apt install -y certbot python3-certbot-nginx
certbot --nginx -d <domain> --non-interactive --agree-tos -m <email>
# Auto-renewal is configured automatically by certbot

Phase 6: Verification

Run these checks and report results:

# Check Docker containers are running
docker compose ps

# Check health status
docker inspect --format='{{.State.Health.Status}}' <container-name>

# Check Nginx is serving
curl -sI https://<domain> | head -5

# Check SSL certificate
echo | openssl s_client -servername <domain> -connect <domain>:443 2>/dev/null | openssl x509 -noout -dates

Report to the user:

  • Container status (running/healthy)
  • HTTP response code
  • SSL expiry date
  • URL to visit

Safety Rules

  • NEVER disable the firewall without asking
  • NEVER expose database ports to the internet
  • ALWAYS verify SSH access with the deploy user BEFORE disabling root login
  • ALWAYS back up existing Nginx configs before overwriting
  • ALWAYS run nginx -t before reloading Nginx
  • ALWAYS ask before running destructive commands (rm, drop, etc.)
  • If anything fails, stop and tell the user what went wrong. Don't chain workarounds.

Troubleshooting

  • Port already in use: lsof -i : to find what's using it
  • Docker build fails: Check Dockerfile, show build logs
  • SSL fails: Verify domain DNS points to VPS IP (dig )
  • App crashes: docker compose logs -f to show logs
  • Can't SSH as deploy user: Don't disable root login yet, fix keys first

Post-Deploy Checklist

Tell the user to:

  1. Set up monitoring (suggest Uptime Kuma)
  2. Configure automated backups for database volumes
  3. Set up log rotation (already configured in compose)
  4. Consider a CI/CD pipeline (suggest /ci-gen skill)
  5. Add the domain to their DNS if not done

版本历史

共 1 个版本

  • v1.0.0 当前
    2026-05-07 14:44 安全 安全

安全检测

腾讯云安全 (Keen)

安全,无风险
查看报告

腾讯云安全 (Sanbu)

安全,无风险
查看报告

🔗 相关推荐

CI/CD Generator

llcsamih
Generate GitHub Actions CI/CD pipelines tailored to the current project. Use when the user says 'set up CI', 'create pip
★ 0 📥 388

Database Migration Manager

llcsamih
数据库迁移管理器。检测正在使用的 ORM/迁移工具,生成迁移脚本,处理回滚,创建种子数据脚本,对比不同环境间的 schema 差异。
★ 0 📥 336

Production Docker Compose

llcsamih
生成适用于任何项目的生产级 docker‑compose.yml,包含每个服务的健康检查、网络分段(前/后端/数据库)以及资源限制。
★ 0 📥 393