Skip to content

Commit 7f58d5e

Browse files
authored
docs: beginner-first README with one-command deploy, FAQs, and fixes
1 parent 0652726 commit 7f58d5e

File tree

1 file changed

+85
-50
lines changed

1 file changed

+85
-50
lines changed

README.md

Lines changed: 85 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,100 @@
11
# launchd
2-
Deterministic deploy orchestrator for single-binary Go services anchored to Linux systemd. launchd operationalizes a minimal, auditable deploy surface by composing battle-tested primitives: the resident Go toolchain for compilation, OpenSSH for transport and privileged control, systemd for service lifecycle, an optional migrator for schema evolution, and an HTTP health contract for liveness attestation. The objective function is predictability under duress, not novelty; the codebase is dependency-thin and tuned for reproducible behavior across heterogeneous fleet baselines.
3-
4-
## Conceptual Premise
5-
6-
The dominant substrate for “small-but-critical” services is a single daemon under systemd supervision. For these domains, heavyweight CI/CD machinery introduces variance without proportional utility. launchd prefers an austere convergence model: converge a binary onto a machine, converge a unit into systemd, converge the database state via idempotent migrations, and converge process readiness via health probes. Each convergence step is a transparent syscall to a canonical tool, yielding failure surfaces that are legible to any seasoned operator.
7-
8-
Assumptions:
9-
- A Go main package constitutes the service.
10-
- SSH reachability with privilege elevation exists to manage units.
11-
- The service exposes `/health` on a chosen TCP port.
12-
13-
## MVP Scope
14-
15-
- CLI: `launchd deploy --host <ip> --user <ssh-user> --app ./path/to/app --port <port> [--timeout <dur>]`.
16-
- Pipeline: Compile ➝ Transfer ➝ systemd Provision ➝ Migrate (optional) ➝ Health Gate.
17-
- Properties: idempotent (safe re-entrance), deterministic (explicit tooling), strict error surfacing, and minimal environmental preconditions (Go + OpenSSH).
18-
19-
### Stage Semantics
20-
- Compile: `go build -o /tmp/<app>` using the resident toolchain; no hermetic wrapper.
21-
- Transfer: `scp` to `/usr/local/bin/<app>` after ensuring parent directory ownership is sane.
22-
- systemd: materialize a unit, `daemon-reload`, `enable`, `restart`—idempotent operations.
23-
- Migrations: opportunistic `migrate up` if a migrator exists on the target PATH.
24-
- Health: poll `http://<host>:<port>/health` until success or deadline expiry.
25-
26-
## Example Usage
2+
Launchd is a simple tool that helps you deploy a Go program (a single binary) to a Linux server that uses systemd. Think of it as a very small CI/CD helper you can run from your laptop.
3+
4+
It does five things for you:
5+
- Build your Go app locally.
6+
- Copy the binary to your server over SSH.
7+
- Create/refresh a systemd service for it.
8+
- Optionally run database migrations.
9+
- Check that the app is healthy before finishing.
10+
11+
If you’re new to servers, follow this guide step by step. You don’t need Docker or a complex CI system.
12+
13+
## What you need (prerequisites)
14+
- A Go project with a `main` package you can build.
15+
- Your laptop/workstation with:
16+
- Go installed
17+
- OpenSSH client (`ssh`, `scp`)
18+
- A Linux server with:
19+
- systemd (most modern distros have it)
20+
- SSH access (you can log in with a user that can use `sudo`)
21+
- Network port open for your app (e.g., 8080)
22+
- Your app should expose a health endpoint like `GET /health` that returns 200 OK when ready.
23+
24+
## Install / Build launchd
25+
Clone this repo and build the CLI:
2726

2827
```bash
29-
launchd deploy --host 203.0.113.10 --user ubuntu --app ./examples/hello --port 8080 --timeout 60s
28+
git clone <this-repo-url>
29+
cd launchd
30+
go build -o launchd ./cmd/launchd
3031
```
3132

32-
On completion, the service is registered as `<app>.service`, executes `/usr/local/bin/<app> --port=<port>`, and is enabled for boot.
33+
This creates a `launchd` binary in the project root. Optionally, move it into your PATH:
3334

34-
## Design Guarantees
35+
```bash
36+
mv launchd /usr/local/bin/
37+
```
3538

36-
- Determinism: all side effects mediated by explicit tools (`go`, `scp`, `ssh`, `systemctl`).
37-
- Idempotence: repeated invocations converge; non-destructive `enable`, guarded migrations.
38-
- Failure Locality: stages short-circuit with precise logging; no ambiguous partial states.
39-
- Observability: microsecond timestamps and stage banners designed for operator cognition.
40-
- Minimality: no bespoke protocol layers; everything deferential to Unix contracts.
39+
## Prepare your app
40+
Make sure your app builds locally:
4141

42-
## Future Roadmap
42+
```bash
43+
go build -o ./bin/myapp ./path/to/your/cmd
44+
```
4345

44-
- Artifact integrity: checksums, content-addressed remote layout, atomic swaps.
45-
- Principle of Least Privilege: dedicated system users, hardening of unit sandboxing.
46-
- Transport hardening: native SSH client (keyboard-interactive, agent-forwarding policies) while preserving zero-daemon requirements.
47-
- Policy engines: JSON-structured logs, exponential backoff policies, retry budgets.
48-
- Migration adapters: goose, golang-migrate, app-native hooks with transactional guards.
46+
Also ensure your app can start with a port flag or env (for example `--port 8080`) and serves `/health`.
4947

50-
## Organizational Context
48+
## Quick start: deploy in one command
49+
Run from your laptop (replace placeholders):
5150

52-
This codebase is authored under the goVerta collective and aspires to the production rigor expected of core-infra artifacts. The project is intentionally conservative in feature accretion, biasing toward operability, determinism, and testable failure semantics over breadth.
51+
```bash
52+
launchd deploy \
53+
--host <server-ip-or-dns> \
54+
--user <ssh-username> \
55+
--app ./path/to/your/app \
56+
--port <port> \
57+
--timeout 60s
58+
```
5359

54-
## Contributors and Roles
60+
What happens:
61+
1) Your app is compiled.
62+
2) The binary is copied to `/usr/local/bin/<app>` on the server.
63+
3) A systemd unit `<app>.service` is created/updated and (re)started.
64+
4) Optional migrations run if configured.
65+
5) Launchd waits for `http://<host>:<port>/health` to be OK.
66+
67+
On success, your service is enabled on boot and running under systemd.
68+
69+
## How it works (simple explanation)
70+
- Build: uses your local Go toolchain to compile your app.
71+
- Transfer: uses `scp` over SSH to put the binary on the server.
72+
- Service: writes a `.service` file, runs `systemctl daemon-reload`, `enable`, and `restart`.
73+
- Migrate (optional): calls a migration tool if you have one installed on the server.
74+
- Health check: polls your `/health` endpoint until it responds OK or times out.
75+
76+
## Common problems and fixes
77+
- SSH fails: verify `ssh <user>@<host>` works and keys/Passwords are set up.
78+
- Sudo prompts: ensure your SSH user can run the necessary `systemctl` and file copy with `sudo`.
79+
- Port in use: stop whatever is using that port or change `--port`.
80+
- Health check fails: make sure your service starts quickly, listens on the right port, and returns 200 on `/health`.
81+
- See logs: `ssh <user>@<host> 'sudo journalctl -u <app>.service -f'`.
82+
83+
## Remove or stop the service (on the server)
84+
```bash
85+
sudo systemctl stop <app>.service
86+
sudo systemctl disable <app>.service
87+
sudo rm -f /usr/local/bin/<app>
88+
sudo rm -f /etc/systemd/system/<app>.service
89+
sudo systemctl daemon-reload
90+
```
5591

56-
- Saad H. Tiwana — lead author, deployment pipeline, systemd strategy, reliability posture
57-
GitHub: https://github.com/saadhtiwana
58-
- Ahmad Mustafa — SSH/SCP transport hardening, testing harnesses
59-
GitHub: https://github.com/ahmadmustafa02
60-
- Majid Farooq Qureshi — QA and Toolsmith, Makefile/CI touchpoints, documentation QA
61-
GitHub: https://github.com/Majid-Farooq-Qureshi
92+
## Safety and re-runs
93+
You can run the same deploy command again. It will overwrite the binary, refresh the unit, and restart safely. This is called idempotent behavior.
6294

63-
Saad authored the core code; Ahmad and Majid contributed engineering and QA functions across transport, tests, and docs.
95+
## FAQ
96+
- Do I need Docker? No.
97+
- Do I need Go on the server? No, only on your laptop (build happens locally).
98+
- Do I need root? You need `sudo` to install the binary and manage systemd.
6499

65-
— saad and gang is who build this
100+
Saad and gang is who build this

0 commit comments

Comments
 (0)