---
title: "How to install Gitea on a VPS with Docker, HTTPS and SSH | StreetHosting"
description: "Host your Git repositories on a VPS with Gitea on Docker Compose, PostgreSQL or SQLite, Git SSH on a separate port, Nginx and HTTPS with Let's Encrypt."
url: "https://streethosting.com.br/en/guides/vps/install-gitea-on-vps"
type: "page"
language: "en-US"
---

VPS · 9 min · Intermediate

Published on Sep 28, 2026 · Updated on Sep 28, 2026

# Gitea on a VPS: your own Git server with a domain and HTTPS

Gitea is a lightweight Git server with a web UI, issues, pull requests and a package registry. See how to bring it up with Docker Compose, choose the database, keep Git's SSH apart from the VPS SSH and publish it with a domain and HTTPS.

By [Equipe StreetHosting](https://streethosting.com.br/en/autores#equipe-streethosting) · StreetHosting infrastructure and support team

[Network, DNS and domains](https://streethosting.com.br/en/guides/topics/networking) [Linux administration](https://streethosting.com.br/en/guides/topics/linux) [Containers and Docker](https://streethosting.com.br/en/guides/topics/docker) [Certificates and HTTPS](https://streethosting.com.br/en/guides/topics/ssl)

Summarize with:

[](https://chat.openai.com/?q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Finstall-gitea-on-vps.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "ChatGPT") [](https://claude.ai/new?q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Finstall-gitea-on-vps.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Claude") [](https://www.google.com/search?udm=50&aep=11&q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Finstall-gitea-on-vps.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Google AI Mode") [](https://x.com/i/grok?text=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Finstall-gitea-on-vps.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Grok") [](https://www.perplexity.ai/search/new?q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Finstall-gitea-on-vps.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Perplexity")

Share:

[](https://x.com/intent/tweet?text=How%20to%20install%20Gitea%20on%20a%20VPS%20with%20Docker%2C%20HTTPS%20and%20SSH&url=https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Finstall-gitea-on-vps "Share on X") [](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Finstall-gitea-on-vps "Share on Facebook") [](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Finstall-gitea-on-vps "Share on LinkedIn") [](https://wa.me/?text=How%20to%20install%20Gitea%20on%20a%20VPS%20with%20Docker%2C%20HTTPS%20and%20SSH%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Finstall-gitea-on-vps "Share on WhatsApp")

For agents: Copy as Markdown [.md](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps.md)

In this guide 8 sections

* [What Gitea offers and what it needs](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#por-que-gitea)
* [PostgreSQL or SQLite](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#banco)
* [Bring up Gitea with Docker Compose](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#docker-compose)
* [Git SSH on a separate port](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#ssh-git)
* [Domain, Nginx and HTTPS](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#nginx-https)
* [Initial setup and security](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#primeiro-acesso)
* [Backup and updates](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#backup-atualizacao)
* [Which VPS to use for Gitea](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#onde-rodar)

Quick answer

To **install Gitea on a VPS**, bring up the official container with Docker Compose, use PostgreSQL (or SQLite for personal use), publish the web UI only on 127.0.0.1:3000 behind Nginx with HTTPS, and expose Git SSH on its own port, such as 2222, so it does not fight over port 22 with the administration SSH. For one person or a small team, 2 vCPU and 2 to 4 GB of RAM are enough.

## What Gitea offers and what it needs[](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#por-que-gitea)

Gitea is a Git server written in Go, shipped as a single binary and light enough to run alongside other applications. It comes with a web UI to browse code, issues, pull requests, a wiki, a package registry and Gitea Actions, which runs pipelines with a syntax compatible with GitHub Actions. Forgejo, a Gitea fork maintained by an independent community, follows an installation process very similar to the one in this guide.

There are usually three reasons to host your own Git server: keeping sensitive code off third-party platforms, not depending on free-plan limits, and having a mirror of your GitHub repositories as a safety copy. Before you start, have on hand:

* A VPS running Ubuntu 24.04 with key-based SSH access
* Docker Engine and the Compose plugin installed
* A subdomain for Gitea pointing to the VPS IP
* Ports 80 and 443 free for Nginx
* A free port for Git SSH, such as 2222

If you do not have Docker yet, follow the guide on [installing Docker on Ubuntu](https://streethosting.com.br/en/guides/vps/install-docker-ubuntu-vps). Before issuing the certificate, the domain already needs an A record pointing to the VPS IP.

## PostgreSQL or SQLite[](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#banco)

Gitea stores repositories on disk and uses a database for users, issues, permissions and metadata. The two most common choices on a VPS are SQLite and PostgreSQL.

| Criterion         | SQLite                                         | PostgreSQL                             |
| ----------------- | ---------------------------------------------- | -------------------------------------- |
| Setup             | None, it is a file inside the volume           | One more container in the compose file |
| Concurrent writes | One at a time, queued                          | Many in parallel                       |
| Backup            | With Gitea stopped or through the dump command | pg\_dump with the service running      |
| Extra memory      | Practically none                               | A few hundred MB                       |
| Best for          | Personal use, up to a few users                | Teams, pipelines and integrations      |

SQLite's limit shows up when several things write at the same time: pushes from different people, webhooks and runners updating statuses. That is when database locked errors and slowdowns appear. If you already know usage will grow, start with PostgreSQL and avoid a database migration later. If you prefer PostgreSQL installed directly on the system, outside Docker, the step-by-step walkthrough is in the guide on [installing PostgreSQL on an Ubuntu VPS](https://streethosting.com.br/en/guides/vps/install-postgresql-ubuntu-vps).

## Bring up Gitea with Docker Compose[](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#docker-compose)

Create a directory for the project and, inside it, the `compose.yaml` file:

`sudo mkdir -p /opt/gitea cd /opt/gitea sudo nano compose.yaml`

`services: server: image: docker.gitea.com/gitea:1.27 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=troque_esta_senha - GITEA__server__DOMAIN=git.seu-dominio.com.br - GITEA__server__SSH_DOMAIN=git.seu-dominio.com.br - GITEA__server__ROOT_URL=https://git.seu-dominio.com.br/ - GITEA__server__SSH_PORT=2222 - GITEA__server__SSH_LISTEN_PORT=22 volumes: - ./gitea:/data - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro ports: - "127.0.0.1:3000:3000" - "2222:22" depends_on: - db db: image: docker.io/library/postgres:16 restart: always environment: - POSTGRES_USER=gitea - POSTGRES_PASSWORD=troque_esta_senha - POSTGRES_DB=gitea volumes: - ./postgres:/var/lib/postgresql/data`

What deserves attention in each part:

* **Image tag:** the `1.27` tag receives the fixes for that series without jumping to the next version on its own. Check the current stable version in the release notes before installing and avoid the `latest` tag.
* **GITEA\_\_ variables:** each one becomes a line in `app.ini`, in section and key format. That is how the database and the domain arrive already configured at first access.
* **USER\_UID and USER\_GID:** set the owner of the files in `./gitea`. 1000 is usually the first user created on the VPS; check with `id`.
* **Port 3000 on 127.0.0.1:** ports published by Docker bypass the UFW rules. Binding the web UI to the local address guarantees it can only be reached through Nginx.
* **Database password:** use the same password in both services and protect the file with `sudo chmod 600 compose.yaml`.

To use SQLite, delete the _db_ service, the `depends_on` and the `GITEA__database__` variables: Gitea uses SQLite by default, with the file inside `./gitea`. Bring it up and follow the log:

`sudo docker compose up -d sudo docker compose logs -f server curl -I http://127.0.0.1:3000`

## Git SSH on a separate port[](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#ssh-git)

The VPS SSH already occupies port 22 for administration. The Gitea container has its own SSH server, which listens on port 22 inside the container and is published on port 2222 of the VPS by the `"2222:22"` line. The two SSH variables in the compose file keep those ideas apart: `SSH_PORT=2222` is the port that appears in clone URLs, and `SSH_LISTEN_PORT=22` is the port inside the container.

Since Docker published the port, it is already reachable from outside. If your provider or your firewall policy requires an explicit rule, add it with `sudo ufw allow 2222/tcp`. After registering your public key in the user settings, under the SSH keys section, create an entry in `~/.ssh/config` on your computer so you do not have to remember the port:

`Host git.seu-dominio.com.br User git Port 2222 IdentityFile ~/.ssh/id_ed25519`

`ssh -T git@git.seu-dominio.com.br git clone ssh://git@git.seu-dominio.com.br:2222/usuario/projeto.git`

The `ssh -T` test should answer with a greeting saying you have authenticated and that Gitea does not provide shell access. If it asks for a password, the key was not registered or the client is offering a different key. If SSH keys are still new to you, see [how to set up an SSH key](https://streethosting.com.br/en/guides/vps/passwordless-ssh-login-vps).

There is an alternative that shares port 22 between the VPS SSH and Gitea, called SSH passthrough in the official documentation. It gives you cleaner URLs, but it touches the system's _git_ user and is harder to debug. For most cases, the separate port is the safer path.

## Domain, Nginx and HTTPS[](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#nginx-https)

With the subdomain's A record pointing to the VPS, install Nginx and create `/etc/nginx/sites-available/gitea`:

`server { listen 80; server_name git.seu-dominio.com.br; client_max_body_size 512M; location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Connection $http_connection; proxy_set_header Upgrade $http_upgrade; 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; } }`

`sudo ln -s /etc/nginx/sites-available/gitea /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx sudo apt install -y certbot python3-certbot-nginx sudo certbot --nginx -d git.seu-dominio.com.br sudo ufw allow "Nginx Full"`

The `client_max_body_size` directive matters because pushes over HTTPS and Git LFS files go through Nginx; with the default 1 MB limit, any larger push fails with a 413 error. The `X-Forwarded` headers tell Gitea that the original connection was HTTPS, which keeps links and redirects correct. The Certbot details and automatic renewal are in the guide on [SSL with Let's Encrypt and Nginx](https://streethosting.com.br/en/guides/vps/lets-encrypt-ssl-certificate-vps).

The three most common symptoms at this stage and their causes:

* **502 Bad Gateway:** the container is not up or port 3000 was not published on 127.0.0.1. Check with `sudo docker compose ps` and with the local _curl_ from the previous section.
* **Links pointing to localhost:3000:** the `ROOT_URL` is wrong or never made it into _app.ini_. Fix the variable and recreate the container.
* **Clone URL without port 2222:** the `GITEA__server__SSH_PORT` variable is missing, and clients try port 22, which belongs to the VPS SSH.

## Initial setup and security[](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#primeiro-acesso)

When you open `https://git.seu-dominio.com.br` for the first time, Gitea shows the installation screen with the database and domain already filled in from the variables. Review the fields, set the site name and create the administrator account in the optional settings section before finishing.

Until the initial installation is complete, whoever reaches the address first can finish the process and become administrator. Complete it right after bringing the container up. If you need time, leave Nginx off and access it through a tunnel with `ssh -N -L 3000:127.0.0.1:3000 usuario@IP_DA_VPS`.

With the administrator created, close open registration, which by default lets any visitor create an account. Add to the `environment` of the _server_ service in `compose.yaml`:

` - GITEA__service__DISABLE_REGISTRATION=true - GITEA__service__REQUIRE_SIGNIN_VIEW=true`

Then run `sudo docker compose up -d`, which recreates the container with the new variables.

The second line hides everything from anyone who is not logged in, useful when the instance belongs only to your team. New users are then created through the admin panel or the command line, with `sudo docker exec -it -u git gitea gitea admin user create --username nome --email nome@seu-dominio.com.br --random-password`. Enable two-factor authentication for the administrator.

For pipelines, Gitea Actions needs a runner, the `act_runner`, registered with the instance. Since jobs execute code from the repositories, run the runner in isolation, preferably on another VPS or in its own container. The automatic deploy architecture is in [how to set up CI/CD on a VPS](https://streethosting.com.br/en/guides/vps/set-up-ci-cd-on-vps).

## Backup and updates[](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#backup-atualizacao)

Two things need to be saved: the database and the `./gitea` directory, which holds repositories, attachments, keys and `app.ini`. Stopping Gitea for a few seconds during the copy avoids capturing a half-finished push:

`cd /opt/gitea sudo mkdir -p /var/backups/gitea sudo docker compose stop server sudo docker compose exec -T db pg_dump -U gitea gitea | gzip | sudo tee /var/backups/gitea/banco_$(date +%F).sql.gz > /dev/null sudo tar czf /var/backups/gitea/dados_$(date +%F).tar.gz -C /opt/gitea gitea sudo docker compose start server`

Gitea also has the `gitea dump` command, which produces a single zip file with the database, repositories and configuration. Whichever method you pick, send the copies off the VPS, as shown in the guide on [automated backups with restic and cron](https://streethosting.com.br/en/guides/vps/vps-backup-restic-cron), and test the restore on another machine from time to time.

To update, back up, read the release notes, change the tag in `compose.yaml` and run `sudo docker compose pull && sudo docker compose up -d`. Gitea applies the database migrations on startup; follow the log until the UI comes back. The PostgreSQL image should only change major version with a dump and restore, because the data from one major version does not open directly in the next.

## Which VPS to use for Gitea[](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#onde-rodar)

Gitea itself is lightweight. What determines the plan is the size of the repositories, Git LFS usage and, above all, whether the pipeline runner will run on the same machine, because compiling and testing code consumes far more CPU and RAM than serving Git. On [StreetHosting VPS](https://streethosting.com.br/en/vps) you get root access on KVM, NVMe, Anti-DDoS and a datacenter in São Paulo, with activation within 60 seconds.

| Scenario                             | Suggested plan                              | Monthly price |
| ------------------------------------ | ------------------------------------------- | ------------- |
| Personal use with SQLite             | Xeon 2 vCPU, 2 GB, 20 GB NVMe               | R$ 26.00      |
| Small team with PostgreSQL           | Xeon 3 vCPU, 4 GB, 40 GB NVMe               | R$ 43.00      |
| Team with the runner on the same VPS | Xeon 6 vCPU, 8 GB, 80 GB NVMe               | R$ 77.00      |
| Fast builds on the runner            | Ryzen 9 9950X 4 vCPU, 8 GB DDR5, 80 GB NVMe | R$ 118.00     |
| Many repositories, LFS and artifacts | Xeon 9 vCPU, 16 GB, 160 GB NVMe             | R$ 145.00     |

The [Xeon VPS](https://streethosting.com.br/en/vps/xeon) gives you more vCPU and disk per real spent, which suits the Git server and the database well. The Ryzen 9 9950X VPS, with clocks up to 5.7 GHz, shortens compile time when the runner runs alongside. If you run out of space, upgrading through the control panel charges only the prorated difference for the cycle and requires a VM restart.

In this guide

* [What Gitea offers and what it needs](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#por-que-gitea)
* [PostgreSQL or SQLite](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#banco)
* [Bring up Gitea with Docker Compose](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#docker-compose)
* [Git SSH on a separate port](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#ssh-git)
* [Domain, Nginx and HTTPS](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#nginx-https)
* [Initial setup and security](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#primeiro-acesso)
* [Backup and updates](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#backup-atualizacao)
* [Which VPS to use for Gitea](https://streethosting.com.br/en/guides/vps/install-gitea-on-vps#onde-rodar)

## Frequently asked questions

Does Gitea need a lot of VPS resources?

No. For personal use or a small team, 2 vCPU and 2 GB of RAM are enough with SQLite, and 4 GB give you headroom with PostgreSQL. What grows most over time is disk, because of the repositories, and CPU when you run pipelines on the same machine.

Should I use SQLite or PostgreSQL with Gitea?

SQLite works for personal use and a handful of users, because it does not require another service. For teams, continuous integration and many concurrent writes, go with PostgreSQL, which handles concurrency better and allows backups without stopping Gitea.

Why use port 2222 for Gitea's SSH?

Port 22 on the VPS is already taken by the administration SSH. Publishing the container's SSH on another port, such as 2222, avoids conflicts and keeps administrative access separate from repository access.

Does Gitea have something like GitHub Actions?

Yes. Gitea Actions uses a workflow syntax compatible with GitHub Actions, but it needs a separate runner, act\_runner, registered with the instance. Since jobs execute code, run the runner in isolation, preferably on another VPS or in its own container.

How do I update Gitea on Docker?

Back up, change the image tag in compose.yaml to the new version, run docker compose pull and docker compose up -d. Gitea applies database migrations on startup; read the release notes before skipping several versions at once.

Next step

See VPS plans

Root VPS in Brazil with NVMe and Anti-DDoS.

[See VPS plans](https://streethosting.com.br/en/vps)

[See Xeon VPS Xeon VPS for steady workloads, automation and long-running projects.](https://streethosting.com.br/en/vps/xeon) [See Ryzen VPS Ryzen 9 9950X VPS in São Paulo with root access, NVMe and gamer Anti-DDoS.](https://streethosting.com.br/en/vps/ryzen)

## Related guides

[VPS Intermediate How to install Docker on Ubuntu 22.04 or 24.04 on a VPS (straight to the point) A stable Docker install on an Ubuntu VPS depends on the right package source and step by step validation. In this guide you set up the official repository, install Engine and Compose, test the daemon and apply basic security measures before deploying applications. 3 min Read guide](https://streethosting.com.br/en/guides/vps/install-docker-ubuntu-vps) [VPS Intermediate How to set up Nginx as a reverse proxy on a VPS Your app runs on an internal port and you want to serve it on a domain with HTTPS. Nginx as a reverse proxy solves that and also brings several apps together in one place. 3 min Read guide](https://streethosting.com.br/en/guides/vps/nginx-reverse-proxy-vps) [VPS Beginner SSL certificate on a VPS with Let's Encrypt and Nginx A site without the padlock loses trust and rankings. This guide shows how to issue, renew and audit a free SSL certificate on your VPS with Nginx and Certbot. 4 min Read guide](https://streethosting.com.br/en/guides/vps/lets-encrypt-ssl-certificate-vps)

[← Back to the Guide Center](https://streethosting.com.br/en/guides)
