File Locations
Where pitchfork stores its files.
Directory Resolution
Pitchfork resolves key directories as follows:
| Directory | Resolution Order |
|---|---|
| Home | SUDO_USER's home (when euid=0) → dirs::home_dir() → /tmp |
| Config | PITCHFORK_CONFIG_DIR env → ~/.config/pitchfork |
| State | PITCHFORK_STATE_DIR env → (root + settings.supervisor.user) configured user's ~/.local/state/pitchfork → (sudo) SUDO_USER's ~/.local/state/pitchfork → (non-sudo) dirs::state_dir()/pitchfork → ~/.local/state/pitchfork |
Note: Under root (euid=0),
settings.supervisor.usercontrols the default state directory owner and location when set. Otherwise,sudoinvocations resolve~fromSUDO_USERvia the system password database, anddirs::state_dir()is bypassed to keep paths consistent with non-sudo invocations. On macOSdirs::state_dir()returnsNone, so the fallback~/.local/stateis always used.
Configuration Files
Pitchfork supports configuration files in multiple locations. Files are merged in order, with later files overriding earlier ones.
| Location | Purpose |
|---|---|
/etc/pitchfork/config.toml | System-wide configuration |
~/.config/pitchfork/config.toml | User configuration |
.config/pitchfork.toml | Project configuration |
.config/pitchfork.local.toml | Project configuration |
pitchfork.toml | Project configuration |
pitchfork.local.toml | Local project overrides |
Config File Precedence (lowest to highest)
/etc/pitchfork/config.toml- System-wide (lowest precedence)~/.config/pitchfork/config.toml- User-wide.config/pitchfork.toml- Project-level (in project's.config/subdirectory).config/pitchfork.local.toml- Project-level (in project's.config/subdirectory)pitchfork.toml- Project-level (in project root)pitchfork.local.toml- Local project overrides (highest precedence)
Global Config: Slug Registry
The global config (~/.config/pitchfork/config.toml) also contains the [slugs] section — the single source of truth for reverse proxy slug→project mappings:
[slugs]
api = { dir = "/home/user/my-api", daemon = "server" }
docs = { dir = "/home/user/docs-site" } # daemon defaults to "docs"Manage slugs with pitchfork proxy add / pitchfork proxy remove.
Within a given project directory, files take precedence in this order:
.config/pitchfork.tomlhas lowest precedence in that project.config/pitchfork.local.tomloverrides.config/pitchfork.tomlpitchfork.tomloverrides anything in.config/pitchfork.local.tomloverrides both (typically git-ignored)
State Directory
Location: ~/.local/state/pitchfork/
| File/Directory | Purpose |
|---|---|
state.toml | Persistent daemon state |
logs/ | Daemon log files |
sock/main.sock | Unix socket for CLI-supervisor communication |
State File
~/.local/state/pitchfork/state.toml tracks:
- Known daemons and their status
- Enabled/disabled state
- Last run information
Logs
Each daemon has its own log directory and file. The log path is determined by the daemon's qualified ID (namespace + name):
~/.local/state/pitchfork/logs/<namespace>--<daemon-name>/<namespace>--<daemon-name>.logThe namespace is derived from top-level namespace in the config when present, otherwise from the project directory name (or global for global config files). For example:
- Daemon
apiin projectmyapp→logs/myapp--api/myapp--api.log - Daemon
apiin projectyourapp→logs/yourapp--api/yourapp--api.log - Daemon
postgresin global config →logs/global--postgres/global--postgres.log
The -- separator is used to convert the / in qualified daemon IDs (e.g., myapp/api) to a filesystem-safe format.
Because -- is reserved for this encoding, project directory names containing -- (or other invalid namespace characters) require a top-level namespace override in pitchfork.toml.
See Namespaces for more details on how daemon IDs work across projects.
IPC Socket
~/.local/state/pitchfork/sock/main.sock
Unix domain socket used for communication between CLI commands and the supervisor daemon.
Boot Start Files
Varies by platform:
| Platform | Location |
|---|---|
| macOS | ~/Library/LaunchAgents/com.pitchfork.agent.plist |
| Linux | ~/.config/systemd/user/pitchfork.service |
