Files
Compose-Files/Backups/Miker/Learning CI-CD/Automatically Deploy to a Live Server.md
T
2026-07-20 09:23:17 -04:00

3.4 KiB

tags
tags
GIT
CI/CD
CI-CD

🚀 Part 2: Automatically Deploy to a Live Server

The safest, cleanest way to deploy to a remote homelab server from a runner is using SSH and Docker Contexts. This allows your Gitea Actions runner to securely command your live server's Docker daemon across your local network without needing Git installed on the destination server.

  1. Generate a Deployment SSH Key [1]

On your local machine or server, generate a dedicated SSH key pair for Gitea Actions. Do not use a passphrase.

ssh-keygen -t ed25519 -f ~/.ssh/gitea_deploy_key -N ""

  • Append the contents of gitea_deploy_key.pub to the ~/.ssh/authorized_keys file on your live deployment server.
  • Copy the contents of the private key gitea_deploy_key. Save it in your Gitea Repository Secrets as DEPLOY_SSH_KEY.
  • Save your live server's local IP address or local hostname in Gitea Secrets as DEPLOY_HOST.
  • Save your live server's SSH username in Gitea Secrets as DEPLOY_USER.
  1. Create the Complete Production Workflow

Create or update your .gitea/workflows/deploy.yaml file. This workflow will validate your code first, and then deploy it only if the branch is main.

name: Validate and Deploy Homelab

on: push: branches: [ "main" ]

jobs: test-and-deploy: runs-on: ubuntu-latest

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

  - name: Verify Compose File Validity
    env:
      DB_ROOT_PASSWORD: ${{ secrets.MYSQL_ROOT_PASSWORD }}
      DB_PASSWORD: ${{ secrets.MYSQL_PASSWORD }}
    run: docker compose config

  # --- DEPLOYMENT PHASE ---
  
  - name: Set up SSH Private Key
    run: |
      mkdir -p ~/.ssh
      echo "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/id_ed25519
      chmod 600 ~/.ssh/id_ed25519
      # Scan the host key to prevent SSH hanging on a manual confirmation prompt
      ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts

  - name: Create Remote Docker Context
    run: |
      # Define a remote endpoint pointing to your live server over SSH
      docker context create homelab-target \
        --docker "host=ssh://${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}"

  - name: Deploy Containers to Live Server
    env:
      # Pass your production secrets to the live deployment step
      DB_ROOT_PASSWORD: ${{ secrets.MYSQL_ROOT_PASSWORD }}
      DB_PASSWORD: ${{ secrets.MYSQL_PASSWORD }}
    run: |
      echo "Switching Docker context to live server..."
      docker context use homelab-target
      
      echo "Pulling latest images and starting services remotely..."
      # The --project-directory . flag ensures it reads the docker-compose file fetched by Git
      docker compose --project-directory . up -d --remove-orphans

💡 Why This Setup Wins for Homelabs

  • Zero Overhead: You do not need to install complex deployment tools or agents on your production server. It only requires standard SSH and Docker.
  • Security: If you ever need to revoke the runner's deployment access, you simply delete the single public key from your live server's authorized_keys file.
  • Atomic Changes: The --remove-orphans flag cleans up old containers that you removed from your Compose file since the last Git commit, keeping your server immaculate.