Gitea Self‑Hosted Deployment
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
Requirements
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 |
Quick Start
1. Clone the repository
git clone https://git.amiirkhl.ir/interanet/gitea-deployment.git
cd gitea-deployment
2. Run the bootstrap script
chmod +x run.sh
./run.sh
The first time you run this, it will create a .env file from the included template and ask you to configure it.
3. Edit your configuration
Open .env in any text editor:
nano .env
At 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
4. Run again
./run.sh
That's it — Gitea will be up and running.
Accessing Gitea
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.
SSL / HTTPS Setup
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 | custom
Option 1: No HTTPS (none)
This 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.com
No extra configuration needed.
Option 2: Let's Encrypt (letsencrypt)
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.com
Prerequisites:
- 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.sh
You can automate this with a weekly cron job:
0 3 * * 1 cd /path/to/gitea-deployment && ./scripts/setup-letsencrypt.sh
Option 3: Custom Certificate (custom)
Use 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.pem
The 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 reload
Data Persistence
All 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.
Managing the Server
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 -d
Repository Structure
gitea-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
Notes
- 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.
License
MIT