ARCX is a modern, secure, and structured daemon manager for Linux user space inspired by PM2, written in Go.
- Process supervision with restart policies and graceful shutdown
- Central daemon with Unix socket IPC (CLI ↔ daemon)
- TOML configurations per daemon with validation
- Structured logging with rotation per daemon and for ARCX itself
- Healthchecks (http/tcp/command) and optional hooks
- Security checks for config directory permissions
arcx/
├── cmd/arcx/ # CLI entrypoint
├── internal/
│ ├── daemon/ # Daemon manager and process lifecycle
│ ├── config/ # TOML parsing, validation, security checks
│ ├── ipc/ # Unix socket server + client
│ └── logs/ # Log manager and rotation
├── pkg/types/ # Shared types (config, IPC, status)
├── examples/ # Example daemon configuration(s)
├── arcx.service # systemd service unit (templated)
├── Makefile # Build / test / service helpers
└── go.mod
git clone https://github.com/sammwyy/arcx.git
cd arcx
make build
sudo make installOptional: install as systemd service (recommended for production)
sudo make install-service
sudo make enable-service
sudo make start-service
# Logs (journal):
journalctl -u arcx@$(whoami) -fManual run for development/testing:
# Runs in foreground; press Ctrl+C to stop
arcx daemon --insecurearcx daemon– start ARCX daemon (foreground)arcx list– list all managed daemons and statusarcx start <name>– start a daemonarcx stop <name>– stop a daemonarcx restart <name>– restart a daemonarcx status <name>– show detailed statusarcx logs <name>– tail last logsarcx new --name <name> --cmd <command> [--cwd <dir>]– generate a daemon configarcx add <file.toml>– add an existing TOML config into ARCX
Global flags:
--config-dir(default:~/.config/arcx)--insecure(bypass security checks; for development only)
Daemon configs live under ~/.config/arcx/daemons/*.toml.
Example:
[daemon]
name = "my-app"
cwd = "/home/user/myapp"
exec = "npm run start"
autostart = true
[environment]
inherit_system = true
dotenv = ".env"
vars = { KEY = "VALUE" }
[policy.restart]
mode = "on-failure" # "on-failure" | "always" | "never"
max_retries = 5
delay = "5s"
[policy.healthcheck]
type = "http" # "http" | "tcp" | "command"
target = "http://127.0.0.1:3000/health"
interval = "10s"
timeout = "3s"
retries = 3
[logging]
path = "~/.config/arcx/logs/my-app.log"
rotate = "10MB" # 10MB per file
keep = 5 # number of rotated files to keepOn startup, ARCX verifies that ~/.config/arcx and subdirectories:
- are owned by the current user
- are not world-writable (no 777)
ARCX will refuse to run if permissions are insecure unless --insecure is passed.
- Per-daemon logs under
~/.config/arcx/logs/<name>.logwith rotation - ARCX daemon log under
~/.config/arcx/arcx.log
# deps, build, test
make deps
make build
go test ./...
# end-to-end smoke test
./test.shThis repo includes a templated unit arcx.service (for arcx@user):
[Unit]
Description=ARCX Daemon Manager
After=network.target
[Service]
Type=simple
User=%i
ExecStart=/usr/local/bin/arcx daemon --config-dir /home/%i/.config/arcx
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/home/%i/.config/arcx
[Install]
WantedBy=multi-user.targetMIT