This commit is contained in:
mguschin
2026-02-02 19:58:01 +03:00
parent e31034d8c6
commit 209a06b21f
4 changed files with 375 additions and 1 deletions

145
README.md
View File

@@ -1,2 +1,145 @@
# gitea
# Gitea Docker Setup
Self-hosted Git service with Docker Compose and SSL certificates for production deployment. Database is managed separately.
## Quick Start
### Local Development
1. Copy the local environment configuration:
```bash
cp .env.local .env
```
2. Update `.env` with your database connection details (ensure database is running):
```bash
nano .env
# Update DB_HOST, DB_USER, DB_PASSWORD
```
3. Start Gitea:
```bash
docker-compose up -d
```
4. Access Gitea at `http://localhost:3000`
### Production Deployment (repos.guschin.info)
1. Copy the production environment configuration:
```bash
cp .env.production .env
```
2. **IMPORTANT**: Edit `.env` and update the database credentials:
```bash
nano .env
# Update DB_HOST, DB_USER, DB_PASSWORD with your external database connection
```
3. **IMPORTANT**: Ensure the MySQL database is running and accessible before starting Gitea
4. Install SSL certificates:
```bash
./install-certificates.sh
```
5. Start Gitea:
```bash
docker-compose up -d
```
## Configuration Files
- `docker-compose.yml` - Docker Compose configuration for Gitea only
- `.env` - Active environment configuration (gitignored)
- `.env.local` - Local development settings
- `.env.production` - Production environment settings
- `install-certificates.sh` - SSL certificate installation for production
## Environment Variables
### Database Configuration (External)
- `DB_HOST` - MySQL host (e.g., db-server.example.com:3306)
- `DB_NAME` - Database name (default: gitea)
- `DB_USER` - Database user (default: gitea)
- `DB_PASSWORD` - Database password (ensure it's secure!)
### Gitea Configuration
- `GITEA_DOMAIN` - Domain name (localhost or repos.guschin.info)
- `GITEA_ROOT_URL` - Full URL to Gitea instance
- `GITEA_HTTP_PORT` - HTTP port mapping (default: 3000)
- `GITEA_SSH_PORT` - SSH port mapping (default: 2222 for local, 22 for production)
## Common Commands
```bash
# Start Gitea
docker-compose up -d
# Stop Gitea
docker-compose down
# View logs
docker-compose logs -f gitea
# Restart Gitea
docker-compose restart gitea
# Check service status
docker-compose ps
```
**Database Backup/Restore**: Use commands on the external database server, not in docker-compose.
## SSL Certificates
The `install-certificates.sh` script will:
1. Install certbot if not present
2. Obtain Let's Encrypt SSL certificates for repos.guschin.info
3. Configure automatic certificate renewal
4. Copy certificates to `./certs` directory
Certificates are automatically renewed every 60 days.
## Volumes
- `gitea-data` - Gitea application data and repositories
## Security Notes
1. Always change default passwords in production
2. Use strong passwords for database credentials
3. Keep the `.env` file secure (it's gitignored by default)
4. Regularly update Docker images: `docker-compose pull && docker-compose up -d`
5. Enable 2FA for Gitea admin accounts
## Ports
- **Local**: HTTP on 3000, SSH on 2222
- **Production**: HTTP on 3000 (behind reverse proxy), SSH on 22
## Troubleshooting
### Database connection issues
Ensure the external database is running and accessible with the credentials in `.env`. Test the connection:
```bash
mysql -h ${DB_HOST} -u ${DB_USER} -p
```
### Certificate issues
```bash
# Test certificate renewal
sudo certbot renew --dry-run
# Check certificate expiry
sudo certbot certificates
```
### Permission issues
```bash
# Fix volume permissions
docker-compose down
sudo chown -R 1000:1000 ./volumes/gitea-data
docker-compose up -d
```

37
docker-compose.yml Normal file
View File

@@ -0,0 +1,37 @@
version: '3.8'
services:
gitea:
image: gitea/gitea:latest
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=mysql
- GITEA__database__HOST=${DB_HOST}
- GITEA__database__NAME=${DB_NAME}
- GITEA__database__USER=${DB_USER}
- GITEA__database__PASSWD=${DB_PASSWORD}
- GITEA__server__DOMAIN=${GITEA_DOMAIN}
- GITEA__server__SSH_DOMAIN=${GITEA_DOMAIN}
- GITEA__server__ROOT_URL=${GITEA_ROOT_URL}
- GITEA__server__HTTP_PORT=3000
- GITEA__server__SSH_PORT=22
restart: unless-stopped
networks:
- gitea
volumes:
- gitea-data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "${GITEA_HTTP_PORT}:3000"
- "${GITEA_SSH_PORT}:22"
networks:
gitea:
driver: bridge
volumes:
gitea-data:
driver: local

22
init-database.sh Executable file
View File

@@ -0,0 +1,22 @@
#!/bin/bash
# Database Note for Gitea
# The MySQL database for Gitea is managed in a separate repository
# This script is deprecated and kept for reference only
echo "=========================================="
echo "Gitea Database Setup"
echo "=========================================="
echo ""
echo "Note: The MySQL database is managed separately."
echo "Please ensure the database is running before starting Gitea."
echo ""
echo "Required database connection details in .env:"
echo " DB_HOST: <database-host>"
echo " DB_NAME: gitea"
echo " DB_USER: gitea"
echo " DB_PASSWORD: <your-password>"
echo ""
echo "To start Gitea, run:"
echo " docker-compose up -d"
echo ""

172
install-certificates.sh Executable file
View File

@@ -0,0 +1,172 @@
#!/bin/bash
# SSL Certificate Installation Script for Gitea Production
# This script installs Let's Encrypt SSL certificates for repos.guschin.info
set -e
echo "==================================="
echo "SSL Certificate Installation"
echo "==================================="
# Load environment variables
if [ -f .env ]; then
source .env
echo "✓ Loaded environment variables from .env"
else
echo "✗ Error: .env file not found!"
exit 1
fi
# Check if running in production environment
if [ "${GITEA_DOMAIN}" != "repos.guschin.info" ]; then
echo "✗ Warning: This script is intended for production (repos.guschin.info)"
echo " Current domain: ${GITEA_DOMAIN}"
read -p "Continue anyway? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi
# Check if certbot is installed
if ! command -v certbot &> /dev/null; then
echo "Certbot is not installed. Installing..."
# Detect OS and install certbot
if [ -f /etc/debian_version ]; then
# Debian/Ubuntu
sudo apt-get update
sudo apt-get install -y certbot
elif [ -f /etc/redhat-release ]; then
# RHEL/CentOS/Fedora
sudo yum install -y certbot
elif [ -f /etc/arch-release ]; then
# Arch Linux
sudo pacman -S --noconfirm certbot
else
echo "✗ Error: Unsupported OS. Please install certbot manually."
exit 1
fi
echo "✓ Certbot installed"
fi
# Verify Docker is running
if ! docker info > /dev/null 2>&1; then
echo "✗ Error: Docker is not running!"
exit 1
fi
echo "✓ Docker is running"
# Create directory for certificates
CERT_DIR="./certs"
mkdir -p ${CERT_DIR}
echo "✓ Certificate directory created: ${CERT_DIR}"
# Email for Let's Encrypt notifications
read -p "Enter email address for Let's Encrypt notifications: " EMAIL
if [ -z "$EMAIL" ]; then
echo "✗ Error: Email address is required!"
exit 1
fi
echo ""
echo "Obtaining SSL certificate for ${GITEA_DOMAIN}..."
echo "This will:"
echo " 1. Verify domain ownership"
echo " 2. Obtain SSL certificate from Let's Encrypt"
echo " 3. Configure automatic renewal"
echo ""
# Stop Gitea if running to free up port 80
if docker ps | grep -q gitea; then
echo "Stopping Gitea container to free up port 80..."
docker-compose stop gitea
fi
# Obtain certificate using standalone mode
sudo certbot certonly \
--standalone \
--preferred-challenges http \
--email ${EMAIL} \
--agree-tos \
--no-eff-email \
-d ${GITEA_DOMAIN}
if [ $? -eq 0 ]; then
echo "✓ SSL certificate obtained successfully!"
# Copy certificates to local directory
sudo cp /etc/letsencrypt/live/${GITEA_DOMAIN}/fullchain.pem ${CERT_DIR}/
sudo cp /etc/letsencrypt/live/${GITEA_DOMAIN}/privkey.pem ${CERT_DIR}/
sudo chown $(id -u):$(id -g) ${CERT_DIR}/*.pem
echo "✓ Certificates copied to ${CERT_DIR}"
else
echo "✗ Error: Failed to obtain SSL certificate!"
exit 1
fi
# Setup automatic renewal
echo ""
echo "Setting up automatic certificate renewal..."
# Create renewal hook script
RENEWAL_HOOK="/etc/letsencrypt/renewal-hooks/deploy/gitea-reload.sh"
sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy
cat << 'EOF' | sudo tee ${RENEWAL_HOOK} > /dev/null
#!/bin/bash
# Gitea SSL certificate renewal hook
CERT_DIR="/path/to/git.git/certs"
DOMAIN="repos.guschin.info"
# Copy new certificates
cp /etc/letsencrypt/live/${DOMAIN}/fullchain.pem ${CERT_DIR}/
cp /etc/letsencrypt/live/${DOMAIN}/privkey.pem ${CERT_DIR}/
# Restart Gitea to load new certificates
cd /path/to/git.git
docker-compose restart gitea
echo "Gitea SSL certificates updated and service restarted"
EOF
# Update the path in renewal hook
sudo sed -i "s|/path/to/git.git|$(pwd)|g" ${RENEWAL_HOOK}
sudo chmod +x ${RENEWAL_HOOK}
echo "✓ Renewal hook installed"
# Test automatic renewal
echo ""
echo "Testing automatic renewal..."
sudo certbot renew --dry-run
if [ $? -eq 0 ]; then
echo "✓ Automatic renewal test passed"
else
echo "✗ Warning: Automatic renewal test failed"
echo " Please check certbot configuration"
fi
echo ""
echo "==================================="
echo "SSL Certificate Installation Complete!"
echo "==================================="
echo ""
echo "Certificate details:"
echo " Domain: ${GITEA_DOMAIN}"
echo " Certificate location: /etc/letsencrypt/live/${GITEA_DOMAIN}/"
echo " Local copy: ${CERT_DIR}"
echo ""
echo "Next steps:"
echo " 1. Update docker-compose.yml to use a reverse proxy (nginx/traefik)"
echo " 2. Configure the reverse proxy to use the certificates"
echo " 3. Start Gitea: docker-compose up -d"
echo ""
echo "Note: Certificates will automatically renew every 60 days"