[Fix]: SSL cert for self-signed and letsencrypt for caddy

This commit is contained in:
Moon Shadow
2025-07-20 15:01:56 +03:00
parent 37d9859598
commit fd2e1525d8
5 changed files with 138 additions and 28 deletions

View File

@@ -96,7 +96,10 @@ RUN echo '#!/bin/bash' > /usr/local/bin/start-app.sh \
&& echo '# Wait for database' >> /usr/local/bin/start-app.sh \
&& echo 'echo "Waiting for database connection..."' >> /usr/local/bin/start-app.sh \
&& echo 'until mariadb -h"$DB_HOST" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" --skip-ssl -e "SELECT 1;" >/dev/null 2>&1; do' >> /usr/local/bin/start-app.sh \
&& echo ' echo "Database not ready, waiting 2 seconds..."' >> /usr/local/bin/start-app.sh \
&& echo ' echo "Database not ready. Trying: mariadb -h$DB_HOST -u$DB_USER -p[HIDDEN] $DB_NAME --skip-ssl"' >> /usr/local/bin/start-app.sh \
&& echo ' mariadb -h"$DB_HOST" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" --skip-ssl -e "SELECT 1;" 2>&1 | head -3' >> /usr/local/bin/start-app.sh \
&& echo ' echo "^ If you see access denied error, run: docker compose down -v && docker compose up -d"' >> /usr/local/bin/start-app.sh \
&& echo ' echo "Waiting 2 seconds..."' >> /usr/local/bin/start-app.sh \
&& echo ' sleep 2' >> /usr/local/bin/start-app.sh \
&& echo 'done' >> /usr/local/bin/start-app.sh \
&& echo 'echo "Database connected successfully!"' >> /usr/local/bin/start-app.sh \

View File

@@ -200,9 +200,12 @@ services:
entrypoint: ["tail", "-f", "/dev/null"] # Keep container running for interactive use
networks:
# Auto-managed bridge network for maximum compatibility
# Docker automatically handles service discovery, subnet assignment, and conflict avoidance
# Containers can communicate using service names (database, app, caddy, etc.)
accounting_network:
driver: bridge
name: accounting_panel_network
# No custom name or subnet - lets Docker handle everything automatically
volumes:
db_data:

View File

@@ -1,5 +1,10 @@
# Caddy Configuration for PersonalAccounter
# This is the default configuration for development/manual setup
# The setup.sh script will replace this with domain-specific configuration
{
admin off
local_certs
}
# HTTP server - works on both ports 80 and 8080
:80, :8080 {
@@ -23,10 +28,14 @@
}
# HTTPS server - default port 443 and 8443 with self-signed certificate
# HTTPS server - default port 443 and 8443
:443, :8443 {
root * /var/www/html/public
# Self-signed TLS certificate for development/testing
# Note: setup.sh will configure proper Let's Encrypt or domain-specific SSL
tls internal
# Security headers
header {
X-Content-Type-Options nosniff
X-Frame-Options DENY

View File

@@ -57,16 +57,19 @@ check_network_conflicts() {
suggest_alternatives() {
echo -e "${BLUE}🛠️ Network Configuration Options:${NC}"
echo ""
echo -e "${GREEN}1. Current Configuration (Customizable):${NC}"
echo -e "${GREEN}1. Auto-Managed (Recommended):${NC}"
echo " • Let Docker choose subnet automatically"
echo " • Automatic service discovery (database, app, etc.)"
echo " • Best for: Most deployments, avoiding conflicts"
echo " • Current status: $(if grep -q 'name:' docker-compose.yml 2>/dev/null; then echo 'Not active'; else echo 'Active'; fi)"
echo ""
echo -e "${GREEN}2. Custom Subnet (Advanced):${NC}"
echo " • Subnet: ${DOCKER_SUBNET:-172.28.0.0/24}"
echo " • Gateway: ${DOCKER_GATEWAY:-172.28.0.1}"
echo " • Good for: Specific network requirements"
echo " • Requires manual configuration"
echo ""
echo -e "${GREEN}2. Auto-Managed (Maximum Compatibility):${NC}"
echo " • Let Docker choose subnet automatically"
echo " • Best for: Avoiding conflicts entirely"
echo ""
echo -e "${GREEN}3. Alternative Subnets:${NC}"
echo -e "${GREEN}3. Alternative Subnets (if conflicts persist):${NC}"
echo " • 172.29.0.0/24 (less common)"
echo " • 172.30.0.0/24 (even less common)"
echo " • 10.99.0.0/24 (private class A)"
@@ -92,18 +95,21 @@ fix_conflicts() {
}
switch_to_auto_managed() {
echo -e "${BLUE}🔄 Switching to auto-managed network...${NC}"
echo -e "${BLUE}🔄 Ensuring auto-managed network configuration...${NC}"
# Create backup
cp docker-compose.yml docker-compose.yml.backup
# Comment out the advanced config and uncomment the simple one
sed -i.tmp '/# Advanced network configuration/,/com.docker.network.driver.mtu: "1500"/s/^/# /' docker-compose.yml
sed -i.tmp '/# Alternative: Simple auto-managed network/,/# *name: accounting_panel_network/s/^# *//' docker-compose.yml
# Check if we're already using the simple configuration
if grep -q "name: accounting_panel_network" docker-compose.yml; then
echo -e "${YELLOW}Removing custom network name for better service discovery...${NC}"
sed -i.tmp '/name: accounting_panel_network/d' docker-compose.yml
rm docker-compose.yml.tmp 2>/dev/null || true
echo -e "${GREEN}✅ Updated to auto-managed network${NC}"
else
echo -e "${GREEN}✅ Already using auto-managed network${NC}"
fi
rm docker-compose.yml.tmp
echo -e "${GREEN}✅ Switched to auto-managed network${NC}"
echo -e "${YELLOW}💡 Backup saved as docker-compose.yml.backup${NC}"
}

113
setup.sh
View File

@@ -443,13 +443,14 @@ setup_directories() {
update_caddy_config() {
print_header "Updating Caddy Configuration"
# Use simplified Caddy configuration that works without environment variables
cat > docker/caddy/Caddyfile << 'EOF'
if [[ "$DOMAIN" == "localhost" ]]; then
# Localhost configuration - HTTP only, port-based
cat > docker/caddy/Caddyfile << 'EOF'
{
admin off
}
# HTTP server - works on both ports 80 and 8080
# HTTP server for localhost - ports 80 and 8080
:80, :8080 {
root * /var/www/html/public
@@ -463,15 +464,25 @@ update_caddy_config() {
# Enable file server
file_server
# Enable gzip compression
# Enable gzip compression
encode gzip
# PHP handling
php_fastcgi app:9000
}
EOF
else
# Domain-based configuration
if [[ "$SSL_TYPE" == "letsencrypt" ]]; then
# Let's Encrypt configuration - automatic HTTPS
cat > docker/caddy/Caddyfile << EOF
{
admin off
email ${ADMIN_EMAIL}
}
# HTTPS server - default port 443 and 8443
:443, :8443 {
# HTTP and HTTPS for ${DOMAIN}
${DOMAIN} {
root * /var/www/html/public
# Security headers
@@ -492,8 +503,64 @@ update_caddy_config() {
php_fastcgi app:9000
}
EOF
else
# Self-signed certificate configuration
cat > docker/caddy/Caddyfile << EOF
{
admin off
local_certs
}
print_success "Caddy configuration updated"
# HTTP server
:80, :8080 {
root * /var/www/html/public
# Security headers
header {
X-Content-Type-Options nosniff
X-Frame-Options DENY
-Server
}
# Enable file server
file_server
# Enable gzip compression
encode gzip
# PHP handling
php_fastcgi app:9000
}
# HTTPS server with self-signed certificates
:443, :8443 {
root * /var/www/html/public
# Self-signed TLS certificate
tls internal
# Security headers
header {
X-Content-Type-Options nosniff
X-Frame-Options DENY
Strict-Transport-Security "max-age=31536000; includeSubDomains"
-Server
}
# Enable file server
file_server
# Enable gzip compression
encode gzip
# PHP handling
php_fastcgi app:9000
}
EOF
fi
fi
print_success "Caddy configuration updated for $DOMAIN with SSL type: ${SSL_TYPE:-none}"
}
# Build and deploy application
@@ -521,7 +588,22 @@ deploy_application() {
local max_wait=300
local count=0
while ! docker compose ps --format json | jq -r '.[] | select(.Health != null) | .Health' | grep -q "healthy"; do
while true; do
# Check health status using multiple methods for compatibility
local health_status=""
if command -v jq >/dev/null 2>&1; then
# Try different health check formats
health_status=$(docker compose ps --format json 2>/dev/null | jq -r '.[].State // .[].Status // "unknown"' 2>/dev/null | grep -c "running\|healthy" || echo "0")
else
# Fallback without jq - just check if containers are running
health_status=$(docker compose ps --format "table {{.State}}" 2>/dev/null | grep -c "running" || echo "0")
fi
# Check if all expected services are healthy/running (at least 4: app, database, caddy, cron)
if [[ "$health_status" -ge 4 ]]; then
break
fi
if [[ $count -ge $max_wait ]]; then
die "Services failed to become healthy within $max_wait seconds"
fi
@@ -565,11 +647,18 @@ initialize_database() {
run_health_checks() {
print_header "Running Health Checks"
# Check container health
if docker compose ps --format json | jq -r '.[] | select(.Health != null) | .Health' | grep -q "healthy"; then
print_success "All containers are healthy"
# Check container health
local running_services=0
if command -v jq >/dev/null 2>&1; then
running_services=$(docker compose ps --format json 2>/dev/null | jq -r '.[].State // .[].Status // "unknown"' 2>/dev/null | grep -c "running\|healthy" || echo "0")
else
print_warning "Some containers may not be healthy"
running_services=$(docker compose ps --format "table {{.State}}" 2>/dev/null | grep -c "running" || echo "0")
fi
if [[ "$running_services" -ge 4 ]]; then
print_success "All containers are healthy ($running_services services running)"
else
print_warning "Some containers may not be healthy ($running_services services running)"
fi
# Check web server