summaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md221
1 files changed, 221 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8125bc9
--- /dev/null
+++ b/README.md
@@ -0,0 +1,221 @@
1# Deploy - VPS Deployment CLI
2
3Simple CLI tool for deploying Go apps and static sites to a VPS with automatic HTTPS via Caddy.
4
5## Features
6
7- Single command deployment from your laptop
8- Automatic HTTPS via Caddy + Let's Encrypt
9- Automatic port allocation (no manual tracking)
10- Environment variable management
11- Systemd process management with auto-restart
12- Support for multiple apps/sites on one VPS
13- State stored locally (VPS is stateless and easily recreatable)
14- Zero dependencies on VPS (just installs Caddy)
15
16## Installation
17
18```bash
19# Build the CLI
20go build -o ~/bin/deploy ./cmd/deploy
21
22# Or install to GOPATH
23go install ./cmd/deploy
24```
25
26## Quick Start
27
28### 1. Initialize Your VPS (One-time)
29
30```bash
31# Initialize a fresh VPS
32deploy init --host user@your-vps-ip
33```
34
35This will:
36- Install Caddy
37- Configure Caddy for automatic HTTPS
38- Create necessary directories
39- Set up the VPS for deployments
40
41### 2. Deploy a Go App
42
43```bash
44# Build your app for Linux
45GOOS=linux GOARCH=amd64 go build -o myapp
46
47# Deploy it
48deploy deploy --host user@vps-ip --binary ./myapp --domain api.example.com
49
50# With environment variables
51deploy deploy --host user@vps-ip --binary ./myapp --domain api.example.com \
52 --env DB_HOST=localhost \
53 --env API_KEY=secret
54
55# Or from an env file
56deploy deploy --host user@vps-ip --binary ./myapp --domain api.example.com \
57 --env-file .env.production
58```
59
60### 3. Deploy a Static Site
61
62```bash
63# Build your site
64npm run build
65
66# Deploy it
67deploy deploy --host user@vps-ip --static --dir ./dist --domain example.com
68```
69
70## App Requirements
71
72Your Go app must:
731. Listen on HTTP (not HTTPS - Caddy handles that)
742. Accept port via `--port` flag or `PORT` environment variable
753. Bind to `localhost` or `127.0.0.1` only
76
77Example:
78
79```go
80package main
81
82import (
83 "flag"
84 "fmt"
85 "net/http"
86 "os"
87)
88
89func main() {
90 port := flag.String("port", os.Getenv("PORT"), "port to listen on")
91 flag.Parse()
92
93 if *port == "" {
94 *port = "8080" // fallback for local dev
95 }
96
97 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
98 w.Write([]byte("Hello World"))
99 })
100
101 addr := "127.0.0.1:" + *port
102 fmt.Printf("Listening on %s\n", addr)
103 http.ListenAndServe(addr, nil)
104}
105```
106
107## Commands
108
109### Initialize VPS
110```bash
111deploy init --host user@vps-ip
112```
113
114### Deploy App/Site
115```bash
116# Go app
117deploy deploy --host user@vps-ip --binary ./myapp --domain api.example.com
118
119# Static site
120deploy deploy --host user@vps-ip --static --dir ./dist --domain example.com
121
122# Custom name (defaults to binary/directory name)
123deploy deploy --host user@vps-ip --name myapi --binary ./myapp --domain api.example.com
124```
125
126### List Deployments
127```bash
128deploy list --host user@vps-ip
129```
130
131### Manage Deployments
132```bash
133# View logs
134deploy logs myapp --host user@vps-ip
135
136# View status
137deploy status myapp --host user@vps-ip
138
139# Restart app
140deploy restart myapp --host user@vps-ip
141
142# Remove deployment
143deploy remove myapp --host user@vps-ip
144```
145
146### Environment Variables
147```bash
148# View current env vars (secrets are masked)
149deploy env myapi --host user@vps-ip
150
151# Set env vars
152deploy env myapi --host user@vps-ip --set DB_HOST=localhost --set API_KEY=secret
153
154# Load from file
155deploy env myapi --host user@vps-ip --file .env.production
156
157# Unset env var
158deploy env myapi --host user@vps-ip --unset API_KEY
159```
160
161## Configuration
162
163Create `~/.config/deploy/config` to avoid typing `--host` every time:
164
165```
166host: user@your-vps-ip
167```
168
169Then you can omit the `--host` flag:
170
171```bash
172deploy list
173deploy deploy --binary ./myapp --domain api.example.com
174```
175
176## How It Works
177
1781. **State on Laptop**: All deployment state lives at `~/.config/deploy/state.json` on your laptop
1792. **SSH Orchestration**: The CLI uses SSH to run commands on your VPS
1803. **File Transfer**: Binaries transferred via SCP, static sites via rsync
1814. **Caddy for HTTPS**: Caddy automatically handles HTTPS certificates
1825. **Systemd for Processes**: Apps run as systemd services with auto-restart
1836. **Dumb VPS**: The VPS is stateless - you can recreate it by redeploying from local state
184
185## File Structure
186
187### On Laptop
188```
189~/.config/deploy/state.json # All deployment state
190~/.config/deploy/config # Optional: default host
191```
192
193### On VPS
194```
195/usr/local/bin/myapp # Go binary
196/var/lib/myapp/ # Working directory
197/etc/systemd/system/myapp.service # Systemd unit
198/etc/caddy/sites-enabled/myapp.caddy # Caddy config
199/etc/deploy/env/myapp.env # Environment variables
200
201/var/www/mysite/ # Static site files
202/etc/caddy/sites-enabled/mysite.caddy # Caddy config
203```
204
205## Security
206
207- Each Go app runs as dedicated system user
208- Systemd security hardening enabled (NoNewPrivileges, PrivateTmp)
209- Static sites served as www-data
210- Caddy automatically manages TLS certificates
211- Environment files stored with 0600 permissions
212- Secrets masked when displaying environment variables
213
214## Supported OS
215
216- Ubuntu 20.04+
217- Debian 11+
218
219## License
220
221MIT