1. Quick Start
Gitea is a painless, self-hosted Git service written in Go. It provides repository hosting, issue tracking, pull requests, code review, CI/CD (Gitea Actions), a built-in package registry, wiki, and project boards — all in a single binary with minimal resource requirements.
Key features:
- Git repository hosting with web-based management
- Issues, pull requests, and code review workflows
- Gitea Actions (GitHub Actions-compatible CI/CD)
- Built-in package registry supporting 20+ formats
- Wiki, project boards, and release management
- Migration from GitHub, GitLab, Bitbucket, Gogs, and more
- LDAP, OAuth2, SMTP, and SAML authentication
- Webhook integrations (Slack, Discord, Telegram, Matrix, Microsoft Teams, and others)
Prerequisites: Git 2.0+, a supported database (SQLite for quick start, PostgreSQL/MySQL/MSSQL for production).
Fastest way to start (Docker):
docker run -d --name gitea -p 3000:3000 -p 2222:22 gitea/gitea:latest
...
Status: Downloaded newer image for gitea/gitea:latest
<container_id>
Open http://localhost:3000 in your browser to complete the initial setup wizard.
Tip
For a quick evaluation without Docker, download the pre-built binary for your platform from the Gitea downloads page and run
./gitea web. Gitea uses SQLite by default, so no external database is needed for testing.
What to try next:
- Create your first repository (see Core Usage below)
- Configure authentication (see Configuration)
- Set up Gitea Actions for CI/CD (see Common Tasks)
- See the Admin Guide for full configuration reference and deployment options
2. Installation
System Requirements
| Component | Minimum | Recommended |
|---|---|---|
| CPU | 1 core | 2+ cores |
| RAM | 512 MB | 1 GB+ |
| Disk | 1 GB | Depends on repository size |
| Git | 2.0+ | Latest stable |
| Database | SQLite 3 | PostgreSQL 12+ / MySQL 8.0+ / MSSQL 2012+ |
| OS | Linux, macOS, Windows, FreeBSD | Linux (amd64) |
Installation Methods
Docker
# Standard (root-based)
docker pull gitea/gitea:latest
docker run -d --name gitea \
-p 3000:3000 -p 2222:22 \
-v /opt/gitea/data:/data \
-v /etc/timezone:/etc/timezone:ro \
-v /etc/localtime:/etc/localtime:ro \
gitea/gitea:latest
Docker (Rootless)
docker pull gitea/gitea:latest-rootless
docker run -d --name gitea \
-p 3000:3000 -p 2222:2222 \
-v /opt/gitea/data:/var/lib/gitea \
-v /opt/gitea/config:/etc/gitea \
gitea/gitea:latest-rootless
Binary
# Download for your platform (example: Linux amd64)
wget -O gitea https://dl.gitea.com/gitea/latest/gitea-latest-linux-amd64
chmod +x gitea
./gitea web
Snap
sudo snap install gitea
Source
git clone https://github.com/go-gitea/gitea.git
cd gitea
TAGS="bindata sqlite sqlite_unlock_notify" make build
./gitea web
Important
When building from source, the
bindatabuild tag embeds web assets into the binary. Without it, Gitea expects assets in the working directory. For production deployments, always build withbindata.
Post-Install Verification
gitea --version
Gitea version 1.26.0 built with go1.26.2 : bindata, sqlite, sqlite_unlock_notify
Then open http://localhost:3000 to access the web-based initial configuration wizard. The wizard will guide you through database setup, admin account creation, and basic settings.
Install Troubleshooting
Error: installed git version is not supported, Gitea requires git version >= 2.0
Cause: Your system Git is too old.
Solution:
- Update Git to version 2.0 or later
- Verify with
git --version
Prevention: Use a package manager that provides current Git versions.
Error: unable to prepare git home directory
Cause: Gitea cannot write to the Git home directory.
Solution:
- Ensure the Gitea process user has write access to the configured home directory
- Check directory permissions:
ls -la /path/to/gitea-home
Prevention: Run Gitea under a dedicated service account with appropriate directory permissions.
Error: LFS server support requires Git >= 2.1.2
Cause: Git LFS features require a newer Git version.
Solution:
- Upgrade Git to 2.1.2 or later
- If you do not need LFS, disable it in configuration
Prevention: Keep Git updated to the latest stable release.
Error: Port 3000 already in use
Cause: Another service is using the default Gitea port.
Solution:
- Stop the conflicting service, or
- Change Gitea's port: set
HTTP_PORTin[server]section ofapp.ini
Prevention: Choose a unique port during initial setup.
Error: Database connection failed
Cause: Database is not running, credentials are wrong, or network is unreachable.
Solution:
- Verify the database service is running
- Check the connection string in
[database]section ofapp.ini - Test connectivity manually (e.g.,
psqlfor PostgreSQL)
Prevention: Verify database access before starting Gitea.
3. Configuration
Gitea uses an INI-format configuration file located at {WorkPath}/custom/conf/app.ini. On first run, the web installer creates this file. You can also override settings via environment variables using the prefix GITEA__SECTION__KEY.
Essential Settings
[server]
HTTP_PORT = 3000
DOMAIN = git.example.com
ROOT_URL = https://git.example.com/
SSH_DOMAIN = git.example.com
[database]
DB_TYPE = postgres
HOST = 127.0.0.1:5432
NAME = gitea
USER = gitea
PASSWD = your_password
[repository]
ROOT = /data/gitea/repositories
Note
ROOT_URLmust match how users access Gitea externally. If behind a reverse proxy with HTTPS, setROOT_URL = https://git.example.com/.
Common Configuration Combinations
| Goal | Settings |
|---|---|
| HTTPS via reverse proxy | [server] PROTOCOL = http, configure reverse proxy for TLS |
| Built-in HTTPS | [server] PROTOCOL = https, CERT_FILE, KEY_FILE |
| Change SSH port | [server] SSH_PORT = 2222 |
| Disable registration | [service] DISABLE_REGISTRATION = true |
| Enable Gitea Actions | [actions] ENABLED = true (enabled by default) |
| Use S3 for storage | [storage] STORAGE_TYPE = minio with endpoint/bucket/keys |
Environment Variable Overrides
Any app.ini setting can be overridden via environment variables:
# Pattern: GITEA__SECTION__KEY=value
GITEA__database__DB_TYPE=postgres
GITEA__server__HTTP_PORT=8080
GITEA__service__DISABLE_REGISTRATION=true
Tip
Environment variable overrides are useful for Docker deployments and CI environments where you want to inject configuration without modifying the config file. Special characters in section or key names can be hex-encoded:
_0X2E_for.,_0X2D_for-.
For the complete configuration reference with every section, key, and default value, see the Admin Guide.
4. Core Usage
Creating and Managing Repositories
Create a new repository:
- Click + in the navigation bar and select New Repository
- Fill in the repository name, description, and visibility (public/private)
- Optionally initialize with a README, .gitignore, and license
- Click Create Repository
Clone a repository:
# HTTPS
git clone https://git.example.com/username/repo.git
# SSH
git clone [email removed]:username/repo.git
Cloning into 'repo'...
remote: Enumerating objects: 42, done.
Fork a repository: Click the Fork button on any repository page to create your own copy.
Mirror a repository: When creating a repository, select New Migration to mirror from an external source. Gitea supports push and pull mirrors that sync automatically.
Issues and Issue Tracking
- Create issues from the repository Issues tab
- Use labels, milestones, and assignees to organize work
- Reference issues in commits with
#123syntax (auto-linked) - Close issues automatically with commit messages:
Closes #123,Fixes #456 - Use issue templates (placed in
.gitea/issue_template/or.github/issue_template/) for structured reporting - Track time on issues with the built-in time tracker
Note
Gitea supports Markdown in all text fields, including GitHub-flavored Markdown extensions like task lists (
- [x] Done), tables, and fenced code blocks with syntax highlighting.
Pull Requests and Code Review
- Push a feature branch to your fork or the same repository
- Click New Pull Request and select the source and target branches
- Add a title, description, labels, and reviewers
- Reviewers can approve, request changes, or leave comments
- Use inline code comments for line-specific feedback
- Merge when reviews pass (merge, rebase, squash, or fast-forward strategies available)
Auto-merge: Enable auto-merge on a pull request so it merges automatically once all required reviews and status checks pass.
Warning
Branch protection rules must be configured by repository admins to enforce review requirements. Without protection rules, any user with write access can push directly to the target branch.
Gitea Actions (CI/CD)
Gitea Actions is a built-in CI/CD system compatible with GitHub Actions workflow syntax. Workflows are defined in .gitea/workflows/ or .github/workflows/ directories.
Example workflow (.gitea/workflows/ci.yml):
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- run: go test ./...
Register a runner:
# Generate a runner registration token
gitea actions generate-runner-token --scope owner/repo
# Or generate a global token
gitea actions generate-runner-token
<runner_registration_token>
Tip
The
GITEA_RUNNER_REGISTRATION_TOKENenvironment variable can also be set to auto-register runners at startup. By default, Gitea resolves action references from GitHub (DEFAULT_ACTIONS_URL = github). SetDEFAULT_ACTIONS_URL = selfin[actions]to use your own Gitea instance as the action source.
Skip workflows: Include any of these strings in a commit message to skip workflow execution: [skip ci], [ci skip], [no ci], [skip actions], [actions skip].
Wiki
Each repository can have an associated wiki. Access it from the Wiki tab.
- Create and edit pages using Markdown
- Wiki content is stored as a separate Git repository (
repo.wiki.git) - Clone and edit wikis locally with Git
Projects (Kanban Boards)
Organize work with project boards at the repository or organization level:
- Go to Projects and create a new project
- Add columns (e.g., To Do, In Progress, Done)
- Link issues and pull requests to the project
- Drag cards between columns to update status
Package Registry
Gitea includes a built-in package registry supporting many formats:
| Format | Path |
|---|---|
| Generic | /api/packages/{owner}/generic/ |
| npm | /api/packages/{owner}/npm/ |
| PyPI | /api/packages/{owner}/pypi/ |
| Maven | /api/packages/{owner}/maven/ |
| NuGet | /api/packages/{owner}/nuget/ |
| Cargo | /api/packages/{owner}/cargo/ |
| Container (OCI) | /v2/{owner}/ |
| Composer | /api/packages/{owner}/composer/ |
| Conan | /api/packages/{owner}/conan/ |
| Conda | /api/packages/{owner}/conda/ |
| Chef | /api/packages/{owner}/chef/ |
| Helm | /api/packages/{owner}/helm/ |
| Vagrant | /api/packages/{owner}/vagrant/ |
| RubyGems | /api/packages/{owner}/rubygems/ |
| Debian | /api/packages/{owner}/debian/ |
| RPM | /api/packages/{owner}/rpm/ |
| Alpine | /api/packages/{owner}/alpine/ |
| Swift | /api/packages/{owner}/swift/ |
| Go | /api/packages/{owner}/go/ |
| CRAN | /api/packages/{owner}/cran/ |
| Pub | /api/packages/{owner}/pub/ |
| Terraform | /api/packages/{owner}/terraform/ |
Note
Package registry authentication uses the same API tokens as the REST API. Generate a personal access token from User Settings > Applications.
Releases
Create releases from the repository Releases tab:
- Click New Release
- Choose or create a tag
- Add a title, description, and optional file attachments
- Mark as pre-release if applicable
- Publish
Releases automatically generate source code archives (.tar.gz and .zip).
Repository Migration
Migrate repositories from other platforms:
- Click + > New Migration
- Select the source platform (GitHub, GitLab, Gitea, Gogs, Bitbucket, OneDev, CodeCommit, Codebase)
- Enter the clone URL and authentication credentials
- Select what to migrate: issues, pull requests, labels, milestones, releases, wiki
- Click Migrate Repository
Organizations and Teams
- Create organizations to group repositories and manage team access
- Teams have configurable permissions per repository or across all organization repositories
- Invite members to organizations and assign them to teams
Webhooks
Configure webhooks from repository, organization, or system settings:
| Service | Description |
|---|---|
| Gitea | Generic Gitea webhook |
| Gogs | Gogs-compatible webhook |
| Slack | Slack channel notifications |
| Discord | Discord channel notifications |
| Telegram | Telegram bot notifications |
| Microsoft Teams | Teams channel notifications |
| Matrix | Matrix room notifications |
| Feishu/Lark | Feishu notifications |
| DingTalk | DingTalk notifications |
| WeCom/WeChatWork | WeCom notifications |
| Packagist | Packagist update trigger |
5. Common Tasks
Task: Set Up a Complete CI/CD Pipeline with Gitea Actions
Goal: Automatically test and build on every push and pull request.
Prerequisites: A running Gitea instance with Actions enabled; at least one registered runner.
Steps:
- Create
.gitea/workflows/ci.ymlin your repository:
name: CI Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: make build
- name: Test
run: make test
- Push the workflow file to your repository
- Verify the workflow runs in the Actions tab
If it fails: Check that a runner is registered and online. Verify the runner can pull the action images.
Task: Migrate a Repository from GitHub
Goal: Move a repository including issues, PRs, and wiki from GitHub.
Prerequisites: A GitHub personal access token with repo scope.
Steps:
- In Gitea, click + > New Migration
- Select GitHub as the source
- Enter the repository URL (e.g.,
https://github.com/owner/repo) - Enter your GitHub access token
- Check the items to migrate (issues, labels, milestones, pull requests, releases, wiki)
- Click Migrate Repository
Verify: Check that issues, PRs, and wiki content appear correctly.
If it fails: Ensure the token has sufficient permissions. For private repositories, the token needs repo scope.
Task: Configure LDAP Authentication
Goal: Allow users to sign in with their LDAP/Active Directory credentials.
Prerequisites: Access to the Gitea admin panel and LDAP server details.
Steps via CLI:
gitea admin auth add-ldap \
--name "Corporate LDAP" \
--security-protocol ldaps \
--host ldap.example.com \
--port 636 \
--user-search-base "ou=Users,dc=example,dc=com" \
--user-filter "(&(objectClass=person)(uid=%[1]s))" \
--email-attribute mail
Steps via Web UI:
- Go to Site Administration > Authentication Sources
- Click Add Authentication Source
- Select LDAP (via BindDN) or LDAP (Simple Auth)
- Fill in the connection details
- Click Add Authentication Source
Verify: Log out and sign in with an LDAP user account.
Task: Set Up Email Notifications
Goal: Enable email delivery for repository events.
Steps:
- Configure the mailer in
app.ini:
[mailer]
ENABLED = true
SMTP_ADDR = smtp.example.com
SMTP_PORT = 587
FROM = [email removed]
USER = [email removed]
PASSWD = your_smtp_password
- Restart Gitea
- Users can configure their notification preferences in User Settings > Notifications
Verify: Create a test issue and confirm the assignee receives an email.
Task: Push a Container Image to the Package Registry
Goal: Push a Docker/OCI container image to Gitea's built-in registry.
Steps:
- Log in to the registry:
docker login git.example.com
- Tag and push:
docker tag myimage:latest git.example.com/username/myimage:latest
docker push git.example.com/username/myimage:latest
The push refers to repository [git.example.com/username/myimage]
latest: digest: sha256:abc123... size: 1234
Verify: Check the Packages tab in your user profile or organization.
Task: Create a Repository Mirror
Goal: Keep a read-only mirror of an external repository synchronized.
Steps:
- Click + > New Migration
- Enter the source repository URL
- Check This repository will be a mirror
- Set the mirror interval (default: 8 hours)
- Click Migrate Repository
Verify: Check the repository page — it should show a "Mirror" badge.
Task: Set Up SSH Key Authentication
Goal: Push and pull via SSH without entering a password each time.
Steps:
- Generate an SSH key if you don't have one:
ssh-keygen -t ed25519 -C "[email removed]"
- Copy the public key:
cat ~/.ssh/id_ed25519.pub
- In Gitea, go to User Settings > SSH / GPG Keys
- Click Add Key, paste the public key, and save
- Clone using the SSH URL:
git clone [email removed]:username/repo.git
Task: Protect a Branch
Goal: Prevent direct pushes to the main branch and require pull request reviews.
Steps:
- Go to repository Settings > Branches
- Click Add New Rule
- Set the branch name pattern (e.g.,
main) - Enable desired protections:
- Require pull request reviews
- Require status checks to pass
- Block force pushes
- Restrict who can push
- Click Save
Task: Run the Gitea Doctor
Goal: Diagnose and fix common issues with your Gitea instance.
gitea doctor check
...
[I] Checking database version
[I] Checking if OpenSSH authorized_keys file is up to date
[I] Checking for incorrectly set repository permissions
[I] All checks passed
Tip
Run
gitea doctor check --fixto automatically repair issues where possible. Always back up your data first.
Task: Export/Dump Your Gitea Instance
Goal: Create a full backup of your Gitea data.
gitea dump --type zip
2026/05/06 12:00:00 ...creating dump archive gitea-dump-1234567890.zip
2026/05/06 12:00:05 ...done
This creates an archive containing the database, repositories, configuration, log files, and custom data.
Task: Use the REST API
Goal: Automate Gitea operations via the API.
Steps:
- Generate a personal access token in User Settings > Applications
- Use the token in API requests:
curl -H "Authorization: token YOUR_TOKEN" \
https://git.example.com/api/v1/repos/search?q=myproject
{
"ok": true,
"data": [
{
"id": 1,
"name": "myproject",
"full_name": "username/myproject"
}
]
}
Note
Full API documentation is available at
https://your-gitea-instance/api/swaggerwhen Swagger is enabled (enabled by default).
6. Troubleshooting
Diagnostic Decision Tree
Gitea not starting?
├── Check logs: gitea web --log-level debug
├── Config file readable? → Check permissions on app.ini
├── Database reachable? → Test connection string manually
├── Port conflict? → Check with netstat/ss
└── Git version? → gitea doctor check
Web UI issues?
├── Blank page → Check ROOT_URL matches actual access URL
├── 502 error → Reverse proxy misconfiguration
├── Assets missing → Missing bindata tag in build
└── CSP errors → Check Content-Security-Policy headers
Git push/pull failures?
├── SSH: Check SSH keys in Gitea UI
├── HTTPS: Verify credentials / token
├── LFS: Check LFS storage configuration
└── Permissions: Check repository access rights
Error: Workflow Post-Run Steps Not Executed When Workflow is Cancelled
Cause: When a Gitea Actions workflow is cancelled, post-run cleanup steps may not execute. This is a known issue (go-gitea/gitea#36983).
Solution:
- Ensure critical cleanup is performed by separate jobs that are not dependent on the cancelled job
- Monitor the issue for upstream fixes
Prevention: Design workflows with independent cleanup jobs where possible.
Error: CSP bug: Missing 'wasm-unsafe-eval' or 'unsafe-eval' when opening .cast files
Cause: The Content Security Policy headers do not include the required directives for rendering asciicast files (go-gitea/gitea#37257).
Solution:
- Add
wasm-unsafe-evalto your CSP configuration if using a custom CSP - Wait for an upstream fix if using default CSP
Error: GetCompareInfo, AddRemote: exit status 128 - error: could not lock config file
Cause: Concurrent Git operations can cause lock contention on the config file (go-gitea/gitea#32018).
Solution:
- Retry the operation after a short wait
- Check for zombie Git processes:
ps aux | grep git - Remove stale lock files if present:
rm -f /path/to/repo/.git/config.lock
Prevention: Ensure adequate system resources. Consider upgrading to a version with improved locking.
Error: CODEOWNERS file doesn't support absolute paths
Cause: Gitea's CODEOWNERS implementation requires relative paths (go-gitea/gitea#28107).
Solution: Use relative paths in your CODEOWNERS file instead of absolute paths starting with /.
Error: Database migration failure
Cause: Interrupted upgrades or incompatible schema changes.
Solution:
- Back up your database before upgrading
- Run
gitea migrateto apply pending migrations - Check logs for specific migration errors
Prevention: Always back up before upgrading Gitea versions.
Error: SSH connection refused
Cause: SSH service is not running or port is blocked.
Solution:
- Verify SSH is enabled in
app.ini:[server] START_SSH_SERVER = true - Check the configured SSH port:
[server] SSH_PORT - Verify firewall rules allow the SSH port
Error: git archive wrong error if repo missed
Cause: Attempting to create a Git archive for a repository that does not exist produces a confusing error (go-gitea/gitea#23425).
Solution: Verify the repository exists and is accessible before attempting archive operations.
Warning
Always back up your Gitea data and database before performing upgrades, migrations, or running
gitea doctor check --fix. Usegitea dumpto create a full backup.
Error: Webhook delivery failures
Cause: Target URL is unreachable, returns errors, or times out.
Solution:
- Check the webhook delivery log in repository Settings > Webhooks > select the webhook > Recent Deliveries
- Verify the target URL is accessible from the Gitea server
- Check for TLS certificate issues if using HTTPS
Error: indexer is not ready
Cause: The search indexer has not finished initializing, or it crashed.
Solution:
- Wait for indexer initialization to complete (check logs)
- If persistent, rebuild the index: delete the indexer data directory and restart Gitea
- Check disk space — indexers require significant storage for large instances
Prevention: Ensure adequate disk space for the configured indexer type.
Caution
Deleting the indexer data directory forces a full re-index, which can take a long time on large instances. Schedule this during a maintenance window.
7. FAQ
Q: What databases does Gitea support?
Gitea supports SQLite, PostgreSQL, MySQL/MariaDB, and Microsoft SQL Server. SQLite is suitable for small deployments and evaluation. PostgreSQL is recommended for production use.
Q: Can I migrate from Gogs to Gitea?
Yes. Gitea started as a fork of Gogs, and many Gogs instances can be upgraded directly. Gitea also supports migrating repositories from Gogs via the migration tool (including issues and other metadata).
Q: Does Gitea support GitHub Actions?
Yes. Gitea Actions is compatible with the GitHub Actions workflow syntax. You can use .github/workflows/ or .gitea/workflows/ directories for your workflow definitions. Most GitHub Actions marketplace actions work with Gitea Actions. You need at least one runner registered to execute workflows.
Q: How do I reset an admin password?
Use the CLI:
gitea admin user change-password --username admin --password new_password
Q: Can Gitea be run behind a reverse proxy?
Yes. Set ROOT_URL to your external URL and configure your reverse proxy (nginx, Caddy, Apache, Traefik) to forward requests. See the Admin Guide for detailed reverse proxy configuration.
Q: How do I enable dark mode?
Go to User Settings > Appearance and select a dark theme. Gitea supports multiple themes including gitea-dark.
Q: What is the maximum file attachment size?
By default, the maximum attachment size is 100 MB with a limit of 5 files per upload. These can be configured in the [attachment] section:
[attachment]
MAX_SIZE = 100
MAX_FILES = 5
ALLOWED_TYPES = .avif,.csv,.docx,.gif,.gz,.jpeg,.jpg,.json,.log,.md,.mov,.mp4,.pdf,.png,.svg,.tgz,.txt,.webm,.webp,.xls,.xlsx,.zip
Q: Does Gitea support two-factor authentication (2FA)?
Yes. Users can enable TOTP-based 2FA or WebAuthn/FIDO2 security keys from User Settings > Security. Admins can require 2FA for all users.
Q: How do I customize Gitea's appearance?
Place custom files in the custom/ directory:
custom/templates/— Override Go templatescustom/public/— Custom static assets (CSS, JS, images)custom/options/label/— Custom issue label setscustom/options/locale/— Custom translations
Q: Can Gitea send email notifications?
Yes. Configure the [mailer] section in app.ini with your SMTP server details. Users can then configure their notification preferences per-repository.
Q: Where are Gitea's logs?
By default, logs are written to {WorkPath}/log/. The log level and output can be configured in the [log] section of app.ini.
Q: How do I upgrade Gitea?
- Back up your data:
gitea dump - Stop the running instance
- Replace the binary with the new version
- Run
gitea migrateto apply database migrations - Start Gitea
Q: Can I use Gitea as a Go module proxy?
Yes. Gitea's package registry supports Go modules. Configure your GOPROXY to include your Gitea instance.