Tutorial

Easily Self-Host Your Private Git Server with Gitea and Docker Compose

2025-08-10 #Docker#Docker Compose#Self-hosted

Introduction

Want a private code repository completely under your control? Gitea is a lightweight, high-performance self-hosted Git service that is feature-rich yet consumes minimal resources, running smoothly even on a Raspberry Pi.

This tutorial will guide you through deploying a secure, private Gitea instance quickly using Docker Compose, giving you a code management experience comparable to GitHub in just a few minutes.

1. Environment Preparation

Before starting, you need your own VPS or a NAS system that supports Docker containers.

1. Installing Docker and Docker Compose

This is the foundation of our containerized deployment. If your server does not have it installed yet, you can refer to the following tutorial.

2. (Optional) Adjusting the Server's SSH Port

Gitea needs port 22 to handle Git SSH operations (such as git clone git@...). To avoid conflicts with the server's own SSH service port, it is recommended to change the server's SSH port to a non-standard port (e.g., 2222).

  • Edit the SSH configuration file:

    1
    vim /etc/ssh/sshd_config
  • Find the line #Port 22, uncomment it (remove #), and change 22 to the new port number.

  • Restart the SSH service to apply changes:

    1
    systemctl restart sshd

    Important Note: Before disconnecting your current session, make sure to open a new terminal window and try logging in using the new port number to ensure you can log in successfully.

3. Creating the Project Directory

Create a dedicated directory for Gitea to store configuration files and data.

1
mkdir -p /opt/gitea && cd /opt/gitea

2. Deploying Gitea using Docker Compose

Creating the docker-compose.yml File

In the project directory (/opt/gitea), create a file named docker-compose.yml.

1
vim docker-compose.yml

Paste the following content into the file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# docker-compose.yml
networks:
gitea:
external: false

services:
gitea:
image: gitea/gitea:1.24.2 # 建议锁定版本以确保稳定性
container_name: gitea
restart: always
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 # 请在生产环境中替换为更强的密码
networks:
- gitea
volumes:
- ./data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000" # Web 界面端口
- "22:22" # SSH Git 操作端口 (主机端口:容器端口)
depends_on:
- db

db:
image: postgres:15 # 建议锁定版本
container_name: gitea-db
restart: always
environment:
- POSTGRES_USER=gitea
- POSTGRES_PASSWORD=gitea # 请在生产环境中替换为更强的密码
- POSTGRES_DB=gitea
networks:
- gitea
volumes:
- ./postgres:/var/lib/postgresql/data

Configuration Explanation:

  • image: We specified explicit versions for both Gitea and the Postgres database, which helps avoid compatibility issues caused by automatic updates in the future.
  • environment: Used to configure the connection details between Gitea and the database. Make sure to replace GITEA__database__PASSWD and POSTGRES_PASSWORD with strong passwords.
  • volumes: Persists Gitea data (repositories, configuration, etc.) and database files in the data and postgres directories under the current host directory, ensuring data is not lost when containers are reconstructed.
  • ports:
    • 3000:3000: Maps Gitea's Web interface to port 3000 of the host.
    • 22:22: Maps Git's SSH operation port to port 22 of the host.

Starting Gitea Services

In the directory where docker-compose.yml is located, execute the following command to pull the images and start the services:

1
docker compose up -d

3. Initializing Gitea Settings

  1. Access the Web Interface: Open a browser and visit http://<your-server-IP>:3000.
  2. Complete the Installation: You will see Gitea's installation page.
    • Database Settings: Already automatically configured via environment variables, no modification needed.
    • General Settings: This is the part you need to pay attention to.
      • Server Domain: Fill in your domain name, e.g., git.yourdomain.com.
      • Gitea Base URL: Fill in the full access URL, e.g., http://git.yourdomain.com/.
  3. Click "Install Gitea", and Gitea will complete the final setup and redirect you to the login page. Please register your administrator account immediately.

4. Security Hardening

For a private Git server, security is paramount.

Disabling User Registration

To prevent unauthorized users from registering, we need to modify Gitea's configuration file.

1 Edit the app.ini file:

1
vim ./data/gitea/conf/app.ini

2 In the [service] section, find and modify or add the following configurations:

1
2
3
[service]
DISABLE_REGISTRATION = true ; 禁用注册功能
SHOW_REGISTRATION_BUTTON = false ; 从主页隐藏注册按钮

3 Restart Gitea to apply the configuration:

1
docker compose restart gitea

Exposing the Web port directly to the public network is unsafe. It is recommended to use Nginx or another reverse proxy tool to serve the Web interface and use HTTPS.

1 Modify Port Mapping: Restrict Gitea's Web port to localhost access only.
Modify the ports section in docker-compose.yml:

1
2
3
ports:
- "127.0.0.1:3000:3000" # 仅允许本地访问
- "22:22"

2 Restart Service:

1
docker compose down

1
docker compose up -d

3 Configure Reverse Proxy: In your reverse proxy tool, set up a proxy rule to forward traffic from git.yourdomain.com to http://127.0.0.1:3000.

Nginx Example (Reverse Proxy Section Only)

The following example reverse proxies HTTP traffic for the domain git.example.com to local 127.0.0.1:3000. Please make sure that you configured the port mapping as 127.0.0.1:3000:3000 in compose, and configured ROOT_URL in Gitea's settings as http://git.example.com/.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
location / {
proxy_pass http://127.0.0.1:3000;

# 透传必要头部,确保生成正确克隆地址与日志 IP
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;

# WebSocket 支持(如通知、终端等)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

# 超时设置,避免大仓库推送中断
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 3600s;
}

Test and reload Nginx configuration

1
nginx -t
1
nginx -s reload 

Conclusion

Congratulations! You now have a feature-rich, secure, and reliable private Git server. Compared to heavy solutions like GitLab, Gitea consumes minimal resources while providing core features, making it ideal for individual developers and small teams. Deploying with Docker Compose makes the process simple, efficient, and easy to maintain.

Comments
Share

Comments