diff --git a/.gitea/workflows/ci-cd.yml b/.gitea/workflows/ci-cd.yml index b8e7703..c6bfaca 100644 --- a/.gitea/workflows/ci-cd.yml +++ b/.gitea/workflows/ci-cd.yml @@ -18,12 +18,13 @@ concurrency: # self-hosted → host runner ← docker build/push/deploy runs here # # Local Nexus: -# Docker registry → mirror.soroushasadi.com (mcr-proxy + drsousan images) +# Docker registry → mirrors.soroushasadi.com (group: pull | host: push) # NuGet → 171.22.25.73:8081/repository/nuget-group/ # # Required Gitea secrets: # ENV_FILE → contents of .env # REGISTRY_PASSWORD → Nexus admin password +# REGISTRY_USER → Nexus username (usually: admin) # ───────────────────────────────────────────────────────────────────────────── jobs: @@ -33,7 +34,7 @@ jobs: name: "CI · dotnet build" runs-on: ubuntu-latest container: - image: mirror.soroushasadi.com/dotnet/sdk:10.0 + image: mirrors.soroushasadi.com/dotnet/sdk:10.0 options: --add-host=gitea:host-gateway steps: - name: Checkout @@ -57,12 +58,14 @@ jobs: working-directory: DrSousan.Api run: dotnet build DrSousan.Api.csproj --no-restore -c Release - # ── Deploy: build image on server → run (push to main only) ──────────────── + # ── CD: build image → push to Nexus → deploy (push to main only) ──────────── deploy: name: "Deploy · drsousan" runs-on: self-hosted env: PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin + REGISTRY: mirrors.soroushasadi.com + IMAGE: mirrors.soroushasadi.com/drsousan/api needs: [ci] if: github.event_name == 'push' && github.ref == 'refs/heads/main' timeout-minutes: 20 @@ -84,11 +87,25 @@ jobs: env: ENV_FILE: ${{ secrets.ENV_FILE }} + - name: Login to Nexus registry + run: echo "$REGISTRY_PASSWORD" | docker login "$REGISTRY" -u "$REGISTRY_USER" --password-stdin + env: + REGISTRY_USER: ${{ secrets.REGISTRY_USER }} + REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} + - name: Build image - run: docker compose build api + run: | + docker compose build api + docker tag mirrors.soroushasadi.com/drsousan/api:latest \ + mirrors.soroushasadi.com/drsousan/api:${{ github.sha }} env: DOCKER_BUILDKIT: 1 + - name: Push image to Nexus + run: | + docker push mirrors.soroushasadi.com/drsousan/api:latest + docker push mirrors.soroushasadi.com/drsousan/api:${{ github.sha }} + - name: Deploy run: docker compose up -d --no-deps api diff --git a/docker-compose.yml b/docker-compose.yml index d57ced5..3be7887 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,33 +2,26 @@ services: # ── .NET API + Razor Pages + Static Files ──────────────────────────────────── api: - image: mirror.soroushasadi.com/drsousan/api:${API_TAG:-latest} - build: # used by local: docker compose build + image: mirrors.soroushasadi.com/drsousan/api:${API_TAG:-latest} + build: context: ./DrSousan.Api dockerfile: Dockerfile container_name: drsousan_api restart: unless-stopped ports: - - "${HOST_PORT:-5000}:8080" # http://localhost:5000 + - "${HOST_PORT:-5000}:8080" volumes: - - db_data:/data # SQLite database (persistent) - - uploads_data:/app/wwwroot/uploads # user-uploaded images (persistent) + - db_data:/data + - uploads_data:/app/wwwroot/uploads environment: - # Database — SQLite stored on /data volume ConnectionStrings__Default: "Data Source=/data/drsousan.db" - - # JWT — CHANGE Jwt__Key in production (min 32 chars) Jwt__Key: "${JWT_KEY:-DrSousanSecretKey2024!ChangeThisInProduction!MinLength32Chars}" Jwt__Issuer: "${JWT_ISSUER:-DrSousanApi}" Jwt__Audience: "${JWT_AUDIENCE:-DrSousanAdmin}" - - # Admin login — override via .env file in production Admin__Username: "${ADMIN_USERNAME:-admin}" Admin__Password: "${ADMIN_PASSWORD:-admin123}" - ASPNETCORE_ENVIRONMENT: "Production" -# ── Named Volumes ──────────────────────────────────────────────────────────── volumes: db_data: driver: local