Add Sigvild Gallery wedding photo application with automated deployment and improve Caddy plugin management

This commit is contained in:
2025-11-15 16:13:18 +01:00
parent 8162e789ee
commit 7c3b02e5ad
16 changed files with 923 additions and 10 deletions

View File

@@ -0,0 +1,45 @@
{{ sigvild_gallery_api_domain }} {
reverse_proxy {{ sigvild_gallery_host }}:{{ sigvild_gallery_port }} {
header_up Host {upstream_hostport}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-Proto https
# Health check
health_uri /api/health
health_timeout 5s
health_interval 30s
}
# CORS headers for frontend domain
@cors {
header Origin https://{{ sigvild_gallery_frontend_domain }}
}
header @cors {
Access-Control-Allow-Origin "https://{{ sigvild_gallery_frontend_domain }}"
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, PATCH, OPTIONS"
Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With"
Access-Control-Allow-Credentials true
Access-Control-Max-Age 86400
}
# Handle preflight requests
@preflight {
method OPTIONS
}
respond @preflight 204
# Security headers for API
header {
X-Frame-Options DENY
X-Content-Type-Options nosniff
X-XSS-Protection "1; mode=block"
Referrer-Policy strict-origin-when-cross-origin
}
# API logging
log {
output file /var/log/caddy/sigvild-api.log
level INFO
format json
}
}

View File

@@ -0,0 +1,42 @@
{{ sigvild_gallery_frontend_domain }} {
root * {{ sigvild_gallery_web_root }}
file_server
# SPA routing - serve index.html for all routes
try_files {path} /index.html
# Security headers
header {
X-Frame-Options DENY
X-Content-Type-Options nosniff
X-XSS-Protection "1; mode=block"
Referrer-Policy strict-origin-when-cross-origin
Permissions-Policy "geolocation=(), microphone=(), camera=()"
}
# Cache static assets aggressively
@static {
path /_app/* /assets/* /icons/* *.ico *.png *.jpg *.jpeg *.svg *.webp *.woff *.woff2
}
header @static {
Cache-Control "public, max-age=31536000, immutable"
Vary "Accept-Encoding"
}
# Cache HTML with shorter duration
@html {
path *.html /
}
header @html {
Cache-Control "public, max-age=3600, must-revalidate"
}
# Enable compression
encode gzip
# Logging for debugging (can be removed in production)
log {
output file /var/log/caddy/sigvild-frontend.log
level INFO
}
}

View File

@@ -0,0 +1,36 @@
[Unit]
Description=Sigvild Wedding Gallery API
After=network.target
[Service]
Type=simple
User={{ sigvild_gallery_user }}
Group={{ sigvild_gallery_user }}
WorkingDirectory={{ sigvild_gallery_home }}
ExecStart={{ sigvild_gallery_binary }} serve --http={{ sigvild_gallery_host }}:{{ sigvild_gallery_port }}
# Environment variables
Environment="SIGVILD_ENVIRONMENT"="production" # Lets caddy handle CORS
Environment="HOST_USERNAME={{ sigvild_gallery_host_username }}"
Environment="HOST_PASSWORD={{ sigvild_gallery_host_password }}"
Environment="HOST_DISPLAY_NAME=Wedding Host"
Environment="GUEST_USERNAME={{ sigvild_gallery_guest_username }}"
Environment="GUEST_PASSWORD={{ sigvild_gallery_guest_password }}"
Environment="GUEST_DISPLAY_NAME=Wedding Guest"
# Restart configuration
Restart=always
RestartSec=3
# Security sandboxing
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths={{ sigvild_gallery_data_dir }}
# Allow binding to port (if needed)
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target