Canonfig
How-to Guides

Run Canonfig unattended

Keep the Source Machine serving and Follower Machines syncing with nobody at the keyboard, including after a reboot.

After these steps, the Source Machine serves Profile Revisions from a user service that restarts on failure, and each Follower Machine applies them on its Synchronization Schedule, with nobody logged in where the platform allows it.

Before you start

  • The Source Machine is set up with canonfig source init, and each Follower Machine is enrolled.
  • Canonfig installs per-user jobs only. It never installs a system service and never runs sudo for you.
  • A scheduled run cannot answer a prompt. The credential store, and SSH to the Source Machine's host if you use the managed tunnel, must work without one.

What each platform supports:

PlatformRuns while you are logged inRuns while you are logged out
Linuxyesonly with lingering on, and a credential store that is reachable and unlocked (or the local-file policy)
macOSin the logged-in desktop session, with the login Keychain unlockedno
Windowsfrom logon, while you stay logged onno

Keep the Source Machine serving

On the Source Machine:

canonfig source service install
canonfig source service status

install takes the same --host and --port as canonfig source serve (default 127.0.0.1 and 17342), then waits up to 20 seconds for the endpoint to answer with this Source Machine's identity. status reports running. If the endpoint does not answer, install exits 7 and leaves the service installed so you can read its logs.

PlatformWhat install createsRestarts after a failed exitLogs
Linuxsystemd user unit ~/.config/systemd/user/canonfig-source.serviceafter 30 s, with no limitjournalctl --user -u canonfig-source.service
macOSLaunchAgent ~/Library/LaunchAgents/dev.canonfig.source.plistat most every 10 s~/.canonfig/source-service.log
WindowsTask Scheduler task Canonfig\canonfig-source, started at your logonevery minute, up to 999 timesEvent Viewer, Microsoft-Windows-TaskScheduler/Operational

Platform requirements:

  • Linux. The service starts with your systemd user manager, which stops when you log out unless lingering is on (see Headless Linux credential storage). The service gets a fixed PATH: the Node.js directory, /usr/local/bin, /usr/bin, and /bin. A helper installed only under ~/.local/bin, such as secret-tool, is not found. Install it with the system package manager (libsecret-tools), then run canonfig source service install again.

  • macOS. Run install from a terminal in the logged-in desktop session, not over SSH. The service reads the Source Machine's keys from the login Keychain of that session.

  • Windows. A scheduled task does not inherit variables from your shell. If CANONFIG_LOCAL_CREDENTIAL_ROOT is set only in the current shell, install refuses. Make it permanent, open another terminal, and run install again:

    setx CANONFIG_LOCAL_CREDENTIAL_ROOT "C:\Users\maria\.canonfig\credentials"

Read the service status

stateMeaningExitWhat to do
runningThe service runs and answers with this Source Machine's identity.0Nothing.
not-installedNo Source Machine service on this machine.0canonfig source service install
not-runningInstalled, but the service manager does not run it.3Read the logs, fix the cause, run install again.
not-servingRunning, but the endpoint does not answer with this Source Machine's identity.3Read the logs, fix the cause, run install again.
driftedThe installed definition differs from what install writes, for example after Node.js or Canonfig moved.4canonfig source service install

The output also shows serving, the log location, and on Linux whether lingering is on.

To stop supervising the Source Machine, run canonfig source service remove. It stops the service and deletes its definition.

Schedule each Follower Machine

On each Follower Machine:

canonfig schedule set daily@09:00
canonfig schedule status

schedule status reports current when the native job matches your schedule. Every scheduled run executes canonfig sync --apply --no-input --scheduled. For calendars, time zones, and the other states, see Sync on a schedule.

Headless Linux credential storage

Skip this on macOS and Windows. On Linux, the Source Machine's service and the Follower Machine's schedule both stop when you log out unless lingering is on:

loginctl enable-linger "$USER"
loginctl show-user "$USER" --property=Linger

The second command prints Linger=yes. If loginctl refuses, the machine's polkit rules do not let you change it; run sudo loginctl enable-linger "$USER".

Lingering keeps the user manager running. It does not unlock an encrypted login keyring, so check that a background process can read your credentials:

env -i HOME="$HOME" PATH="$PATH" XDG_RUNTIME_DIR="/run/user/$(id -u)" canonfig secrets bootstrap

This runs with the environment a scheduled job has. If it fails:

  • /run/user/<uid>/bus does not exist: no user manager runs for you. Turn lingering on and try again.
  • The keyring is locked: it unlocks when you log in with your password. A machine that reboots and stays logged out keeps it locked.

Do not use dbus-run-session

dbus-run-session starts a private, empty session bus. Its keyring is not your login keyring, and it asks for a graphical prompt nobody can answer.

Machines without a usable keyring

If the machine has no Secret Service, or it stays locked, you can store credentials as plain files with mode 0600 under your home directory. Choose this before Canonfig writes the first credential:

CANONFIG_LOCAL_CREDENTIAL_ROOT="$HOME/.canonfig/credentials" canonfig secrets bootstrap

The output names the local-file policy and reports the storage as unencrypted.

  • Follower Machine: set the variable when you run canonfig follower enroll as well. Enrollment records the policy, so scheduled runs use it without the variable.
  • Source Machine: Canonfig reads the variable on every command. Export it in your shell profile so source init, source publish, and source service install see it; install copies it into the service.

Reconnect to a remote Source Machine after a reboot

Skip this if the Follower Machine and the Source Machine are the same host. A Follower Machine on another host reaches the Source Machine through the managed SSH tunnel it set up during enrollment. Canonfig recorded that tunnel, so you do not need the invitation again.

  1. On the Source Machine, check that it serves:

    canonfig source service status
  2. On the Follower Machine, start the tunnel:

    canonfig tunnel start
    canonfig tunnel status

    tunnel status reports running, down (recorded as running, but the process is gone), stopped, or not-configured.

A scheduled run restarts a down tunnel once before it fetches. A manual canonfig sync does not, and nothing restarts a tunnel you stopped with canonfig tunnel stop. On Linux, the restarted tunnel runs as its own systemd user service, which needs systemd-run and a reachable user manager.

The tunnel runs SSH in batch mode, so SSH to the Source Machine's host must authenticate without a passphrase prompt.

On Windows, a tunnel started from a remote SSH session ends when that session ends. Run canonfig tunnel start from a terminal in your desktop session.

Check that it works

On the Source Machine:

  • canonfig source service status reports running and serving: true.
  • After a reboot (on Linux with lingering, without logging in), it still reports running.

On each Follower Machine:

  • canonfig schedule status reports current, with the timezone and nextRun you expect.
  • With a remote Source Machine, canonfig tunnel status reports running.
  • After the scheduled time, canonfig doctor --no-input shows no failed probe, and its scheduler line says the native scheduler has run the job.

If something fails

MessageCauseFix
"the systemd user manager stops when you log out (Linger=no), so the job only runs while you are logged in" (warning)Lingering is off.See Headless Linux credential storage.
"the systemd user manager is not reachable: this session has no user session bus" (exit 3)You ran the command from a session without a user bus, for example su or a bare SSH command.Run it from a login session of that user, or turn lingering on and retry.
"a Source is already answering at <endpoint> outside the service manager"A canonfig source serve you started by hand holds the port.Stop it, then run canonfig source service install.
"CANONFIG_LOCAL_CREDENTIAL_ROOT is set in this shell only"Windows only: a scheduled task cannot see a variable set in your shell.Run the setx command it prints, open another terminal, and retry. See Keep the Source Machine serving.
"The login Keychain is locked in this SSH or background session"macOS over SSH.security unlock-keychain ~/Library/Keychains/login.keychain-db unlocks it for that SSH session only. Install services and schedules from the desktop session.
"the Task Scheduler task uses an interactive logon, so it only runs while you are logged on to Windows" (warning)A Windows limit.Stay logged on.
"the scheduled run at <time> did not start"Windows: nobody was logged on, the machine was off, or task conditions blocked it. Skipped runs are not caught up.Run canonfig sync --apply and stay logged on at the scheduled time.
"the Source is unreachable because the managed tunnel <endpoint> is down" or "is stopped" (exit 6)The tunnel is not running.Run canonfig tunnel start.
"the Source is reached through the managed tunnel <endpoint>, which is down (...), and restarting it failed"A scheduled run tried to restart the tunnel and failed.Fix the cause it names, then run canonfig tunnel start.
"SSH to <user@host> is connected, but the Source at <host:port> on that host is not answering through the tunnel"SSH works; the Source Machine is not serving.On the Source Machine, check canonfig source service status, then run canonfig tunnel start on the Follower Machine.
"the SSH process for <user@host> exited before the tunnel was ready"SSH failed. The message ends with the SSH log.Fix the SSH error, for example a missing key or a changed host key.
"SSH to <user@host> did not open the forward at <endpoint> within N ms"SSH connected, but the forward did not open in time.Retry with a longer canonfig tunnel start --timeout-ms 60000.

For errors from a sync itself, see Recover from a failed or blocked sync. For each doctor probe, see Doctor probes and exit codes.

On this page