How to Set Up a Personal Git Server with Gitea: A Complete Self-Hosting Guide
To set up a personal Git server with Gitea, deploy the official gitea/gitea Docker image with persistent volumes for data and SQLite, complete the initial configuration via the web installer, and optionally add a reverse proxy like Caddy for HTTPS.
Gitea is a lightweight, self-hosted Git service written in Go and released under the MIT license. As a community-maintained fork of Gogs, it provides a fully-featured web UI for managing repositories, users, teams, pull requests, and issues. According to the mikeroyal/Self-Hosting-Guide repository, Gitea is distributed as a single binary or Docker image, storing all data on the host file system, making it ideal for personal or small-team Git servers.
Architecture Overview
A typical Gitea deployment consists of several components working together:
- Gitea binary or Docker image: Handles HTTP API, web UI, authentication, and Git operations. The official image is
gitea/gitea:latest. - Persistent storage: Host-mounted directories (e.g.,
/var/lib/gitea) that hold repositories, database files, and configuration. - Database: Built-in SQLite for personal use, or external MySQL/PostgreSQL for larger setups.
- Reverse proxy (optional): Provides TLS termination and URL rewriting using Caddy, Nginx, or Traefik.
- SSH daemon: Integrated into Gitea via the
gitea sshsub-command or external OpenSSH forgit@host:repo.gitcloning.
Prerequisites
Before deploying Gitea, ensure your system meets these requirements:
- Operating system: Any modern Linux distribution (Ubuntu 22.04 LTS, Debian 12, etc.)
- Docker Engine: Version 20.10 or newer
- Docker Compose: v2 plugin installed
- Network access: Ports 80/443 for HTTP/HTTPS and optionally port 22 for SSH
- Disk space: At least 2 GB for the container plus additional space for repositories
- Permissions: Root or sudo access to install Docker if not already present
Step-by-Step Deployment with Docker Compose
The simplest production-ready approach uses a Docker Compose stack with SQLite persistence.
Prepare the Directory Structure
Create the host directories that will store Gitea data and database files:
mkdir -p $HOME/gitea/data $HOME/gitea/db/sqlite
chmod -R 755 $HOME/gitea
The resulting layout should look like this:
$HOME/gitea/
├── docker-compose.yml
├── data/
│ └── gitea/
│ ├── custom/
│ ├── data/
│ ├── logs/
│ └── repositories/
└── db/
└── sqlite/
Create the Docker Compose Configuration
Create a docker-compose.yml file in $HOME/gitea/ with the following content:
version: "3.8"
services:
gitea:
image: gitea/gitea:latest
container_name: gitea
restart: unless-stopped
environment:
- USER_UID=1000
- USER_GID=1000
ports:
- "3000:3000"
- "2222:22"
volumes:
- ./data/gitea:/var/lib/gitea
Key configuration points:
- Ports:
3000exposes the web UI, while2222maps to the internal SSH server on port22. - Volumes: The
./data/gitea:/var/lib/giteamount ensures all data persists across container restarts. - Environment:
USER_UIDandUSER_GIDshould match your host user to maintain consistent file ownership.
Launch the Gitea Container
Navigate to your Gitea directory and start the stack:
cd $HOME/gitea
docker compose up -d
Docker will pull the gitea/gitea image (approximately 180 MB) and launch the container.
Complete the Web-Based Installation
Open your browser and navigate to http://<YOUR_HOST_IP>:3000. On the first-time setup page, configure the following fields:
- Database Type: Select
SQLite3(pre-selected by default) - Path:
/var/lib/gitea/data/gitea.db - Application URL:
http://<YOUR_HOST_IP>:3000/ - Server Domain: Your host IP or DNS name
- SSH Port:
2222(the host-exposed port) - Repository Root Path:
/var/lib/gitea/data/git/repositories - Disable Registration: Enabled (recommended for personal servers)
Click Install Gitea to create the SQLite database, write the configuration to your mounted volume, and initialize the web UI.
Optional: Secure Your Server with HTTPS Using Caddy
For production use, add a reverse proxy to handle TLS termination automatically.
Add the Caddy Service
Extend your docker-compose.yml to include Caddy:
caddy:
image: caddy:latest
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
volumes:
caddy_data:
caddy_config:
Configure the Caddyfile
Create ./caddy/Caddyfile with the following configuration:
yourdomain.example.com {
reverse_proxy gitea:3000
tls you@example.com
}
Replace yourdomain.example.com with your actual DNS name. After adding the service, restart the stack:
docker compose up -d
Caddy automatically provisions Let's Encrypt certificates, allowing you to access Gitea securely at https://yourdomain.example.com.
Using Your Personal Git Server
Once deployed, you can immediately start hosting code.
Creating Your First Repository
- Log in with the admin account created during installation.
- Click New Repository, provide a name (e.g.,
my-project), and select Public or Private. - Click Create Repository to initialize the repository.
Clone via HTTPS
Use the standard Git clone command with your server address:
git clone http://<HOST_OR_DOMAIN>/username/my-project.git
Clone via SSH
First, add your public SSH key under Settings → SSH / GPG Keys in the Gitea web interface. Then clone using:
git clone ssh://git@<HOST_OR_DOMAIN>:2222/username/my-project.git
If you configured the default port 22 on the host, omit the :2222 port specification.
Maintenance and Backup
Regular maintenance ensures your Git server remains secure and reliable:
-
Backup the entire Gitea data directory:
docker exec gitea tar czf - /var/lib/gitea | gzip > gitea-backup-$(date +%F).tgz -
Upgrade Gitea to the latest version:
docker compose pull gitea && docker compose up -d gitea -
Check container logs:
docker logs -f gitea -
Clean up unused Docker resources:
docker system prune -f
Source Files and References
This guide references the following files from the mikeroyal/Self-Hosting-Guide repository:
README.md(lines 346-364): Lists Gitea as a community-managed self-hosted Git service.README.md(line 466): Provides the official Gitea URL reference.Getting Started with Self-Hosting.dockerfile: Demonstrates the Docker-based environment setup used throughout the guide.CONTRIBUTING.md: Documents how community members can contribute to or update this documentation.
Summary
- Gitea provides a lightweight, single-binary solution for self-hosted Git repositories, ideal for personal use.
- Docker Compose with SQLite offers the simplest deployment path, requiring only a persistent volume and port mapping.
- Data persistence is achieved through host-mounted volumes at
/var/lib/gitea, making backups and migrations straightforward file operations. - Security enhancements like HTTPS via Caddy reverse proxy are recommended for production deployments.
- SSH access on a custom port (e.g.,
2222) allows secure Git operations without interfering with the host's SSH daemon.
Frequently Asked Questions
What is the difference between Gitea and Gogs?
Gitea is a community-maintained fork of Gogs that was created to ensure open governance and continued development. While Gogs development slowed, Gitea has expanded to include features like built-in package management, GitHub Actions support via act runners, and a more active maintenance cycle. Both are lightweight Go-based Git servers, but Gitea offers more frequent updates and a larger feature set for self-hosting.
Can I use MySQL or PostgreSQL instead of SQLite?
Yes, Gitea supports MySQL, PostgreSQL, and MSSQL as alternatives to SQLite. For a personal server with low traffic, SQLite is sufficient and requires no additional containers. For larger teams or heavy usage, uncomment the db service in the Docker Compose configuration and set the database type to MySQL or PostgreSQL during the initial setup. External databases provide better concurrency and backup options for production environments.
How do I migrate my existing repositories to Gitea?
Gitea provides a built-in migration feature accessible from the web UI. Click the + menu and select New Migration, then choose your source (GitHub, GitLab, or another Gitea instance). Enter the repository URL and credentials if needed. Alternatively, you can manually push existing repositories by adding your Gitea instance as a remote and using git push --mirror to transfer all branches and tags.
Why should I disable user registration on a personal server?
Disabling registration prevents unauthorized users from creating accounts on your private Git server. In the initial setup wizard, enable the Disable Registration option to ensure only the administrator can create accounts. This is a critical security measure for personal servers exposed to the internet, as it prevents unauthorized access and resource consumption by public users.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →