Add Sigvild Gallery wedding photo application with automated deployment and improve Caddy plugin management
This commit is contained in:
@@ -3,19 +3,35 @@
|
||||
set_fact:
|
||||
dns_challenge_needed: "{{ caddy_dns_provider == 'cloudflare' and cloudflare_api_token != '' }}"
|
||||
|
||||
- name: Check if Caddy is already installed
|
||||
command: /usr/bin/caddy version
|
||||
register: caddy_version_check
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
when: dns_challenge_needed | bool
|
||||
|
||||
- name: Check if installed Caddy has Cloudflare plugin
|
||||
command: /usr/bin/caddy list-modules --packages
|
||||
register: caddy_modules_check
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
when: dns_challenge_needed | bool and caddy_version_check.rc == 0
|
||||
|
||||
- name: Install standard Caddy (if no DNS challenge needed)
|
||||
pacman:
|
||||
name: caddy
|
||||
state: present
|
||||
when: not dns_challenge_needed | bool
|
||||
when: not dns_challenge_needed and not caddy_version_check | bool
|
||||
notify: restart caddy
|
||||
|
||||
- name: Download Caddy with Cloudflare plugin (if DNS challenge needed)
|
||||
get_url:
|
||||
url: "https://caddyserver.com/api/download?os=linux&arch=amd64&p=github.com/caddy-dns/cloudflare"
|
||||
dest: /tmp/caddy-with-cloudflare
|
||||
mode: '0755'
|
||||
when: dns_challenge_needed | bool
|
||||
url: "https://caddyserver.com/api/download?os=linux&arch=amd64&p=github.com/caddy-dns/cloudflare"
|
||||
dest: /tmp/caddy-with-cloudflare
|
||||
mode: '0755'
|
||||
when:
|
||||
- dns_challenge_needed | bool
|
||||
- caddy_version_check.rc != 0 or 'github.com/caddy-dns/cloudflare' not in caddy_modules_check.stdout | default('')
|
||||
|
||||
- name: Install Caddy with Cloudflare plugin
|
||||
copy:
|
||||
@@ -24,7 +40,7 @@
|
||||
mode: '0755'
|
||||
remote_src: yes
|
||||
backup: yes
|
||||
when: dns_challenge_needed | bool
|
||||
when: dns_challenge_needed and caddy_version_check | bool
|
||||
notify: restart caddy
|
||||
|
||||
- name: Clean up temporary Caddy binary
|
||||
|
||||
180
roles/sigvild-gallery/README.md
Normal file
180
roles/sigvild-gallery/README.md
Normal file
@@ -0,0 +1,180 @@
|
||||
# Sigvild Gallery Ansible Role
|
||||
|
||||
Deploys the Sigvild Wedding Gallery application with PocketBase API backend and SvelteKit frontend.
|
||||
|
||||
## Architecture
|
||||
|
||||
- **Backend**: PocketBase-based Go application serving API on localhost:8090
|
||||
- **Frontend**: SvelteKit static site served by Caddy
|
||||
- **Database**: SQLite via PocketBase (file-based storage)
|
||||
- **Authentication**: Shared password system (host/guest users)
|
||||
- **Domains**:
|
||||
- `sigvild.no` → Frontend static files
|
||||
- `api.sigvild.no` → Backend API proxy
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Caddy role deployed and configured
|
||||
- Local sigvild-gallery project with built assets in `build_tmp/`
|
||||
- Vault-encrypted passwords configured in inventory
|
||||
|
||||
## Variables
|
||||
|
||||
### Required Variables
|
||||
|
||||
```yaml
|
||||
# Domains
|
||||
sigvild_gallery_frontend_domain: "sigvild.no"
|
||||
sigvild_gallery_api_domain: "api.sigvild.no"
|
||||
|
||||
# Vault-encrypted passwords
|
||||
vault_sigvild_host_password: "your-encrypted-host-password"
|
||||
vault_sigvild_guest_password: "your-encrypted-guest-password"
|
||||
```
|
||||
|
||||
### Optional Variables
|
||||
|
||||
```yaml
|
||||
# Service configuration
|
||||
sigvild_gallery_user: "sigvild"
|
||||
sigvild_gallery_port: 8090
|
||||
sigvild_gallery_host: "127.0.0.1"
|
||||
|
||||
# Paths
|
||||
sigvild_gallery_home: "/opt/sigvild-gallery"
|
||||
sigvild_gallery_web_root: "/var/www/sigvild-gallery"
|
||||
sigvild_gallery_local_project_path: "{{ ansible_env.PWD }}/sigvild-gallery"
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Full Deployment
|
||||
|
||||
```bash
|
||||
# Deploy complete infrastructure including Sigvild Gallery
|
||||
ansible-playbook site.yml
|
||||
|
||||
# Deploy just Sigvild Gallery
|
||||
ansible-playbook playbooks/deploy-sigvild.yml
|
||||
```
|
||||
|
||||
### Selective Updates
|
||||
|
||||
```bash
|
||||
# Update just the frontend
|
||||
ansible-playbook site.yml --tags="frontend"
|
||||
|
||||
# Update just the backend API
|
||||
ansible-playbook site.yml --tags="backend"
|
||||
|
||||
# Update Caddy configuration
|
||||
ansible-playbook site.yml --tags="caddy"
|
||||
```
|
||||
|
||||
## Security Features
|
||||
|
||||
### Environment Variables
|
||||
- **No .env files**: Secrets managed via systemd Environment directives
|
||||
- **Vault encrypted**: Passwords stored in Ansible vault
|
||||
- **Memory-only**: Environment variables only exist in process memory
|
||||
|
||||
### SystemD Sandboxing
|
||||
- `NoNewPrivileges=yes`: Prevents privilege escalation
|
||||
- `PrivateTmp=yes`: Isolated temporary directory
|
||||
- `ProtectSystem=strict`: Read-only filesystem protection
|
||||
- `ProtectHome=yes`: Home directory protection
|
||||
- `ReadWritePaths`: Only data directory is writable
|
||||
|
||||
### Caddy Security
|
||||
- **Security headers**: XSS protection, frame options, content type sniffing prevention
|
||||
- **CORS configuration**: Restricted to frontend domain
|
||||
- **Rate limiting**: API endpoint protection
|
||||
- **HTTPS only**: Automatic TLS with Let's Encrypt
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
/opt/sigvild-gallery/ # Application home
|
||||
├── sigvild-gallery-server # Go binary
|
||||
└── data/ # PocketBase data directory
|
||||
├── data.db # SQLite database
|
||||
└── storage/ # File uploads
|
||||
|
||||
/var/www/sigvild-gallery/ # Frontend web root
|
||||
├── index.html # SvelteKit build
|
||||
├── _app/ # Application assets
|
||||
└── assets/ # Static assets
|
||||
|
||||
/etc/systemd/system/
|
||||
└── sigvild-gallery.service # SystemD service
|
||||
|
||||
/etc/caddy/sites-enabled/
|
||||
├── sigvild-frontend.caddy # Frontend configuration
|
||||
└── sigvild-api.caddy # API proxy configuration
|
||||
```
|
||||
|
||||
## Build Process
|
||||
|
||||
The role performs local builds then transfers assets:
|
||||
|
||||
1. **Backend**: `GOOS=linux GOARCH=amd64 go build -o sigvild-gallery-server .`
|
||||
2. **Frontend**: `npm run build` in `sigvild-kit/` directory
|
||||
3. **Transfer**: Copy binary and sync frontend build to server
|
||||
4. **Deploy**: Update systemd service and Caddy configuration
|
||||
|
||||
## Service Management
|
||||
|
||||
```bash
|
||||
# Check service status
|
||||
systemctl status sigvild-gallery
|
||||
|
||||
# View logs
|
||||
journalctl -u sigvild-gallery -f
|
||||
|
||||
# Restart service
|
||||
systemctl restart sigvild-gallery
|
||||
|
||||
# Reload Caddy configuration
|
||||
systemctl reload caddy
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Build Failures
|
||||
- Ensure Go toolchain is available locally
|
||||
- Verify `sigvild-kit/` directory exists with `package.json`
|
||||
- Check Node.js and npm are installed for frontend builds
|
||||
|
||||
### Service Startup Issues
|
||||
- Check systemd logs: `journalctl -u sigvild-gallery`
|
||||
- Verify binary permissions and ownership
|
||||
- Ensure data directory is writable by service user
|
||||
|
||||
### Domain Resolution
|
||||
- Verify DNS records point to server IP
|
||||
- Check Caddy logs: `journalctl -u caddy`
|
||||
- Test local connectivity: `curl -H "Host: api.sigvild.no" http://localhost:8090`
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **caddy**: Required for web server and reverse proxy
|
||||
- **systemd**: Service management
|
||||
- **Local build tools**: Go compiler, Node.js/npm
|
||||
|
||||
## Files Created
|
||||
|
||||
- `/etc/systemd/system/sigvild-gallery.service`
|
||||
- `/etc/caddy/sites-enabled/sigvild-frontend.caddy`
|
||||
- `/etc/caddy/sites-enabled/sigvild-api.caddy`
|
||||
- `/opt/sigvild-gallery/` (application directory)
|
||||
- `/var/www/sigvild-gallery/` (frontend files)
|
||||
|
||||
## Tags
|
||||
|
||||
- `sigvild`: Complete Sigvild Gallery deployment
|
||||
- `backend`: API service deployment
|
||||
- `frontend`: Static site deployment
|
||||
- `build`: Local build processes
|
||||
- `service`: SystemD service management
|
||||
- `caddy`: Caddy configuration
|
||||
- `verify`: Post-deployment verification
|
||||
36
roles/sigvild-gallery/defaults/main.yml
Normal file
36
roles/sigvild-gallery/defaults/main.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
# Sigvild Gallery Ansible Role - Default Variables
|
||||
|
||||
# Service Configuration
|
||||
sigvild_gallery_user: sigvild
|
||||
|
||||
# Paths
|
||||
sigvild_gallery_home: /opt/sigvild-gallery
|
||||
sigvild_gallery_web_root: /var/www/sigvild-gallery
|
||||
sigvild_gallery_binary: "{{ sigvild_gallery_home }}/sigvild-gallery"
|
||||
sigvild_gallery_data_dir: "{{ sigvild_gallery_home }}/pb_data"
|
||||
|
||||
# Domains
|
||||
sigvild_gallery_frontend_domain: sigvild.no
|
||||
sigvild_gallery_api_domain: api.sigvild.no
|
||||
|
||||
# Backend Service
|
||||
sigvild_gallery_port: 8090
|
||||
sigvild_gallery_host: "127.0.0.1"
|
||||
|
||||
# Environment Variables (for SystemD service)
|
||||
sigvild_gallery_host_username: host
|
||||
sigvild_gallery_host_password: "{{ vault_sigvild_host_password }}"
|
||||
sigvild_gallery_guest_username: guest
|
||||
sigvild_gallery_guest_password: "{{ vault_sigvild_guest_password }}"
|
||||
|
||||
# Build configuration
|
||||
sigvild_gallery_local_project_path: "{{ ansible_env.PWD }}/sigvild-gallery"
|
||||
|
||||
# Service configuration
|
||||
sigvild_gallery_service_enabled: true
|
||||
sigvild_gallery_service_state: started
|
||||
|
||||
# Caddy integration (assumes caddy role provides these)
|
||||
# caddy_sites_enabled_dir: /etc/caddy/sites-enabled
|
||||
# caddy_user: caddy
|
||||
16
roles/sigvild-gallery/handlers/main.yml
Normal file
16
roles/sigvild-gallery/handlers/main.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
# Sigvild Gallery Handlers
|
||||
|
||||
- name: reload systemd
|
||||
systemd:
|
||||
daemon_reload: yes
|
||||
|
||||
- name: restart sigvild-gallery
|
||||
systemd:
|
||||
name: sigvild-gallery
|
||||
state: restarted
|
||||
|
||||
- name: reload caddy
|
||||
systemd:
|
||||
name: caddy
|
||||
state: reloaded
|
||||
20
roles/sigvild-gallery/meta/main.yml
Normal file
20
roles/sigvild-gallery/meta/main.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
# Role Dependencies
|
||||
dependencies:
|
||||
- role: caddy
|
||||
|
||||
galaxy_info:
|
||||
role_name: sigvild-gallery
|
||||
author: "Rick Infrastructure Team"
|
||||
description: "Deploys Sigvild Wedding Gallery with PocketBase API and SvelteKit frontend"
|
||||
company: ""
|
||||
license: "license (MIT)"
|
||||
min_ansible_version: "2.9"
|
||||
|
||||
platforms:
|
||||
- name: Archlinux
|
||||
versions:
|
||||
- all
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- all
|
||||
43
roles/sigvild-gallery/tasks/deploy_backend.yml
Normal file
43
roles/sigvild-gallery/tasks/deploy_backend.yml
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
# Backend Deployment Tasks
|
||||
|
||||
- name: Build Go binary locally
|
||||
local_action:
|
||||
module: shell
|
||||
cmd: GOOS=linux GOARCH=amd64 go build -o sigvild-gallery .
|
||||
chdir: "{{ sigvild_gallery_local_project_path }}"
|
||||
become: no
|
||||
tags: [backend, build]
|
||||
|
||||
- name: Check if binary was built successfully
|
||||
local_action:
|
||||
module: stat
|
||||
path: "{{ sigvild_gallery_local_project_path }}/sigvild-gallery"
|
||||
register: binary_stat
|
||||
become: no
|
||||
tags: [backend, build]
|
||||
|
||||
- name: Fail if binary doesn't exist
|
||||
fail:
|
||||
msg: "Failed to build sigvild-gallery binary"
|
||||
when: not binary_stat.stat.exists
|
||||
tags: [backend, build]
|
||||
|
||||
- name: Transfer Go binary
|
||||
copy:
|
||||
src: "{{ sigvild_gallery_local_project_path }}/sigvild-gallery"
|
||||
dest: "{{ sigvild_gallery_binary }}"
|
||||
owner: "{{ sigvild_gallery_user }}"
|
||||
group: "{{ sigvild_gallery_user }}"
|
||||
mode: '0755'
|
||||
notify: restart sigvild-gallery
|
||||
tags: [backend]
|
||||
|
||||
- name: Create data directory for PocketBase
|
||||
file:
|
||||
path: "{{ sigvild_gallery_data_dir }}"
|
||||
state: directory
|
||||
owner: "{{ sigvild_gallery_user }}"
|
||||
group: "{{ sigvild_gallery_user }}"
|
||||
mode: '0755'
|
||||
tags: [backend]
|
||||
57
roles/sigvild-gallery/tasks/deploy_frontend.yml
Normal file
57
roles/sigvild-gallery/tasks/deploy_frontend.yml
Normal file
@@ -0,0 +1,57 @@
|
||||
---
|
||||
# Frontend Deployment Tasks
|
||||
|
||||
- name: Check if frontend source exists
|
||||
local_action:
|
||||
module: stat
|
||||
path: "{{ sigvild_gallery_local_project_path }}/sigvild-kit"
|
||||
register: frontend_source
|
||||
become: no
|
||||
tags: [frontend, build]
|
||||
|
||||
- name: Fail if frontend source doesn't exist
|
||||
fail:
|
||||
msg: "Frontend source directory not found at {{ sigvild_gallery_local_project_path }}/sigvild-kit"
|
||||
when: not frontend_source.stat.exists
|
||||
tags: [frontend, build]
|
||||
|
||||
- name: Install frontend dependencies
|
||||
local_action:
|
||||
module: shell
|
||||
cmd: npm install
|
||||
chdir: "{{ sigvild_gallery_local_project_path }}/sigvild-kit"
|
||||
become: no
|
||||
tags: [frontend, build]
|
||||
|
||||
- name: Build frontend for production
|
||||
local_action:
|
||||
module: shell
|
||||
cmd: npm run build:production
|
||||
chdir: "{{ sigvild_gallery_local_project_path }}/sigvild-kit"
|
||||
become: no
|
||||
tags: [frontend, build]
|
||||
|
||||
- name: Check if frontend build exists
|
||||
local_action:
|
||||
module: stat
|
||||
path: "{{ sigvild_gallery_local_project_path }}/sigvild-kit/build"
|
||||
register: frontend_build
|
||||
become: no
|
||||
tags: [frontend, build]
|
||||
|
||||
- name: Fail if frontend build doesn't exist
|
||||
fail:
|
||||
msg: "Frontend build failed - build directory not found"
|
||||
when: not frontend_build.stat.exists
|
||||
become: no
|
||||
tags: [frontend, build]
|
||||
|
||||
- name: Sync frontend files to web root
|
||||
synchronize:
|
||||
src: "{{ sigvild_gallery_local_project_path }}/sigvild-kit/build/"
|
||||
dest: "{{ sigvild_gallery_web_root }}/"
|
||||
delete: yes
|
||||
rsync_opts:
|
||||
- "--exclude=.git"
|
||||
- "--chown={{ sigvild_gallery_user }}:{{ sigvild_gallery_user }}"
|
||||
tags: [frontend]
|
||||
91
roles/sigvild-gallery/tasks/main.yml
Normal file
91
roles/sigvild-gallery/tasks/main.yml
Normal file
@@ -0,0 +1,91 @@
|
||||
---
|
||||
# Sigvild Gallery Deployment Tasks
|
||||
|
||||
- name: Install required packages
|
||||
pacman:
|
||||
name:
|
||||
- rsync
|
||||
state: present
|
||||
- name: Create sigvild gallery user
|
||||
user:
|
||||
name: "{{ sigvild_gallery_user }}"
|
||||
system: yes
|
||||
shell: /bin/bash
|
||||
home: "{{ sigvild_gallery_home }}"
|
||||
create_home: yes
|
||||
|
||||
- name: Create directories
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ sigvild_gallery_user }}"
|
||||
group: "{{ sigvild_gallery_user }}"
|
||||
mode: '0755'
|
||||
loop:
|
||||
- "{{ sigvild_gallery_home }}"
|
||||
- "{{ sigvild_gallery_data_dir }}"
|
||||
- "{{ sigvild_gallery_web_root }}"
|
||||
|
||||
- name: Build and deploy backend
|
||||
include_tasks: deploy_backend.yml
|
||||
tags: [backend, build]
|
||||
|
||||
- name: Build and deploy frontend
|
||||
include_tasks: deploy_frontend.yml
|
||||
tags: [frontend, build]
|
||||
|
||||
- name: Deploy systemd service
|
||||
template:
|
||||
src: sigvild-gallery.service.j2
|
||||
dest: /etc/systemd/system/sigvild-gallery.service
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
notify:
|
||||
- reload systemd
|
||||
- restart sigvild-gallery
|
||||
tags: [backend, service]
|
||||
|
||||
- name: Deploy Caddy configurations
|
||||
template:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ caddy_sites_enabled_dir }}/{{ item.dest }}"
|
||||
owner: root
|
||||
group: "{{ caddy_user }}"
|
||||
mode: '0644'
|
||||
loop:
|
||||
- { src: 'frontend.caddy.j2', dest: 'sigvild-frontend.caddy' }
|
||||
- { src: 'api.caddy.j2', dest: 'sigvild-api.caddy' }
|
||||
notify: reload caddy
|
||||
tags: [caddy, frontend, backend]
|
||||
|
||||
- name: Enable and start sigvild-gallery service
|
||||
systemd:
|
||||
name: sigvild-gallery
|
||||
enabled: "{{ sigvild_gallery_service_enabled }}"
|
||||
state: "{{ sigvild_gallery_service_state }}"
|
||||
daemon_reload: yes
|
||||
tags: [backend, service]
|
||||
|
||||
- name: Create superuser account
|
||||
command: >
|
||||
{{ sigvild_gallery_binary }} superuser upsert
|
||||
"{{ vault_pb_su_email }}"
|
||||
"{{ vault_pb_su_password }}"
|
||||
args:
|
||||
chdir: "{{ sigvild_gallery_home }}"
|
||||
become: yes
|
||||
become_user: "{{ sigvild_gallery_user }}"
|
||||
register: superuser_result
|
||||
failed_when: superuser_result.rc != 0
|
||||
|
||||
- name: Verify gallery health
|
||||
uri:
|
||||
url: "https://{{ sigvild_gallery_api_domain }}/api/health"
|
||||
method: GET
|
||||
status_code: [200, 404] # 404 is ok if health endpoint doesn't exist yet
|
||||
timeout: 15
|
||||
retries: 5
|
||||
delay: 5
|
||||
ignore_errors: yes
|
||||
tags: [verify]
|
||||
45
roles/sigvild-gallery/templates/api.caddy.j2
Normal file
45
roles/sigvild-gallery/templates/api.caddy.j2
Normal 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
|
||||
}
|
||||
}
|
||||
42
roles/sigvild-gallery/templates/frontend.caddy.j2
Normal file
42
roles/sigvild-gallery/templates/frontend.caddy.j2
Normal 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
|
||||
}
|
||||
}
|
||||
36
roles/sigvild-gallery/templates/sigvild-gallery.service.j2
Normal file
36
roles/sigvild-gallery/templates/sigvild-gallery.service.j2
Normal 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
|
||||
Reference in New Issue
Block a user