| 1 | <?xml version="1.0" encoding="UTF-8"?> |
| 2 | <!-- |
| 3 | launchd agent for anvil-worker on the build host (docs/remote-runners.md). |
| 4 | |
| 5 | Install: |
| 6 | cp deploy/worker/com.anvil.worker.plist ~/Library/LaunchAgents/ |
| 7 | # edit the paths, URL and token below first |
| 8 | chmod 600 ~/Library/LaunchAgents/com.anvil.worker.plist |
| 9 | launchctl load -w ~/Library/LaunchAgents/com.anvil.worker.plist |
| 10 | |
| 11 | The token sits in this file in plaintext, so keep it 0600 and do not commit |
| 12 | a filled-in copy. It is the credential for every runner on the instance |
| 13 | (`[ci] runner_token`), not one scoped to this machine. |
| 14 | |
| 15 | A LaunchAgent (per-user) rather than a LaunchDaemon (system): Docker Desktop |
| 16 | runs as the logged-in user, so its socket only exists in that user's session. |
| 17 | A root daemon would start before Docker and never find it. |
| 18 | |
| 19 | Run natively like this, NOT in a container. A containerized runner needs the |
| 20 | Docker socket mounted into it, which rebuilds exactly the root-equivalent |
| 21 | hole that moving execution off the forge was meant to remove. |
| 22 | --> |
| 23 | <plist version="1.0"> |
| 24 | <dict> |
| 25 | <key>Label</key> |
| 26 | <string>com.anvil.worker</string> |
| 27 | |
| 28 | <key>ProgramArguments</key> |
| 29 | <array> |
| 30 | <string>/usr/local/bin/anvil-worker</string> |
| 31 | <string>--url</string> |
| 32 | <string>https://anvil.richardscollin.com</string> |
| 33 | <string>--name</string> |
| 34 | <string>macmini</string> |
| 35 | </array> |
| 36 | |
| 37 | <key>EnvironmentVariables</key> |
| 38 | <dict> |
| 39 | <!-- Docker Desktop does not create /var/run/docker.sock unless "Allow |
| 40 | the default Docker socket to be used" is ticked, so point at the |
| 41 | real one. Colima/OrbStack put it elsewhere again. --> |
| 42 | <key>DOCKER_HOST</key> |
| 43 | <string>unix:///Users/collin/.docker/run/docker.sock</string> |
| 44 | <key>ANVIL_RUNNER_TOKEN</key> |
| 45 | <string>REPLACE_ME</string> |
| 46 | </dict> |
| 47 | |
| 48 | <key>RunAtLoad</key> |
| 49 | <true/> |
| 50 | |
| 51 | <!-- The claim loop is meant to run forever; if it exits, something is |
| 52 | wrong and it should come back. --> |
| 53 | <key>KeepAlive</key> |
| 54 | <true/> |
| 55 | |
| 56 | <!-- Do not spin if it is crash-looping (a bad token, no daemon). --> |
| 57 | <key>ThrottleInterval</key> |
| 58 | <integer>30</integer> |
| 59 | |
| 60 | <key>StandardOutPath</key> |
| 61 | <string>/tmp/anvil-worker.log</string> |
| 62 | <key>StandardErrorPath</key> |
| 63 | <string>/tmp/anvil-worker.log</string> |
| 64 | </dict> |
| 65 | </plist> |