Files
homelab/.gitea/workflows/deploy.yml
2025-10-27 23:44:13 +01:00

226 lines
7.6 KiB
YAML

name: Deploy Docker Compose
on:
workflow_dispatch:
inputs:
server:
description: 'Target server to deploy'
required: true
type: choice
options:
- devops
- production
- staging
- all
service:
description: 'Service to deploy (leave empty for all)'
required: false
type: string
default: ''
action:
description: 'Docker Compose action'
required: true
type: choice
options:
- up
- restart
- pull-and-up
- down
- logs
default: 'pull-and-up'
detach:
description: 'Run in detached mode'
required: false
type: boolean
default: true
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set deployment context
id: context
run: |
echo "=== Deployment Configuration ==="
echo "Server: ${{ inputs.server }}"
echo "Service: ${{ inputs.service || 'all services' }}"
echo "Action: ${{ inputs.action }}"
echo "Detached: ${{ inputs.detach }}"
# Git Repo URL (aus Gitea)
REPO_URL="https://git.hashdot.co/${{ github.repository }}.git"
echo "REPO_URL=$REPO_URL" >> $GITHUB_ENV
# Server-Konfiguration setzen
case "${{ inputs.server }}" in
devops)
echo "HOST=10.0.0.175" >> $GITHUB_ENV
echo "USER=lars" >> $GITHUB_ENV
echo "COMPOSE_PATH=/home/lars/homelab/servers/production/devops" >> $GITHUB_ENV
;;
production)
echo "HOST=10.0.0.180" >> $GITHUB_ENV
echo "USER=lars" >> $GITHUB_ENV
echo "COMPOSE_PATH=/home/lars/production" >> $GITHUB_ENV
;;
staging)
echo "HOST=10.0.0.185" >> $GITHUB_ENV
echo "USER=lars" >> $GITHUB_ENV
echo "COMPOSE_PATH=/home/lars/staging" >> $GITHUB_ENV
;;
all)
echo "DEPLOY_ALL=true" >> $GITHUB_ENV
;;
esac
# Service-Parameter setzen
if [ -n "${{ inputs.service }}" ]; then
echo "SERVICE_ARG=${{ inputs.service }}" >> $GITHUB_ENV
else
echo "SERVICE_ARG=" >> $GITHUB_ENV
fi
# Detach-Flag setzen
if [ "${{ inputs.detach }}" == "true" ]; then
echo "DETACH_FLAG=-d" >> $GITHUB_ENV
else
echo "DETACH_FLAG=" >> $GITHUB_ENV
fi
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
# Füge alle möglichen Hosts hinzu
ssh-keyscan -H 10.0.0.175 >> ~/.ssh/known_hosts 2>/dev/null || true
ssh-keyscan -H 10.0.0.180 >> ~/.ssh/known_hosts 2>/dev/null || true
ssh-keyscan -H 10.0.0.185 >> ~/.ssh/known_hosts 2>/dev/null || true
- name: Deploy to single server
if: inputs.server != 'all'
run: |
echo "=== Deploying to ${{ inputs.server }} ==="
# Check ob Repo existiert, sonst clonen
ssh $USER@$HOST "
export COMPOSE_PATH='$COMPOSE_PATH'
export REPO_URL='$REPO_URL'
if [ -d \"\$COMPOSE_PATH/.git\" ]; then
echo 'Repository already exists, pulling latest changes...'
cd \$COMPOSE_PATH && git pull
else
echo 'Repository not found, cloning...'
PARENT_DIR=\$(dirname \$COMPOSE_PATH)
mkdir -p \$PARENT_DIR
cd \$PARENT_DIR
git clone \$REPO_URL \$(basename \$COMPOSE_PATH)
echo 'Repository cloned successfully'
fi
"
# Docker Compose Aktion ausführen
case "${{ inputs.action }}" in
up)
ssh $USER@$HOST "cd $COMPOSE_PATH && docker compose up $DETACH_FLAG $SERVICE_ARG"
;;
restart)
ssh $USER@$HOST "cd $COMPOSE_PATH && docker compose restart $SERVICE_ARG"
;;
pull-and-up)
ssh $USER@$HOST "cd $COMPOSE_PATH && docker compose pull $SERVICE_ARG && docker compose up $DETACH_FLAG $SERVICE_ARG"
;;
down)
ssh $USER@$HOST "cd $COMPOSE_PATH && docker compose down $SERVICE_ARG"
;;
logs)
ssh $USER@$HOST "cd $COMPOSE_PATH && docker compose logs --tail=100 $SERVICE_ARG"
;;
esac
- name: Deploy to all servers
if: inputs.server == 'all'
run: |
echo "=== Deploying to all servers ==="
# Definiere alle Server
declare -A SERVERS=(
["devops"]="lars@10.0.0.175:/home/lars/ghq/git.hashdot.co/lars/homelab/servers/production/devops"
["production"]="lars@10.0.0.180:/home/lars/production"
["staging"]="lars@10.0.0.185:/home/lars/staging"
)
for server in "${!SERVERS[@]}"; do
IFS=':' read -r user_host compose_path <<< "${SERVERS[$server]}"
echo ""
echo ">>> Deploying to $server..."
# Check ob Repo existiert, sonst clonen
ssh $user_host "
export COMPOSE_PATH='$compose_path'
export REPO_URL='$REPO_URL'
if [ -d \"\$COMPOSE_PATH/.git\" ]; then
echo 'Repository already exists, pulling latest changes...'
cd \$COMPOSE_PATH && git pull
else
echo 'Repository not found, cloning...'
PARENT_DIR=\$(dirname \$COMPOSE_PATH)
mkdir -p \$PARENT_DIR
cd \$PARENT_DIR
git clone \$REPO_URL \$(basename \$COMPOSE_PATH)
echo 'Repository cloned successfully'
fi
" || { echo "Failed to setup git for $server"; continue; }
# Docker Compose Aktion
case "${{ inputs.action }}" in
up)
ssh $user_host "cd $compose_path && docker compose up $DETACH_FLAG $SERVICE_ARG"
;;
restart)
ssh $user_host "cd $compose_path && docker compose restart $SERVICE_ARG"
;;
pull-and-up)
ssh $user_host "cd $compose_path && docker compose pull $SERVICE_ARG && docker compose up $DETACH_FLAG $SERVICE_ARG"
;;
down)
ssh $user_host "cd $compose_path && docker compose down $SERVICE_ARG"
;;
logs)
ssh $user_host "cd $compose_path && docker compose logs --tail=100 $SERVICE_ARG"
;;
esac
echo ">>> $server deployment completed"
done
- name: Verify deployment
if: inputs.action != 'down' && inputs.action != 'logs'
run: |
echo "=== Verifying deployment ==="
if [ "${{ inputs.server }}" != "all" ]; then
ssh $USER@$HOST "cd $COMPOSE_PATH && docker compose ps"
else
echo "Skipping verification for 'all' - check individual server logs"
fi
- name: Deployment summary
if: always()
run: |
echo "=== Deployment Summary ==="
echo "Server: ${{ inputs.server }}"
echo "Service: ${{ inputs.service || 'all services' }}"
echo "Action: ${{ inputs.action }}"
echo "Status: ${{ job.status }}"
echo ""
echo "Deployment completed at $(date)"