Add Gitea deployment guide
This commit is contained in:
@@ -0,0 +1,296 @@
|
||||
# How I Set Up Gitea on a Google Cloud VM
|
||||
|
||||
This repository documents how I deployed a small self-hosted Gitea instance at:
|
||||
|
||||
```text
|
||||
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`.
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
VPC network -> Firewall -> Create firewall rule
|
||||
```
|
||||
|
||||
## 3. Point DNS to the VM
|
||||
|
||||
Create an `A` record for the Gitea subdomain:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
sudo apt install -y nginx
|
||||
sudo systemctl enable nginx
|
||||
sudo systemctl start nginx
|
||||
```
|
||||
|
||||
## 6. Install Certbot
|
||||
|
||||
```bash
|
||||
sudo apt install -y certbot python3-certbot-nginx
|
||||
```
|
||||
|
||||
## 7. Create the Gitea Directory
|
||||
|
||||
Create a working directory for the Compose project:
|
||||
|
||||
```bash
|
||||
mkdir -p ~/gitea
|
||||
cd ~/gitea
|
||||
```
|
||||
|
||||
## 8. Add the Compose File
|
||||
|
||||
Use the [`compose.yaml`](./compose.yaml) file from this repository.
|
||||
|
||||
Copy it to the VM inside `~/gitea`:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```yaml
|
||||
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:
|
||||
|
||||
```bash
|
||||
sudo docker compose up -d
|
||||
```
|
||||
|
||||
Check that both containers are running:
|
||||
|
||||
```bash
|
||||
sudo docker ps
|
||||
```
|
||||
|
||||
You should see containers for:
|
||||
|
||||
- `gitea`
|
||||
- `gitea-postgres`
|
||||
|
||||
## 10. Configure Nginx
|
||||
|
||||
Create an Nginx site config:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/nginx/sites-available/gitea
|
||||
```
|
||||
|
||||
Use this config:
|
||||
|
||||
```nginx
|
||||
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:
|
||||
|
||||
```bash
|
||||
sudo ln -s /etc/nginx/sites-available/gitea /etc/nginx/sites-enabled/gitea
|
||||
```
|
||||
|
||||
Remove the default site if it is still enabled:
|
||||
|
||||
```bash
|
||||
sudo rm /etc/nginx/sites-enabled/default
|
||||
```
|
||||
|
||||
Test and reload Nginx:
|
||||
|
||||
```bash
|
||||
sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
## 11. Enable HTTPS
|
||||
|
||||
Request a Let's Encrypt certificate for the real domain:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```text
|
||||
https://git.low-level-guy.com
|
||||
```
|
||||
|
||||
## 12. Complete the Gitea Setup Wizard
|
||||
|
||||
Open the site in a browser:
|
||||
|
||||
```text
|
||||
https://git.low-level-guy.com
|
||||
```
|
||||
|
||||
Use PostgreSQL as the database:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
git clone ssh://git@git.low-level-guy.com:2222/username/repository.git
|
||||
```
|
||||
|
||||
HTTPS clone URLs should look like this:
|
||||
|
||||
```bash
|
||||
git clone https://git.low-level-guy.com/username/repository.git
|
||||
```
|
||||
Reference in New Issue
Block a user