SetupOrion ByImpa

SkillDB 作者 impa365 v1.0.0

Setup completo de VPS Ubuntu/Debian para produção com Docker Swarm, Traefik v3 (SSL/HTTPS automático), Portainer CE e rede overlay. Baseado no SetupOrion v2.8.0. Executa todos os comandos automaticamente.

源码 ↗

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install skilldb:impa365~setuporion-byimpa
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/skilldb%3Aimpa365~setuporion-byimpa/file -o setuporion-byimpa.md
Git 仓库获取源码
git clone https://github.com/openclaw/skills/commit/69e150c6a501a724d0f3cacd56bc49faed36f3ba
# VPS Setup - Docker Swarm + Traefik + Portainer

Setup automatizado de VPS para produção. Instala Docker, inicia Swarm, cria rede overlay, deploya Traefik v3 com SSL automático e Portainer CE.

**Requisitos:** Ubuntu 20.04+ ou Debian 11+ com acesso root/sudo.

---

## Execução Completa (todos os passos em ordem)

Execute cada etapa na ordem. Todas as etapas são idempotentes (seguro re-executar).

---

### Etapa 1 - Atualizar Sistema e Configurar Servidor

```bash
# Atualizar sistema
sudo apt-get update && sudo apt-get upgrade -y

# Instalar utilitários essenciais
sudo apt-get install -y apt-utils apparmor-utils curl jq htpasswd ca-certificates gnupg lsb-release

# Configurar timezone
sudo timedatectl set-timezone America/Sao_Paulo

# Definir hostname do servidor
sudo hostnamectl set-hostname $VPS_HOSTNAME
sudo sed -i "s/127.0.0.1[[:space:]]localhost/127.0.0.1 $VPS_HOSTNAME/g" /etc/hosts
```

**Verificação:**
```bash
timedatectl | grep "Time zone"
# Esperado: America/Sao_Paulo

hostname
# Esperado: $VPS_HOSTNAME
```

---

### Etapa 2 - Instalar Docker

```bash
# Instalar Docker via script oficial
curl -fsSL https://get.docker.com | bash

# Habilitar e iniciar Docker
sudo systemctl enable docker
sudo systemctl start docker

# Fix: garantir compatibilidade com API mínima
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo bash -c 'cat > /etc/systemd/system/docker.service.d/override.conf <<EOF
[Service]
Environment=DOCKER_MIN_API_VERSION=1.24
EOF'

sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl restart docker
```

**Se falhar**, instalar manualmente:
```bash
sudo install -m 0755 -d /etc/apt/keyrings
OS_ID=$(source /etc/os-release && echo "$ID")
OS_CODENAME=$(source /etc/os-release && echo "$VERSION_CODENAME")

curl -fsSL https://download.docker.com/linux/$OS_ID/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/$OS_ID $OS_CODENAME stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable docker
sudo systemctl start docker
```

**Verificação:**
```bash
docker --version
# Esperado: Docker version 2X.x.x

docker info --format '{{.Swarm.LocalNodeState}}'
# Esperado: inactive (ainda não iniciamos o Swarm)
```

---

### Etapa 3 - Iniciar Docker Swarm

```bash
# Obter IP público da VPS (ignora loopback e IPs internos)
IP=$(hostname -I | tr ' ' '\n' | grep -v '^127\.' | grep -v '^10\.0\.0\.' | head -n1)

# Iniciar Swarm
docker swarm init --advertise-addr $IP
```

**Verificação:**
```bash
docker info --format '{{.Swarm.LocalNodeState}}'
# Esperado: active

docker node ls
# Esperado: 1 node com STATUS=Ready, MANAGER STATUS=Leader
```

---

### Etapa 4 - Criar Rede Overlay e Volumes

```bash
# Criar rede overlay para comunicação entre containers
docker network create --driver=overlay $VPS_NETWORK

# Criar volumes necessários
docker volume create volume_swarm_shared
docker volume create volume_swarm_certificates
docker volume create portainer_data
docker volume create postgres_data
docker volume create evolution_instances
docker volume create evolution_redis
```

**Verificação:**
```bash
docker network ls | grep $VPS_NETWORK
# Esperado: linha com $VPS_NETWORK, DRIVER=overlay, SCOPE=swarm

docker volume ls | grep -E "shared|certificates|portainer|postgres|evolution"
# Esperado: 6 volumes listados
```

---

### Etapa 5 - Deploy do Traefik v3 (Proxy Reverso + SSL)

Criar o arquivo `traefik.yaml` e fazer deploy:

```bash
cat > /root/traefik.yaml << 'TRAEFIKEOF'
version: "3.7"
services:
  traefik:
    image: traefik:v3.5.3
    command:
      - "--api.dashboard=true"
      - "--providers.swarm=true"
      - "--providers.docker.endpoint=unix:///var/run/docker.sock"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.network=NETWORK_PLACEHOLDER"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entryPoint.scheme=https"
      - "--entrypoints.web.http.redirections.entrypoint.permanent=true"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.web.transport.respondingTimeouts.idleTimeout=3600"
      - "--certificatesresolvers.letsencryptresolver.acme.httpchallenge=true"
      - "--certificatesresolvers.letsencryptresolver.acme.httpchallenge.entrypoint=web"
      - "--certificatesresolvers.letsencryptresolver.acme.storage=/etc/traefik/letsencrypt/acme.json"
      - "--certificatesresolvers.letsencryptresolver.acme.email=EMAIL_PLACEHOLDER"
      - "--log.level=DEBUG"
      - "--log.format=common"
      - "--log.filePath=/var/log/traefik/traefik.log"
      - "--accesslog=true"
      - "--accesslog.filepath=/var/log/traefik/access-log"

    volumes:
      - "vol_certificates:/etc/traefik/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

    networks:
      - network_overlay

    ports:
      - target: 80
        published: 80
        mode: host
      - target: 443
        published: 443
        mode: host

    deploy:
      placement:
        constraints:
          - node.role == manager
      labels:
        - "traefik.enable=true"
        - "traefik.http.middlewares.redirect-https.redirectscheme.scheme=https"
        - "traefik.http.middlewares.redirect-https.redirectscheme.permanent=true"
        - "traefik.http.routers.http-catchall.rule=Host(`{host:.+}`)"
        - "traefik.http.routers.http-catchall.entrypoints=web"
        - "traefik.http.routers.http-catchall.middlewares=redirect-https@docker"
        - "traefik.http.routers.http-catchall.priority=1"

volumes:
  vol_shared:
    external: true
    name: volume_swarm_shared
  vol_certificates:
    external: true
    name: volume_swarm_certificates

networks:
  network_overlay:
    external: true
    attachable: true
    name: NETWORK_PLACEHOLDER
TRAEFIKEOF

# Substituir placeholders pelas variáveis reais
sed -i "s/NETWORK_PLACEHOLDER/$VPS_NETWORK/g" /root/traefik.yaml
sed -i "s/EMAIL_PLACEHOLDER/$VPS_EMAIL_SSL/g" /root/traefik.yaml

# Deploy
docker stack deploy --prune --resolve-image always -c /root/traefik.yaml traefik
```

**Aguardar Traefik ficar online:**
```bash
# Verificar a cada 10s até o serviço mostrar 1/1
while ! docker service ls --filter name='traefik_traefik' --format '{{.Replicas}}' | grep -q '1/1'; do
  echo "Aguardando Traefik..."
  sleep 10
done
echo "Traefik online!"
```

**Verificação:**
```bash
docker service ls --filter name=traefik
# Esperado: traefik_traefik   1/1

curl -sI http://localhost:80 | head -3
# Esperado: HTTP redirect ou resposta do Traefik
```

---

### Etapa 6 - Deploy do Portainer CE (Gerenciador Docker)

Criar o arquivo `portainer.yaml` e fazer deploy:

```bash
cat > /root/portainer.yaml << 'PORTAINEREOF'
version: "3.7"
services:
  agent:
    image: portainer/agent:latest
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/lib/docker/volumes:/var/lib/docker/volumes
    networks:
      - network_overlay
    deploy:
      mode: global
      placement:
        constraints: [node.platform.os == linux]

  portainer:
    image: portainer/portainer-ce:latest
    command: -H tcp://tasks.agent:9001 --tlsskipverify
    volumes:
      - portainer_data:/data
    networks:
      - network_overlay
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints: [node.role == manager]
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers