# 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: ```bash kubectl exec -it -n gitea deployment/gitea -- sh ``` 2. Edit `app.ini`: ```bash vi /data/gitea/conf/app.ini ``` 3. Add/update the following section: ```ini [packages] ENABLED = true ``` 4. Restart Gitea: ```bash kubectl rollout restart deployment/gitea -n gitea ``` ## Using the Container Registry ### Authentication #### For Developers (Docker CLI) ```bash # 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` = `` ### Push Images Manually ```bash # 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 ```bash # 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`: ```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 ```yaml 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) ```yaml 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: ```bash 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: ```yaml 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: ```yaml # 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**: ```bash 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: ```bash 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: ```bash kubectl exec -n gitea deployment/gitea -- df -h /data ``` 2. Expand PVC: ```bash 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 ```yaml 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 - [Gitea Packages Documentation](https://docs.gitea.com/usage/packages/overview) - [Gitea Actions Documentation](https://docs.gitea.com/usage/actions/overview) - [Docker Registry HTTP API](https://docs.docker.com/registry/spec/api/)