Creating MacOS specific documentation, configuration, and examples.

This commit is contained in:
hackdefendr 2026-06-05 16:17:29 -05:00
parent b2096d4a8d
commit 7655a988e7
6 changed files with 673 additions and 4 deletions

207
INSTALL-MACOS.md Normal file
View File

@ -0,0 +1,207 @@
# Installing OliveTin on macOS
> **Draft** — local Markdown draft intended to replace the current stub at
> <https://docs.olivetin.app/install/macos.html>. We'll convert this to AsciiDoc
> for the Antora docs (`docs/` in the OliveTin repo) before opening a PR.
OliveTin runs natively on macOS on both **Apple Silicon (M1/M2/M3/M4)** and
**Intel** Macs. It is a single self-contained binary written in Go — there is no
installer and no background dependencies to install.
---
## 1. Choose the right download
macOS builds are published on the
[GitHub releases page](https://github.com/OliveTin/OliveTin/releases). Pick the
archive that matches your Mac's processor:
| Your Mac | Archive |
|---|---|
| Apple Silicon (M-series) | `OliveTin-darwin-arm64.tar.gz` |
| Intel | `OliveTin-darwin-amd64.tar.gz` |
Not sure which you have? Run this in Terminal:
```sh
uname -m
```
`arm64` → Apple Silicon, `x86_64` → Intel.
> If you download the wrong architecture, macOS will refuse to run it with a
> "Bad CPU type in executable" error.
---
## 2. Extract and place the binary
```sh
# Move to your Downloads folder (adjust if needed)
cd ~/Downloads
# Extract — replace arm64 with amd64 on Intel
tar -xzf OliveTin-darwin-arm64.tar.gz
cd OliveTin-darwin-arm64
```
For a quick try-out you can run it straight from this folder. To install it
system-wide, copy the binary somewhere on your `PATH`:
```sh
sudo cp OliveTin /usr/local/bin/OliveTin
```
---
## 3. Clear the Gatekeeper quarantine
Because the binary is downloaded from the internet and is **not notarized by
Apple**, macOS Gatekeeper will block the first run with a message like
*"OliveTin can't be opened because Apple cannot check it for malicious
software."*
Remove the quarantine attribute so it will run:
```sh
xattr -dr com.apple.quarantine ./OliveTin
```
Alternatively, the first time only, you can right-click the binary in Finder →
**Open**, or approve it under **System Settings → Privacy & Security**.
---
## 4. Create a configuration file
OliveTin looks for a file named `config.yaml` in its **config directory**, which
defaults to the current directory (`.`). You can point elsewhere with
`-configdir /path/to/dir`.
A minimal `config.yaml` to confirm everything works:
```yaml
listenAddressSingleHTTPFrontend: 0.0.0.0:1337
logLevel: "INFO"
actions:
- title: Hello macOS
icon: terminal
shell: echo "Hello from $(scutil --get ComputerName)!"
popupOnStart: execution-dialog-stdout-only
```
For a fuller, macOS-tuned starting point — with working examples for
notifications (`osascript`), `caffeinate`, `pmset`, disk usage, the unified
system log, and Docker — see the **`macos.config.yaml`** that ships alongside
this guide. Copy it in place with:
```sh
cp macos.config.yaml config.yaml
```
---
## 5. Run OliveTin
From the folder that contains both `OliveTin` and `config.yaml`:
```sh
./OliveTin
```
Or, if you installed it to `/usr/local/bin` and keep your config elsewhere:
```sh
OliveTin -configdir /usr/local/etc/OliveTin
```
Then open the web interface at:
```
http://localhost:1337
```
(or `http://<your-mac-hostname>:1337` from another device on your network).
Press **Ctrl-C** in the Terminal to stop it.
---
## 6. Run OliveTin as a background service (launchd)
On Linux, OliveTin is managed by **systemd**. The macOS equivalent is
**launchd**. A ready-to-use service definition ships next to this guide as
[`app.olivetin.olivetin.plist`](app.olivetin.olivetin.plist).
You have two choices:
* **LaunchAgent** (recommended for a desktop Mac) — runs as *your* user, starts
when you log in, no root required.
* **LaunchDaemon** — runs as root, starts at boot before any user logs in. Use
this for a headless / always-on Mac.
### As a LaunchAgent (per-user)
```sh
# Edit the two paths inside the plist to match your install first!
cp app.olivetin.olivetin.plist ~/Library/LaunchAgents/
# Start now and on every login
launchctl load ~/Library/LaunchAgents/app.olivetin.olivetin.plist
```
To stop and disable it:
```sh
launchctl unload ~/Library/LaunchAgents/app.olivetin.olivetin.plist
```
### As a LaunchDaemon (system-wide, at boot)
```sh
sudo cp app.olivetin.olivetin.plist /Library/LaunchDaemons/
sudo chown root:wheel /Library/LaunchDaemons/app.olivetin.olivetin.plist
sudo launchctl load /Library/LaunchDaemons/app.olivetin.olivetin.plist
```
The plist sets `KeepAlive` (restart on crash, equivalent to systemd's
`Restart=always`) and `RunAtLoad` (start immediately). It also writes logs to
`/usr/local/var/log/olivetin.log`.
---
## Troubleshooting
**"Bad CPU type in executable"** — you downloaded the wrong architecture. Get
the `arm64` build for Apple Silicon, `amd64` for Intel (see step 1).
**Gatekeeper still blocks it** — re-run the `xattr -dr com.apple.quarantine`
command in step 3, or approve the app under **System Settings → Privacy &
Security**.
**It runs but the page won't load** — check that nothing else is using port
1337 (`lsof -i :1337`), and that you're browsing to `http://` (not `https://`).
**Reading the logs**
* Running in Terminal: the log is printed directly to the window.
* Running under launchd: tail the log file configured in the plist:
```sh
tail -f /usr/local/var/log/olivetin.log
```
* You can raise detail by setting `logLevel: "DEBUG"` in `config.yaml`.
**Still stuck?** Ask in the
[OliveTin Discord](https://discord.gg/jhYWWpNJ3v) or open an issue on
[GitHub](https://github.com/OliveTin/OliveTin/issues).
---
## Next steps
* [Create your first action](https://docs.olivetin.app/action_execution/create_your_first.html)
* [Configuration reference](https://docs.olivetin.app/)
* [Security & authentication](https://docs.olivetin.app/security/local.html)

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!--
launchd service definition for OliveTin on macOS.
This is the macOS equivalent of the Linux systemd unit (var/systemd/OliveTin.service).
As a per-user LaunchAgent (recommended, no root needed):
cp app.olivetin.olivetin.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/app.olivetin.olivetin.plist # start now + at login
launchctl unload ~/Library/LaunchAgents/app.olivetin.olivetin.plist # stop + disable
As a system-wide LaunchDaemon (starts at boot, before login; needs root):
sudo cp app.olivetin.olivetin.plist /Library/LaunchDaemons/
sudo chown root:wheel /Library/LaunchDaemons/app.olivetin.olivetin.plist
sudo launchctl load /Library/LaunchDaemons/app.olivetin.olivetin.plist
Edit the two paths below to match where you installed the binary and config.
-->
<plist version="1.0">
<dict>
<key>Label</key>
<string>app.olivetin.olivetin</string>
<!-- Path to the OliveTin binary, then flags. -configdir is the directory
that contains your config.yaml. -->
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/OliveTin</string>
<string>-configdir</string>
<string>/usr/local/etc/OliveTin</string>
</array>
<!-- systemd's Restart=always -->
<key>KeepAlive</key>
<true/>
<!-- Start at load (login for a LaunchAgent, boot for a LaunchDaemon) -->
<key>RunAtLoad</key>
<true/>
<!-- Where stdout/stderr go; tail these for troubleshooting -->
<key>StandardOutPath</key>
<string>/usr/local/var/log/olivetin.log</string>
<key>StandardErrorPath</key>
<string>/usr/local/var/log/olivetin.log</string>
</dict>
</plist>

View File

@ -18,6 +18,7 @@
*** xref:install/windows.adoc[Windows] *** xref:install/windows.adoc[Windows]
**** xref:install/windows_service.adoc[Windows Service] **** xref:install/windows_service.adoc[Windows Service]
*** xref:install/macos.adoc[MacOS] *** xref:install/macos.adoc[MacOS]
**** xref:install/macos_service.adoc[MacOS Service]
*** xref:install/choose_package.adoc[All download options] *** xref:install/choose_package.adoc[All download options]
* Upgrade Guide * Upgrade Guide
** xref:upgrade/2k3k.adoc[Understanding 2k vs 3k] ** xref:upgrade/2k3k.adoc[Understanding 2k vs 3k]

View File

@ -1,8 +1,51 @@
= MacOS = macOS
Sorry that these instructions are so primitive, the main developer of OliveTin's MacOS machine died :-( If you can help with instructions and screenshots that would be great. OliveTin runs natively on macOS, on both Apple Silicon (M-series) and Intel Macs. It is a single, self-contained binary - there is no installer and no dependencies to set up.
. There is a .tar.gz that you can download, extract. Link: link:https://github.com/OliveTin/OliveTin/releases/latest/download/OliveTin-darwin-amd64.tar.gz[`OliveTin-darwin-amd64.tar.gz`] If you want OliveTin to run in the background and start automatically, follow the xref:install/macos_service.adoc[install OliveTin as a launchd service] instructions instead.
. Start a terminal and CD into the OliveTin directory.
== Download
macOS builds are published on the link:https://github.com/OliveTin/OliveTin/releases/latest[releases page]. Choose the archive that matches your Mac's processor:
[cols="1,1"]
|===
| Your Mac | Archive
| Apple Silicon (M1/M2/M3/M4)
| link:https://github.com/OliveTin/OliveTin/releases/latest/download/OliveTin-darwin-arm64.tar.gz[`OliveTin-darwin-arm64.tar.gz`]
| Intel
| link:https://github.com/OliveTin/OliveTin/releases/latest/download/OliveTin-darwin-amd64.tar.gz[`OliveTin-darwin-amd64.tar.gz`]
|===
Not sure which you have? Run `uname -m` in Terminal - `arm64` means Apple Silicon, `x86_64` means Intel.
[NOTE]
If you run the wrong architecture, macOS reports `Bad CPU type in executable`. Download the other archive if you see this.
== Extract
Start a terminal, then extract the archive and change into the directory (replace `arm64` with `amd64` on Intel):
[source,shell]
----
tar -xzf OliveTin-darwin-arm64.tar.gz
cd OliveTin-darwin-arm64
----
== Remove the Gatekeeper quarantine
The binary is downloaded from the internet and is not notarized by Apple, so on first run Gatekeeper blocks it with a message like _"OliveTin can't be opened because Apple cannot check it for malicious software."_
Clear the quarantine attribute so it will run:
[source,shell]
----
xattr -dr com.apple.quarantine ./OliveTin
----
[TIP]
Alternatively, the first time only, right-click the binary in Finder and choose *Open*, or approve it under *System Settings -> Privacy & Security*.
include::partial$install/post_generic.adoc[] include::partial$install/post_generic.adoc[]

View File

@ -0,0 +1,109 @@
= macOS launchd service install
This option installs OliveTin as a launchd service, so it runs in the background and starts automatically. This is the macOS equivalent of running OliveTin as a Linux systemd service or a xref:install/windows_service.adoc[Windows service]. If you just want to run OliveTin as a regular application, follow the xref:install/macos.adoc[macOS install] instructions instead.
Before continuing, complete the xref:install/macos.adoc[macOS install] steps (download, extract, and clear the Gatekeeper quarantine) and confirm OliveTin starts correctly by running `./OliveTin`.
== Install the files
Copy the binary somewhere on your `PATH`, and put your configuration in a dedicated directory:
[source,shell]
----
sudo cp OliveTin /usr/local/bin/OliveTin
sudo mkdir -p /usr/local/etc/OliveTin
sudo cp config.yaml /usr/local/etc/OliveTin/config.yaml
----
[NOTE]
OliveTin looks for `config.yaml` in the directory given by the `-configdir` flag, which defaults to the current directory. The service definition below passes `-configdir /usr/local/etc/OliveTin` explicitly.
== Choose LaunchAgent or LaunchDaemon
launchd offers two ways to run a background service:
* *LaunchAgent* - runs as your user and starts when you log in. No root required. Best for a desktop Mac.
* *LaunchDaemon* - runs as root and starts at boot, before any user logs in. Best for a headless, always-on Mac.
== Create the service definition
Create a file named `app.olivetin.olivetin.plist` with the following contents. Adjust the two paths if you installed OliveTin elsewhere.
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>app.olivetin.olivetin</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/OliveTin</string>
<string>-configdir</string>
<string>/usr/local/etc/OliveTin</string>
</array>
<key>KeepAlive</key>
<true/>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>/usr/local/var/log/olivetin.log</string>
<key>StandardErrorPath</key>
<string>/usr/local/var/log/olivetin.log</string>
</dict>
</plist>
----
`KeepAlive` restarts OliveTin if it exits (like systemd's `Restart=always`), and `RunAtLoad` starts it as soon as the service is loaded.
== Register and start the service
=== As a LaunchAgent (per-user)
[source,shell]
----
mkdir -p /usr/local/var/log
cp app.olivetin.olivetin.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/app.olivetin.olivetin.plist
----
To stop and disable it:
[source,shell]
----
launchctl unload ~/Library/LaunchAgents/app.olivetin.olivetin.plist
----
=== As a LaunchDaemon (system-wide, at boot)
[source,shell]
----
sudo mkdir -p /usr/local/var/log
sudo cp app.olivetin.olivetin.plist /Library/LaunchDaemons/
sudo chown root:wheel /Library/LaunchDaemons/app.olivetin.olivetin.plist
sudo launchctl load /Library/LaunchDaemons/app.olivetin.olivetin.plist
----
To stop and disable it:
[source,shell]
----
sudo launchctl unload /Library/LaunchDaemons/app.olivetin.olivetin.plist
----
== Verify
Open http://localhost:1337 in a browser. If the page does not load, check the service log:
[source,shell]
----
tail -f /usr/local/var/log/olivetin.log
----
include::partial$install/post_generic.adoc[]

262
macos.config.yaml Normal file
View File

@ -0,0 +1,262 @@
# =============================================================================
# OliveTin example configuration — macOS (Apple Silicon & Intel)
# =============================================================================
#
# This is a macOS-flavoured version of the stock `example.config.yaml`. Every
# action that differs from the Linux example carries a `# Linux equivalent:`
# comment so you can see exactly what was changed and why.
#
# All commands here are tested against macOS with /bin/zsh (the default login
# shell since macOS Catalina) and also work under /bin/bash. OliveTin runs the
# `shell:` string with `sh -c` by default, so these are written to be portable
# POSIX/zsh/bash one-liners.
#
# To use this file, copy it next to the OliveTin binary as `config.yaml`:
# cp macos.config.yaml config.yaml
# ./OliveTin
#
# Docs: https://docs.olivetin.app/
# =============================================================================
# The built-in micro proxy hosts the WebUI and REST API on a single port.
# Listen on all addresses, port 1337. Open http://localhost:1337 after start.
listenAddressSingleHTTPFrontend: 0.0.0.0:1337
# Choose from INFO (default), WARN and DEBUG.
# Docs: https://docs.olivetin.app/advanced_configuration/logs.html
logLevel: "INFO"
# Actions are commands that OliveTin executes, normally shown as buttons.
# Docs: https://docs.olivetin.app/action_execution/create_your_first.html
actions:
# The simplest possible action: run a command, flash the button for status.
# `ping` works identically on macOS and Linux.
- title: Ping the Internet
shell: ping -c 3 1.1.1.1
icon: ping
popupOnStart: execution-dialog-stdout-only
execOnStartup: true
# Show just the command output in a popup.
#
# Linux equivalent: shell: df -h /media
# macOS has no /media mountpoint. The root volume is `/`; external/USB disks
# mount under /Volumes. `df -h /` shows the boot disk; drop the path to list
# every mounted volume.
- title: Check disk space
icon: disk
shell: df -h /
popupOnStart: execution-dialog-stdout-only
# Show a fuller dialog with details about the command that ran.
#
# Linux equivalent: shell: dmesg | tail
# macOS `dmesg` requires root and is rarely useful. The unified logging
# system is the macOS way to read kernel/system messages. This shows the
# last 2 minutes of high-level system log entries.
- title: Recent system log
shell: log show --last 2m --style compact | tail -n 40
icon: logs
popupOnStart: execution-dialog
# A mini button that links to the logs, with rate limiting and an hourly cron.
# `date` is identical across platforms.
- title: date
shell: date
id: date
timeout: 6
icon: clock
popupOnStart: execution-button
maxRate:
- limit: 3
duration: 1m
execOnCron:
- "@hourly"
# ---------------------------------------------------------------------------
# macOS-native actions (no Linux equivalent — these showcase the platform)
# ---------------------------------------------------------------------------
# Send a real macOS Notification Center banner via AppleScript.
- title: Send a notification
icon: '&#128276;' # bell
shell: osascript -e 'display notification "Triggered from OliveTin" with title "OliveTin" sound name "Glass"'
popupOnStart: execution-button
# Stop the Mac from sleeping for 1 hour (handy during long jobs/downloads).
# `caffeinate` is a built-in macOS utility. `-t` is seconds.
- title: Keep awake for 1 hour
icon: '&#9749;' # hot beverage
shell: caffeinate -d -i -t 3600 &
popupOnStart: execution-button
# Put the displays to sleep immediately (the Mac stays running).
- title: Sleep the displays
icon: '&#128164;' # zzz
shell: pmset displaysleepnow
popupOnStart: execution-button
# Battery / power summary using the built-in `pmset`.
- title: Power & battery status
icon: '&#128267;' # battery
shell: pmset -g batt
popupOnStart: execution-dialog-stdout-only
# ---------------------------------------------------------------------------
# Prompt the user for input with `arguments`. `ping` again works as-is.
# Docs: https://docs.olivetin.app/action_examples/ping.html
- title: Ping host
id: ping_host
shell: ping {{ host }} -c {{ count }}
icon: ping
timeout: 100
popupOnStart: execution-dialog-stdout-only
arguments:
- name: host
title: Host
type: ascii_identifier
default: example.com
description: The host that you want to ping
- name: count
title: Count
type: int
default: 3
description: How many times do you want to ping?
# OliveTin can control Docker containers — `docker` is just a CLI app.
# On macOS this requires Docker Desktop (or colima/podman) to be installed
# and running. The command itself is identical to Linux.
# Docs: https://docs.olivetin.app/solutions/container-control-panel/index.html
- title: Restart Docker Container
icon: restart
shell: docker restart {{ container }}
arguments:
- name: container
title: Container name
choices:
- value: plex
- value: traefik
- value: grafana
# The special `confirmation` argument guards against accidental clicks.
# Docs: https://docs.olivetin.app/args/input_confirmation.html
#
# Linux equivalent: shell: rm -rf /opt/oldBackups/
# Using a path under the user's home is more natural on macOS.
- title: Delete old backups
icon: ashtonished
shell: rm -rf "$HOME/Backups/old/"
arguments:
- name: confirm
type: confirmation
title: Are you sure?!
# Run your own scripts, not just OS commands. `maxConcurrent` prevents
# parallel runs; `timeout` kills a command that runs too long.
#
# Linux equivalent: shell: /opt/backupScript.sh
# macOS convention is to keep personal scripts under your home directory.
- title: Run backup script
shell: "$HOME/bin/backupScript.sh"
shellAfterCompleted: "osascript -e 'display notification \"Backup finished with code {{ exitCode }}\" with title \"OliveTin\"'"
maxConcurrent: 1
timeout: 10
icon: backup
popupOnStart: execution-dialog
# Download themes using a script bundled with OliveTin. You still need to set
# `themeName` in this config to actually use the theme.
# Docs: https://docs.olivetin.app/reference/reference_themes_for_users.html
- title: Get OliveTin Theme
exec:
- "olivetin-get-theme"
- "{{ themeGitRepo }}"
- "{{ themeFolderName }}"
icon: theme
arguments:
- name: themeGitRepo
title: Theme's Git Repository
description: Find new themes at https://olivetin.app/themes
type: url
- name: themeFolderName
title: Theme's Folder Name
type: ascii_identifier
# Run actions on other servers over SSH. macOS ships with an OpenSSH client,
# so this works out of the box. The helper below is optional.
# Docs: https://docs.olivetin.app/action_examples/ssh-easy.html
- title: "Setup easy SSH"
icon: ssh
shell: olivetin-setup-easy-ssh
popupOnStart: execution-dialog
# Entities let you generate actions dynamically from "things" (servers,
# containers, VMs) loaded from files on disk.
# Docs: https://docs.olivetin.app/entities/intro.html
#
# entities:
# - file: entities/servers.yaml
# name: server
# Dashboards organise actions into folders and fieldsets.
# Docs: https://docs.olivetin.app/dashboards/intro.html
#
# dashboards:
# - title: My Mac
# contents:
# - title: Power & battery status
# - title: Sleep the displays
# =============================================================================
# Security - Authentication
# =============================================================================
# If "true", users must log in before doing anything.
authRequireGuestsToLogin: false
# The simplest auth: define users/passwords in this config. OliveTin also
# supports header-based auth, OAuth2 and JWT (documented separately).
# Docs: https://docs.olivetin.app/security/local.html
#
# Generating an argon2id hash on macOS:
# brew install argon2
# echo -n 'yourPassword' | argon2 "$(openssl rand -base64 16)" -id -e
# (Linux equivalent typically uses the distro's `argon2` package directly.)
authLocalUsers:
enabled: true
# users:
# - username: alice
# usergroup: admins
# password: "$argon2id$v=19$m=65536,t=4,p=2$puyxA0s555TSFx7hnFLCXA$PyhLGpZtvpMMvc2DgMWkM8OJMKO55euwV5gm//1iwx4"
# =============================================================================
# Security - Access Control
# =============================================================================
# Policies affect the whole app (eg: ability to view the log list).
# Docs: https://docs.olivetin.app/security/acl.html
defaultPolicy:
showDiagnostics: true
showLogList: true
# Permissions affect individual actions.
defaultPermissions:
view: true
exec: true
logs: true
# ACLs match policy/permissions to users.
accessControlLists:
- name: admin_acl
matchUsergroups: ["admins"]
policy:
showDiagnostics: true
permissions:
view: true
exec: true
logs: true
# OliveTin has many more options not shown here. See docs.olivetin.app.