Skip to main content

Overview

Gitea includes a comprehensive package registry that supports multiple package formats, enabling you to host and distribute your software packages alongside your source code. This integrated approach simplifies dependency management and distribution workflows.

Supported Package Types

Gitea supports a wide variety of package formats:

Container

Docker and OCI-compatible container images

npm

Node.js packages for JavaScript/TypeScript

Maven

Java packages and dependencies

PyPI

Python packages (pip)

NuGet

.NET packages

Go

Go modules

Cargo

Rust crates

Composer

PHP packages

RubyGems

Ruby gems

Helm

Kubernetes charts

Debian

.deb packages

RPM

.rpm packages

Package Type Implementation

// From models/packages/package.go
type Type string

const (
    TypeAlpine    Type = "alpine"
    TypeArch      Type = "arch"
    TypeCargo     Type = "cargo"
    TypeChef      Type = "chef"
    TypeComposer  Type = "composer"
    TypeConan     Type = "conan"
    TypeConda     Type = "conda"
    TypeContainer Type = "container"
    TypeCran      Type = "cran"
    TypeDebian    Type = "debian"
    TypeGeneric   Type = "generic"
    TypeGo        Type = "go"
    TypeHelm      Type = "helm"
    TypeMaven     Type = "maven"
    TypeNpm       Type = "npm"
    TypeNuGet     Type = "nuget"
    TypePub       Type = "pub"
    TypePyPI      Type = "pypi"
    TypeRpm       Type = "rpm"
    TypeRubyGems  Type = "rubygems"
    TypeSwift     Type = "swift"
    TypeVagrant   Type = "vagrant"
)

Enabling Packages

1

Enable Package Registry

Instance administrators must enable packages in Gitea configuration:
[packages]
ENABLED = true
2

Configure Storage

Set up storage backend for package files (local, S3, etc.)
3

Set Quotas (Optional)

Configure storage quotas per user/organization:
[packages]
LIMIT_TOTAL_OWNER_SIZE = 10GB
LIMIT_SIZE_ALPINE = 1GB
LIMIT_SIZE_CARGO = 2GB
LIMIT_SIZE_COMPOSER = 1GB
LIMIT_SIZE_CONTAINER = 5GB
LIMIT_SIZE_NPM = 2GB

Docker / Container Registry

Configuring Docker Client

# Login to Gitea container registry
docker login gitea.example.com

# Enter username and password/token

Multi-Architecture Images

# Build multi-arch image
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 \
  -t gitea.example.com/username/myapp:latest \
  --push .

npm Packages

Publishing npm Packages

1

Configure npm Client

# Set registry for scope
npm config set @username:registry https://gitea.example.com/api/packages/username/npm/

# Or configure in .npmrc
echo "@username:registry=https://gitea.example.com/api/packages/username/npm/" >> .npmrc
2

Authenticate

# Login to Gitea npm registry
npm login --scope=@username --registry=https://gitea.example.com/api/packages/username/npm/
3

Publish Package

# Publish package
npm publish

Installing npm Packages

# Install from Gitea registry
npm install @username/package-name

# Install specific version
npm install @username/[email protected]

Maven Packages

Publishing Maven Packages

Configure pom.xml:
<project>
  <distributionManagement>
    <repository>
      <id>gitea</id>
      <name>Gitea Maven Repository</name>
      <url>https://gitea.example.com/api/packages/username/maven</url>
    </repository>
  </distributionManagement>
</project>
Configure ~/.m2/settings.xml:
<settings>
  <servers>
    <server>
      <id>gitea</id>
      <username>your-username</username>
      <password>your-token</password>
    </server>
  </servers>
</settings>
Deploy package:
mvn deploy

Using Maven Packages

<repositories>
  <repository>
    <id>gitea</id>
    <url>https://gitea.example.com/api/packages/username/maven</url>
  </repository>
</repositories>

<dependencies>
  <dependency>
    <groupId>com.example</groupId>
    <artifactId>mylib</artifactId>
    <version>1.0.0</version>
  </dependency>
</dependencies>

Python / PyPI Packages

Publishing Python Packages

1

Install Twine

pip install twine
2

Build Package

python setup.py sdist bdist_wheel
3

Configure .pypirc

[distutils]
index-servers = gitea

[gitea]
repository = https://gitea.example.com/api/packages/username/pypi
username = your-username
password = your-token
4

Upload Package

twine upload -r gitea dist/*

Installing Python Packages

# Install from Gitea
pip install --index-url https://gitea.example.com/api/packages/username/pypi/simple package-name

# Or configure in pip.conf
[global]
index-url = https://gitea.example.com/api/packages/username/pypi/simple

NuGet Packages

Publishing NuGet Packages

# Add source
dotnet nuget add source https://gitea.example.com/api/packages/username/nuget/index.json \
  --name gitea \
  --username your-username \
  --password your-token

# Pack project
dotnet pack

# Push package
dotnet nuget push package.nupkg --source gitea

Installing NuGet Packages

# Install package
dotnet add package PackageName --source gitea

Go Modules

Using Go Packages

Gitea automatically serves Go modules from repository:
# Set GOPROXY to use Gitea
export GOPROXY=https://gitea.example.com/api/packages/username/go,direct

# Import in go.mod
import "gitea.example.com/username/package"

# Install dependencies
go get gitea.example.com/username/[email protected]

Package Management

Package Creation Flow

// From services/packages/packages.go
type PackageCreationInfo struct {
    PackageInfo
    SemverCompatible  bool
    Creator           *user_model.User
    Metadata          any
    PackageProperties map[string]string
    VersionProperties map[string]string
}

func CreatePackageAndAddFile(ctx context.Context, 
                             pvci *PackageCreationInfo, 
                             pfci *PackageFileCreationInfo) (
    *packages_model.PackageVersion, 
    *packages_model.PackageFile, 
    error) {
    
    return createPackageAndAddFile(ctx, pvci, pfci, false)
}

func createPackageAndAddFile(ctx context.Context, 
                            pvci *PackageCreationInfo, 
                            pfci *PackageFileCreationInfo, 
                            allowDuplicate bool) (
    *packages_model.PackageVersion, 
    *packages_model.PackageFile, 
    error) {
    
    // Create package version
    pv, created, err := createPackageAndVersion(ctx, pvci, allowDuplicate)
    if err != nil {
        return nil, nil, err
    }
    
    // Add file to package
    pf, pb, blobCreated, err := addFileToPackageVersion(ctx, pv, 
                                                        &pvci.PackageInfo, pfci)
    return pv, pf, err
}

Viewing Packages

  • Navigate to Packages tab in repository
  • View all packages in the repository
  • See package versions
  • Download package files

Package Versions

Version Management

Semantic Versioning

  • Follow semver (v1.2.3)
  • Major.Minor.Patch
  • Pre-release tags (v1.0.0-beta.1)
  • Build metadata (v1.0.0+build.123)

Version Operations

  • View all versions
  • Download specific versions
  • Delete old versions
  • View version metadata

Version Listing

# List all versions of a package
curl https://gitea.example.com/api/packages/username/npm/@scope/package

# View specific version details
curl https://gitea.example.com/api/packages/username/npm/@scope/package/1.0.0

Authentication

Token-Based Authentication

Create access tokens for package operations:
1

Generate Token

Navigate to SettingsApplicationsGenerate New Token
2

Select Scopes

Choose appropriate scopes:
  • read:package - Read packages
  • write:package - Publish packages
  • delete:package - Delete packages
3

Use Token

Use token in package client configuration instead of password

Package Cleanup

Cleanup Rules

Automate package cleanup to manage storage:
Retention Policies
  • Keep N most recent versions
  • Delete versions older than X days
  • Keep versions matching pattern
  • Delete untagged container images
Configuration Example
[packages]
CLEANUP_ENABLED = true
CLEANUP_INTERVAL = 24h
RETENTION_DAYS = 90
KEEP_COUNT = 10
Manual Cleanup
  • Delete individual versions
  • Delete entire packages
  • Bulk deletion operations
  • Cleanup orphaned files

Storage Quotas

Control package storage usage:

User Quotas

  • Total storage limit per user
  • Per-package-type limits
  • Soft and hard limits
  • Quota warnings

Organization Quotas

  • Organization-wide limits
  • Shared among members
  • Per-package-type limits
  • Usage monitoring

Package Visibility

  • Accessible without authentication
  • Listed in public package index
  • Can be used by anyone
  • Promotes open source sharing

Package API

REST API Endpoints

# List packages
GET /api/v1/packages/{owner}

# Get package details
GET /api/v1/packages/{owner}/{type}/{name}/{version}

# Delete package version
DELETE /api/v1/packages/{owner}/{type}/{name}/{version}

# List package files
GET /api/v1/packages/{owner}/{type}/{name}/{version}/files

Integration with Actions

Publish packages automatically with Gitea Actions:
name: Publish Package

on:
  release:
    types: [published]

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          registry-url: 'https://gitea.example.com/api/packages/username/npm/'
      
      - run: npm ci
      - run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.GITEA_TOKEN }}

Best Practices

Versioning
  • Follow semantic versioning
  • Tag releases in Git
  • Document breaking changes
  • Use pre-release versions for testing
Security
  • Use access tokens, not passwords
  • Rotate tokens regularly
  • Set appropriate visibility
  • Scan for vulnerabilities
  • Sign packages when possible
Organization
  • Use consistent naming conventions
  • Add package descriptions
  • Include README files
  • Link to source repository
  • Document dependencies
Storage Management
  • Configure cleanup rules
  • Monitor storage usage
  • Delete unused packages
  • Archive old versions
  • Use external storage for large packages

Troubleshooting

Authentication Issues

  • Verify token has correct scopes
  • Check token expiration
  • Confirm username/token format
  • Review registry URL

Publishing Failures

  • Check package format
  • Verify version doesn’t exist
  • Confirm storage quota
  • Review package size limits

See Also

Build docs developers (and LLMs) love