
How to Install Gitea on Ubuntu Using Docker
Setting up Gitea on Ubuntu using Docker is one of the most efficient ways to deploy a lightweight, self-hosted Git service without dealing with complex installation procedures. Gitea provides a solid alternative to GitLab and GitHub for teams who want version control with a clean interface, issue tracking, and collaborative features while maintaining full control over their repositories. In this guide, you’ll learn how to install Gitea using Docker containers, configure it properly, and troubleshoot common issues that might arise during setup.
What is Gitea and How Does it Work
Gitea is a community-managed fork of Gogs, written in Go, designed to be a lightweight yet powerful Git hosting solution. Unlike resource-heavy alternatives like GitLab, Gitea can run smoothly on modest hardware while still providing essential features like pull requests, issue tracking, project wikis, and organizational tools.
The application follows a three-tier architecture: a web interface built with Go’s templating system, a Git backend that handles repository operations, and a database layer (SQLite, MySQL, or PostgreSQL) for storing metadata. When deployed through Docker, Gitea runs in an isolated container environment, making it easier to manage dependencies, updates, and backups.
Key technical advantages include:
- Low memory footprint (typically 50-100MB RAM)
- Built-in SSH server for Git operations
- Support for Git LFS (Large File Storage)
- RESTful API for automation and integrations
- Multi-database backend support
Gitea vs Alternatives Comparison
Feature | Gitea | GitLab CE | Gogs | GitHub Enterprise |
---|---|---|---|---|
Memory Usage | 50-100MB | 4GB+ | 30-50MB | 8GB+ |
Built-in CI/CD | Gitea Actions (since v1.19) | Yes | No | Yes |
Container Registry | Yes | Yes | No | Yes |
License | MIT | MIT/Enterprise | MIT | Proprietary |
Development Activity | High | Very High | Low | High |
Prerequisites and System Requirements
Before starting the installation, ensure your Ubuntu system meets these requirements:
- Ubuntu 18.04 LTS or newer (tested on 20.04 and 22.04)
- Minimum 1GB RAM (2GB recommended for multiple users)
- Docker Engine 20.10+ and Docker Compose v2
- At least 10GB free disk space
- Non-root user with sudo privileges
Install Docker if you haven’t already:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
newgrp docker
Step-by-Step Installation Guide
Method 1: Quick Setup with Single Container
For testing or small teams, a single-container setup works perfectly:
mkdir -p /opt/gitea/{data,config}
sudo chown -R 1000:1000 /opt/gitea
docker run -d \
--name gitea \
--restart unless-stopped \
-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
Method 2: Production Setup with Docker Compose
For production environments, use Docker Compose with a separate database. Create a docker-compose.yml
file:
version: "3.8"
services:
gitea:
image: gitea/gitea:1.21
container_name: gitea
restart: unless-stopped
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=db:5432
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=gitea_password
networks:
- gitea
volumes:
- ./gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "2222:22"
depends_on:
- db
db:
image: postgres:15
restart: unless-stopped
environment:
- POSTGRES_USER=gitea
- POSTGRES_PASSWORD=gitea_password
- POSTGRES_DB=gitea
networks:
- gitea
volumes:
- ./postgres:/var/lib/postgresql/data
networks:
gitea:
external: false
Deploy the stack:
docker compose up -d
Initial Configuration and Setup
Navigate to http://your-server-ip:3000
to access the initial setup wizard. Key configuration points:
- Database Settings: If using the compose setup, the database fields should auto-populate
- Server Domain: Set to your actual domain or IP address
- SSH Server Port: Change to 2222 (since container port 22 maps to host 2222)
- HTTP Port: Keep as 3000 or change if using a reverse proxy
- Application URL: Must match your actual access URL
Create the first admin user during setup. This cannot be easily changed later without database manipulation.
Advanced Configuration and Customization
Gitea’s configuration is stored in /data/gitea/conf/app.ini
. Key settings for production use:
[server]
DOMAIN = your-domain.com
SSH_DOMAIN = your-domain.com
ROOT_URL = https://your-domain.com/
DISABLE_SSH = false
SSH_PORT = 2222
LFS_START_SERVER = true
[security]
INSTALL_LOCK = true
SECRET_KEY = your-secret-key-here
INTERNAL_TOKEN = your-internal-token
[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = false
ENABLE_CAPTCHA = true
[mailer]
ENABLED = true
FROM = gitea@your-domain.com
MAILER_TYPE = smtp
HOST = smtp.your-provider.com:587
USER = your-smtp-user
Restart the container after configuration changes:
docker restart gitea
Setting up Reverse Proxy with Nginx
For production deployments, use Nginx as a reverse proxy. Install and configure:
sudo apt install nginx certbot python3-certbot-nginx
# Create Nginx configuration
sudo nano /etc/nginx/sites-available/gitea
Add this configuration:
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_max_body_size 512M;
}
}
Enable the site and get SSL:
sudo ln -s /etc/nginx/sites-available/gitea /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d your-domain.com
Real-World Use Cases and Examples
Small Development Team (5-10 developers): Single-container deployment with SQLite database, using 512MB RAM and handling 100+ repositories efficiently.
Enterprise Setup: Multi-container deployment with PostgreSQL, Redis caching, and external storage integration. Supports 100+ concurrent users with proper resource allocation.
CI/CD Integration: Gitea Actions (similar to GitHub Actions) can be enabled for automated testing and deployment:
# .gitea/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.21'
- run: go test ./...
Common Issues and Troubleshooting
SSH Clone Issues: The most common problem is SSH port confusion. Users need to configure their Git client:
# ~/.ssh/config
Host your-domain.com
Port 2222
User git
Permission Problems: Ensure proper ownership of data directories:
sudo chown -R 1000:1000 /opt/gitea/data
# Check container logs for permission errors
docker logs gitea
Database Connection Issues: Verify database connectivity and credentials:
# Test database connection from container
docker exec -it gitea sh
# Inside container:
nc -zv db 5432
Memory Issues: Monitor resource usage and adjust if needed:
docker stats gitea
# Limit memory if necessary
docker update --memory=1g gitea
Best Practices and Security Considerations
- Regular Backups: Backup both data directory and database regularly
- Update Strategy: Test updates in staging before production deployment
- Network Security: Use firewall rules to restrict access to necessary ports only
- HTTPS Enforcement: Always use SSL certificates in production
- User Management: Disable public registration and use SSO when possible
- Resource Monitoring: Set up monitoring for disk space, memory, and database performance
Backup script example:
#!/bin/bash
# Backup Gitea data and database
BACKUP_DIR="/backup/gitea/$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR
# Backup data directory
tar -czf $BACKUP_DIR/gitea-data.tar.gz /opt/gitea/data
# Backup database (PostgreSQL)
docker exec gitea-db pg_dump -U gitea gitea > $BACKUP_DIR/gitea-db.sql
# Keep only last 7 days of backups
find /backup/gitea -type d -mtime +7 -exec rm -rf {} \;
Performance monitoring can be implemented using Prometheus metrics endpoint available at /metrics
when enabled in configuration.
For additional information and advanced configuration options, refer to the official Gitea documentation at https://docs.gitea.io/ and the Docker Hub repository at https://hub.docker.com/r/gitea/gitea.

This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.
This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.