fix: Gitea Traefik routing and connection pool optimization
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled

- Remove middleware reference from Gitea Traefik labels (caused routing issues)
- Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s)
- Add explicit service reference in Traefik labels
- Fix intermittent 504 timeouts by improving PostgreSQL connection handling

Fixes Gitea unreachability via git.michaelschiemer.de
This commit is contained in:
2025-11-09 14:46:15 +01:00
parent 85c369e846
commit 36ef2a1e2c
1366 changed files with 104925 additions and 28719 deletions

View File

@@ -0,0 +1,320 @@
#!/bin/bash
#
# Production SSL Certificate Setup Script for michaelschiemer.de
# Sets up Let's Encrypt SSL certificates on the production server
#
set -euo pipefail
# Configuration
SERVER_USER="deploy"
SERVER_IP="94.16.110.151"
REMOTE_PATH="/home/deploy/michaelschiemer"
DOMAIN="michaelschiemer.de"
EMAIL="michael@michaelschiemer.de" # Change this to your email
SSH_OPTS="-i ~/.ssh/production -o StrictHostKeyChecking=no"
# Colors for output
GREEN="\e[32m"
YELLOW="\e[33m"
RED="\e[31m"
BLUE="\e[34m"
RESET="\e[0m"
log_info() {
echo -e "${BLUE}[INFO]${RESET} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${RESET} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${RESET} $1"
}
log_error() {
echo -e "${RED}[ERROR]${RESET} $1"
}
# Check if domain resolves to production server
check_dns() {
log_info "Checking DNS resolution for $DOMAIN..."
local resolved_ip=$(dig +short "$DOMAIN" | head -1)
if [[ "$resolved_ip" == "$SERVER_IP" ]]; then
log_success "Domain $DOMAIN resolves correctly to $SERVER_IP"
else
log_warning "Domain $DOMAIN resolves to $resolved_ip (expected: $SERVER_IP)"
log_warning "SSL certificate might fail if DNS is incorrect"
fi
}
# Install certbot on production server
install_certbot() {
log_info "Installing certbot on production server..."
ssh $SSH_OPTS "$SERVER_USER@$SERVER_IP" '
# Update package list
sudo apt update
# Install snapd if not present
if ! command -v snap &> /dev/null; then
sudo apt install -y snapd
fi
# Install certbot via snap
if ! command -v certbot &> /dev/null; then
sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo ln -sf /snap/bin/certbot /usr/bin/certbot
fi
# Verify certbot installation
certbot --version
'
log_success "Certbot installed successfully"
}
# Stop nginx temporarily for certificate generation
prepare_nginx() {
log_info "Preparing nginx for certificate generation..."
ssh $SSH_OPTS "$SERVER_USER@$SERVER_IP" "
cd $REMOTE_PATH
# Stop nginx container temporarily
docker compose down web 2>/dev/null || true
# Create ssl directory
mkdir -p ssl
# Create temporary nginx config for certbot
cat > ssl/nginx-temp.conf << 'EOF'
server {
listen 80;
server_name $DOMAIN;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://\$server_name\$request_uri;
}
}
EOF
# Start temporary nginx for certificate validation
docker run -d --name nginx-temp \\
-p 80:80 \\
-v \$(pwd)/ssl/nginx-temp.conf:/etc/nginx/conf.d/default.conf \\
-v \$(pwd)/ssl/certbot-webroot:/var/www/certbot \\
nginx:alpine
"
log_success "Nginx prepared for certificate generation"
}
# Generate Let's Encrypt certificate
generate_certificate() {
log_info "Generating Let's Encrypt certificate for $DOMAIN..."
ssh $SSH_OPTS "$SERVER_USER@$SERVER_IP" "
cd $REMOTE_PATH
# Create webroot directory
mkdir -p ssl/certbot-webroot
# Generate certificate
docker run --rm \\
-v \$(pwd)/ssl/certbot-webroot:/var/www/certbot \\
-v \$(pwd)/ssl:/etc/letsencrypt \\
certbot/certbot certonly \\
--webroot \\
--webroot-path=/var/www/certbot \\
--email $EMAIL \\
--agree-tos \\
--no-eff-email \\
-d $DOMAIN
# Copy certificates to expected location
if [ -d \"ssl/live/$DOMAIN\" ]; then
cp ssl/live/$DOMAIN/fullchain.pem ssl/fullchain.pem
cp ssl/live/$DOMAIN/privkey.pem ssl/privkey.pem
chmod 644 ssl/fullchain.pem ssl/privkey.pem
log_success 'SSL certificates generated and copied'
else
log_error 'Certificate generation failed'
exit 1
fi
"
log_success "SSL certificate generated successfully"
}
# Clean up temporary nginx
cleanup_nginx() {
log_info "Cleaning up temporary nginx..."
ssh $SSH_OPTS "$SERVER_USER@$SERVER_IP" "
cd $REMOTE_PATH
# Stop and remove temporary nginx
docker stop nginx-temp 2>/dev/null || true
docker rm nginx-temp 2>/dev/null || true
# Clean up temporary files
rm -f ssl/nginx-temp.conf
rm -rf ssl/certbot-webroot
"
log_success "Temporary nginx cleaned up"
}
# Start the application with SSL
start_application() {
log_info "Starting application with SSL certificates..."
ssh $SSH_OPTS "$SERVER_USER@$SERVER_IP" "
cd $REMOTE_PATH
# Start all services
docker compose up -d
# Wait for services to start
sleep 10
# Check container status
docker compose ps
"
log_success "Application started with SSL certificates"
}
# Test SSL certificate
test_ssl() {
log_info "Testing SSL certificate..."
# Test HTTPS connection
if curl -sSf "https://$DOMAIN" > /dev/null 2>&1; then
log_success "HTTPS connection successful!"
else
log_warning "HTTPS connection test failed - checking certificate..."
fi
# Check certificate details
echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN:443" 2>/dev/null | openssl x509 -noout -dates
log_info "SSL setup completed!"
log_success "Your site should now be accessible at: https://$DOMAIN"
}
# Setup certificate renewal
setup_renewal() {
log_info "Setting up automatic certificate renewal..."
ssh $SSH_OPTS "$SERVER_USER@$SERVER_IP" "
# Create renewal script
cat > /home/deploy/renew-certificates.sh << 'RENEWAL_SCRIPT'
#!/bin/bash
cd /home/deploy/michaelschiemer
# Stop nginx container
docker compose down web
# Renew certificate
docker run --rm \\
-v \$(pwd)/ssl:/etc/letsencrypt \\
-v \$(pwd)/ssl/certbot-webroot:/var/www/certbot \\
certbot/certbot renew \\
--webroot \\
--webroot-path=/var/www/certbot
# Copy renewed certificates
if [ -f \"ssl/live/$DOMAIN/fullchain.pem\" ]; then
cp ssl/live/$DOMAIN/fullchain.pem ssl/fullchain.pem
cp ssl/live/$DOMAIN/privkey.pem ssl/privkey.pem
chmod 644 ssl/fullchain.pem ssl/privkey.pem
fi
# Restart services
docker compose up -d
RENEWAL_SCRIPT
chmod +x /home/deploy/renew-certificates.sh
# Add cron job for automatic renewal (runs twice daily)
(crontab -l 2>/dev/null; echo '0 12,0 * * * /home/deploy/renew-certificates.sh >> /var/log/letsencrypt-renewal.log 2>&1') | crontab -
"
log_success "Automatic certificate renewal configured"
}
# Main execution
main() {
log_info "Starting SSL certificate setup for $DOMAIN"
# Check DNS
check_dns
# Install certbot
install_certbot
# Prepare nginx
prepare_nginx
# Generate certificate
generate_certificate
# Clean up temporary nginx
cleanup_nginx
# Start application
start_application
# Test SSL
test_ssl
# Setup renewal
setup_renewal
log_success "SSL certificate setup completed successfully!"
log_info "Next steps:"
echo " 1. Test your site: https://$DOMAIN"
echo " 2. Certificates will auto-renew twice daily"
echo " 3. Check renewal logs: ssh $SERVER_USER@$SERVER_IP 'tail -f /var/log/letsencrypt-renewal.log'"
}
# Show usage
show_usage() {
echo "Usage: $0 [--help]"
echo ""
echo "This script sets up Let's Encrypt SSL certificates for $DOMAIN"
echo ""
echo "Prerequisites:"
echo " - Domain $DOMAIN must point to $SERVER_IP"
echo " - SSH access to production server configured"
echo " - Docker and docker-compose installed on server"
echo ""
echo "Options:"
echo " --help Show this help message"
}
# Parse arguments
case "${1:-}" in
--help|-h)
show_usage
exit 0
;;
"")
main
;;
*)
log_error "Unknown option: $1"
show_usage
exit 1
;;
esac