5.7 KiB
How I Set Up Gitea on a Google Cloud VM
This repository documents how I deployed a small self-hosted Gitea instance at:
https://git.low-level-guy.com
The setup uses:
- Google Compute Engine
- Ubuntu Server 26.04 LTS
- Docker Compose
- Gitea
- PostgreSQL
- Nginx as a reverse proxy
- Let's Encrypt HTTPS certificates through Certbot
- Gitea SSH on port
2222
This is meant as a practical guide for deploying Gitea the same way I did. It is not a hardened production checklist.
Deployment Overview
The VM runs Nginx directly on the host. Nginx terminates HTTPS and proxies web traffic to the Gitea container on port 3000.
Gitea and PostgreSQL run in Docker. Gitea also exposes SSH on host port 2222, so repositories can be cloned over SSH without conflicting with the VM's normal SSH service on port 22.
Internet
|
| HTTPS 443
v
Nginx on VM
|
| HTTP 3000
v
Gitea container
|
| PostgreSQL 5432
v
Postgres container
1. Create the VM
Create a Google Compute Engine VM.
The instance I used:
- Machine type:
e2-small - Boot disk:
10 GB - OS: Ubuntu Server 26.04 LTS
- External IP: static or at least stable enough to point DNS at it
A larger disk is a good idea if you expect many repositories, users, packages, or large Git history.
2. Configure the Firewall
Allow these TCP ports to reach the VM:
22 VM administration over SSH
80 HTTP for Let's Encrypt validation and redirect
443 HTTPS for the Gitea web UI
2222 Git over SSH through Gitea
In Google Cloud, this is configured under:
VPC network -> Firewall -> Create firewall rule
3. Point DNS to the VM
Create an A record for the Gitea subdomain:
A git.low-level-guy.com <VM_EXTERNAL_IP>
Wait for DNS propagation before requesting the HTTPS certificate.
4. Install Docker
SSH into the VM and install Docker from Docker's Ubuntu repository:
sudo apt update
sudo apt install -y \
ca-certificates \
curl \
gnupg
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu noble stable" \
| sudo tee /etc/apt/sources.list.d/docker.list
sudo apt update
sudo apt install -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-compose-plugin
Verify the install:
sudo docker --version
sudo docker compose version
I did not add my user to the docker group, so the Docker commands in this guide use sudo.
5. Install Nginx
sudo apt install -y nginx
sudo systemctl enable nginx
sudo systemctl start nginx
6. Install Certbot
sudo apt install -y certbot python3-certbot-nginx
7. Create the Gitea Directory
Create a working directory for the Compose project:
mkdir -p ~/gitea
cd ~/gitea
8. Add the Compose File
Use the compose.yaml file from this repository.
Copy it to the VM inside ~/gitea:
cd ~/gitea
nano compose.yaml
Paste the contents of this repo's compose.yaml.
The password values in the repo are placeholders. Change them before using this on a real server:
POSTGRES_PASSWORD: gitea
GITEA__database__PASSWD=gitea
Both values must match because Gitea uses that password to connect to PostgreSQL.
9. Start Gitea and PostgreSQL
From ~/gitea, start the containers:
sudo docker compose up -d
Check that both containers are running:
sudo docker ps
You should see containers for:
giteagitea-postgres
10. Configure Nginx
Create an Nginx site config:
sudo nano /etc/nginx/sites-available/gitea
Use this config:
server {
listen 80;
server_name git.low-level-guy.com;
location / {
proxy_pass http://127.0.0.1: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;
}
}
Enable the site:
sudo ln -s /etc/nginx/sites-available/gitea /etc/nginx/sites-enabled/gitea
Remove the default site if it is still enabled:
sudo rm /etc/nginx/sites-enabled/default
Test and reload Nginx:
sudo nginx -t
sudo systemctl reload nginx
11. Enable HTTPS
Request a Let's Encrypt certificate for the real domain:
sudo certbot --nginx -d git.low-level-guy.com
When Certbot asks, choose the option to redirect HTTP traffic to HTTPS.
After this, the site should be available at:
https://git.low-level-guy.com
12. Complete the Gitea Setup Wizard
Open the site in a browser:
https://git.low-level-guy.com
Use PostgreSQL as the database:
Database type: PostgreSQL
Host: postgres:5432
Database name: gitea
Username: gitea
Password: <the password from compose.yaml>
Use the public domain for the server settings:
Server domain: git.low-level-guy.com
Gitea base URL: https://git.low-level-guy.com/
SSH server domain: git.low-level-guy.com
SSH port: 2222
During this step, create the initial administrator account.
13. Test Git over SSH
After the setup wizard completes, test the Gitea SSH endpoint:
ssh -p 2222 git@git.low-level-guy.com
Once your SSH key is added to your Gitea account, a successful connection should authenticate against Gitea instead of the VM's normal SSH service.
Repository clone URLs should look like this:
git clone ssh://git@git.low-level-guy.com:2222/username/repository.git
HTTPS clone URLs should look like this:
git clone https://git.low-level-guy.com/username/repository.git