# Custom Caddy systemd service file # Combines official Caddy service with enhanced security and API persistence # Generated by Ansible - DO NOT EDIT MANUALLY [Unit] Description=Caddy web server Documentation=https://caddyserver.com/docs/ After=network.target network-online.target Requires=network-online.target [Service] Type=notify User={{ caddy_user }} Group={{ caddy_user }} ExecStart=/usr/bin/caddy run --environ --config {{ caddy_config_file }}{% if caddy_api_enabled %} --resume{% endif %} ExecReload=/usr/bin/caddy reload --config {{ caddy_config_file }} --force {% if caddy_api_enabled %} # Wait for API to be ready before considering service started ExecStartPost=/bin/bash -c 'until curl -s http://{{ caddy_admin_listen }}/config/ >/dev/null 2>&1; do sleep 1; done' {% endif %} # Standard settings from official service TimeoutStopSec=5s LimitNOFILE=1048576 PrivateTmp=true {% if caddy_systemd_security | default(true) %} # Enhanced security hardening NoNewPrivileges=true CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE RemoveIPC=true # Filesystem restrictions (upgrade from ProtectSystem=full) ProtectSystem=strict ProtectHome=true ReadWritePaths={{ caddy_data_dir }} {{ caddy_log_dir }} BindReadOnlyPaths={{ caddy_config_dir }} ProtectKernelTunables=true ProtectKernelModules=true ProtectKernelLogs=true ProtectClock=true # Network and namespace restrictions RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX RestrictNamespaces=true RestrictRealtime=true RestrictSUIDSGID=true # Process restrictions LimitNPROC=1048576 MemoryDenyWriteExecute=true SystemCallFilter=@system-service SystemCallErrorNumber=EPERM # Logging (explicit configuration) StandardOutput=journal StandardError=journal SyslogIdentifier=caddy {% else %} # Standard security from official service ProtectSystem=full AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE {% endif %} [Install] WantedBy=multi-user.target