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