# .github/workflows/deploy.yml name: Deploy Gateway to VPS on: push: branches: [ "disbaled" ] paths: - "docker-compose.yml" - ".github/workflows/deploy.yml" workflow_dispatch: env: REMOTE_DIR: ${{ secrets.REMOTE_DIR }} concurrency: group: deploy-prod cancel-in-progress: true jobs: deploy: name: Ship to VPS runs-on: ubuntu-latest environment: production steps: - name: Checkout uses: actions/checkout@v4 - name: Setup SSH key run: | mkdir -p ~/.ssh echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa ssh-keyscan -p "${{ secrets.SSH_PORT }}" "${{ secrets.SSH_HOST }}" >> ~/.ssh/known_hosts - name: Login to GitHub Container Registry on VPS run: | ssh -p "${{ secrets.SSH_PORT }}" "${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}" \ "echo '${{ secrets.GITHUB_TOKEN }}' | docker login ghcr.io -u '${{ github.actor }}' --password-stdin" - name: Deploy (pull, up, prune) run: | ssh -p "${{ secrets.SSH_PORT }}" "${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}" \ "export REMOTE_DIR='${{ secrets.REMOTE_DIR }}'; bash -se" <<'EOF' set -euo pipefail cd "$REMOTE_DIR" git pull origin main docker compose pull docker compose up -d --remove-orphans docker image prune -af || true EOF - name: Post-deploy smoke checks run: | echo "Deployed to ${{ secrets.SSH_HOST }}:${{ secrets.SSH_PORT }} → ${REMOTE_DIR}" echo "Traefik: https://traefik.gate.${{ secrets.DOMAIN }}" echo "Portainer: https://portainer.gate.${{ secrets.DOMAIN }}" echo "Uptime Kuma: https://uptime.gate.${{ secrets.DOMAIN }}" echo "Umami: https://umami.gate.${{ secrets.DOMAIN }}" echo "pgAdmin: https://pgadmin.gate.${{ secrets.DOMAIN }}"