From 209a06b21f2240c845522be5a1bfe66b5bc01e58 Mon Sep 17 00:00:00 2001 From: mguschin Date: Mon, 2 Feb 2026 19:58:01 +0300 Subject: [PATCH] Init. --- README.md | 145 ++++++++++++++++++++++++++++++++- docker-compose.yml | 37 +++++++++ init-database.sh | 22 +++++ install-certificates.sh | 172 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 375 insertions(+), 1 deletion(-) create mode 100644 docker-compose.yml create mode 100755 init-database.sh create mode 100755 install-certificates.sh diff --git a/README.md b/README.md index bb4a2ef..ce0ab3e 100644 --- a/README.md +++ b/README.md @@ -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 +``` diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..a87adc9 --- /dev/null +++ b/docker-compose.yml @@ -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 diff --git a/init-database.sh b/init-database.sh new file mode 100755 index 0000000..c67abc3 --- /dev/null +++ b/init-database.sh @@ -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: " +echo " DB_NAME: gitea" +echo " DB_USER: gitea" +echo " DB_PASSWORD: " +echo "" +echo "To start Gitea, run:" +echo " docker-compose up -d" +echo "" diff --git a/install-certificates.sh b/install-certificates.sh new file mode 100755 index 0000000..0b50798 --- /dev/null +++ b/install-certificates.sh @@ -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"