Skip to content

Commit b4ee01e

Browse files
Merge pull request #11 from bloom-housing/release/2-3-26
feat: release 2-3-26
2 parents eafd8ad + e2dc93d commit b4ee01e

File tree

18 files changed

+3470
-1033
lines changed

18 files changed

+3470
-1033
lines changed

.dockerignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Dockerfile
2+
.dockerignore
3+
**/node_modules
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
name: Docker Compose CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
check-docker-compose:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Check out Git repository
19+
uses: actions/checkout@v6
20+
21+
- name: build
22+
shell: bash
23+
run: |
24+
if ! docker compose build; then
25+
echo 'ERROR: docker compose build failed'
26+
fi
27+
28+
- name: dbinitcheck
29+
shell: bash
30+
run: |
31+
if ! docker compose up \
32+
--exit-code-from dbinit \
33+
db dbinit
34+
then
35+
echo 'ERROR: dbinit first execution did not exit with 0'
36+
exit 1
37+
fi
38+
39+
if ! docker compose up \
40+
--exit-code-from dbinit \
41+
db dbinit
42+
then
43+
echo 'ERROR: dbinit second execution did not exit with 0'
44+
exit 1
45+
fi
46+
47+
if ! docker compose down; then
48+
echo 'ERROR: docker compose down failed'
49+
fi
50+
51+
- name: dbreadonlycheck
52+
shell: bash
53+
run: |
54+
if ! COMPOSE_PROFILES=ci docker compose up \
55+
--exit-code-from dbreadonlycheck \
56+
dbreadonlycheck
57+
then
58+
echo 'ERROR: dbreadonlycheck did not exit with 0'
59+
exit 1
60+
fi
61+
62+
if ! docker compose down; then
63+
echo 'ERROR: docker compose down failed'
64+
fi
65+
66+
- name: sites-smoke-test
67+
shell: bash
68+
run: |
69+
if ! docker compose up --wait; then
70+
echo 'ERROR: docker compose up --wait did not exit with 0'
71+
exit 1
72+
fi
73+
74+
if ! curl --fail http://127.0.0.1:3001; then
75+
echo 'ERROR: partners site is not accessible. Logs:'
76+
docker compose logs partners
77+
exit 1
78+
fi
79+
80+
if ! curl --fail http://127.0.0.1:3000; then
81+
echo 'ERROR: public site is not accessible. Logs:'
82+
docker compose logs public
83+
exit 1
84+
fi
85+
86+
if ! docker compose down; then
87+
echo 'ERROR: docker compose down failed'
88+
exit 1
89+
fi

.github/workflows/docker_image_build.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ jobs:
3131
docker_context: "{{defaultContext}}:api"
3232
dockerfile: Dockerfile.dbseed
3333
platforms: linux/amd64
34+
- container: dbinit
35+
docker_context: "{{defaultContext}}:api/dbinit"
36+
dockerfile: Dockerfile
37+
platforms: linux/amd64
3438
- container: partners
3539
docker_context: "{{defaultContext}}"
3640
dockerfile: Dockerfile.sites.partners

api/Dockerfile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ RUN yarn build
3333
#
3434
# IMPORTANT: keep the 'build' layer above in sync.
3535
FROM node:22@sha256:23c24e85395992be118734a39903e08c8f7d1abc73978c46b6bda90060091a49 AS run
36-
WORKDIR /run
36+
WORKDIR /bloom_api
3737

3838
# Copy over build artifacts.
3939
COPY --from=build /build/runtime_dependencies/ .
@@ -47,9 +47,9 @@ COPY --from=build /build/prisma/migrations ./prisma/migrations
4747
COPY --from=build /build/node_modules/.prisma ./node_modules/.prisma
4848

4949
# Create a non-root user to run (principle of least privilege).
50-
WORKDIR /run
51-
RUN groupadd --gid 2002 run && useradd --gid 2002 --uid 2002 --home /run run
52-
RUN chown --recursive 2002:2002 /run
50+
WORKDIR /bloom_api
51+
RUN groupadd --gid 2002 bloom_api && useradd --gid 2002 --uid 2002 --home /bloom_api bloom_api
52+
RUN chown --recursive 2002:2002 /bloom_api
5353
USER 2002:2002
5454

5555
# Run any DB migrations then start the server.

api/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ The tests require the TIME_ZONE environment variable to be set. Create a `.env`
187187

188188
```bash
189189
echo 'TIME_ZONE=America/Los_Angeles' > .env
190+
echo 'CLOUDINARY_CLOUD_NAME=exygy' >> .env
190191
```
191192

192193
Running the following will run all unit tests: `yarn test`

api/dbinit/Dockerfile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# To update, find the latest stable version from:
2+
# https://hub.docker.com/_/postgres/tags
3+
#
4+
# Explicitly pin the version tag and image sha.
5+
FROM docker.io/postgres:18.1@sha256:5773fe724c49c42a7a9ca70202e11e1dff21fb7235b335a73f39297d200b73a2
6+
7+
COPY --chown=postgres:postgres *.sql .
8+
9+
USER postgres:postgres

api/dbinit/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# dbinit
2+
3+
Creates a docker container that is used to initialize the Bloom postgres database.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
-- Test the bloom_readonly expected permissions.
2+
\set ON_ERROR_STOP on
3+
4+
DO $$
5+
BEGIN
6+
-- Should succeed (PERFORM is like a SELECT but the results are discarded).
7+
PERFORM id FROM jurisdictions;
8+
RAISE NOTICE 'SELECT: OK';
9+
10+
-- Should fail
11+
BEGIN
12+
INSERT INTO applicant DEFAULT VALUES;
13+
RAISE EXCEPTION 'INSERT unexpectedly succeeded';
14+
EXCEPTION WHEN insufficient_privilege THEN
15+
RAISE NOTICE 'INSERT: correctly denied';
16+
END;
17+
END $$;

api/dbinit/docker-compose.init.sql

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
-- Creates the bloom_prisma database and database users.
2+
-- Follows examples from https://aws.amazon.com/blogs/database/managing-postgresql-users-and-roles/.
3+
4+
\set ON_ERROR_STOP on
5+
6+
-- Database
7+
SELECT 'CREATE DATABASE bloom_prisma'
8+
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'bloom_prisma')\gexec
9+
\c bloom_prisma
10+
11+
-- Revoke public privleges
12+
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
13+
REVOKE ALL ON DATABASE bloom_prisma FROM PUBLIC;
14+
15+
-- Roles
16+
-- bloom_api
17+
DO $$
18+
BEGIN
19+
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'bloom_api') THEN
20+
CREATE USER bloom_api PASSWORD 'bloom_api_pw';
21+
GRANT CONNECT ON DATABASE bloom_prisma TO bloom_api;
22+
GRANT ALL PRIVILEGES ON DATABASE bloom_prisma TO bloom_api;
23+
GRANT ALL PRIVILEGES ON SCHEMA public TO bloom_api;
24+
END IF;
25+
END
26+
$$;
27+
28+
29+
-- bloom_readonly
30+
DO $$
31+
BEGIN
32+
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'bloom_readonly') THEN
33+
CREATE USER bloom_readonly PASSWORD 'bloom_readonly_pw';
34+
GRANT CONNECT ON DATABASE bloom_prisma TO bloom_readonly;
35+
GRANT USAGE ON SCHEMA public TO bloom_readonly;
36+
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO bloom_readonly;
37+
END IF;
38+
END
39+
$$;
40+
41+
-- Set local role within transation.
42+
BEGIN;
43+
SET LOCAL ROLE bloom_api;
44+
45+
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO bloom_readonly;
46+
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE ON SEQUENCES TO bloom_readonly;
47+
COMMIT;

api/dbinit/rds.init.sql

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
-- Creates the bloom_prisma database and database users.
2+
-- Follows examples from https://aws.amazon.com/blogs/database/managing-postgresql-users-and-roles/.
3+
4+
\set ON_ERROR_STOP on
5+
6+
-- Database
7+
SELECT 'CREATE DATABASE bloom_prisma'
8+
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'bloom_prisma')\gexec
9+
\c bloom_prisma
10+
11+
-- Revoke public privleges
12+
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
13+
REVOKE ALL ON DATABASE bloom_prisma FROM PUBLIC;
14+
15+
-- Roles
16+
-- bloom_api
17+
DO $$
18+
BEGIN
19+
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'bloom_api') THEN
20+
CREATE USER bloom_api;
21+
GRANT rds_iam TO bloom_api;
22+
GRANT CONNECT ON DATABASE bloom_prisma TO bloom_api;
23+
GRANT ALL PRIVILEGES ON DATABASE bloom_prisma TO bloom_api;
24+
GRANT ALL PRIVILEGES ON SCHEMA public TO bloom_api;
25+
END IF;
26+
END
27+
$$;
28+
29+
30+
-- bloom_readonly
31+
DO $$
32+
BEGIN
33+
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'bloom_readonly') THEN
34+
CREATE USER bloom_readonly;
35+
GRANT rds_iam TO bloom_readonly;
36+
GRANT CONNECT ON DATABASE bloom_prisma TO bloom_readonly;
37+
GRANT USAGE ON SCHEMA public TO bloom_readonly;
38+
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO bloom_readonly;
39+
END IF;
40+
END
41+
$$;
42+
43+
-- Set local role within transation.
44+
BEGIN;
45+
SET LOCAL ROLE bloom_api;
46+
47+
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO bloom_readonly;
48+
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE ON SEQUENCES TO bloom_readonly;
49+
COMMIT;

0 commit comments

Comments
 (0)