A simple, automated way to deploy your own Git server using Gitea and Docker Compose.
This project sets up everything you need for a production‑ready Git hosting platform:
- One‑command deployment via a bootstrap script
- PostgreSQL database (included)
- Nginx reverse proxy for HTTP / HTTPS
- Three SSL modes: none, Let's Encrypt, or custom certificate
- Optional SMTP email notifications
- Persistent data storage with easy backups
You'll need a Linux server (Ubuntu or Debian recommended) with the following:
| Requirement | Minimum |
|---|---|
| Docker | 20.10+ |
| Docker Compose | v2+ |
| CPU | 2 cores |
| RAM | 2–4 GB |
| Disk | 10 GB free |
git clone https://github.com/Quera-Education/interanet-gitea-deployment.git
cd gitea-deploymentchmod +x run.sh
./run.shThe first time you run this, it will create a .env file from the included template and ask you to configure it.
Open .env in any text editor:
nano .envAt a minimum, set these values:
GITEA_EXTERNAL_URL=http://YOUR_SERVER_IP # or https://your-domain.com
GITEA_DOMAIN=YOUR_SERVER_IP # your domain or IP
GITEA_ROOT_USER=admin
GITEA_ROOT_PASSWORD=SomeStrongPassword
GITEA_ROOT_EMAIL=you@example.com./run.shThat's it — Gitea will be up and running.
Once deployed, open your browser and go to:
http://YOUR_SERVER_IP
or, if you configured HTTPS:
https://your-domain.com
Log in with the admin credentials you set in .env.
This project uses an Nginx reverse proxy in front of Gitea to handle HTTPS. You control the behavior with a single variable in .env:
SSL_MODE=none # Options: none | letsencrypt | customThis is the default. Nginx listens on port 80 and proxies traffic to Gitea over plain HTTP.
SSL_MODE=none
GITEA_EXTERNAL_URL=http://your-domain.comNo extra configuration needed.
Automatically provisions a free TLS certificate from Let's Encrypt. HTTP traffic on port 80 is redirected to HTTPS on port 443.
SSL_MODE=letsencrypt
GITEA_EXTERNAL_URL=https://your-domain.com
GITEA_DOMAIN=your-domain.com
LETSENCRYPT_EMAIL=you@example.comPrerequisites:
- Your domain must point to your server's public IP (A record in DNS)
- Ports 80 and 443 must be open and reachable from the internet
The bootstrap script handles everything else — it starts Nginx, runs Certbot for the ACME challenge, and reloads Nginx with the new certificate.
To renew the certificate later:
./scripts/setup-letsencrypt.shYou can automate this with a weekly cron job:
0 3 * * 1 cd /path/to/gitea-deployment && ./scripts/setup-letsencrypt.shUse your own certificate files (purchased, Cloudflare origin, self‑signed, etc.). HTTP traffic is redirected to HTTPS.
SSL_MODE=custom
GITEA_EXTERNAL_URL=https://your-domain.com
GITEA_DOMAIN=your-domain.com
SSL_CERT_PATH=/path/to/your/fullchain.pem
SSL_KEY_PATH=/path/to/your/privkey.pemThe script copies your cert and key into ./nginx/ssl/ and configures Nginx to use them.
To update your certificate later without restarting everything:
cp /path/to/new/fullchain.pem ./nginx/ssl/cert.pem
cp /path/to/new/privkey.pem ./nginx/ssl/key.pem
chmod 600 ./nginx/ssl/key.pem
docker exec gitea-nginx nginx -s reloadAll persistent data lives in the ./gitea-data directory:
gitea-data/
├── gitea/ # repositories, config, attachments
└── postgres/ # database files
To back up your instance, just copy this directory somewhere safe. It contains everything you need to restore later.
Here are the most common commands you'll use:
# View live logs
docker compose logs -f
# Stop all services
docker compose down
# Restart services
docker compose restart
# Update Gitea to the latest version
docker compose pull
docker compose up -dgitea-deployment/
├── docker-compose.yml # Defines all services (Gitea, PostgreSQL, Nginx, Certbot)
├── run.sh # Main bootstrap script
├── .env.sample # Configuration template
├── README.md
├── nginx/ # Generated at runtime (gitignored)
│ ├── conf.d/ # Nginx site config
│ └── ssl/ # Custom SSL certs (if applicable)
└── scripts/
├── setup-swap.sh # Configures swap space if needed
├── setup-ssl.sh # Generates Nginx config based on SSL_MODE
└── setup-letsencrypt.sh # Provisions / renews Let's Encrypt certs
- On first start, Gitea automatically initializes the database — no manual setup required.
- Admin credentials come from your
.envfile and are created during the bootstrap. - SMTP is optional but recommended for production use (password resets, notifications).
- The
nginx/directory is generated by the scripts and should not be committed to git.
MIT