unitup 0.0.9 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +401 -181
- package/docs/index.html +544 -0
- package/index.d.ts +140 -153
- package/package.json +18 -4
- package/src/cli.js +259 -55
- package/src/doctor.js +73 -14
- package/src/index.js +16 -1
- package/src/runtimes/bun.js +46 -0
- package/src/runtimes/common.js +73 -0
- package/src/runtimes/deno.js +46 -0
- package/src/runtimes/elixir.js +46 -0
- package/src/runtimes/go.js +46 -0
- package/src/runtimes/index.js +155 -0
- package/src/runtimes/native.js +38 -0
- package/src/runtimes/node.js +57 -0
- package/src/runtimes/php.js +46 -0
- package/src/runtimes/python.js +46 -0
- package/src/runtimes/ruby.js +46 -0
- package/src/runtimes/shell.js +46 -0
- package/src/systemd.js +262 -30
- package/src/unit.js +59 -21
- package/src/utils.js +139 -4
- package/tsconfig.json +13 -0
package/docs/index.html
ADDED
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" class="light">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<meta name="color-scheme" content="light dark" />
|
|
7
|
+
<meta name="description" content="unitup — Minimal, zero-dependency systemd-native service manager for Node.js, Python, Ruby, PHP, Bun, Deno, Go, Elixir, Shell, and native binaries." />
|
|
8
|
+
<!-- Google tag (gtag.js) -->
|
|
9
|
+
<script async src="https://www.googletagmanager.com/gtag/js?id=G-MEASUREMENT_ID"></script>
|
|
10
|
+
<script>
|
|
11
|
+
window.dataLayer = window.dataLayer || [];
|
|
12
|
+
function gtag(){dataLayer.push(arguments);}
|
|
13
|
+
gtag('js', new Date());
|
|
14
|
+
|
|
15
|
+
gtag('config', 'G-MEASUREMENT_ID');
|
|
16
|
+
</script>
|
|
17
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
18
|
+
<script>
|
|
19
|
+
tailwind.config = { darkMode: 'class' }
|
|
20
|
+
</script>
|
|
21
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css" />
|
|
22
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
|
23
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/bash.min.js"></script>
|
|
24
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/typescript.min.js"></script>
|
|
25
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/yaml.min.js"></script>
|
|
26
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/ini.min.js"></script>
|
|
27
|
+
<style>
|
|
28
|
+
html { scroll-behavior: smooth; }
|
|
29
|
+
pre { tab-size: 2; margin: 0; }
|
|
30
|
+
pre code { padding: 1rem; background: #0f172a; border-radius: 0.75rem; font-size: 0.875rem; }
|
|
31
|
+
code { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; }
|
|
32
|
+
.doc-section { scroll-margin-top: 2rem; }
|
|
33
|
+
table { border-collapse: collapse; width: 100%; }
|
|
34
|
+
th, td { border: 1px solid #e2e8f0; padding: 0.75rem 1rem; text-align: left; }
|
|
35
|
+
th { background: #f8fafc; font-weight: 600; }
|
|
36
|
+
.dark th, .dark td { border-color: #334155; }
|
|
37
|
+
.dark th { background: #1e293b; }
|
|
38
|
+
</style>
|
|
39
|
+
</head>
|
|
40
|
+
<body class="bg-slate-50 text-slate-900 antialiased dark:bg-slate-950 dark:text-slate-100 transition-colors">
|
|
41
|
+
<div class="max-w-6xl mx-auto px-6 py-10">
|
|
42
|
+
<!-- Top Navigation Bar -->
|
|
43
|
+
<div class="flex items-center justify-between mb-10 gap-4 flex-wrap pb-6 border-b border-slate-200 dark:border-slate-800">
|
|
44
|
+
<div class="flex items-center gap-3">
|
|
45
|
+
<span class="text-2xl font-black tracking-tight text-cyan-600 dark:text-cyan-400">unitup</span>
|
|
46
|
+
<span class="text-xs px-2.5 py-0.5 rounded-full bg-cyan-100 text-cyan-800 dark:bg-cyan-950 dark:text-cyan-300 font-semibold border border-cyan-300 dark:border-cyan-800">v0.0.10</span>
|
|
47
|
+
<a href="https://github.com/litepacks/unitup" target="_blank" rel="noopener noreferrer" class="text-slate-500 hover:text-cyan-600 dark:text-slate-400 dark:hover:text-cyan-400 transition-colors" aria-label="GitHub Repository">
|
|
48
|
+
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.53 1.032 1.53 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"/></svg>
|
|
49
|
+
</a>
|
|
50
|
+
</div>
|
|
51
|
+
<nav class="flex flex-wrap gap-x-4 gap-y-2 text-sm font-medium" aria-label="Page sections">
|
|
52
|
+
<a href="#overview" class="text-slate-600 hover:text-cyan-600 dark:text-slate-400 dark:hover:text-cyan-400">Overview</a>
|
|
53
|
+
<a href="#comparison" class="text-slate-600 hover:text-cyan-600 dark:text-slate-400 dark:hover:text-cyan-400">vs PM2</a>
|
|
54
|
+
<a href="#architecture" class="text-slate-600 hover:text-cyan-600 dark:text-slate-400 dark:hover:text-cyan-400">Architecture</a>
|
|
55
|
+
<a href="#runtimes" class="text-slate-600 hover:text-cyan-600 dark:text-slate-400 dark:hover:text-cyan-400">Runtimes</a>
|
|
56
|
+
<a href="#cli" class="text-slate-600 hover:text-cyan-600 dark:text-slate-400 dark:hover:text-cyan-400">CLI Reference</a>
|
|
57
|
+
<a href="#api" class="text-slate-600 hover:text-cyan-600 dark:text-slate-400 dark:hover:text-cyan-400">API</a>
|
|
58
|
+
<a href="#declarative" class="text-slate-600 hover:text-cyan-600 dark:text-slate-400 dark:hover:text-cyan-400">Roadmap</a>
|
|
59
|
+
<a href="#troubleshooting" class="text-slate-600 hover:text-cyan-600 dark:text-slate-400 dark:hover:text-cyan-400">Lingering</a>
|
|
60
|
+
<a href="https://github.com/litepacks/unitup" target="_blank" rel="noopener noreferrer" class="text-cyan-600 dark:text-cyan-400 hover:underline flex items-center gap-1 font-semibold">GitHub →</a>
|
|
61
|
+
</nav>
|
|
62
|
+
<button id="theme-toggle" type="button" class="p-2 rounded-lg border border-slate-200 dark:border-slate-800 text-slate-500 hover:bg-slate-200 dark:hover:bg-slate-800 dark:text-slate-400 shrink-0" aria-label="Toggle dark mode">
|
|
63
|
+
<svg class="w-5 h-5 hidden dark:block" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"/></svg>
|
|
64
|
+
<svg class="w-5 h-5 block dark:hidden" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/></svg>
|
|
65
|
+
</button>
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
<!-- Header / Hero Section -->
|
|
69
|
+
<header class="mb-14">
|
|
70
|
+
<div class="inline-flex items-center gap-2 px-3 py-1 rounded-full text-xs font-semibold bg-cyan-50 dark:bg-cyan-950/60 text-cyan-700 dark:text-cyan-300 border border-cyan-200 dark:border-cyan-800 mb-4">
|
|
71
|
+
⚡ Zero-Daemon · Systemd-Native · Multi-Runtime
|
|
72
|
+
</div>
|
|
73
|
+
<h1 class="text-4xl sm:text-5xl font-extrabold text-slate-900 dark:text-white tracking-tight mb-4">
|
|
74
|
+
Systemd Service Management,<br class="hidden sm:inline" />Simplified for Any App.
|
|
75
|
+
</h1>
|
|
76
|
+
<p class="text-lg text-slate-600 dark:text-slate-400 max-w-3xl leading-relaxed mb-6">
|
|
77
|
+
<strong class="text-slate-800 dark:text-slate-200">unitup</strong> is a zero-dependency CLI & library to run Node.js, Python, Ruby, PHP, Bun, Deno, Go, Elixir, Shell scripts, and compiled native executables as native OS <code class="text-cyan-700 dark:text-cyan-400">systemd</code> user services without requiring <code class="text-cyan-700 dark:text-cyan-400">sudo</code>.
|
|
78
|
+
</p>
|
|
79
|
+
|
|
80
|
+
<!-- Quick Try Code Block -->
|
|
81
|
+
<div class="rounded-xl border border-slate-200 dark:border-slate-800 bg-slate-900 p-4 max-w-2xl shadow-xl">
|
|
82
|
+
<div class="flex items-center justify-between text-xs text-slate-400 mb-2 font-mono border-b border-slate-800 pb-2">
|
|
83
|
+
<span>Quick Start (30-second try)</span>
|
|
84
|
+
<span>bash</span>
|
|
85
|
+
</div>
|
|
86
|
+
<pre><code class="language-bash">npm install -g unitup
|
|
87
|
+
|
|
88
|
+
# Add & start Node.js server
|
|
89
|
+
unitup add server.js --start
|
|
90
|
+
unitup status server
|
|
91
|
+
unitup logs server --follow
|
|
92
|
+
|
|
93
|
+
# Multi-runtime & Native executables
|
|
94
|
+
unitup add worker.py --runtime python --start
|
|
95
|
+
unitup add ./server --runtime native --name api --start</code></pre>
|
|
96
|
+
</div>
|
|
97
|
+
</header>
|
|
98
|
+
|
|
99
|
+
<!-- Section: Overview -->
|
|
100
|
+
<section id="overview" class="doc-section mb-14">
|
|
101
|
+
<h2 class="text-2xl font-bold text-slate-900 dark:text-white mb-4">Core Promises</h2>
|
|
102
|
+
<div class="grid sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
103
|
+
<div class="p-5 rounded-xl border border-slate-200 dark:border-slate-800 bg-white/70 dark:bg-slate-900/50 shadow-sm">
|
|
104
|
+
<div class="text-cyan-600 dark:text-cyan-400 text-xl font-bold mb-1">⚡ No Resident Daemon</div>
|
|
105
|
+
<p class="text-sm text-slate-600 dark:text-slate-400 leading-relaxed">
|
|
106
|
+
Exits immediately after configuring services. Zero persistent memory or CPU overhead from unitup itself.
|
|
107
|
+
</p>
|
|
108
|
+
</div>
|
|
109
|
+
<div class="p-5 rounded-xl border border-slate-200 dark:border-slate-800 bg-white/70 dark:bg-slate-900/50 shadow-sm">
|
|
110
|
+
<div class="text-cyan-600 dark:text-cyan-400 text-xl font-bold mb-1">🌐 Multi-Runtime</div>
|
|
111
|
+
<p class="text-sm text-slate-600 dark:text-slate-400 leading-relaxed">
|
|
112
|
+
Out-of-the-box support for Node.js, Python, Ruby, PHP, Bun, Deno, Go, Elixir, Shell, and native binaries.
|
|
113
|
+
</p>
|
|
114
|
+
</div>
|
|
115
|
+
<div class="p-5 rounded-xl border border-slate-200 dark:border-slate-800 bg-white/70 dark:bg-slate-900/50 shadow-sm">
|
|
116
|
+
<div class="text-cyan-600 dark:text-cyan-400 text-xl font-bold mb-1">🔒 Safe & Transparent</div>
|
|
117
|
+
<p class="text-sm text-slate-600 dark:text-slate-400 leading-relaxed">
|
|
118
|
+
Avoids shell execution (<code class="text-xs">shell: false</code>). Saves standard text unit files directly to <code class="text-xs">~/.config/systemd/user/</code>.
|
|
119
|
+
</p>
|
|
120
|
+
</div>
|
|
121
|
+
<div class="p-5 rounded-xl border border-slate-200 dark:border-slate-800 bg-white/70 dark:bg-slate-900/50 shadow-sm">
|
|
122
|
+
<div class="text-cyan-600 dark:text-cyan-400 text-xl font-bold mb-1">🛠️ Absolute Pathing</div>
|
|
123
|
+
<p class="text-sm text-slate-600 dark:text-slate-400 leading-relaxed">
|
|
124
|
+
Resolves absolute binary & script paths and automatically injects proper <code class="text-xs">PATH</code> environment into unit files.
|
|
125
|
+
</p>
|
|
126
|
+
</div>
|
|
127
|
+
<div class="p-5 rounded-xl border border-slate-200 dark:border-slate-800 bg-white/70 dark:bg-slate-900/50 shadow-sm">
|
|
128
|
+
<div class="text-cyan-600 dark:text-cyan-400 text-xl font-bold mb-1">📦 Zero Dependencies</div>
|
|
129
|
+
<p class="text-sm text-slate-600 dark:text-slate-400 leading-relaxed">
|
|
130
|
+
Built strictly with Node.js standard library modules. Extremely lightweight ESM & CJS footprint.
|
|
131
|
+
</p>
|
|
132
|
+
</div>
|
|
133
|
+
<div class="p-5 rounded-xl border border-slate-200 dark:border-slate-800 bg-white/70 dark:bg-slate-900/50 shadow-sm">
|
|
134
|
+
<div class="text-cyan-600 dark:text-cyan-400 text-xl font-bold mb-1">🔄 100% Backward Compatible</div>
|
|
135
|
+
<p class="text-sm text-slate-600 dark:text-slate-400 leading-relaxed">
|
|
136
|
+
Full support for existing Node.js configurations and legacy metadata formats without breaking changes.
|
|
137
|
+
</p>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
</section>
|
|
141
|
+
|
|
142
|
+
<!-- Section: Comparison -->
|
|
143
|
+
<section id="comparison" class="doc-section mb-14">
|
|
144
|
+
<h2 class="text-2xl font-bold text-slate-900 dark:text-white mb-4">unitup vs PM2</h2>
|
|
145
|
+
<p class="text-slate-600 dark:text-slate-400 mb-6 leading-relaxed">
|
|
146
|
+
<strong class="text-slate-800 dark:text-slate-200">unitup</strong> is not a PM2 replacement or an independent process manager. While PM2 runs its own master daemon, unitup is strictly a thin, transparent CLI layer on top of Linux OS <code class="text-cyan-600 dark:text-cyan-400">systemd</code>.
|
|
147
|
+
</p>
|
|
148
|
+
|
|
149
|
+
<div class="overflow-x-auto">
|
|
150
|
+
<table>
|
|
151
|
+
<thead>
|
|
152
|
+
<tr>
|
|
153
|
+
<th>Feature</th>
|
|
154
|
+
<th>unitup</th>
|
|
155
|
+
<th>PM2</th>
|
|
156
|
+
</tr>
|
|
157
|
+
</thead>
|
|
158
|
+
<tbody class="text-sm">
|
|
159
|
+
<tr>
|
|
160
|
+
<td class="font-semibold">Background Process (Daemon)</td>
|
|
161
|
+
<td><strong class="text-emerald-600 dark:text-emerald-400">No resident daemon</strong>. Systemd directly supervises processes.</td>
|
|
162
|
+
<td>Runs a persistent process-management daemon.</td>
|
|
163
|
+
</tr>
|
|
164
|
+
<tr>
|
|
165
|
+
<td class="font-semibold">System Integration</td>
|
|
166
|
+
<td>Native Linux OS <code class="text-xs">systemd</code> user service (<code class="text-xs">~/.config/systemd/user/</code>).</td>
|
|
167
|
+
<td>Custom process monitoring via PM2's internal daemon.</td>
|
|
168
|
+
</tr>
|
|
169
|
+
<tr>
|
|
170
|
+
<td class="font-semibold">Multi-Runtime Support</td>
|
|
171
|
+
<td><strong class="text-emerald-600 dark:text-emerald-400">Node, Python, Ruby, PHP, Bun, Deno, Go, Elixir, Shell, Native Binaries</strong>.</td>
|
|
172
|
+
<td>Node.js-focused process manager with support for running other commands.</td>
|
|
173
|
+
</tr>
|
|
174
|
+
<tr>
|
|
175
|
+
<td class="font-semibold">Privileges Required</td>
|
|
176
|
+
<td>Does <strong class="text-emerald-600 dark:text-emerald-400">not</strong> require <code class="text-xs">sudo</code> for normal service creation and management.</td>
|
|
177
|
+
<td>Boot integration commonly requires running PM2 startup with elevated privileges.</td>
|
|
178
|
+
</tr>
|
|
179
|
+
<tr>
|
|
180
|
+
<td class="font-semibold">Dependencies</td>
|
|
181
|
+
<td><strong class="text-emerald-600 dark:text-emerald-400">0 Runtime Dependencies</strong> (Node.js standard modules only).</td>
|
|
182
|
+
<td>Dozens of 3rd party npm packages.</td>
|
|
183
|
+
</tr>
|
|
184
|
+
<tr>
|
|
185
|
+
<td class="font-semibold">Log Management</td>
|
|
186
|
+
<td>Delegates 100% to native Linux <code class="text-xs">journald</code> system (<code class="text-xs">journalctl</code>).</td>
|
|
187
|
+
<td>Manages <code class="text-xs">.pm2/logs</code> files (requires <code class="text-xs">pm2-logrotate</code> plugin).</td>
|
|
188
|
+
</tr>
|
|
189
|
+
<tr>
|
|
190
|
+
<td class="font-semibold">Boot Startup</td>
|
|
191
|
+
<td>Native systemd lingering (<code class="text-xs">loginctl enable-linger</code>).</td>
|
|
192
|
+
<td>Custom startup script launching PM2 master daemon.</td>
|
|
193
|
+
</tr>
|
|
194
|
+
</tbody>
|
|
195
|
+
</table>
|
|
196
|
+
</div>
|
|
197
|
+
</section>
|
|
198
|
+
|
|
199
|
+
<!-- Section: Architecture -->
|
|
200
|
+
<section id="architecture" class="doc-section mb-14">
|
|
201
|
+
<h2 class="text-2xl font-bold text-slate-900 dark:text-white mb-4">Core Architecture</h2>
|
|
202
|
+
<p class="text-slate-600 dark:text-slate-400 mb-6 leading-relaxed">
|
|
203
|
+
At its core, unitup generates systemd service unit files directly from a generic <code class="text-cyan-600 dark:text-cyan-400">command + args</code> model rather than being hardcoded to Node.js:
|
|
204
|
+
</p>
|
|
205
|
+
|
|
206
|
+
<div class="grid md:grid-cols-2 gap-6">
|
|
207
|
+
<div>
|
|
208
|
+
<h3 class="text-sm font-semibold uppercase tracking-wider text-cyan-600 dark:text-cyan-400 mb-2">JSON Execution Model</h3>
|
|
209
|
+
<pre><code class="language-json">{
|
|
210
|
+
"command": "/usr/bin/python3",
|
|
211
|
+
"args": ["/home/user/apps/worker.py"],
|
|
212
|
+
"cwd": "/home/user/apps",
|
|
213
|
+
"env": {
|
|
214
|
+
"APP_ENV": "production"
|
|
215
|
+
}
|
|
216
|
+
}</code></pre>
|
|
217
|
+
</div>
|
|
218
|
+
<div>
|
|
219
|
+
<h3 class="text-sm font-semibold uppercase tracking-wider text-cyan-600 dark:text-cyan-400 mb-2">Generated Unit File (<code class="text-xs">unitup-worker.service</code>)</h3>
|
|
220
|
+
<pre><code class="language-ini">[Unit]
|
|
221
|
+
Description=unitup service: worker
|
|
222
|
+
After=network.target
|
|
223
|
+
|
|
224
|
+
[Service]
|
|
225
|
+
Type=simple
|
|
226
|
+
SyslogIdentifier=unitup-worker
|
|
227
|
+
WorkingDirectory=/home/user/apps
|
|
228
|
+
ExecStart=/usr/bin/python3 /home/user/apps/worker.py
|
|
229
|
+
Restart=on-failure
|
|
230
|
+
RestartSec=3
|
|
231
|
+
Environment=PATH="/usr/bin:/usr/local/bin:/bin"
|
|
232
|
+
Environment=APP_ENV="production"
|
|
233
|
+
|
|
234
|
+
[Install]
|
|
235
|
+
WantedBy=default.target</code></pre>
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
</section>
|
|
239
|
+
|
|
240
|
+
<!-- Section: Runtimes -->
|
|
241
|
+
<section id="runtimes" class="doc-section mb-14">
|
|
242
|
+
<h2 class="text-2xl font-bold text-slate-900 dark:text-white mb-4">Supported Runtimes & Auto-Detection</h2>
|
|
243
|
+
|
|
244
|
+
<div class="overflow-x-auto mb-6">
|
|
245
|
+
<table>
|
|
246
|
+
<thead>
|
|
247
|
+
<tr>
|
|
248
|
+
<th>Runtime</th>
|
|
249
|
+
<th>Extension / Auto-Detection</th>
|
|
250
|
+
<th>Command Executed</th>
|
|
251
|
+
</tr>
|
|
252
|
+
</thead>
|
|
253
|
+
<tbody class="text-sm">
|
|
254
|
+
<tr>
|
|
255
|
+
<td class="font-semibold text-cyan-600 dark:text-cyan-400">Node.js</td>
|
|
256
|
+
<td><code class="text-xs">.js, .mjs, .cjs</code> or shebang <code class="text-xs">#!/usr/bin/env node</code></td>
|
|
257
|
+
<td><code class="text-xs">node <script></code></td>
|
|
258
|
+
</tr>
|
|
259
|
+
<tr>
|
|
260
|
+
<td class="font-semibold text-cyan-600 dark:text-cyan-400">Python</td>
|
|
261
|
+
<td><code class="text-xs">.py</code> or shebang <code class="text-xs">#!/usr/bin/env python3</code></td>
|
|
262
|
+
<td><code class="text-xs">python3 <script></code></td>
|
|
263
|
+
</tr>
|
|
264
|
+
<tr>
|
|
265
|
+
<td class="font-semibold text-cyan-600 dark:text-cyan-400">Ruby</td>
|
|
266
|
+
<td><code class="text-xs">.rb</code> or shebang <code class="text-xs">#!/usr/bin/env ruby</code></td>
|
|
267
|
+
<td><code class="text-xs">ruby <script></code></td>
|
|
268
|
+
</tr>
|
|
269
|
+
<tr>
|
|
270
|
+
<td class="font-semibold text-cyan-600 dark:text-cyan-400">PHP</td>
|
|
271
|
+
<td><code class="text-xs">.php</code> or shebang <code class="text-xs">#!/usr/bin/env php</code></td>
|
|
272
|
+
<td><code class="text-xs">php <script></code> (Supports <code class="text-xs">-S 0.0.0.0:8080</code>)</td>
|
|
273
|
+
</tr>
|
|
274
|
+
<tr>
|
|
275
|
+
<td class="font-semibold text-cyan-600 dark:text-cyan-400">Bun</td>
|
|
276
|
+
<td>Explicit <code class="text-xs">--runtime bun</code> or shebang <code class="text-xs">#!/usr/bin/env bun</code></td>
|
|
277
|
+
<td><code class="text-xs">bun <script></code></td>
|
|
278
|
+
</tr>
|
|
279
|
+
<tr>
|
|
280
|
+
<td class="font-semibold text-cyan-600 dark:text-cyan-400">Deno</td>
|
|
281
|
+
<td>Explicit <code class="text-xs">--runtime deno</code> or shebang <code class="text-xs">#!/usr/bin/env deno</code></td>
|
|
282
|
+
<td><code class="text-xs">deno run <script></code></td>
|
|
283
|
+
</tr>
|
|
284
|
+
<tr>
|
|
285
|
+
<td class="font-semibold text-cyan-600 dark:text-cyan-400">Go</td>
|
|
286
|
+
<td><code class="text-xs">.go</code> or shebang <code class="text-xs">#!/usr/bin/env go</code></td>
|
|
287
|
+
<td><code class="text-xs">go run <script></code></td>
|
|
288
|
+
</tr>
|
|
289
|
+
<tr>
|
|
290
|
+
<td class="font-semibold text-cyan-600 dark:text-cyan-400">Elixir</td>
|
|
291
|
+
<td><code class="text-xs">.ex, .exs</code> or shebang <code class="text-xs">#!/usr/bin/env elixir</code></td>
|
|
292
|
+
<td><code class="text-xs">elixir <script></code></td>
|
|
293
|
+
</tr>
|
|
294
|
+
<tr>
|
|
295
|
+
<td class="font-semibold text-cyan-600 dark:text-cyan-400">Shell</td>
|
|
296
|
+
<td><code class="text-xs">.sh</code> or shebang <code class="text-xs">#!/bin/bash</code> / <code class="text-xs">#!/bin/sh</code></td>
|
|
297
|
+
<td><code class="text-xs">bash <script></code></td>
|
|
298
|
+
</tr>
|
|
299
|
+
<tr>
|
|
300
|
+
<td class="font-semibold text-cyan-600 dark:text-cyan-400">Native Executable</td>
|
|
301
|
+
<td>Explicit <code class="text-xs">--runtime native</code></td>
|
|
302
|
+
<td>Direct binary execution (<code class="text-xs">./server</code>)</td>
|
|
303
|
+
</tr>
|
|
304
|
+
</tbody>
|
|
305
|
+
</table>
|
|
306
|
+
</div>
|
|
307
|
+
|
|
308
|
+
<div class="p-4 rounded-xl border border-amber-200 dark:border-amber-900/60 bg-amber-50/60 dark:bg-amber-950/20 text-sm text-amber-900 dark:text-amber-300">
|
|
309
|
+
💡 <strong>Go Production Recommendation:</strong> For production deployments, compiling the Go application and registering the resulting native binary (<code class="text-xs">unitup add ./server --runtime native</code>) is recommended instead of <code class="text-xs">go run</code>.
|
|
310
|
+
</div>
|
|
311
|
+
</section>
|
|
312
|
+
|
|
313
|
+
<!-- Section: CLI Reference -->
|
|
314
|
+
<section id="cli" class="doc-section mb-14">
|
|
315
|
+
<h2 class="text-2xl font-bold text-slate-900 dark:text-white mb-6">CLI Reference</h2>
|
|
316
|
+
|
|
317
|
+
<div class="space-y-6">
|
|
318
|
+
<!-- doctor -->
|
|
319
|
+
<div class="p-5 rounded-xl border border-slate-200 dark:border-slate-800 bg-white/70 dark:bg-slate-900/50">
|
|
320
|
+
<h3 class="text-lg font-bold text-cyan-600 dark:text-cyan-400 mb-2"><code class="text-base">unitup doctor</code></h3>
|
|
321
|
+
<p class="text-sm text-slate-600 dark:text-slate-400 mb-3">Runs system readiness diagnostics (Linux OS, systemd PID 1, user bus, lingering, unit directory permissions, and detected runtimes).</p>
|
|
322
|
+
<pre><code class="language-bash">unitup doctor</code></pre>
|
|
323
|
+
</div>
|
|
324
|
+
|
|
325
|
+
<!-- add -->
|
|
326
|
+
<div class="p-5 rounded-xl border border-slate-200 dark:border-slate-800 bg-white/70 dark:bg-slate-900/50">
|
|
327
|
+
<h3 class="text-lg font-bold text-cyan-600 dark:text-cyan-400 mb-2"><code class="text-base">unitup add <script|exec> [options]</code></h3>
|
|
328
|
+
<p class="text-sm text-slate-600 dark:text-slate-400 mb-3">Generates and registers a new systemd user service unit file.</p>
|
|
329
|
+
<pre><code class="language-bash"># Flags:
|
|
330
|
+
# --name <name> Service name (default: script basename)
|
|
331
|
+
# --runtime <name> Specify runtime (node, python, ruby, php, bun, deno, shell, go, elixir, native)
|
|
332
|
+
# --runtime-arg <val> Argument passed to binary (e.g. -S 0.0.0.0:8080 or --allow-net)
|
|
333
|
+
# --command <path> Explicit binary executable (bypasses auto-detection)
|
|
334
|
+
# --arg <val> Argument to pass to command
|
|
335
|
+
# --group <group> Assign service to group (default: default)
|
|
336
|
+
# --env KEY=val Set environment variable
|
|
337
|
+
# --env-file <path> Load environment file
|
|
338
|
+
# --start Enable and start service immediately
|
|
339
|
+
# --force, -f Force overwrite of currently running service
|
|
340
|
+
|
|
341
|
+
unitup add worker.py --name worker --group backend --env APP_ENV=production --start</code></pre>
|
|
342
|
+
</div>
|
|
343
|
+
|
|
344
|
+
<!-- list / ls -->
|
|
345
|
+
<div class="p-5 rounded-xl border border-slate-200 dark:border-slate-800 bg-white/70 dark:bg-slate-900/50">
|
|
346
|
+
<h3 class="text-lg font-bold text-cyan-600 dark:text-cyan-400 mb-2"><code class="text-base">unitup list</code> / <code class="text-base">unitup ls</code></h3>
|
|
347
|
+
<p class="text-sm text-slate-600 dark:text-slate-400 mb-3">Lists all managed services in a clean aligned table.</p>
|
|
348
|
+
<pre><code class="language-bash">unitup list --group backend</code></pre>
|
|
349
|
+
</div>
|
|
350
|
+
|
|
351
|
+
<!-- inspect -->
|
|
352
|
+
<div class="p-5 rounded-xl border border-slate-200 dark:border-slate-800 bg-white/70 dark:bg-slate-900/50">
|
|
353
|
+
<h3 class="text-lg font-bold text-cyan-600 dark:text-cyan-400 mb-2"><code class="text-base">unitup inspect <name></code></h3>
|
|
354
|
+
<p class="text-sm text-slate-600 dark:text-slate-400 mb-3">Displays full service configuration overview (Command, Arguments, Working directory, Unit file) without revealing secrets or environment variables.</p>
|
|
355
|
+
<pre><code class="language-bash">unitup inspect worker</code></pre>
|
|
356
|
+
</div>
|
|
357
|
+
|
|
358
|
+
<!-- start / stop / restart -->
|
|
359
|
+
<div class="p-5 rounded-xl border border-slate-200 dark:border-slate-800 bg-white/70 dark:bg-slate-900/50">
|
|
360
|
+
<h3 class="text-lg font-bold text-cyan-600 dark:text-cyan-400 mb-2"><code class="text-base">unitup start / stop / restart <name|@group></code></h3>
|
|
361
|
+
<p class="text-sm text-slate-600 dark:text-slate-400 mb-3">Controls service state individually or in batch using <code class="text-xs">@group</code> syntax.</p>
|
|
362
|
+
<pre><code class="language-bash">unitup start @backend --enable
|
|
363
|
+
unitup restart worker
|
|
364
|
+
unitup stop @backend</code></pre>
|
|
365
|
+
</div>
|
|
366
|
+
|
|
367
|
+
<!-- limits -->
|
|
368
|
+
<div class="p-5 rounded-xl border border-slate-200 dark:border-slate-800 bg-white/70 dark:bg-slate-900/50">
|
|
369
|
+
<h3 class="text-lg font-bold text-cyan-600 dark:text-cyan-400 mb-2"><code class="text-base">unitup limits <name> [options]</code></h3>
|
|
370
|
+
<p class="text-sm text-slate-600 dark:text-slate-400 mb-3">Configures native systemd memory limits for a service or resets limits back to system defaults.</p>
|
|
371
|
+
<pre><code class="language-bash">unitup limits api --memory-high 400M --memory-max 512M --swap-max 256M
|
|
372
|
+
unitup limits api --reset-memory</code></pre>
|
|
373
|
+
</div>
|
|
374
|
+
|
|
375
|
+
<!-- status & logs -->
|
|
376
|
+
<div class="p-5 rounded-xl border border-slate-200 dark:border-slate-800 bg-white/70 dark:bg-slate-900/50">
|
|
377
|
+
<h3 class="text-lg font-bold text-cyan-600 dark:text-cyan-400 mb-2"><code class="text-base">unitup status / logs <name></code></h3>
|
|
378
|
+
<p class="text-sm text-slate-600 dark:text-slate-400 mb-3">Inspects process status with live memory metrics or streams journalctl logs with advanced filtering.</p>
|
|
379
|
+
<pre><code class="language-bash">unitup status worker
|
|
380
|
+
unitup logs worker --follow --since 1h --priority err --json</code></pre>
|
|
381
|
+
</div>
|
|
382
|
+
|
|
383
|
+
<!-- journal -->
|
|
384
|
+
<div class="p-5 rounded-xl border border-slate-200 dark:border-slate-800 bg-white/70 dark:bg-slate-900/50">
|
|
385
|
+
<h3 class="text-lg font-bold text-cyan-600 dark:text-cyan-400 mb-2"><code class="text-base">unitup journal <action> [options]</code></h3>
|
|
386
|
+
<p class="text-sm text-slate-600 dark:text-slate-400 mb-3">Performs safe journalctl storage maintenance (disk-usage, rotate, vacuum by size, time, or file count).</p>
|
|
387
|
+
<pre><code class="language-bash">unitup journal disk-usage
|
|
388
|
+
unitup journal rotate
|
|
389
|
+
unitup journal vacuum --size 500M --yes
|
|
390
|
+
unitup journal vacuum --time 14d --dry-run</code></pre>
|
|
391
|
+
</div>
|
|
392
|
+
|
|
393
|
+
<!-- remove -->
|
|
394
|
+
<div class="p-5 rounded-xl border border-slate-200 dark:border-slate-800 bg-white/70 dark:bg-slate-900/50">
|
|
395
|
+
<h3 class="text-lg font-bold text-cyan-600 dark:text-cyan-400 mb-2"><code class="text-base">unitup remove <name|@group> [--force]</code></h3>
|
|
396
|
+
<p class="text-sm text-slate-600 dark:text-slate-400 mb-3">Stops, disables, and deletes a service or group. Active running services require <code class="text-xs">--force</code> / <code class="text-xs">-f</code> to prevent accidental deletion.</p>
|
|
397
|
+
<pre><code class="language-bash">unitup remove worker
|
|
398
|
+
unitup remove @backend --force</code></pre>
|
|
399
|
+
</div>
|
|
400
|
+
</div>
|
|
401
|
+
</section>
|
|
402
|
+
|
|
403
|
+
<!-- Section: API -->
|
|
404
|
+
<section id="api" class="doc-section mb-14">
|
|
405
|
+
<h2 class="text-2xl font-bold text-slate-900 dark:text-white mb-4">Programmatic API</h2>
|
|
406
|
+
<p class="text-slate-600 dark:text-slate-400 mb-6 leading-relaxed">
|
|
407
|
+
unitup exports full ESM and CommonJS interfaces with TypeScript declarations (<code class="text-cyan-600 dark:text-cyan-400">index.d.ts</code>).
|
|
408
|
+
</p>
|
|
409
|
+
|
|
410
|
+
<div class="space-y-6">
|
|
411
|
+
<div>
|
|
412
|
+
<h3 class="text-sm font-semibold uppercase tracking-wider text-cyan-600 dark:text-cyan-400 mb-2">ESM / TypeScript Example</h3>
|
|
413
|
+
<pre><code class="language-typescript">import {
|
|
414
|
+
createService,
|
|
415
|
+
startService,
|
|
416
|
+
stopService,
|
|
417
|
+
restartService,
|
|
418
|
+
getServiceStatus,
|
|
419
|
+
listServices,
|
|
420
|
+
isSystemdAvailable
|
|
421
|
+
} from "unitup";
|
|
422
|
+
|
|
423
|
+
import type {
|
|
424
|
+
CreateServiceOptions,
|
|
425
|
+
ServiceStatus
|
|
426
|
+
} from "unitup";
|
|
427
|
+
|
|
428
|
+
if (await isSystemdAvailable()) {
|
|
429
|
+
// Add service with explicit command + args
|
|
430
|
+
await createService({
|
|
431
|
+
name: "worker",
|
|
432
|
+
command: "/usr/bin/python3",
|
|
433
|
+
args: ["/home/user/apps/worker.py"],
|
|
434
|
+
cwd: "/home/user/apps",
|
|
435
|
+
restart: "on-failure",
|
|
436
|
+
start: true
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
const status: ServiceStatus = await getServiceStatus("worker");
|
|
440
|
+
console.log(`PID: ${status.pid}, Status: ${status.status}`);
|
|
441
|
+
}</code></pre>
|
|
442
|
+
</div>
|
|
443
|
+
|
|
444
|
+
<div>
|
|
445
|
+
<h3 class="text-sm font-semibold uppercase tracking-wider text-cyan-600 dark:text-cyan-400 mb-2">CommonJS Support</h3>
|
|
446
|
+
<pre><code class="language-javascript">const {
|
|
447
|
+
createService,
|
|
448
|
+
startService,
|
|
449
|
+
getServiceStatus
|
|
450
|
+
} = require("unitup");
|
|
451
|
+
|
|
452
|
+
await createService({
|
|
453
|
+
name: "api",
|
|
454
|
+
script: "./server.js",
|
|
455
|
+
start: true
|
|
456
|
+
});</code></pre>
|
|
457
|
+
</div>
|
|
458
|
+
</div>
|
|
459
|
+
</section>
|
|
460
|
+
|
|
461
|
+
<!-- Section: Declarative Roadmap -->
|
|
462
|
+
<section id="declarative" class="doc-section mb-14">
|
|
463
|
+
<h2 class="text-2xl font-bold text-slate-900 dark:text-white mb-4">Declarative Stack Configuration (Roadmap Preview)</h2>
|
|
464
|
+
<p class="text-slate-600 dark:text-slate-400 mb-6 leading-relaxed">
|
|
465
|
+
Define your entire application stack declaratively using <code class="text-cyan-600 dark:text-cyan-400">unitup.yml</code> or <code class="text-cyan-600 dark:text-cyan-400">unitup.json</code>:
|
|
466
|
+
</p>
|
|
467
|
+
|
|
468
|
+
<div class="grid md:grid-cols-2 gap-6 mb-4">
|
|
469
|
+
<div>
|
|
470
|
+
<h3 class="text-sm font-semibold uppercase tracking-wider text-cyan-600 dark:text-cyan-400 mb-2"><code class="text-xs">unitup.yml</code> Spec</h3>
|
|
471
|
+
<pre><code class="language-yaml">apps:
|
|
472
|
+
api:
|
|
473
|
+
runtime: node
|
|
474
|
+
script: ./server.js
|
|
475
|
+
env:
|
|
476
|
+
NODE_ENV: production
|
|
477
|
+
PORT: 3000
|
|
478
|
+
start: true
|
|
479
|
+
|
|
480
|
+
worker:
|
|
481
|
+
runtime: python
|
|
482
|
+
script: ./worker.py
|
|
483
|
+
env:
|
|
484
|
+
APP_ENV: production
|
|
485
|
+
|
|
486
|
+
native-service:
|
|
487
|
+
runtime: native
|
|
488
|
+
command: ./server</code></pre>
|
|
489
|
+
</div>
|
|
490
|
+
|
|
491
|
+
<div>
|
|
492
|
+
<h3 class="text-sm font-semibold uppercase tracking-wider text-cyan-600 dark:text-cyan-400 mb-2">Planned Declarative Commands</h3>
|
|
493
|
+
<pre><code class="language-bash"># Preview differences against active units
|
|
494
|
+
unitup diff
|
|
495
|
+
|
|
496
|
+
# Apply unitup.yml configuration
|
|
497
|
+
unitup apply
|
|
498
|
+
|
|
499
|
+
# Perform batch operations on group
|
|
500
|
+
unitup restart @default</code></pre>
|
|
501
|
+
</div>
|
|
502
|
+
</div>
|
|
503
|
+
|
|
504
|
+
<p class="text-xs text-slate-500 dark:text-slate-500">
|
|
505
|
+
*Note: Relative script, command, cwd, and env-file paths in <code class="text-xs">unitup.yml</code> are resolved relative to the configuration file.
|
|
506
|
+
</p>
|
|
507
|
+
</section>
|
|
508
|
+
|
|
509
|
+
<!-- Section: Troubleshooting -->
|
|
510
|
+
<section id="troubleshooting" class="doc-section mb-14">
|
|
511
|
+
<h2 class="text-2xl font-bold text-slate-900 dark:text-white mb-4">Troubleshooting & User Lingering</h2>
|
|
512
|
+
|
|
513
|
+
<div class="p-5 rounded-xl border border-slate-200 dark:border-slate-800 bg-white/70 dark:bg-slate-900/50 space-y-4">
|
|
514
|
+
<h3 class="font-bold text-slate-900 dark:text-white">Enable User Lingering (Persistent Services)</h3>
|
|
515
|
+
<p class="text-sm text-slate-600 dark:text-slate-400 leading-relaxed">
|
|
516
|
+
Depending on the Linux distribution and systemd-logind configuration, user services may stop after logout. Enable lingering to allow them to continue running without an active login session:
|
|
517
|
+
</p>
|
|
518
|
+
<pre><code class="language-bash">loginctl enable-linger $USER</code></pre>
|
|
519
|
+
<p class="text-xs text-slate-500 dark:text-slate-500">
|
|
520
|
+
Verify lingering state anytime with <code class="text-xs">unitup doctor</code>. unitup will warn if lingering is disabled but will never prompt for sudo automatically.
|
|
521
|
+
</p>
|
|
522
|
+
</div>
|
|
523
|
+
</section>
|
|
524
|
+
|
|
525
|
+
<!-- Footer -->
|
|
526
|
+
<footer class="pt-8 border-t border-slate-200 dark:border-slate-800 text-center text-sm text-slate-500 dark:text-slate-500">
|
|
527
|
+
<p><a href="https://github.com/litepacks/unitup" target="_blank" rel="noopener noreferrer" class="text-cyan-600 dark:text-cyan-400 hover:underline">github.com/litepacks/unitup</a> · Released under <a href="https://opensource.org/licenses/MIT" target="_blank" rel="noopener noreferrer" class="underline hover:text-slate-700 dark:hover:text-slate-300">MIT License</a>.</p>
|
|
528
|
+
</footer>
|
|
529
|
+
</div>
|
|
530
|
+
|
|
531
|
+
<script>
|
|
532
|
+
// Theme toggle logic
|
|
533
|
+
const themeToggleBtn = document.getElementById('theme-toggle');
|
|
534
|
+
themeToggleBtn.addEventListener('click', () => {
|
|
535
|
+
document.documentElement.classList.toggle('dark');
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
// Highlight code blocks
|
|
539
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
540
|
+
hljs.highlightAll();
|
|
541
|
+
});
|
|
542
|
+
</script>
|
|
543
|
+
</body>
|
|
544
|
+
</html>
|