-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTaskfile.yml
More file actions
234 lines (204 loc) · 7.89 KB
/
Copy pathTaskfile.yml
File metadata and controls
234 lines (204 loc) · 7.89 KB
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
222
223
224
225
226
227
228
229
230
231
232
233
234
version: "1"
name: codereview.pl
description: >
codereview.pl deployment — 3 stages.
Single docker-compose.yml as source of truth.
Local: Docker + Traefik | Prod: Podman Quadlet + Traefik
default_env: local
variables:
APP_NAME: codereview
REGISTRY: ghcr.io/softreck
TAG: latest
COMPOSE_FILE: docker-compose.yml
# VPS Configuration - auto-configured from .env
VPS_IP: ${VPS_IP:-vps.codereview.pl}
VPS_USER: ${VPS_USER:-deploy}
VPS_SSH_KEY: ${VPS_SSH_KEY:-~/.ssh/id_ed25519}
# Smart defaults: ssh_host → podman/quadlet/~/.ssh/id_ed25519
# env_file defaults to .env.{env_name}
environments:
local: {}
prod:
# SSH auto-configured from VPS_IP, VPS_USER variables
# Just set: echo "VPS_IP=your.vps.ip" > .env
ssh_host: ${VPS_IP}
ssh_user: ${VPS_USER:-deploy}
ssh_key: ${VPS_SSH_KEY:-~/.ssh/id_ed25519}
# ═══════════════════════════════════════════════════
# Pipeline — defines CI/CD stages
# Generate configs: taskfile ci generate --all
# Run locally: taskfile ci run
# ═══════════════════════════════════════════════════
pipeline:
python_version: "3.12"
runner_image: ubuntu-latest
branches: [main]
install_cmd: "pip install taskfile"
secrets:
- SSH_PRIVATE_KEY
- REGISTRY_TOKEN
stages:
- name: test
tasks: [build]
# Build validates Dockerfile syntax + dependencies
- name: build
tasks: [push]
docker_in_docker: true
- name: generate
tasks: [generate]
artifacts:
- deploy/quadlet/
- name: deploy
tasks: [deploy-quick]
env: prod
when: manual
# ═══════════════════════════════════════════════════
# Tasks
# ═══════════════════════════════════════════════════
tasks:
# ─── Build ────────────────────────────────────────
build:
desc: Build all images
cmds:
- ${COMPOSE} build
build-app:
desc: Build single service (--var SVC=app)
cmds:
- ${COMPOSE} build ${SVC}
push:
desc: Build and push all images to registry
deps: [build]
cmds:
- ${COMPOSE} push app api
- echo "📦 Pushed ${REGISTRY}/codereview-app:${TAG}"
- echo "📦 Pushed ${REGISTRY}/codereview-api:${TAG}"
# ─── Development & Operations ──────────────────────
dev:
desc: Start full local environment
env: [local]
cmds:
- ${COMPOSE} up -d --build
- echo ""
- "echo '✅ codereview.pl running locally:'"
- "echo ' App: http://codereview.localhost'"
- "echo ' API: http://api.codereview.localhost'"
- "echo ' Traefik: http://localhost:8080'"
# ─── Quadlet generation ──────────────────────────
#
# This is the KEY feature: generate Quadlet from the
# same docker-compose.yml using .env.prod variables.
# No separate Quadlet config to maintain!
#
generate:
desc: Generate Quadlet files from docker-compose.yml + .env.prod
cmds:
- taskfile quadlet generate --compose ${COMPOSE_FILE} --env-file .env.prod -o deploy/quadlet
- echo ""
- echo "📁 Quadlet files in deploy/quadlet/"
- ls -la deploy/quadlet/
# ─── Production deploy ───────────────────────────
deploy:
desc: "Full deploy: generate Quadlet → upload → pull → restart"
env: [prod]
deps: [push, generate]
cmds:
- echo "🚀 Deploying codereview.pl to production..."
# Upload Quadlet files
- scp deploy/quadlet/*.container deploy/quadlet/*.network deploy/quadlet/*.volume ${SSH_USER:-deploy}@${SSH_HOST}:~/.config/containers/systemd/
# Reload systemd
- "@remote systemctl --user daemon-reload"
# Pull new images
- "@remote podman pull ${REGISTRY}/codereview-app:${TAG}"
- "@remote podman pull ${REGISTRY}/codereview-api:${TAG}"
# Restart services
- "@remote systemctl --user restart app"
- "@remote systemctl --user restart api"
# Cleanup
- "@remote podman image prune -f"
- echo ""
- echo "✅ codereview.pl deployed to production"
deploy-quick:
desc: Quick deploy — pull + restart only (no Quadlet regeneration)
env: [prod]
cmds:
- "@remote podman pull ${REGISTRY}/codereview-app:${TAG}"
- "@remote podman pull ${REGISTRY}/codereview-api:${TAG}"
- "@remote systemctl --user restart app"
- "@remote systemctl --user restart api"
- "@remote podman image prune -f"
- echo "✅ Quick deploy done"
deploy-service:
desc: Deploy single service (--var SVC=app)
env: [prod]
cmds:
- "@remote podman pull ${REGISTRY}/codereview-${SVC}:${TAG}"
- "@remote systemctl --user restart ${SVC}"
- echo "✅ Deployed ${SVC}"
upload-quadlets:
desc: Upload Quadlet files without restarting
env: [prod]
cmds:
- scp deploy/quadlet/*.container deploy/quadlet/*.network deploy/quadlet/*.volume ${SSH_USER:-deploy}@${SSH_HOST}:~/.config/containers/systemd/
- "@remote systemctl --user daemon-reload"
- echo "✅ Quadlet files synced"
# ─── Operations (local + prod) ─────────────────────
status:
desc: Show service status
env: [local, prod]
cmds:
- "@local ${COMPOSE} ps"
- "@remote podman ps --format 'table {{.Names}}\\t{{.Status}}\\t{{.Ports}}'"
logs:
desc: View logs (--var SVC=app)
env: [local, prod]
cmds:
- "@local ${COMPOSE} logs -f ${SVC:-}"
- "@remote journalctl --user -u ${SVC:-app} -f --no-pager -n 100"
restart:
desc: Restart service (--var SVC=app)
env: [local, prod]
cmds:
- "@local ${COMPOSE} restart ${SVC:-}"
- "@remote systemctl --user restart ${SVC:-app}"
stop:
desc: Stop service (--var SVC=app)
env: [local, prod]
cmds:
- "@local ${COMPOSE} down"
- "@remote systemctl --user stop ${SVC:-app}"
ram:
desc: Check RAM usage on production server
env: [prod]
cmds:
- "@remote free -h"
- "@remote podman stats --no-stream --format 'table {{.Name}}\\t{{.MemUsage}}\\t{{.MemPerc}}'"
cleanup:
desc: Clean unused images/volumes on production
env: [prod]
cmds:
- "@remote podman image prune -af"
- "@remote podman volume prune -f"
- echo "🧹 Cleaned"
# ─── Initial server setup ────────────────────────
setup-server:
desc: First-time production server setup
env: [prod]
cmds:
- "@remote sudo apt-get update && sudo apt-get install -y podman"
- "@remote mkdir -p ~/.config/containers/systemd"
- "@remote podman network create proxy 2>/dev/null || true"
- "@remote podman network create codereview-backend 2>/dev/null || true"
- "@remote loginctl enable-linger $(whoami)"
- "@remote mkdir -p /opt/codereview/uploads"
- echo "✅ Server ready for Podman Quadlet"
# ─── Release ─────────────────────────────────────
release:
desc: Tagged release — build, push, deploy with version tag
cmds:
- echo "🚀 Releasing codereview.pl ${TAG}"
- git tag -a ${TAG} -m "Release ${TAG}"
- git push origin ${TAG}
- ${COMPOSE} build
- ${COMPOSE} push app api
- echo "📦 Released ${TAG} — deploy with:"
- echo " taskfile --env prod run deploy-quick --var TAG=${TAG}"