Skip to content

Commit 8f7db20

Browse files
committed
docs: Add deployment strategy and slash command workflow documentation
1 parent c29241f commit 8f7db20

File tree

1 file changed

+372
-0
lines changed

1 file changed

+372
-0
lines changed

docs/DEPLOYMENT_AND_WORKFLOW.md

Lines changed: 372 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,372 @@
1+
# Deployment & Workflow Documentation
2+
3+
**Project:** CORE - Rails 8 Monolith
4+
**Updated:** 2025-11-03
5+
**Maintainer:** RECTOR
6+
7+
---
8+
9+
## 1. Slash Command Enhancements (`/work:story`)
10+
11+
### What Changed
12+
13+
**Duplicate Detection** - Checks if work story already exists before generating
14+
**Database Integration** - Automatically saves to local database
15+
**User Choice on Duplicates** - Options to replace, create new version, or cancel
16+
**Production Deployment Guidance** - Clear instructions for syncing to production
17+
18+
### New Workflow
19+
20+
```bash
21+
# Run the slash command
22+
/work:story https://github.com/RECTOR-LABS/some-repo
23+
24+
# 1. Validates URL format
25+
# 2. Checks for existing story in database
26+
# 3. If duplicate exists:
27+
# → Shows existing story details
28+
# → Asks: Replace (1) | New version (2) | Cancel (3)
29+
# 4. Generates story from GitHub data
30+
# 5. Saves to LOCAL database automatically
31+
# 6. Shows success confirmation + local URL
32+
# 7. Provides production deployment instructions
33+
```
34+
35+
### Handling Duplicates
36+
37+
**Scenario 1: First time for repo**
38+
```
39+
✅ No existing story found
40+
→ Generates and saves new work
41+
→ /work/repo-name
42+
```
43+
44+
**Scenario 2: Story already exists**
45+
```
46+
⚠️ Work story already exists for this repository!
47+
48+
Repository: RECTOR-LABS/core
49+
Existing story: "CORE"
50+
URL: /work/core
51+
Created: 2 days ago
52+
53+
What would you like to do?
54+
55+
1. Replace existing story (overwrites current content)
56+
2. Create new version with different slug (keeps both)
57+
3. Cancel and keep existing story
58+
59+
Your choice (1/2/3):
60+
```
61+
62+
**Option 1 - Replace:**
63+
- Updates existing Work record in-place
64+
- Same slug, same URL
65+
- Story content replaced
66+
67+
**Option 2 - New Version:**
68+
- Creates new Work record
69+
- New slug: `core-v2` or `core-2025`
70+
- Both stories exist side-by-side
71+
72+
**Option 3 - Cancel:**
73+
- Stops execution
74+
- No changes made
75+
76+
### Local vs Production
77+
78+
**Local (Development):**
79+
- Slash command saves directly to local PostgreSQL database
80+
- Test immediately at `http://localhost:3000/work/[slug]`
81+
- No manual DB commands needed
82+
83+
**Production (Deployment):**
84+
85+
After slash command completes locally:
86+
87+
**Option A (Recommended): Update seeds.rb**
88+
```bash
89+
# 1. Edit db/seeds.rb with new work
90+
# 2. Commit and push to main
91+
git add db/seeds.rb
92+
git commit -m "feat: Add work story for [project]"
93+
git push origin main
94+
95+
# 3. SSH to production and seed
96+
ssh core << 'ENDSSH'
97+
cd ~/apps/core
98+
export PATH="$HOME/.rbenv/bin:$PATH"
99+
eval "$(rbenv init - bash)"
100+
export $(cat .env | grep -v '^#' | xargs)
101+
RAILS_ENV=production bin/rails db:seed
102+
ENDSSH
103+
```
104+
105+
**Option B (Quick): Manual Rails runner on production**
106+
```bash
107+
# SSH and create directly
108+
ssh core << 'ENDSSH'
109+
cd ~/apps/core
110+
export PATH="$HOME/.rbenv/bin:$PATH"
111+
eval "$(rbenv init - bash)"
112+
export $(cat .env | grep -v '^#' | xargs)
113+
RAILS_ENV=production bin/rails runner "
114+
Work.create!(
115+
title: 'Project Name',
116+
slug: 'project-name',
117+
story: <<~MARKDOWN
118+
# Story content here
119+
MARKDOWN,
120+
# ... rest of attributes
121+
)
122+
"
123+
ENDSSH
124+
```
125+
126+
---
127+
128+
## 2. Current Deployment Strategy
129+
130+
### Type: **Phased Restart** (Zero-Downtime)
131+
132+
**What You Have:**
133+
134+
**Zero-downtime deployments**
135+
**Graceful worker restarts**
136+
**Automatic recovery on failure**
137+
**No blue-green environments**
138+
**No automatic rollback**
139+
**No pre-deployment health checks**
140+
141+
### Architecture
142+
143+
```
144+
┌─────────────────────────────────────────────────┐
145+
│ GitHub Actions (CI/CD) │
146+
│ ├─ Lint, Test, Security Scan │
147+
│ └─ Deploy on main push │
148+
└─────────────────┬───────────────────────────────┘
149+
150+
v
151+
┌─────────────────────────────────────────────────┐
152+
│ VPS (176.222.53.185) │
153+
│ User: core │
154+
│ ├─ Pull latest code (git reset --hard) │
155+
│ ├─ Bundle install │
156+
│ ├─ Assets precompile │
157+
│ ├─ Database migrations │
158+
│ └─ Puma reload (systemctl reload core-puma) │
159+
└─────────────────────────────────────────────────┘
160+
```
161+
162+
### Puma Configuration
163+
164+
**Cluster Mode:**
165+
- 2 worker processes
166+
- 3 threads per worker
167+
- Preload app for memory efficiency
168+
169+
**Graceful Reload (USR1 Signal):**
170+
```
171+
1. New workers start with updated code
172+
2. Old workers finish current requests
173+
3. Old workers shutdown gracefully
174+
4. No dropped connections
175+
```
176+
177+
**Service Configuration:**
178+
```systemd
179+
ExecReload=/bin/kill -USR1 $MAINPID
180+
Restart=always
181+
RestartSec=10
182+
```
183+
184+
### Deployment Flow
185+
186+
```mermaid
187+
sequenceDiagram
188+
Developer->>GitHub: git push origin main
189+
GitHub->>CI: Trigger workflow
190+
CI->>CI: Run tests
191+
CI->>VPS: SSH deploy
192+
VPS->>VPS: Pull code
193+
VPS->>VPS: Bundle install
194+
VPS->>VPS: Migrate database
195+
VPS->>VPS: Precompile assets
196+
VPS->>Puma: Send USR1 signal
197+
Puma->>Puma: Start new workers
198+
Puma->>Puma: Kill old workers
199+
Puma->>VPS: Deployment complete
200+
```
201+
202+
**Average Deployment Time:** 30-45 seconds
203+
204+
### What's Missing (Blue-Green)
205+
206+
**Blue-Green would add:**
207+
- Two identical production environments
208+
- Traffic switch between blue/green
209+
- Quick rollback by switching back
210+
- Health checks before switching
211+
- Zero risk during deployment
212+
213+
**Cost of Blue-Green:**
214+
- 2x infrastructure cost
215+
- More complex deployment pipeline
216+
- Database migration complexity
217+
- Not needed for solo projects
218+
219+
### Rollback Strategy (Current)
220+
221+
**If deployment breaks:**
222+
223+
**Option 1: Git revert + redeploy**
224+
```bash
225+
git revert HEAD
226+
git push origin main
227+
# CI/CD auto-deploys previous version
228+
```
229+
230+
**Option 2: Manual rollback**
231+
```bash
232+
ssh core
233+
cd ~/apps/core
234+
git reset --hard <previous-commit>
235+
bundle install
236+
RAILS_ENV=production bin/rails db:migrate
237+
sudo systemctl reload core-puma
238+
```
239+
240+
**Downtime during rollback:** ~1-2 minutes
241+
242+
---
243+
244+
## 3. Recommendations
245+
246+
### Current Setup is Good For:
247+
- ✅ Solo developer projects
248+
- ✅ Low-to-medium traffic
249+
- ✅ Fast iteration speed
250+
- ✅ Cost efficiency
251+
252+
### Consider Blue-Green When:
253+
- Traffic is critical (thousands of concurrent users)
254+
- Zero-tolerance for downtime
255+
- Need instant rollback
256+
- Have budget for 2x infrastructure
257+
258+
### Immediate Improvements (Optional)
259+
260+
**1. Add Health Checks:**
261+
```yaml
262+
# In .github/workflows/deploy.yml
263+
- name: Health check
264+
run: |
265+
for i in {1..10}; do
266+
if curl -f https://rectorspace.com/up; then
267+
echo "Health check passed"
268+
exit 0
269+
fi
270+
sleep 3
271+
done
272+
echo "Health check failed"
273+
exit 1
274+
```
275+
276+
**2. Add Deployment Tagging:**
277+
```bash
278+
# Tag each production deploy
279+
git tag -a "v$(date +%Y%m%d-%H%M%S)" -m "Production deploy"
280+
git push --tags
281+
```
282+
283+
**3. Keep Last 5 Releases:**
284+
```bash
285+
# On VPS, keep recent commits
286+
git reflog expire --expire=30.days --all
287+
git gc --prune=30.days
288+
```
289+
290+
### Kamal Deployment (Future Option)
291+
292+
The Gemfile includes Kamal - Rails' official Docker deployment tool.
293+
294+
**Benefits:**
295+
- Blue-green built-in
296+
- Multi-server support
297+
- SSL auto-renewal
298+
- Asset management
299+
300+
**Setup if interested:**
301+
```bash
302+
kamal init
303+
kamal setup
304+
kamal deploy
305+
```
306+
307+
But current approach works great for your scale.
308+
309+
---
310+
311+
## 4. Quick Reference
312+
313+
### Test Locally
314+
```bash
315+
RBENV_VERSION=3.2.2 bin/rails server
316+
# Visit http://localhost:3000/work
317+
```
318+
319+
### Deploy to Production
320+
```bash
321+
git push origin main
322+
# GitHub Actions handles rest
323+
```
324+
325+
### Check Production Status
326+
```bash
327+
ssh core "sudo systemctl status core-puma"
328+
```
329+
330+
### Manual Production Seed
331+
```bash
332+
ssh core << 'ENDSSH'
333+
cd ~/apps/core
334+
export PATH="$HOME/.rbenv/bin:$PATH"
335+
eval "$(rbenv init - bash)"
336+
export $(cat .env | grep -v '^#' | xargs)
337+
RAILS_ENV=production bin/rails db:seed
338+
ENDSSH
339+
```
340+
341+
### View Production Logs
342+
```bash
343+
ssh core "tail -f ~/apps/core/log/production.log"
344+
```
345+
346+
---
347+
348+
## Summary
349+
350+
**Your Questions Answered:**
351+
352+
1. **Slash command database interaction**: ✅ Now saves to local DB automatically, with production deployment guidance
353+
2. **Blue-green deployment**: ❌ Current setup is phased restart (zero-downtime but no blue-green fallback)
354+
3. **Duplicate validation**: ✅ Command now checks for existing stories and offers replace/new/cancel options
355+
356+
**Current deployment is solid for:**
357+
- Solo projects
358+
- Fast iteration
359+
- Zero-downtime updates
360+
- Cost efficiency
361+
362+
**Upgrade to blue-green if:**
363+
- High traffic (1000+ concurrent)
364+
- Mission-critical uptime
365+
- Instant rollback needed
366+
- Budget allows 2x infra
367+
368+
**For now**: Your deployment strategy is appropriate and working well! 🚀
369+
370+
---
371+
372+
**Building for Eternity** | RECTOR LABS | 2025

0 commit comments

Comments
 (0)