Docs

Self-hosted scheduling without GitHub Actions

Postline does not need GitHub Actions, a hosted scheduler, or usage credits. It can stay running on any machine with Node.js 20 or newer and persistent storage.

Install from the GitHub release

Download and install the release package without npm publishing:

npm install --global postline
postline --version

Install Chromium once on machines that render cards:

npx playwright-core@1.64.1 install chromium

Run the built-in daemon

From the content project:

postline daemon --every 15

The first check runs immediately. Later checks run serially at the requested interval, so one daemon never overlaps itself. Configuration and posts are reloaded on every check, and a failed check is logged without stopping the daemon. SIGINT and SIGTERM stop it cleanly.

The machine must remain awake and connected. Keep .postline/ledger.json on persistent storage. While a check runs, postline holds .postline/publish.lock, so a second daemon or a manual postline publish on the same project waits for the next check instead of sending the same post. (--dry-run doesn't take the lock.) A lock left by a process that crashed is cleared automatically on the same machine.

If a process dies during a network request, the durable attempting entry prevents an automatic duplicate, and a request that ends without a clear answer is recorded as uncertain. Inspect the destination and use postline mark or postline retry.

Keep it running with systemd

Copy the example created by postline init and replace every /ABSOLUTE/PATH placeholder:

mkdir -p ~/.config/systemd/user
cp schedulers/systemd/postline.service.example ~/.config/systemd/user/postline.service
systemctl --user daemon-reload
systemctl --user enable --now postline.service
systemctl --user status postline.service
journalctl --user -u postline.service -f

The environment file contains ordinary NAME=value lines for the channels you configured. Restrict it to your account:

chmod 600 /absolute/path/to/postline.env

On a Linux server, enable user lingering if the service must continue after logout:

loginctl enable-linger "$USER"

Other process managers

Launchd, Docker Compose, Kubernetes, PM2, supervisord, and Windows Task Scheduler can all run postline daemon --every 15. If the scheduler invokes one-shot jobs, run postline publish from the content project and ensure jobs cannot overlap.

For disposable runners, use publish --prepare-only, persist the ledger, run publish --resume-prepared, and persist the final ledger. That two-phase sequence is required because the local filesystem disappears between runs.