Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
277 lines (224 loc) · 9.62 KB
/
Copy pathMakefile
File metadata and controls
277 lines (224 loc) · 9.62 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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# MicroHelium Makefile
# Docker commands for development and production
.PHONY: help build up down restart logs shell migrate seed fresh test lint format deploy rollback smoke
# Default target
help:
@echo "MicroHelium Docker Commands"
@echo ""
@echo "Setup:"
@echo " make setup - Initial project setup"
@echo " make build - Build Docker images"
@echo " make up - Start all containers"
@echo " make down - Stop all containers"
@echo " make restart - Restart all containers"
@echo ""
@echo "Development:"
@echo " make dev - Start with development tools (Vite, Mailpit)"
@echo " make logs - View container logs"
@echo " make shell - Open shell in app container"
@echo " make shell-db - Open MySQL shell"
@echo " make shell-redis - Open Redis CLI"
@echo ""
@echo "Laravel:"
@echo " make migrate - Run database migrations"
@echo " make seed - Run database seeders"
@echo " make fresh - Fresh migrate with seeders"
@echo " make key - Generate application key"
@echo " make cache - Clear all caches"
@echo " make optimize - Optimize application"
@echo ""
@echo "Queue:"
@echo " make queue - Start queue worker"
@echo " make judge - Start auto-judge worker"
@echo ""
@echo "Testing:"
@echo " make test - Run PHPUnit tests"
@echo " make lint - Run PHP linter"
@echo " make format - Format code with Pint"
@echo ""
@echo "Production:"
@echo " make prod - Build for production"
@echo " make prod-up - Start production containers"
@echo " make deploy - Build+tag a new image, roll it out, run smoke tests"
@echo " make rollback PREV=<tag> - Re-point :prod at a previously built image, no rebuild"
@echo " make smoke - Run post-deploy smoke checks against the live stack"
# =============================================================================
# Setup
# =============================================================================
setup: build
@echo "Creating .env file..."
@cp -n .env.docker .env 2>/dev/null || true
@echo "Starting containers..."
@docker compose up -d db redis
@echo "Waiting for database..."
@sleep 10
@docker compose up -d
@echo "Generating application key..."
@docker compose exec app php artisan key:generate
@echo "Running migrations..."
@docker compose exec app php artisan migrate --force
@echo "Creating storage link..."
@docker compose exec app php artisan storage:link
@echo ""
@echo "Setup complete! Access the application at http://localhost:8000"
build:
@docker compose build
up:
@docker compose up -d
down:
@docker compose down
restart: down up
# =============================================================================
# Development
# =============================================================================
dev:
@docker compose --profile dev up -d
dev-tools:
@docker compose --profile dev --profile tools up -d
logs:
@docker compose logs -f
logs-app:
@docker compose logs -f app
logs-queue:
@docker compose logs -f queue
logs-judge:
@docker compose logs -f autojudge
shell:
@docker compose exec app sh
shell-root:
@docker compose exec -u root app sh
shell-db:
@docker compose exec db mysql -u microhelium -psecret microhelium
shell-redis:
@docker compose exec redis redis-cli
# =============================================================================
# Laravel Commands
# =============================================================================
migrate:
@docker compose exec app php artisan migrate
seed:
@docker compose exec app php artisan db:seed
fresh:
@docker compose exec app php artisan migrate:fresh --seed
key:
@docker compose exec app php artisan key:generate
cache:
@docker compose exec app php artisan cache:clear
@docker compose exec app php artisan config:clear
@docker compose exec app php artisan route:clear
@docker compose exec app php artisan view:clear
optimize:
@docker compose exec app php artisan optimize
@docker compose exec app php artisan view:cache
@docker compose exec app php artisan event:cache
tinker:
@docker compose exec app php artisan tinker
# =============================================================================
# Queue & Judge
# =============================================================================
# -u www because `docker compose exec` bypasses the image ENTRYPOINT, and
# so bypasses the privilege drop docker/php/entrypoint.sh does for the
# `queue` service (issue #136). Without it this target is the one
# remaining way to run the judging path -- queue:work dispatches
# JudgeRunJob, which compiles and executes submitted code -- as uid 0.
queue:
@docker compose exec -u www app php artisan queue:work --verbose
queue-restart:
@docker compose exec app php artisan queue:restart
# -u judge for the same reason, against the guarantee Dockerfile.judge's
# entrypoint has made since #86: `exec` starts a new process directly, so
# this one was running the autojudge loop as root even though the
# service's own main process is uid 1000.
judge:
@docker compose exec -u judge autojudge php artisan autojudge:start --sleep=5
# =============================================================================
# Testing & Code Quality
# =============================================================================
test:
@docker compose exec app php artisan test
test-coverage:
@docker compose exec app php artisan test --coverage
lint:
@docker compose exec app ./vendor/bin/pint --test
format:
@docker compose exec app ./vendor/bin/pint
# =============================================================================
# Assets
# =============================================================================
npm-install:
@docker compose exec node npm install
npm-dev:
@docker compose exec node npm run dev
npm-build:
@docker compose exec node npm run build
# =============================================================================
# Production
# =============================================================================
# IMAGE_TAG defaults to :prod here (not :latest) so `make prod`/`prod-up`
# share the same tag universe as `make deploy`/`rollback` below -- otherwise
# `prod-up` would run :latest while `rollback` only knows about :prod/sha
# tags, and a rollback after a plain `prod-up` would silently swap in
# whatever :prod last happened to reference instead of anything related to
# what's actually running. Override with `make prod-up IMAGE_TAG=<tag>` if
# you need a specific tag.
IMAGE_TAG ?= prod
PROD_COMPOSE = docker compose -f docker-compose.yml -f docker-compose.prod.yml
prod:
@IMAGE_TAG=$(IMAGE_TAG) $(PROD_COMPOSE) build
prod-up:
@IMAGE_TAG=$(IMAGE_TAG) $(PROD_COMPOSE) up -d
prod-down:
@$(PROD_COMPOSE) down
# =============================================================================
# Deploy / Rollback (issue #54)
#
# Every build is tagged with the git sha that produced it (microhelium-app,
# microhelium-judge), so a rollback is just re-pointing the ":prod" tag at a
# previously built image and restarting -- no rebuild, no migration replay.
# `docker images microhelium-app` / `microhelium-judge` lists what's
# available to roll back to.
# =============================================================================
# := (not ?=/lazy) so this is computed once per `make` invocation instead of
# re-running `git rev-parse` on every one of the several references below.
DEPLOY_TAG := $(shell git rev-parse --short HEAD)
deploy:
@echo "Building images tagged $(DEPLOY_TAG)..."
@IMAGE_TAG=$(DEPLOY_TAG) $(PROD_COMPOSE) build app autojudge
@echo "Promoting $(DEPLOY_TAG) to :prod..."
@docker tag microhelium-app:$(DEPLOY_TAG) microhelium-app:prod
@docker tag microhelium-judge:$(DEPLOY_TAG) microhelium-judge:prod
@echo "Starting db/redis/app/webserver and running migrations before touching background workers..."
@IMAGE_TAG=prod $(PROD_COMPOSE) up -d --wait --wait-timeout 120 db redis app webserver
@$(PROD_COMPOSE) exec -T app php artisan migrate --force
@echo "Migrations applied. Starting queue/scheduler/autojudge on the new image..."
@IMAGE_TAG=prod $(PROD_COMPOSE) up -d --wait --wait-timeout 120 queue scheduler autojudge
@echo "Deployed $(DEPLOY_TAG). Running smoke tests..."
@$(MAKE) smoke || (echo "" && echo "Smoke tests FAILED after deploying $(DEPLOY_TAG)." && echo "Roll back with: make rollback PREV=<previous-tag>" && exit 1)
@echo "Deploy of $(DEPLOY_TAG) verified healthy."
# NOTE: this re-points images and restarts containers only -- it does NOT
# revert database migrations. If the deploy being rolled back included a
# schema-breaking migration (a dropped/renamed column the old code still
# reads), rolling back the image alone will not restore compatibility; you
# must also manually run the down migration(s) for that deploy first.
rollback:
ifndef PREV
$(error Usage: make rollback PREV=<git-sha-tag>. List available tags with: docker images microhelium-app)
endif
@echo "Rolling back :prod to $(PREV) (no rebuild, migrations NOT reverted -- see Makefile comment)..."
@docker tag microhelium-app:$(PREV) microhelium-app:prod
@docker tag microhelium-judge:$(PREV) microhelium-judge:prod
@IMAGE_TAG=prod $(PROD_COMPOSE) up -d --no-build --wait --wait-timeout 120
@echo "Rolled back to $(PREV). Running smoke tests..."
@$(MAKE) smoke
@echo "Rollback to $(PREV) verified healthy."
smoke:
@./scripts/smoke.sh
# =============================================================================
# Cleanup
# =============================================================================
clean:
@docker compose down -v --remove-orphans
@docker system prune -f
clean-all:
@docker compose down -v --remove-orphans --rmi all
@docker system prune -af --volumes