Skip to content

Commit 02b4932

Browse files
committed
feat: add native Komodo Periphery addon
1 parent 1ed3543 commit 02b4932

2 files changed

Lines changed: 352 additions & 0 deletions

File tree

‎docs/komodo-periphery.md‎

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Komodo Periphery addon
2+
3+
Install the native Komodo Periphery agent on an existing Debian or Ubuntu Docker
4+
LXC or VM. It runs under systemd and connects outbound to an existing Komodo Core
5+
v2 server. No Komodo Core or database is installed, no Docker TCP socket is exposed,
6+
and Periphery's inbound server is disabled.
7+
8+
For a new Docker host, create a Docker LXC with the existing ProxmoxVE Docker
9+
script, then run this addon **inside that LXC**. Periphery manages that host's
10+
Docker containers and Compose stacks; it does not manage Proxmox LXC/VM resources.
11+
Internet access is required for the shared engine and official Komodo releases.
12+
13+
## Install
14+
15+
Create a Server Onboarding Key in Komodo Core and run inside the Docker guest:
16+
17+
```bash
18+
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/DevScripts/main/tools/addon/komodo-periphery.sh)"
19+
```
20+
21+
Enter the Core URL, a unique server name and the onboarding key. Secret input is
22+
masked. Confirm the server's connection status in Komodo Core after installation:
23+
an active systemd service alone does not confirm successful registration.
24+
25+
For a fork or branch, set the script source explicitly so the generated update
26+
command continues to use it:
27+
28+
```bash
29+
export COMMUNITY_SCRIPTS_URL=https://raw.githubusercontent.com/YOUR_USER/DevScripts/YOUR_BRANCH
30+
bash -c "$(curl -fsSL "$COMMUNITY_SCRIPTS_URL/tools/addon/komodo-periphery.sh")"
31+
```
32+
33+
The same script can be run from a local checkout. Set `COMMUNITY_SCRIPTS_CORE_DIR`
34+
to a local `community-scripts/core` checkout to load the shared helpers locally.
35+
The generated updater downloads its script from `COMMUNITY_SCRIPTS_URL`.
36+
37+
## Configuration
38+
39+
| Variable | Meaning | Default |
40+
| --- | --- | --- |
41+
| `var_komodo_core_address` | Reachable Core URL, such as `https://komodo.example.com` or `http://192.168.1.10:9120` | Prompted |
42+
| `var_komodo_server_name` | Server name to register in Core | Guest hostname |
43+
| `var_komodo_onboarding_key` | Server Onboarding Key | Required; prompted interactively |
44+
| `var_komodo_core_public_key` | Optional trusted Core public key | Pin the first Core to `file:/etc/komodo/keys/core.pub` |
45+
| `var_komodo_agent_version` | `latest` or a stable v2 release, with or without `v` | `latest` |
46+
47+
Supply variables before launching to avoid interaction. HTTPS requires a
48+
certificate trusted by the guest. Core public keys and onboarding keys are
49+
different credentials. The optional public key field allows explicitly pinning
50+
a known Core instead of trusting the first connection.
51+
52+
Configuration is stored in `/etc/komodo/periphery.config.json` with mode `0600`.
53+
Keys and stack/repository data live in `/etc/komodo`. After successful registration,
54+
the onboarding key can be removed from the configuration and revoked in Core.
55+
Preserve `/etc/komodo/keys` for subsequent authenticated connections.
56+
57+
The binary is `/opt/komodo-periphery/periphery`. Upstream publishes x86_64 and
58+
aarch64 Linux binaries. ARM64 execution has not been verified by the contributor.
59+
Alpine is not supported by this systemd addon.
60+
61+
## Updates
62+
63+
```bash
64+
update_komodo_periphery
65+
```
66+
67+
The selected version policy is persisted. To switch to an explicit release,
68+
replace `v2.X.Y` below with a published version compatible with your Core:
69+
70+
```bash
71+
var_komodo_agent_version=v2.X.Y update_komodo_periphery
72+
```
73+
74+
To resume tracking the latest stable v2 release:
75+
76+
```bash
77+
var_komodo_agent_version=latest update_komodo_periphery
78+
```
79+
80+
The addon uses the shared release-check and download helpers. Downloads complete
81+
before the agent is stopped. The previous binary and release cache are backed up
82+
under `/opt/komodo-periphery.backup` and restored if the new agent cannot start.
83+
Configuration, private keys, stacks and repositories are retained.
84+
85+
The addon updates Periphery only. Use the Docker LXC's existing `update` command
86+
for Docker/system maintenance and Komodo for application container updates. The
87+
addon does not replace an existing guest's `update` command. On a guest dedicated
88+
to Periphery, you can explicitly choose the shorter command:
89+
90+
```bash
91+
ln -sf /usr/local/bin/update_komodo_periphery /usr/local/bin/update
92+
```
93+
94+
Verify `command -v update` resolves to this link before using it. Calling this
95+
alias updates Periphery; it does not update Docker or application containers.
96+
97+
## Checks and existing installations
98+
99+
```bash
100+
systemctl status periphery --no-pager
101+
journalctl -u periphery -n 100 --no-pager
102+
docker info
103+
docker compose version
104+
```
105+
106+
If Periphery was installed by another method, the addon refuses to overwrite its
107+
configuration or service. An installation with the same binary/config paths as
108+
this addon can use its update path without replacing configuration. Review those
109+
paths before adopting an existing installation.
110+
111+
Sources: [Komodo setup](https://komo.do/docs/setup/connect-servers),
112+
[upstream systemd installer](https://github.com/moghtech/komodo/blob/main/scripts/setup-periphery.py),
113+
[Periphery configuration](https://github.com/moghtech/komodo/blob/main/config/periphery.config.toml).

‎tools/addon/komodo-periphery.sh‎

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
#!/usr/bin/env bash
2+
3+
# Copyright (c) 2026 community-scripts ORG
4+
# Author: Sofiane A. (soflane)
5+
# License: MIT | https://github.com/community-scripts/DevScripts/raw/main/LICENSE
6+
# Source: https://komo.do/ | https://github.com/moghtech/komodo
7+
8+
for _cs_file in core/core.func lib/tools.func core/error_handler.func; do
9+
if [[ -n "${COMMUNITY_SCRIPTS_CORE_DIR:-}" && -f "${COMMUNITY_SCRIPTS_CORE_DIR}/${_cs_file}" ]]; then
10+
# shellcheck source=/dev/null
11+
source "${COMMUNITY_SCRIPTS_CORE_DIR}/${_cs_file}"
12+
else
13+
# shellcheck source=/dev/null
14+
source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/${_cs_file}")
15+
fi
16+
done
17+
18+
APP="Komodo Periphery"
19+
APP_TYPE="addon"
20+
NSAPP="komodo-periphery"
21+
BACKUP_DIR="/opt/komodo-periphery.backup"
22+
INSTALL_PATH="/opt/komodo-periphery"
23+
CONFIG_PATH="/etc/komodo/periphery.config.json"
24+
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/community-scripts/DevScripts/main}"
25+
26+
load_functions
27+
set -Eeuo pipefail
28+
trap 'error_handler' ERR
29+
header_info
30+
31+
if [[ "$EUID" -ne 0 ]]; then
32+
msg_error "Run the Komodo Periphery addon as root inside a Docker LXC or VM."
33+
exit 1
34+
fi
35+
confirm_not_pve_host
36+
require_debian_like
37+
if [[ ! -d /run/systemd/system ]]; then
38+
msg_error "Komodo Periphery requires a running systemd instance."
39+
exit 238
40+
fi
41+
case "$(uname -m)" in
42+
x86_64 | aarch64 | arm64) ;;
43+
*)
44+
msg_error "Komodo Periphery supports x86_64 and aarch64 only."
45+
exit 238
46+
;;
47+
esac
48+
if ! command -v docker &>/dev/null; then
49+
msg_error "Install Docker first, for example with the Docker LXC script."
50+
exit 237
51+
fi
52+
ensure_docker
53+
$STD docker info
54+
ensure_dependencies git jq
55+
56+
var_komodo_agent_version="${var_komodo_agent_version:-$(cat "${INSTALL_PATH}/version-policy" 2>/dev/null || echo latest)}"
57+
release="$var_komodo_agent_version"
58+
if [[ "$release" == "latest" ]]; then
59+
release=$(get_latest_github_release "moghtech/komodo" false)
60+
fi
61+
if [[ ! "$release" =~ ^v?2\.[0-9]+\.[0-9]+$ ]]; then
62+
msg_error "Choose a stable Komodo v2 release compatible with Core using var_komodo_agent_version."
63+
exit 1
64+
fi
65+
release="v${release#v}"
66+
67+
function write_update_command() {
68+
local scripts_url core_url update_file
69+
printf -v scripts_url '%q' "$COMMUNITY_SCRIPTS_URL"
70+
printf -v core_url '%q' "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}"
71+
msg_info "Creating Komodo Periphery update command"
72+
update_file=$(mktemp /usr/local/bin/.update_komodo_periphery.XXXXXX)
73+
cat <<EOF >"$update_file"
74+
#!/usr/bin/env bash
75+
set -Eeuo pipefail
76+
export COMMUNITY_SCRIPTS_URL=${scripts_url}
77+
export COMMUNITY_SCRIPTS_CORE_URL=${core_url}
78+
addon_script=\$(curl -fsSL "\${COMMUNITY_SCRIPTS_URL}/tools/addon/komodo-periphery.sh")
79+
type=update bash -c "\$addon_script"
80+
EOF
81+
chmod 755 "$update_file"
82+
mv -f "$update_file" /usr/local/bin/update_komodo_periphery
83+
cat <<EOF >"${INSTALL_PATH}/version-policy"
84+
${var_komodo_agent_version}
85+
EOF
86+
chmod 600 "${INSTALL_PATH}/version-policy"
87+
msg_ok "Created Komodo Periphery update command"
88+
}
89+
90+
function update_periphery() {
91+
if [[ ! -x "${INSTALL_PATH}/periphery" || ! -f "$CONFIG_PATH" ]]; then
92+
msg_error "No Komodo Periphery installation managed by this addon was found."
93+
exit 233
94+
fi
95+
96+
local update_status staging_dir
97+
if check_for_gh_release "periphery" "moghtech/komodo" "$release"; then
98+
create_backup "${INSTALL_PATH}/periphery" "$HOME/.periphery"
99+
staging_dir=$(mktemp -d "${INSTALL_PATH}/.download.XXXXXX")
100+
# The release helper caches versions even when the download target is only staging.
101+
if ! FORCE_UPDATE=1 var_appversion="$release" fetch_and_deploy_gh_release \
102+
"periphery" "moghtech/komodo" "singlefile" "$release" "$staging_dir" \
103+
"periphery-$(arch_resolve "x86_64" "aarch64")"; then
104+
restore_backup
105+
rm -rf "$staging_dir"
106+
msg_error "Komodo Periphery download failed. The existing service was kept running."
107+
exit 1
108+
fi
109+
if [[ "$(cat "$HOME/.periphery")" != "${release#v}" ]]; then
110+
restore_backup
111+
rm -rf "$staging_dir"
112+
msg_error "Komodo Periphery download did not match the requested release. Kept the existing agent."
113+
exit 1
114+
fi
115+
116+
msg_info "Replacing Komodo Periphery binary"
117+
systemctl stop periphery
118+
if ! command install -m 755 "$staging_dir/periphery" "${INSTALL_PATH}/periphery.new" ||
119+
! mv -f "${INSTALL_PATH}/periphery.new" "${INSTALL_PATH}/periphery"; then
120+
restore_backup
121+
systemctl start periphery
122+
rm -rf "$staging_dir"
123+
msg_error "Could not replace Komodo Periphery. Restored the previous agent."
124+
exit 1
125+
fi
126+
rm -rf "$staging_dir"
127+
if ! systemctl start periphery || ! sleep 2 || ! systemctl is-active --quiet periphery; then
128+
systemctl stop periphery
129+
restore_backup
130+
systemctl start periphery
131+
msg_error "Komodo Periphery could not start. Restored the previous binary; check journalctl -u periphery."
132+
exit 1
133+
fi
134+
msg_ok "Replaced Komodo Periphery binary"
135+
rm -rf "$BACKUP_DIR"
136+
else
137+
update_status=$?
138+
if [[ "$update_status" -ne 1 ]]; then
139+
msg_error "Could not check Komodo Periphery releases. The existing agent was kept."
140+
exit "$update_status"
141+
fi
142+
systemctl start periphery
143+
$STD systemctl is-active --quiet periphery
144+
fi
145+
write_update_command
146+
msg_ok "Komodo Periphery update completed"
147+
}
148+
149+
function install_periphery() {
150+
if [[ -e "$CONFIG_PATH" || -e /etc/komodo/periphery.config.toml || -e /etc/systemd/system/periphery.service ]]; then
151+
msg_error "An existing Periphery configuration or service was found. Keep it and use its existing updater."
152+
exit 233
153+
fi
154+
var_komodo_core_address=$(prompt_input_required "Komodo Core URL:" "" 120 "var_komodo_core_address")
155+
if [[ -z "$var_komodo_core_address" || "$var_komodo_core_address" == *[[:space:]]* ]]; then
156+
msg_error "A reachable Komodo Core v2 URL without whitespace is required."
157+
exit 1
158+
fi
159+
var_komodo_server_name=$(prompt_input_required "Komodo server name:" "$(hostname)" 120 "var_komodo_server_name")
160+
if [[ -z "${var_komodo_onboarding_key:-}" && -t 0 ]]; then
161+
read -r -s -p "${TAB3}Komodo Server Onboarding Key: " var_komodo_onboarding_key || true
162+
echo
163+
fi
164+
if [[ -z "${var_komodo_onboarding_key:-}" ]]; then
165+
msg_error "Supply var_komodo_onboarding_key or enter a Server Onboarding Key interactively."
166+
exit 1
167+
fi
168+
169+
FORCE_UPDATE=1 var_appversion="$release" fetch_and_deploy_gh_release \
170+
"periphery" "moghtech/komodo" "singlefile" "$release" "$INSTALL_PATH" \
171+
"periphery-$(arch_resolve "x86_64" "aarch64")"
172+
if [[ "$(cat "$HOME/.periphery")" != "${release#v}" ]]; then
173+
msg_error "The downloaded Komodo Periphery release did not match the requested version."
174+
exit 1
175+
fi
176+
177+
msg_info "Configuring Komodo Periphery"
178+
command install -d -m 700 /etc/komodo /etc/komodo/keys
179+
local config_file
180+
config_file=$(mktemp /etc/komodo/.periphery.config.XXXXXX)
181+
# JSON is an upstream-supported format; jq escapes user-supplied credentials and names.
182+
jq -n \
183+
--arg address "$var_komodo_core_address" \
184+
--arg name "$var_komodo_server_name" \
185+
--arg key "$var_komodo_onboarding_key" \
186+
--arg core_key "${var_komodo_core_public_key:-file:/etc/komodo/keys/core.pub}" \
187+
'{root_directory: "/etc/komodo", core_address: $address, connect_as: $name,
188+
onboarding_key: $key, core_public_keys: $core_key, server_enabled: false}' >"$config_file"
189+
chmod 600 "$config_file"
190+
mv -f "$config_file" "$CONFIG_PATH"
191+
unset var_komodo_onboarding_key
192+
msg_ok "Configured Komodo Periphery"
193+
194+
msg_info "Creating Komodo Periphery service"
195+
cat <<'EOF' >/etc/systemd/system/periphery.service
196+
[Unit]
197+
Description=Komodo Periphery agent
198+
Documentation=https://komo.do/docs/setup/connect-servers
199+
Wants=network-online.target
200+
After=network-online.target docker.service
201+
Requires=docker.service
202+
203+
[Service]
204+
Type=simple
205+
User=root
206+
Environment=HOME=/root
207+
WorkingDirectory=/etc/komodo
208+
ExecStart=/opt/komodo-periphery/periphery --config-path /etc/komodo/periphery.config.json
209+
Restart=on-failure
210+
RestartSec=5
211+
UMask=0077
212+
213+
[Install]
214+
WantedBy=multi-user.target
215+
EOF
216+
systemctl enable -q --now periphery
217+
sleep 2
218+
$STD systemctl is-active --quiet periphery
219+
msg_ok "Created Komodo Periphery service"
220+
write_update_command
221+
msg_ok "Confirm the server is connected in Komodo Core. Check journalctl -u periphery if it is not."
222+
}
223+
224+
case "${type:-}" in
225+
update)
226+
update_periphery
227+
;;
228+
"" | install)
229+
if [[ -x "${INSTALL_PATH}/periphery" && -f "$CONFIG_PATH" ]]; then
230+
update_periphery
231+
else
232+
install_periphery
233+
fi
234+
;;
235+
*)
236+
msg_error "Komodo Periphery supports type=install or type=update."
237+
exit 1
238+
;;
239+
esac

0 commit comments

Comments
 (0)