-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathMakefile
More file actions
521 lines (433 loc) · 22 KB
/
Makefile
File metadata and controls
521 lines (433 loc) · 22 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
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
.PHONY: help list
export DOCKER_BUILDKIT = 1
# herokuish cheatsheet for when you can't run herokuish --help
# $ herokuish
# Available commands:
# buildpack Use and install buildpacks
# build Build an application using installed buildpacks
# install Install buildpack from Git URL and optional committish
# list List installed buildpacks
# test Build and run tests for an application using installed buildpacks
# help Shows help information for a command
# paths Shows path settings
# procfile Use Procfiles and run app commands
# exec Run as unprivileged user with Heroku-like env
# parse Get command string for a process type from Procfile
# start Run process type command from Procfile through exec
# slug Manage application slugs
# export Export generated slug tarball to URL (PUT) or STDOUT
# generate Generate a gzipped slug tarball from the current app
# import Import a gzipped slug tarball from URL or STDIN
# test Test running an app through Herokuish
# version Show version and supported version info
test_network_name=outpost-test-network
test_mongo_container_name=outpost-test-mongo
test_mongo_port=27019
test_mongo_volume_name=outpost-test-mongo-volume
test_mongo_db_name=outpost_api_test
test_mongo_db_user=outpost
test_mongo_db_password=password
test_mongo_init_db_user=admin
test_mongo_init_db_password=password
test_mongo_local_db_uri="mongodb://$(test_mongo_db_user):$(test_mongo_db_password)@localhost:$(test_mongo_port)/$(test_mongo_db_name)"
test_mongo_internal_db_uri="mongodb://$(test_mongo_db_user):$(test_mongo_db_password)@$(test_mongo_container_name):27017/$(test_mongo_db_name)"
test_postgres_container_name=outpost-test-postgres
test_postgres_port=5434
test_postgres_volume_name=outpost-test-postgres-volume
test_postgres_db_name=outpost_test
test_postgres_db_user=outpost
test_postgres_db_password=password
test_postgres_local_db_uri="postgresql://$(test_postgres_db_user):$(test_postgres_db_password)@localhost:$(test_postgres_port)/$(test_postgres_db_name)"
test_postgres_internal_db_uri="postgresql://$(test_postgres_db_user):$(test_postgres_db_password)@$(test_postgres_container_name):5432/outpost?"
prod_network_name=outpost-production-network
prod_container_name=outpost_production
prod_container_port=3000
prod_mongo_container_name=outpost-production-mongo
prod_mongo_port=27020
prod_mongo_volume_name=outpost-production-mongo-volume
prod_mongo_db_name=outpost_api_production
prod_mongo_db_user=outpost
prod_mongo_db_password=password
prod_mongo_init_db_user=admin
prod_mongo_init_db_password=password
prod_mongo_local_db_uri="mongodb://$(prod_mongo_db_user):$(prod_mongo_db_password)@localhost:$(prod_mongo_port)/$(prod_mongo_db_name)"
prod_mongo_internal_db_uri="mongodb://$(prod_mongo_db_user):$(prod_mongo_db_password)@$(prod_mongo_container_name):27017/$(prod_mongo_db_name)"
prod_postgres_container_name=outpost-test-postgres
prod_postgres_port=5435
prod_postgres_volume_name=outpost-production-postgres-volume
prod_postgres_db_name=outpost_production
prod_postgres_db_user=outpost
prod_postgres_db_password=password
prod_postgres_local_db_uri="postgresql://$(prod_postgres_db_user):$(prod_postgres_db_password)@localhost:$(prod_postgres_port)/$(prod_postgres_db_name)"
prod_postgres_internal_db_uri="postgresql://$(prod_postgres_db_user):$(prod_postgres_db_password)@$(prod_postgres_container_name):5432/outpost?"
help: ## Lists all documented Make targets.
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m\make %-30s\033[0m %s\n", $$1, $$2}'
list: help
# ╔══════════════════════════════════╗
# ║ BUILD IMAGES ║
# ╚══════════════════════════════════╝
build-development: ## build the development image
docker build --no-cache --progress=plain \
--build-arg NODE_ENV=development \
--build-arg RAILS_ENV=development \
-f "Dockerfile" \
-t outpost:development "."
build-development-arm64: ## build the development image
docker build --no-cache --progress=plain \
--platform linux/arm64 \
--build-arg NODE_ENV=development \
--build-arg RAILS_ENV=development \
-f "Dockerfile" \
-t outpost:development "."
# nb: wont work on silicone macs (so untested)
build-development-amd64: ## build the development image
docker build --no-cache --progress=plain \
--platform linux/amd64 \
--build-arg NODE_ENV=development \
--build-arg RAILS_ENV=development \
-f "Dockerfile" \
-t outpost:development "."
# --------------------
# nb: wont work on silicone macs (so untested)
build-test: ## build the test image
docker build --no-cache --progress=plain \
--platform linux/amd64 \
--build-arg NODE_ENV=development \
--build-arg RAILS_ENV=test \
-f "Dockerfile.test" \
-t outpost:test "."
# --------------------
# nb: wont work on silicone macs (so untested)
build-prod: ## build the production image
docker build --no-cache --progress=plain \
--platform linux/amd64 \
--build-arg TRACE=true \
--build-arg NODE_ENV=production \
--build-arg RAILS_ENV=production \
-f "Dockerfile.production" \
-t outpost:production "."
# ------------------------------------------------------------------------------
# ╔══════════════════════════════════╗
# ║ RUN IMAGES ║
# ╚══════════════════════════════════╝
# example of the '/app/.docker/docker-entrypoint-migrate.sh' entrypoint to migrate then run the application
# you can also set the entrypoint to /start and the command to web or migrate_web to run the application
up-prod: ## Start the application as if it were in production
make env-prod
@if ! docker container ls -a | grep -q $(prod_container_name); then \
docker run -it -d --name $(prod_container_name) \
--platform linux/amd64 \
--network $(prod_network_name) \
--entrypoint /app/.docker/docker-entrypoint-migrate.sh \
-p $(prod_container_port):3000/tcp \
-e SECRET_KEY_BASE=dummy \
-e DATABASE_URL=$(prod_postgres_internal_db_uri) \
-e DB_URI=$(prod_mongo_internal_db_uri) \
ghcr.io/wearefuturegov/outpost:latest web; \
echo "Container $(prod_container_name) is now running"; \
else \
echo "Container $(prod_container_name) is already running"; \
fi
@echo "Don't forget to run ngrok! ngrok http $(prod_container_port)"
seed-prod: ## Seed production database
make cmd-exec-prod cmd="bin/rails SEED_ADMIN_USER=true SEED_DUMMY_DATA=true SEED_DEFAULT_DATA=true db:seed"
# /exec run command on the container as unprivileged user eg bin/rails c
cmd-exec-prod: ## execute a command as an unprivileged user on the application eg make cmd-exec-prod cmd="bin/rails c"
@if [ -z "$(cmd)" ]; then echo "cmd is required"; exit 1; fi
docker exec -it $(prod_container_name) /exec $(cmd)
# /start run any command from procfile eg web or migrate
# nb /start is the default entrypoint for the production image
cmd-start-prod: ## execute a command on the production image as if you were heroku eg make cmd-start-prod cmd="release"
@if [ -z "$(cmd)" ]; then echo "cmd is required"; exit 1; fi
docker exec -it $(prod_container_name) /start $(cmd)
start-prod: ## start prod environment
@if ! docker container ls -a | grep -q $(prod_container_name); then \
echo "Container $(prod_container_name) isn't running, nothing to start"; \
else \
docker container start $(prod_container_name); \
echo "Container $(prod_container_name) is now started"; \
fi
stop-prod: ## stop prod environment
@if ! docker container ls -a | grep -q $(prod_container_name); then \
echo "Container $(prod_container_name) isn't running, nothing to stop"; \
else \
docker container stop $(prod_container_name); \
echo "Container $(prod_container_name) is now stopped"; \
fi
rm-prod: ## remove prod environment
@if ! docker container ls -a | grep -q $(prod_container_name); then \
echo "Container $(prod_container_name) isn't running, nothing to remove"; \
else \
docker container stop $(prod_container_name); \
docker container rm $(prod_container_name); \
echo "Container $(prod_container_name) is now gone 💥"; \
fi
# ╔══════════════════════════════════╗
# ║ SETUP ENVIRONMENT ║
# ╚══════════════════════════════════╝
env-test: ## Start the test environment
make env-test-setup
make test-postgres
make test-mongo
env-test-setup: ## Setup the test environment
@if ! docker network ls | grep -q $(test_network_name); then \
echo "Network $(test_network_name) does not exist, creating..."; \
docker network create $(test_network_name); \
else \
echo "Network $(test_network_name) already exists."; \
fi
@if ! docker volume ls | grep -q $(test_postgres_volume_name); then \
echo "Volume $(test_postgres_volume_name) does not exist, creating..."; \
docker volume create $(test_postgres_volume_name); \
else \
echo "Volume $(test_postgres_volume_name) already exists."; \
fi
@if ! docker volume ls | grep -q $(test_mongo_volume_name); then \
echo "Volume $(test_mongo_volume_name) does not exist, creating..."; \
docker volume create $(test_mongo_volume_name); \
else \
echo "Volume $(test_mongo_volume_name) already exists."; \
fi
env-test-clear: ## Remove the test environment
@if ! docker network ls | grep -q $(test_network_name); then \
echo "Network $(test_network_name) does not exist"; \
else \
echo "Network $(test_network_name) exists, deleting..."; \
docker network rm $(test_network_name); \
fi
@if ! docker volume ls | grep -q $(test_postgres_volume_name); then \
echo "Volume $(test_postgres_volume_name) does not exist"; \
else \
echo "Volume $(test_postgres_volume_name) exists, deleting..."; \
docker volume rm $(test_postgres_volume_name); \
fi
@if ! docker volume ls | grep -q $(test_mongo_volume_name); then \
echo "Volume $(test_mongo_volume_name) does not exist"; \
else \
echo "Volume $(test_mongo_volume_name) exists, deleting..."; \
docker volume rm $(test_mongo_volume_name); \
fi
# --------------------
env-prod: ## Start the prod environment
make env-prod-setup
make prod-postgres
make prod-mongo
env-prod-setup: ## Setup the prod environment
@if ! docker network ls | grep -q $(prod_network_name); then \
echo "Network $(prod_network_name) does not exist, creating..."; \
docker network create $(prod_network_name); \
else \
echo "Network $(prod_network_name) already exists."; \
fi
@if ! docker volume ls | grep -q $(prod_postgres_volume_name); then \
echo "Volume $(prod_postgres_volume_name) does not exist, creating..."; \
docker volume create $(prod_postgres_volume_name); \
else \
echo "Volume $(prod_postgres_volume_name) already exists."; \
fi
@if ! docker volume ls | grep -q $(prod_mongo_volume_name); then \
echo "Volume $(prod_mongo_volume_name) does not exist, creating..."; \
docker volume create $(prod_mongo_volume_name); \
else \
echo "Volume $(prod_mongo_volume_name) already exists."; \
fi
env-prod-clear: ## Remove the prod environment
@if ! docker network ls | grep -q $(prod_network_name); then \
echo "Network $(prod_network_name) does not exist"; \
else \
echo "Network $(prod_network_name) exists, deleting..."; \
docker network rm $(prod_network_name); \
fi
@if ! docker volume ls | grep -q $(prod_postgres_volume_name); then \
echo "Volume $(prod_postgres_volume_name) does not exist"; \
else \
echo "Volume $(prod_postgres_volume_name) exists, deleting..."; \
docker volume rm $(prod_postgres_volume_name); \
fi
@if ! docker volume ls | grep -q $(prod_mongo_volume_name); then \
echo "Volume $(prod_mongo_volume_name) does not exist"; \
else \
echo "Volume $(prod_mongo_volume_name) exists, deleting..."; \
docker volume rm $(prod_mongo_volume_name); \
fi
# ------------------------------------------------------------------------------
# ╔══════════════════════════════════╗
# ║ SETUP POSTGRES ║
# ╚══════════════════════════════════╝
test-postgres: ## run postgres for the test environment
make env-test-setup
@if ! docker container ls -a | grep -q $(test_postgres_container_name); then \
docker run -d --name $(test_postgres_container_name) \
--network $(test_network_name) \
-p $(test_postgres_port):5432 \
-v $(test_postgres_volume_name):/var/lib/postgresql/data \
-e POSTGRES_DB=$(test_postgres_db_name) \
-e POSTGRES_PASSWORD=$(test_postgres_db_password) \
-e POSTGRES_USER=$(test_postgres_db_user) \
postgres:13.7-alpine; \
echo "Container $(test_postgres_container_name) is now running"; \
else \
echo "Container $(test_postgres_container_name) is already running"; \
fi
@echo "Connect to it from your machine at: $(test_postgres_local_db_uri)"
@echo "The DATABASE_URL connection string will be: $(test_postgres_internal_db_uri)"
test-postgres-stop: ## stop postgres for the test environment
@if ! docker container ls -a | grep -q $(test_postgres_container_name); then \
echo "Container $(test_postgres_container_name) isn't running, nothing to stop"; \
else \
docker container stop $(test_postgres_container_name); \
echo "Container $(test_postgres_container_name) is now stopped"; \
fi
test-postgres-rm: ## remove postgres for the test environment
@if ! docker container ls -a | grep -q $(test_postgres_container_name); then \
echo "Container $(test_postgres_container_name) isn't running, nothing to remove"; \
else \
docker container stop $(test_postgres_container_name); \
docker container rm $(test_postgres_container_name); \
echo "Container $(test_postgres_container_name) is now gone 💥"; \
fi
# --------------------
prod-postgres: ## run postgres for the prod environment
make env-prod-setup
@if ! docker container ls -a | grep -q $(prod_postgres_container_name); then \
docker run -d --name $(prod_postgres_container_name) \
--network $(prod_network_name) \
-p $(prod_postgres_port):5432 \
-v $(prod_postgres_volume_name):/var/lib/postgresql/data \
-e POSTGRES_DB=$(prod_postgres_db_name) \
-e POSTGRES_PASSWORD=$(prod_postgres_db_password) \
-e POSTGRES_USER=$(prod_postgres_db_user) \
postgres:13.7-alpine; \
echo "Container $(prod_postgres_container_name) is now running"; \
else \
echo "Container $(prod_postgres_container_name) is already running"; \
fi
@echo "Connect to it from your machine at: $(test_postgres_local_db_uri)"
@echo "The DATABASE_URL connection string will be: $(test_postgres_internal_db_uri)"
prod-postgres-stop: ## stop postgres for the prod environment
@if ! docker container ls -a | grep -q $(prod_postgres_container_name); then \
echo "Container $(prod_postgres_container_name) isn't running, nothing to stop"; \
else \
docker container stop $(prod_postgres_container_name); \
echo "Container $(prod_postgres_container_name) is now stopped"; \
fi
prod-postgres-rm: ## remove postgres for the prod environment
@if ! docker container ls -a | grep -q $(prod_postgres_container_name); then \
echo "Container $(prod_postgres_container_name) isn't running, nothing to remove"; \
else \
docker container stop $(prod_postgres_container_name); \
docker container rm $(prod_postgres_container_name); \
echo "Container $(prod_postgres_container_name) is now gone 💥"; \
fi
# ------------------------------------------------------------------------------
# ╔══════════════════════════════════╗
# ║ SETUP MONGO ║
# ╚══════════════════════════════════╝
test-mongo: ## run postgres for the test environment
make env-test-setup
@if ! docker container ls -a | grep -q $(test_mongo_container_name); then \
docker run -d --name $(test_mongo_container_name) \
--platform=linux/arm64 \
--network $(test_network_name) \
-p $(test_mongo_port):27017 \
-v $(test_mongo_volume_name):/data/db \
-v "./.docker/services/mongo/setup-mongodb.js:/docker-entrypoint-initdb.d/mongo-init.js:ro" \
-e MONGO_INITDB_ROOT_USERNAME=$(test_mongo_init_db_user) \
-e MONGO_INITDB_ROOT_PASSWORD=$(test_mongo_init_db_password) \
-e MONGO_INITDB_USERNAME=$(test_mongo_db_user) \
-e MONGO_INITDB_PASSWORD=$(test_mongo_db_password) \
-e MONGO_INITDB_DATABASE=$(test_mongo_db_name) \
mongo:6; \
echo "Container $(test_mongo_container_name) is now running"; \
else \
echo "Container $(test_mongo_container_name) is already running"; \
fi
@echo "Connect to it from your machine at: $(test_mongo_local_db_uri)"
@echo "The DB_URI connection string will be: $(test_mongo_internal_db_uri)"
test-mongo-stop: ## stop mongo for the test environment
@if ! docker container ls -a | grep -q $(test_mongo_container_name); then \
echo "Container $(test_mongo_container_name) isn't running, nothing to stop"; \
else \
docker container stop $(test_mongo_container_name); \
echo "Container $(test_mongo_container_name) is now stopped"; \
fi
test-mongo-rm: ## remove mongo for the test environment
@if ! docker container ls -a | grep -q $(test_mongo_container_name); then \
echo "Container $(test_mongo_container_name) isn't running, nothing to remove"; \
else \
docker container stop $(test_mongo_container_name); \
docker container rm $(test_mongo_container_name); \
echo "Container $(test_mongo_container_name) is now gone 💥"; \
fi
# --------------------
prod-mongo: ## run postgres for the prod environment
make env-prod-setup
@if ! docker container ls -a | grep -q $(prod_mongo_container_name); then \
docker run -d --name $(prod_mongo_container_name) \
--platform=linux/arm64 \
--network $(prod_network_name) \
-p $(prod_mongo_port):27017 \
-v $(prod_mongo_volume_name):/data/db \
-v "./.docker/services/mongo/setup-mongodb.js:/docker-entrypoint-initdb.d/mongo-init.js:ro" \
-e MONGO_INITDB_ROOT_USERNAME=$(prod_mongo_init_db_user) \
-e MONGO_INITDB_ROOT_PASSWORD=$(prod_mongo_init_db_password) \
-e MONGO_INITDB_USERNAME=$(prod_mongo_db_user) \
-e MONGO_INITDB_PASSWORD=$(prod_mongo_db_password) \
-e MONGO_INITDB_DATABASE=$(prod_mongo_db_name) \
mongo:6; \
echo "Container $(prod_mongo_container_name) is now running"; \
else \
echo "Container $(prod_mongo_container_name) is already running"; \
fi
@echo "Connect to it from your machine at: $(prod_mongo_local_db_uri)"
@echo "The DB_URI connection string will be: $(prod_mongo_internal_db_uri)"
prod-mongo-stop: ## stop mongo for the prod environment
@if ! docker container ls -a | grep -q $(prod_mongo_container_name); then \
echo "Container $(prod_mongo_container_name) isn't running, nothing to stop"; \
else \
docker container stop $(prod_mongo_container_name); \
echo "Container $(prod_mongo_container_name) is now stopped"; \
fi
prod-mongo-rm: ## remove mongo for the prod environment
@if ! docker container ls -a | grep -q $(prod_mongo_container_name); then \
echo "Container $(prod_mongo_container_name) isn't running, nothing to remove"; \
else \
docker container stop $(prod_mongo_container_name); \
docker container rm $(prod_mongo_container_name); \
echo "Container $(prod_mongo_container_name) is now gone 💥"; \
fi
# ------------------------------------------------------------------------------
# ╔══════════════════════════════════╗
# ║ DEVELOPMENT ║
# ╚══════════════════════════════════╝
# some helpers when developing locally
dev-up: ## run local development environment
docker compose up -d
dev-build: ## build local image
docker compose build
dev-down: ## remove all local containers
docker compose down
dev-seed: ## seed the local database with send_needs etc
docker compose exec outpost bin/rails db:seed
dev-seed-admin: ## seed local database with send_needs etc and an admin user
docker compose exec outpost bin/rails SEED_ADMIN_USER=true db:seed
dev-seed-data: ## seed local database with dummy data
docker compose exec outpost bin/rails SEED_DUMMY_DATA=true db:seed
dev-seed-default-data: ## seed local database with send_needs etc
docker compose exec outpost bin/rails SEED_DEFAULT_DATA=true db:seed
dev-seed-all: ## seed local database with admin user, dummy data and send_needs etc
docker compose exec outpost bin/rails SEED_ADMIN_USER=true SEED_DUMMY_DATA=true SEED_DEFAULT_DATA=true db:seed
dev-ssh: ## access outpost from cli
docker compose exec outpost bash
dev-railsc: ## run rails console
docker compose exec outpost bin/rails c
dev-tests: ## run tests
# docker compose exec outpost bash -c "DISABLE_SPRING=1 NODE_ENV=development RAILS_ENV=test bundle exec rspec ./spec/features/filtering_services_spec.rb:64"
# docker compose exec outpost bash -c "DISABLE_SPRING=1 NODE_ENV=development RAILS_ENV=test bundle exec rspec ./spec/features/test_for_tests.rb"
docker compose exec outpost bash -c "DISABLE_SPRING=1 NODE_ENV=development RAILS_ENV=test bundle exec rspec"
dev-rake: ## run rake tasks
docker compose exec outpost bash -c "DISABLE_SPRING=1 NODE_ENV=development RAILS_ENV=test rake"
dev-coverage: ## open test coverage summary
open coverage/index.html
dev-index: ## populate the api
docker compose exec outpost bin/rails update_public_index