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>
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
- Access Gitea UI at
http://10.0.1.10 - Go to any repository
- Look for "Packages" tab
- If visible, registry is enabled
Enable via Configuration (if needed)
If the container registry is not enabled, update Gitea configuration:
-
Access the Gitea pod:
kubectl exec -it -n gitea deployment/gitea -- sh -
Edit
app.ini:vi /data/gitea/conf/app.ini -
Add/update the following section:
[packages] ENABLED = true -
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:
- Gitea UI → User Settings → Applications → Access Tokens
- Click "Generate New Token"
- Name: "CI/CD Container Registry"
- Select scopes:
write:packageread:package
- Generate and copy the token
Add as repository secret:
- Repository → Settings → Secrets
- 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)
-
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 -
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
- Go to repository in Gitea UI
- Click "Packages" tab
- See all published container images
Delete Images
- Repository → Packages
- Click on the package
- Click on specific version
- 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:
- Generate personal access token with
write:packagescope - Add as repository secret named
GITEA_TOKEN - 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:
- Verify image name and tag are correct
- 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 - Add imagePullSecrets to pod spec
Registry Running Out of Space
Issue: Gitea PVC full
Solutions:
-
Check PVC usage:
kubectl exec -n gitea deployment/gitea -- df -h /data -
Expand PVC:
kubectl edit pvc gitea-data -n gitea # Increase spec.resources.requests.storage -
Clean up old images via Gitea UI
Best Practices
Tagging Strategy
- Latest tag: Always update
lateston main branch builds - Semantic versions: Use tags like
v1.2.3for 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
- Build on every commit to main
- Tag with semantic version on git tags
- Run tests before building
- Scan images for vulnerabilities
- 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