diff --git a/.gitea/workflows/build-and-push.yaml b/.gitea/workflows/build-and-push.yaml index df92766..d896a0b 100644 --- a/.gitea/workflows/build-and-push.yaml +++ b/.gitea/workflows/build-and-push.yaml @@ -65,3 +65,75 @@ jobs: run: | echo "🎉 Build and Push completed successfully!" echo "📦 Image: ${{ vars.REGISTRY_URL }}/${{ vars.NAMESPACE }}/${{ vars.REPO_NAME }}:${{ steps.tag.outputs.IMAGE_TAG }}" + + deploy: + runs-on: ubuntu-latest + needs: build-and-push + + steps: + - name: Determine Image Tag + id: tag + run: | + # Prüfe ob es ein Git Tag ist + if [[ "${{ github.ref }}" == refs/tags/* ]]; then + TAG="${{ github.ref_name }}" + elif [[ "${{ github.ref_name }}" == "main" ]]; then + TAG="latest" + else + TAG="${{ github.ref_name }}-${{ github.sha }}" + TAG="${TAG:0:50}" + fi + echo "IMAGE_TAG=${TAG}" >> $GITHUB_OUTPUT + echo "📦 Deploying Image Tag: ${TAG}" + + - name: Setup SSH + run: | + mkdir -p ~/.ssh + echo "${{ secrets.DEPLOY_SSH_PRIVATE_KEY }}" > ~/.ssh/deploy_key + chmod 600 ~/.ssh/deploy_key + ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts + + - name: Deploy to Server + env: + IMAGE_NAME: ${{ vars.REGISTRY_URL }}/${{ vars.NAMESPACE }}/${{ vars.REPO_NAME }}:${{ steps.tag.outputs.IMAGE_TAG }} + CONTAINER_NAME: ${{ vars.REPO_NAME }} + CONTAINER_PORT: ${{ vars.CONTAINER_PORT }} + run: | + echo "🚀 Starting deployment to ${{ secrets.DEPLOY_HOST }}..." + + ssh -i ~/.ssh/deploy_key ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} << 'EOF' + set -e + + echo "📦 Logging in to registry..." + echo "${{ secrets.CI_GITEA_TOKEN }}" | docker login ${{ vars.REGISTRY_URL }} -u "${{ secrets.CI_GITEA_USER }}" --password-stdin + + echo "📥 Pulling new image: ${{ env.IMAGE_NAME }}" + docker pull ${{ env.IMAGE_NAME }} + + echo "🛑 Stopping old container (if exists)..." + docker stop ${{ env.CONTAINER_NAME }} 2>/dev/null || true + docker rm ${{ env.CONTAINER_NAME }} 2>/dev/null || true + + echo "🚀 Starting new container on port ${{ env.CONTAINER_PORT }}..." + docker run -d \ + --name ${{ env.CONTAINER_NAME }} \ + --restart unless-stopped \ + -p ${{ env.CONTAINER_PORT }}:8080 \ + ${{ env.IMAGE_NAME }} + + echo "✅ Deployment completed successfully!" + docker ps | grep ${{ env.CONTAINER_NAME }} + EOF + + - name: Cleanup + if: always() + run: | + rm -f ~/.ssh/deploy_key + + - name: Deployment Summary + run: | + echo "🎉 Deployment completed successfully!" + echo "🖥️ Server: ${{ secrets.DEPLOY_HOST }}" + echo "📦 Image: ${{ vars.REGISTRY_URL }}/${{ vars.NAMESPACE }}/${{ vars.REPO_NAME }}:${{ steps.tag.outputs.IMAGE_TAG }}" + echo "🐳 Container: ${{ vars.REPO_NAME }}" + echo "🌐 URL: http://${{ secrets.DEPLOY_HOST }}:${{ vars.CONTAINER_PORT }}" diff --git a/docker/GITEA_SETUP.md b/docker/GITEA_SETUP.md index 716e800..d668d89 100644 --- a/docker/GITEA_SETUP.md +++ b/docker/GITEA_SETUP.md @@ -34,8 +34,11 @@ Erstellen Sie folgende Variables: | `REGISTRY_URL` | URL der Gitea Registry | `gitea.moz-tech.de` | | `NAMESPACE` | Namespace/Benutzer | `murat` | | `REPO_NAME` | Repository Name | `enerport-web-app` | +| `CONTAINER_PORT` | Port auf dem Zielserver | `8080` oder `80` | -**Hinweis:** `IMAGE_TAG` wird automatisch aus dem Commit/Tag generiert und muss nicht als Variable gesetzt werden. +**Hinweise:** +- `IMAGE_TAG` wird automatisch aus dem Commit/Tag generiert und muss nicht als Variable gesetzt werden +- `CONTAINER_PORT` definiert den Host-Port auf dem Zielserver (Container-intern ist immer Port 8080) ### Secrets (vertraulich) @@ -43,14 +46,72 @@ Navigieren Sie zu: **Settings → Actions → Secrets** Erstellen Sie folgende Secrets: +#### Registry Authentifizierung | Name | Wert | Beispiel | |------|------|----------| | `CI_GITEA_USER` | Gitea Benutzername | `murat` | | `CI_GITEA_TOKEN` | Gitea Access Token | `74a7738116bfb99497a7781291efc5766901f497` | -**Hinweis:** +#### Deployment (SSH) +| Name | Wert | Beispiel | +|------|------|----------| +| `DEPLOY_HOST` | Hostname/IP des Zielservers | `server.example.com` oder `192.168.1.100` | +| `DEPLOY_USER` | SSH Benutzername | `deploy` oder `root` | +| `DEPLOY_SSH_PRIVATE_KEY` | SSH Private Key | `-----BEGIN OPENSSH PRIVATE KEY-----\n...` | + +**Hinweise:** - User und Token werden zusammen als Secrets gespeichert für eine sichere Authentifizierung - Der Prefix `CI_GITEA_` ist erforderlich, da Gitea keine Variablen mit dem Prefix `GITEA_` erlaubt +- Der SSH Private Key muss im OpenSSH-Format vorliegen + +## SSH-Key für Deployment erstellen + +### 1. SSH-Schlüsselpaar generieren (auf Ihrem lokalen Rechner) + +```bash +ssh-keygen -t ed25519 -C "gitea-deploy" -f ~/.ssh/gitea_deploy_key +``` + +Dies erstellt: +- `~/.ssh/gitea_deploy_key` (Private Key) - Für Gitea Secret +- `~/.ssh/gitea_deploy_key.pub` (Public Key) - Für Zielserver + +### 2. Public Key auf Zielserver hinzufügen + +Kopieren Sie den Public Key auf den Zielserver: + +```bash +ssh-copy-id -i ~/.ssh/gitea_deploy_key.pub user@server.example.com +``` + +Oder manuell: +```bash +# Public Key anzeigen +cat ~/.ssh/gitea_deploy_key.pub + +# Auf dem Zielserver in ~/.ssh/authorized_keys einfügen +``` + +### 3. Private Key als Secret hinzufügen + +```bash +# Private Key anzeigen +cat ~/.ssh/gitea_deploy_key +``` + +Kopieren Sie den **gesamten Inhalt** (inklusive `-----BEGIN` und `-----END` Zeilen) und fügen Sie ihn als Secret `DEPLOY_SSH_PRIVATE_KEY` in Gitea ein. + +### 4. Voraussetzungen auf dem Zielserver + +Der Zielserver muss folgendes installiert haben: +- Docker +- SSH-Server + +Stellen Sie sicher, dass der Deploy-User Docker-Befehle ausführen darf: +```bash +# Auf dem Zielserver: +sudo usermod -aG docker deploy-user +``` ## Access Token erstellen @@ -61,29 +122,65 @@ Erstellen Sie folgende Secrets: 5. Klicken Sie auf **Generate Token** 6. Kopieren Sie den Token und fügen Sie ihn als Secret `CI_GITEA_TOKEN` hinzu +## Workflow und Deployment + +Der Workflow besteht aus zwei Jobs: + +### Job 1: Build and Push +1. ✅ Checkout Code +2. ✅ Image Tag bestimmen (automatisch) +3. ✅ Docker Image bauen +4. ✅ Image zur Registry pushen + +### Job 2: Deploy (läuft nach erfolgreichem Build) +1. ✅ SSH-Verbindung zum Zielserver aufbauen +2. ✅ Login zur Docker Registry auf dem Zielserver +3. ✅ Neues Image pullen +4. ✅ Alten Container stoppen und entfernen +5. ✅ Neuen Container starten (Port: `CONTAINER_PORT:8080`, auto-restart) + ## Workflow testen Nach der Einrichtung der Variables und Secrets: -### Test 1: Push auf main Branch (erstellt 'latest' Tag) +### Test 1: Push auf main Branch (baut, pusht und deployt 'latest') ```bash git add . -git commit -m "Test CI/CD workflow" +git commit -m "Test CI/CD workflow with deployment" git push origin main ``` -→ Erstellt Image: `gitea.moz-tech.de/murat/enerport-web-app:latest` -### Test 2: Git Tag erstellen (erstellt versioniertes Image) +→ Erstellt Image: `gitea.moz-tech.de/murat/enerport-web-app:latest` +→ Deployed auf: `http://:` + +### Test 2: Git Tag erstellen (baut, pusht und deployt versioniertes Image) ```bash git tag v1.0.0 git push origin v1.0.0 ``` -→ Erstellt Image: `gitea.moz-tech.de/murat/enerport-web-app:v1.0.0` + +→ Erstellt Image: `gitea.moz-tech.de/murat/enerport-web-app:v1.0.0` +→ Deployed auf: `http://:` ### Workflow-Status überprüfen: - Navigieren Sie zu **Actions** in Ihrem Gitea Repository - Sie sollten den Workflow "Build and Push Docker Image" sehen -- Klicken Sie darauf, um die Logs und den verwendeten Tag zu sehen +- Der Workflow zeigt zwei Jobs: `build-and-push` und `deploy` +- Klicken Sie auf die Jobs, um detaillierte Logs zu sehen + +### Deployment verifizieren: +```bash +# Auf dem Zielserver prüfen: +ssh user@server.example.com "docker ps | grep enerport-web-app" + +# Oder im Browser: +# http://: +``` + +**Port-Mapping:** +- Container-intern läuft die App immer auf Port 8080 +- Auf dem Zielserver ist die App unter `CONTAINER_PORT` erreichbar +- Beispiel: `CONTAINER_PORT=80` → App erreichbar unter http://server.example.com ## Troubleshooting