Talos/GITEA_CONTAINER_REGISTRY.md
0xWheatyz 6d280f6773 docs: add comprehensive Gitea container registry guide
Add detailed documentation for using Gitea's built-in container
registry with Gitea Actions for automated Docker image builds.

New documentation:
- GITEA_CONTAINER_REGISTRY.md: Complete guide covering:
  - Enabling and configuring container registry
  - Authentication for Docker CLI and CI/CD
  - Automated builds with Gitea Actions workflows
  - Using registry images in Kubernetes deployments
  - FluxCD integration with Gitea registry
  - Troubleshooting common issues
  - Best practices for tagging and security

Updates to CLAUDE.md:
- Added reference to GITEA_CONTAINER_REGISTRY.md in repo structure
- Added Container Registry section to Gitea deployment docs
- Included quick reference for registry login and usage

This enables complete GitOps CI/CD pipelines with Gitea similar
to GitLab Container Registry functionality.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-04 02:59:05 +00:00

10 KiB

Gitea Container Registry Guide

This guide explains how to use the Gitea Container Registry with Gitea Actions for automated Docker image builds and deployments.

Overview

Gitea includes a built-in container registry (via the Packages feature) that supports Docker/OCI images. Combined with Gitea Actions, this provides a complete CI/CD pipeline similar to GitLab CI/CD with Container Registry.

Enabling Container Registry

Check if Enabled

  1. Access Gitea UI at http://10.0.1.10
  2. Go to any repository
  3. Look for "Packages" tab
  4. If visible, registry is enabled

Enable via Configuration (if needed)

If the container registry is not enabled, update Gitea configuration:

  1. Access the Gitea pod:

    kubectl exec -it -n gitea deployment/gitea -- sh
    
  2. Edit app.ini:

    vi /data/gitea/conf/app.ini
    
  3. Add/update the following section:

    [packages]
    ENABLED = true
    
  4. Restart Gitea:

    kubectl rollout restart deployment/gitea -n gitea
    

Using the Container Registry

Authentication

For Developers (Docker CLI)

# Log in to registry
docker login 10.0.1.10 -u your-username

# When prompted, enter your Gitea password or personal access token

For CI/CD (Gitea Actions)

Create a personal access token:

  1. Gitea UI → User Settings → Applications → Access Tokens
  2. Click "Generate New Token"
  3. Name: "CI/CD Container Registry"
  4. Select scopes:
    • write:package
    • read:package
  5. Generate and copy the token

Add as repository secret:

  1. Repository → Settings → Secrets
  2. Add secret: GITEA_TOKEN = <your-token>

Push Images Manually

# Log in
docker login 10.0.1.10 -u your-username

# Tag your image
docker tag my-app:latest 10.0.1.10/your-username/my-repo:latest

# Push to registry
docker push 10.0.1.10/your-username/my-repo:latest

Pull Images

# Public images (no auth needed)
docker pull 10.0.1.10/username/repo:tag

# Private images (auth required)
docker login 10.0.1.10 -u your-username
docker pull 10.0.1.10/username/repo:tag

Automated Builds with Gitea Actions

Basic Workflow

Create .gitea/workflows/build.yaml:

name: Build and Push Docker Image

on:
  push:
    branches:
      - main
    tags:
      - '*'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set image tags
        id: tags
        run: |
          REGISTRY="10.0.1.10"
          IMAGE="${REGISTRY}/${{ gitea.repository }}"
          echo "IMAGE_TAG=${IMAGE}:${{ gitea.sha_short }}" >> $GITHUB_OUTPUT
          echo "IMAGE_LATEST=${IMAGE}:latest" >> $GITHUB_OUTPUT          

      - name: Log in to registry
        run: |
          echo "${{ secrets.GITEA_TOKEN }}" | docker login 10.0.1.10 -u "${{ gitea.actor }}" --password-stdin          

      - name: Build and push
        run: |
          docker build -t ${{ steps.tags.outputs.IMAGE_TAG }} -t ${{ steps.tags.outputs.IMAGE_LATEST }} .
          docker push ${{ steps.tags.outputs.IMAGE_TAG }}
          docker push ${{ steps.tags.outputs.IMAGE_LATEST }}          

Advanced Workflow with Multi-stage Build

name: Build Multi-platform Image

on:
  push:
    branches: [main]
    tags: ['v*']

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to registry
        run: |
          echo "${{ secrets.GITEA_TOKEN }}" | docker login 10.0.1.10 -u "${{ gitea.actor }}" --password-stdin          

      - name: Build and push
        run: |
          IMAGE="10.0.1.10/${{ gitea.repository }}"
          docker buildx build \
            --platform linux/amd64,linux/arm64 \
            -t ${IMAGE}:${{ gitea.sha_short }} \
            -t ${IMAGE}:latest \
            --push .          

Using Images in Kubernetes

Pull from Gitea Registry in Deployments

Public Images (No Authentication)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  template:
    spec:
      containers:
      - name: app
        image: 10.0.1.10/username/my-app:latest

Private Images (With Authentication)

  1. Create a Docker registry secret:

    kubectl create secret docker-registry gitea-registry \
      --docker-server=10.0.1.10 \
      --docker-username=your-username \
      --docker-password=your-token \
      -n your-namespace
    
  2. Reference in deployment:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-app
    spec:
      template:
        spec:
          imagePullSecrets:
          - name: gitea-registry
          containers:
          - name: app
            image: 10.0.1.10/username/my-app:latest
    

GitOps Deployment with FluxCD

FluxCD can monitor and deploy images from Gitea registry:

# image-repository.yaml
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata:
  name: my-app
  namespace: flux-system
spec:
  image: 10.0.1.10/username/my-app
  interval: 1m
  secretRef:
    name: gitea-registry
---
# image-policy.yaml
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
  name: my-app
  namespace: flux-system
spec:
  imageRepositoryRef:
    name: my-app
  policy:
    semver:
      range: '>=1.0.0'

Registry Management

View Packages

  1. Go to repository in Gitea UI
  2. Click "Packages" tab
  3. See all published container images

Delete Images

  1. Repository → Packages
  2. Click on the package
  3. Click on specific version
  4. Click "Delete"

View Package Details

Each package shows:

  • Image tags
  • Size
  • Published date
  • Pull commands

Troubleshooting

Cannot Push: 404 Not Found

Issue: Registry not enabled

Solution:

kubectl exec -it -n gitea deployment/gitea -- sh
vi /data/gitea/conf/app.ini
# Add: [packages] ENABLED = true
kubectl rollout restart deployment/gitea -n gitea

Cannot Push: 401 Unauthorized

Issue: Invalid credentials

Solutions:

  • Verify username and password/token
  • Regenerate personal access token
  • Check token scopes include write:package

Workflow Cannot Push

Issue: Missing or invalid GITEA_TOKEN secret

Solution:

  1. Generate personal access token with write:package scope
  2. Add as repository secret named GITEA_TOKEN
  3. Re-run workflow

Image Not Showing in Packages Tab

Issue: Push succeeded but package not visible

Solutions:

  • Refresh the page
  • Check if logged in as correct user
  • Verify repository permissions
  • Check Gitea logs: kubectl logs -n gitea deployment/gitea

Kubernetes Cannot Pull Image

Issue: ImagePullBackOff error

Solutions:

  1. Verify image name and tag are correct
  2. For private repos, create imagePullSecret:
    kubectl create secret docker-registry gitea-registry \
      --docker-server=10.0.1.10 \
      --docker-username=your-user \
      --docker-password=your-token \
      -n namespace
    
  3. Add imagePullSecrets to pod spec

Registry Running Out of Space

Issue: Gitea PVC full

Solutions:

  1. Check PVC usage:

    kubectl exec -n gitea deployment/gitea -- df -h /data
    
  2. Expand PVC:

    kubectl edit pvc gitea-data -n gitea
    # Increase spec.resources.requests.storage
    
  3. Clean up old images via Gitea UI

Best Practices

Tagging Strategy

  • Latest tag: Always update latest on main branch builds
  • Semantic versions: Use tags like v1.2.3 for releases
  • Commit SHA: Tag with short SHA for traceability
  • Branch names: Tag feature branches for testing

Security

  • Use personal access tokens instead of passwords
  • Limit token scopes to minimum required
  • Rotate tokens periodically
  • Use imagePullSecrets for private images in Kubernetes

Image Size Optimization

  • Use multi-stage builds
  • Use Alpine-based images where possible
  • Clean up package manager caches
  • Use .dockerignore to exclude unnecessary files

CI/CD Pipeline

  1. Build on every commit to main
  2. Tag with semantic version on git tags
  3. Run tests before building
  4. Scan images for vulnerabilities
  5. Deploy automatically via FluxCD

Example: Complete CI/CD Pipeline

name: Complete CI/CD Pipeline

on:
  push:
    branches: [main]
    tags: ['v*']
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run tests
        run: |
          pip install -r requirements.txt
          pytest          

  build:
    needs: test
    if: github.event_name == 'push'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set image tags
        id: tags
        run: |
          IMAGE="10.0.1.10/${{ gitea.repository }}"
          if [[ "${{ gitea.ref }}" == refs/tags/* ]]; then
            VERSION=${GITHUB_REF#refs/tags/}
            echo "IMAGE_TAG=${IMAGE}:${VERSION}" >> $GITHUB_OUTPUT
          else
            echo "IMAGE_TAG=${IMAGE}:${{ gitea.sha_short }}" >> $GITHUB_OUTPUT
          fi
          echo "IMAGE_LATEST=${IMAGE}:latest" >> $GITHUB_OUTPUT          

      - name: Build and push
        run: |
          echo "${{ secrets.GITEA_TOKEN }}" | docker login 10.0.1.10 -u "${{ gitea.actor }}" --password-stdin
          docker build -t ${{ steps.tags.outputs.IMAGE_TAG }} -t ${{ steps.tags.outputs.IMAGE_LATEST }} .
          docker push ${{ steps.tags.outputs.IMAGE_TAG }}
          docker push ${{ steps.tags.outputs.IMAGE_LATEST }}          

      - name: Update Kubernetes manifest
        if: github.ref == 'refs/heads/main'
        run: |
          # Update image tag in Kubernetes manifest
          sed -i "s|image:.*|image: ${{ steps.tags.outputs.IMAGE_TAG }}|" k8s/deployment.yaml
          git config user.name "Gitea Actions"
          git config user.email "actions@gitea.local"
          git add k8s/deployment.yaml
          git commit -m "chore: update image to ${{ steps.tags.outputs.IMAGE_TAG }}"
          git push          

References