ifcurl/forgejo/server-config/ifcurl-api.service
Bruno Postle bcf9d58470 service: fix preview pipeline for local Forgejo deployment
- auth.py: catch OSError (not just FileNotFoundError) so ProtectHome=yes
  doesn't crash token lookup — returns None and falls back to anonymous
- git.py: wipe partial bare-clone dir before HTTP fallback so git can retry
  after HTTPS fails (port 443 not available on local HTTP-only Forgejo)
- pyproject.toml: add python-multipart to service deps (FastAPI form data)
- ifcurl-api.service: fix ExecStart path (/opt/ifcurl), set allowed-hosts
  to localhost, add MPLCONFIGDIR to silence matplotlib cache warning
- ifcurl-render.service: fix ExecStart path, add CacheDirectory + MPLCONFIGDIR
- nginx-ifcurl.conf: new file tracking the nginx reverse-proxy config;
  listen on [::]:80 so IPv6 loopback requests reach the Forgejo proxy block

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 23:10:35 +01:00

55 lines
1.8 KiB
Desktop File

[Unit]
Description=ifcurl API service (git fetch + caching + SSRF protection)
Documentation=https://github.com/brunopostle/ifcurl
After=network.target ifcurl-render.service
Requires=ifcurl-render.service
[Service]
Type=simple
User=ifcurl
Group=ifcurl
EnvironmentFile=-/etc/ifcurl/env
# Tell the API service where to find the render service Unix socket
Environment=IFCURL_RENDER_SOCKET=/run/ifcurl/render.sock
ExecStart=/opt/ifcurl/bin/ifcurl serve \
--host 127.0.0.1 \
--port 8000 \
--allowed-hosts localhost
Restart=on-failure
RestartSec=5
# Cache configuration — override in /etc/ifcurl/env:
# IFCURL_CACHE_MAX_GB=10 max bare-repo disk cache
# IFCURL_T2_MAX=8 max IFC blobs in memory
# IFCURL_T3_MAX=64 max selector results in memory
# ---------------------------------------------------------------------------
# Sandbox hardening
#
# The API service fetches from git remotes and reads tokens from
# /etc/ifcurl/env — it needs network access and execve for git CLI calls.
# IFC parsing and rendering are delegated to ifcurl-render.service over
# a Unix socket, so this service never loads ifcopenshell or pyvista.
# ---------------------------------------------------------------------------
Environment=XDG_CACHE_HOME=/var/cache
Environment=MPLCONFIGDIR=/var/cache/ifcurl
CacheDirectory=ifcurl
NoNewPrivileges=yes
RestrictSUIDSGID=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/cache/ifcurl /run/ifcurl
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
RestrictNamespaces=yes
LockPersonality=yes
RestrictRealtime=yes
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
SystemCallArchitectures=native
SystemCallFilter=@system-service @process @files @io-event @network-io
SystemCallErrorNumber=EPERM
[Install]
WantedBy=multi-user.target