Files
orion/docs/deployment/gitea.md
Samir Boulahtit 0437af67ec
Some checks failed
CI / ruff (push) Has been cancelled
CI / pytest (push) Has been cancelled
CI / architecture (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / audit (push) Has been cancelled
CI / docs (push) Has been cancelled
feat(merchant): extract merchant portal as first-class frontend with auth, Tailwind fixes, and Gitea CI
- Extract login/dashboard from billing module into core (matching admin pattern)
- Add merchant auth API with path-isolated cookies (path=/merchants)
- Add merchant base layout with sidebar/header partials and Alpine.js init
- Add frontend detection and login redirect for MERCHANT type
- Wire merchant token in shared api-client.js (get/clear)
- Migrate billing templates to merchant base with dark mode support
- Fix Tailwind: rename shop→storefront in sources and config
- DRY Makefile tailwind targets with TAILWIND_FRONTENDS loop
- Rebuild all Tailwind outputs (production minified)
- Add Gitea Actions CI workflow (ruff, pytest, architecture, docs)
- Add Gitea deployment documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:25:29 +01:00

7.9 KiB

Gitea CI/CD Deployment Guide

This document describes how to self-host Gitea on an external server and migrate CI/CD from GitLab to Gitea Actions (GitHub Actions-compatible).


Why Gitea?

  • Lightweight, self-hosted Git forge (single binary or Docker image)
  • Built-in CI/CD via Gitea Actions (GitHub Actions-compatible YAML)
  • Built-in migration tool imports repos, issues, and PRs from GitLab
  • Low resource usage compared to GitLab

1. Server Prerequisites

# Ubuntu/Debian
sudo apt update && sudo apt install -y docker.io docker-compose-plugin
sudo systemctl enable --now docker
sudo usermod -aG docker $USER   # log out/in after this

2. Gitea Server Setup (Docker Compose)

Create a directory on your server:

mkdir -p ~/gitea && cd ~/gitea

Create docker-compose.yml:

services:
  gitea:
    image: gitea/gitea:latest
    container_name: gitea
    restart: always
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - GITEA__database__DB_TYPE=postgres
      - GITEA__database__HOST=gitea-db:5432
      - GITEA__database__NAME=gitea
      - GITEA__database__USER=gitea
      - GITEA__database__PASSWD=<CHANGE_ME>
      - GITEA__server__ROOT_URL=https://git.yourdomain.com/
      - GITEA__server__SSH_DOMAIN=git.yourdomain.com
      - GITEA__server__DOMAIN=git.yourdomain.com
      - GITEA__actions__ENABLED=true
    volumes:
      - gitea-data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"   # Web UI
      - "2222:22"     # SSH (Git over SSH)
    depends_on:
      gitea-db:
        condition: service_healthy

  gitea-db:
    image: postgres:15
    container_name: gitea-db
    restart: always
    environment:
      POSTGRES_DB: gitea
      POSTGRES_USER: gitea
      POSTGRES_PASSWORD: <CHANGE_ME>
    volumes:
      - gitea-db-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U gitea"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Gitea Actions runner — executes CI workflows
  gitea-runner:
    image: gitea/act_runner:latest
    container_name: gitea-runner
    restart: always
    environment:
      GITEA_INSTANCE_URL: http://gitea:3000
      GITEA_RUNNER_REGISTRATION_TOKEN: <RUNNER_TOKEN>
      GITEA_RUNNER_NAME: default-runner
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - gitea-runner-data:/data
    depends_on:
      - gitea

volumes:
  gitea-data:
  gitea-db-data:
  gitea-runner-data:

!!! warning "Replace placeholders" Replace <CHANGE_ME> with a strong database password and <RUNNER_TOKEN> with the token from step 4.

Start Gitea and the database first:

docker compose up -d gitea gitea-db

Visit http://your-server-ip:3000 and complete the initial setup wizard.


3. Reverse Proxy with HTTPS (Nginx + Let's Encrypt)

sudo apt install -y nginx certbot python3-certbot-nginx

Create /etc/nginx/sites-available/gitea:

server {
    server_name git.yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        client_max_body_size 100M;
    }
}

Enable and get a certificate:

sudo ln -s /etc/nginx/sites-available/gitea /etc/nginx/sites-enabled/
sudo certbot --nginx -d git.yourdomain.com
sudo systemctl reload nginx

4. Enable Actions & Register the Runner

  1. Go to Site Administration > Runners in the Gitea web UI.
  2. Click Create new Runner and copy the registration token.
  3. Paste the token into docker-compose.yml as GITEA_RUNNER_REGISTRATION_TOKEN.
  4. Start the runner:
docker compose up -d gitea-runner

Verify the runner appears as Online in the admin panel.


5. Migrate Your Repository

Option A: Git push (code only)

# On your local machine
cd /path/to/letzshop-product-import
git remote add gitea ssh://git@git.yourdomain.com:2222/your-username/letzshop-product-import.git
git push gitea --all
git push gitea --tags

Option B: Gitea built-in migration (code + issues + PRs)

  1. In Gitea, click + > New Migration.
  2. Select GitLab as the source.
  3. Enter your GitLab URL and a Personal Access Token.
  4. Gitea will import the repository, issues, labels, milestones, and merge requests.

6. CI/CD — GitLab vs Gitea Actions

The workflow file lives in .gitea/workflows/ci.yml (already created in this repository).

GitLab CI (.gitlab-ci.yml) Gitea Actions (.gitea/workflows/ci.yml)
stages: + stage: per job Jobs run in parallel; use needs: for ordering
services: (top-level on job) services: nested under each job with options:
allow_failure: true continue-on-error: true
rules: - if: on: triggers + if: conditionals per job
artifacts: paths: actions/upload-artifact@v4
cache: paths: actions/cache@v4
coverage: '/regex/' Use coverage action or parse in step
CI/CD Variables (UI) Repository Settings > Secrets

7. CI/CD Secrets

Configure these in your Gitea repository under Settings > Actions > Secrets:

Secret Description Used by
SSH_PRIVATE_KEY Private key for deployment server Deploy job (if added)
SERVER_HOST Production server IP/hostname Deploy job
SERVER_USER SSH user on production server Deploy job
SERVER_PATH App directory on server Deploy job

8. Pipeline Overview

The CI pipeline (.gitea/workflows/ci.yml) runs:

push/PR to master
├── ruff          (lint)
├── pytest        (tests + PostgreSQL service)
├── architecture  (architecture validation)
├── dependency-scanning  (pip-audit, non-blocking)
├── audit         (custom audit, non-blocking)
└── docs          (mkdocs build, master-only, after lint+test pass)

All jobs run in parallel except docs, which waits for ruff, pytest, and architecture to pass.


9. Adding a Deploy Job (Optional)

To add automated deployment via SSH (similar to the GitLab deploy stage), add this job to .gitea/workflows/ci.yml:

  deploy:
    runs-on: ubuntu-latest
    if: github.event_name == 'push' && github.ref == 'refs/heads/master'
    needs: [ruff, pytest, architecture]
    steps:
      - uses: actions/checkout@v4

      - name: Deploy via SSH
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd ${{ secrets.SERVER_PATH }}
            git pull origin master
            source .venv/bin/activate
            uv sync --frozen
            python -m alembic upgrade head
            sudo systemctl restart wizamart

10. Firewall Configuration

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable

11. Maintenance

# View Gitea logs
docker compose -f ~/gitea/docker-compose.yml logs -f gitea

# View runner logs
docker compose -f ~/gitea/docker-compose.yml logs -f gitea-runner

# Update Gitea
cd ~/gitea
docker compose pull
docker compose up -d

# Backup Gitea data
docker run --rm -v gitea-data:/data -v $(pwd):/backup alpine \
    tar czf /backup/gitea-backup-$(date +%Y%m%d).tar.gz /data

12. Removing GitLab (After Migration)

Once you have verified everything works on Gitea:

  1. Update your local git remote:
    git remote set-url origin ssh://git@git.yourdomain.com:2222/your-username/letzshop-product-import.git
    
  2. The .gitlab-ci.yml file can be removed from the repository.
  3. Archive or delete the GitLab project.