Skip to content

Commit 4824c96

Browse files
authored
Merge pull request #34 from CS3219-AY2425S1/anun/docker-question
PEER-252 Dockerize question service
2 parents cb25c64 + 7b32a74 commit 4824c96

File tree

10 files changed

+135
-22
lines changed

10 files changed

+135
-22
lines changed

backend/question/.env.compose

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
EXPRESS_ENV="compose"
2+
PEERPREP_UI_HOST="http://frontend:3000"
3+
4+
EXPRESS_PORT=9002
5+
EXPRESS_DB_HOST="qn-db"
6+
EXPRESS_DB_PORT=5433
7+
POSTGRES_DB="question"
8+
POSTGRES_USER="peerprep-qn-express"
9+
POSTGRES_PASSWORD="Xk8qEcEI2sizjfEn/lF6mLqiyBECjIHY3q6sdXf9poQ="
10+
PGDATA="/data/qn-db"
11+
12+
EXPRESS_JWT_SECRET_KEY="jd+9qlXA0a3YsmVf2KJgyiJ3SprIR318IAwhRXck4Y8="

backend/question/.env.docker

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
EXPRESS_ENV=local
2+
PEERPREP_UI_HOST=http://localhost:5173
3+
4+
EXPRESS_PORT=9002
5+
EXPRESS_DB_HOST=host.docker.internal
6+
EXPRESS_DB_PORT=5433
7+
POSTGRES_DB=question
8+
POSTGRES_USER=peerprep-qn-express
9+
POSTGRES_PASSWORD=Xk8qEcEI2sizjfEn/lF6mLqiyBECjIHY3q6sdXf9poQ=
10+
PGDATA=/data/qn-db
11+
12+
EXPRESS_JWT_SECRET_KEY=jd+9qlXA0a3YsmVf2KJgyiJ3SprIR318IAwhRXck4Y8=

backend/question/README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,40 @@
33
This directory contains the code for the Template
44
Service.
55

6+
7+
# Questions Service
8+
9+
## Running with Docker (Standalone)
10+
11+
1. Run this command to build:
12+
```sh
13+
docker build \
14+
-t question-express-local \
15+
--build-arg port=9002 \
16+
-f express.Dockerfile .
17+
```
18+
2. Run this command, from the root folder:
19+
```sh
20+
make db-up
21+
```
22+
23+
3. Run the necessary migrate and seed commands, if you haven't yet.
24+
25+
4. Run this command to expose the container:
26+
```sh
27+
docker run -p 9002:9002 --env-file ./.env.docker question-express-local
28+
```
29+
30+
## Running with Docker-Compose (Main config)
31+
32+
Edit the variables in the `.env.compose` file and run `make up` from the root folder.
33+
34+
Any startup instructions will be run from `entrypoint.sh` instead.
35+
36+
37+
38+
39+
640
## Database
741
842
We use:

backend/question/docker-compose.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ services:
2525
target: build
2626
args:
2727
# For building with the correct env vars
28-
- env=${EXPRESS_ENV}
28+
- port=${EXPRESS_PORT}
2929
ports:
30-
- "9002:8001"
30+
- "9001:${EXPRESS_PORT}"
3131
command: node dist/index.js
3232
env_file:
3333
- ./.env.local

backend/question/entrypoint.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/sh
2+
3+
# Drizzle will handle its own logic to remove conflicts
4+
npm run db:prod:migrate
5+
6+
# Checks admin table and will not seed if data exists
7+
npm run db:prod:seed
8+
9+
rm -rf drizzle src tsconfig.json
10+
11+
npm uninstall tsx drizzle-kit
12+
13+
npm run start

backend/question/express.Dockerfile

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,25 @@ FROM node:lts-alpine AS build
22
WORKDIR /data/question-express
33
COPY package*.json ./
44
RUN npm install
5+
ARG env
56
COPY . .
67
RUN npm run build
78

89
FROM node:lts-alpine AS production
910
WORKDIR /data/question-express
1011
COPY --from=build /data/question-express/package*.json ./
11-
RUN npm ci --omit=dev
1212
COPY --from=build --chown=node:node /data/question-express/dist ./dist
1313

14-
ARG env
15-
COPY ".env.${env}" .
16-
EXPOSE 8001
17-
CMD [ "npm", "run", "start" ]
14+
RUN npm ci --omit=dev
15+
16+
# For migration
17+
RUN npm install tsx drizzle-kit
18+
COPY drizzle ./drizzle
19+
COPY src/lib/db/ ./src/lib/db
20+
COPY src/config.ts ./src
21+
COPY tsconfig.json .
22+
COPY entrypoint.sh .
23+
24+
ARG port
25+
EXPOSE ${port}
26+
ENTRYPOINT [ "/bin/sh", "entrypoint.sh" ]

backend/question/package.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
"main": "dist/index.js",
55
"scripts": {
66
"dev": "env-cmd -f .env.local nodemon src/index.ts | pino-pretty",
7-
"build": "env-cmd -f .env.local tsc && tsc-alias",
8-
"start": "env-cmd -f .env.local node dist/index.js",
9-
"build:prod": "env-cmd -f .env.prod tsc && tsc-alias",
10-
"start:prod": "env-cmd -f .env.local node dist/index.js",
7+
"build": "tsc && tsc-alias",
8+
"start": "node dist/index.js",
9+
"build:local": "env-cmd -f .env.local tsc && tsc-alias",
10+
"start:local": "env-cmd -f .env.local node dist/index.js",
1111
"db:generate": "env-cmd -f .env.local drizzle-kit generate",
1212
"db:migrate": "env-cmd -f .env.local tsx ./src/lib/db/migrate.ts",
1313
"db:seed": "env-cmd -f .env.local tsx ./src/lib/db/seed.ts",
14+
"db:prod:migrate": "tsx ./src/lib/db/migrate.ts",
15+
"db:prod:seed": "tsx ./src/lib/db/seed.ts",
1416
"db:inspect": "env-cmd -f .env.local drizzle-kit studio",
1517
"fmt": "prettier --config .prettierrc src --write",
1618
"test": "echo \"Error: no test specified\" && exit 1"
@@ -21,6 +23,7 @@
2123
"description": "",
2224
"dependencies": {
2325
"cors": "^2.8.5",
26+
"dotenv": "^16.4.5",
2427
"drizzle-orm": "^0.33.0",
2528
"env-cmd": "^10.1.0",
2629
"express": "^4.21.0",
@@ -33,6 +36,7 @@
3336
"devDependencies": {
3437
"@swc/core": "^1.7.26",
3538
"@swc/helpers": "^0.5.13",
39+
"@types/cors": "^2.8.17",
3640
"@types/express": "^4.17.21",
3741
"@types/node": "^22.5.5",
3842
"drizzle-kit": "^0.24.2",

backend/question/src/lib/db/seed.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const seedQuestions = async () => {
99
const seedRecords = await trx.select().from(adminTable).where(eq(adminTable.action, 'SEED'));
1010
if (seedRecords && seedRecords.length > 0) {
1111
console.info(
12-
`[Users]: Seeded already at: ${(seedRecords[seedRecords.length - 1].createdAt ?? new Date()).toLocaleString()}`
12+
`[Questions]: Seeded already at: ${(seedRecords[seedRecords.length - 1].createdAt ?? new Date()).toLocaleString()}`
1313
);
1414
return;
1515
}
@@ -32,6 +32,7 @@ const seedQuestions = async () => {
3232
.values({ ...question, id: undefined }) // Let DB set ID
3333
.onConflictDoNothing();
3434
}
35+
await trx.insert(adminTable).values({ action: 'SEED' });
3536
});
3637
} catch (error) {
3738
console.log('[Questions]: Error seeding question data', error);

docker-compose.yaml

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ services:
44
# Databases
55
user-db:
66
hostname: 'user-db'
7-
image: postgres:16.4
7+
image: 'postgres:16.4'
88
container_name: 'user-db'
99
build:
1010
context: ./backend/user/src/lib/db
@@ -55,8 +55,6 @@ services:
5555
restart: unless-stopped
5656
networks:
5757
- question-db-network
58-
ports:
59-
- 5433:5432
6058
healthcheck:
6159
test: ['CMD-SHELL', 'pg_isready -U peerprep-qn-express -d question']
6260
interval: 10s
@@ -75,8 +73,6 @@ services:
7573
args:
7674
# For building with the correct env vars
7775
- port=${USER_EXPRESS_PORT}
78-
ports:
79-
- '9001:${USER_EXPRESS_PORT}'
8076
env_file:
8177
- ./backend/user/.env.compose
8278
environment:
@@ -91,12 +87,42 @@ services:
9187
- user-db-network
9288
- user-api-network
9389
healthcheck:
94-
test: wget --no-verbose --tries=1 --spider http://localhost:9001/health || exit 1
90+
test: wget --no-verbose --tries=1 --spider http://localhost:${USER_EXPRESS_PORT}/health || exit 1
9591
interval: 30s
9692
timeout: 10s
9793
retries: 5
9894
start_period: 5s
9995

96+
question-service:
97+
image: "question-express"
98+
container_name: '${QUESTION_SERVICE_NAME}'
99+
build:
100+
context: ./backend/question
101+
dockerfile: express.Dockerfile
102+
target: production
103+
args:
104+
# For building with the correct env vars
105+
- port=${QUESTION_EXPRESS_PORT}
106+
env_file:
107+
- ./backend/question/.env.compose
108+
environment:
109+
# Docker Compose Specific for Service Discovery
110+
- EXPRESS_DB_HOST=question-db
111+
- EXPRESS_DB_PORT=5432
112+
depends_on:
113+
question-db:
114+
condition: service_healthy
115+
restart: true
116+
networks:
117+
- question-db-network
118+
- question-api-network
119+
healthcheck:
120+
test: wget --no-verbose --tries=1 --spider http://localhost:${QUESTION_EXPRESS_PORT}/health || exit 1
121+
interval: 30s
122+
timeout: 10s
123+
retries: 5
124+
start_period: 5s
125+
100126
# Frontend
101127

102128
frontend:
@@ -113,13 +139,15 @@ services:
113139
- ./frontend/.env.compose
114140
environment:
115141
- VITE_USER_SERVICE=http://${USER_SERVICE_NAME}:${USER_EXPRESS_PORT}
116-
##to remove localhost once integrating question
117-
- VITE_QUESTION_SERVICE=http://host.docker.internal:${QUESTION_EXPRESS_PORT}
142+
- VITE_QUESTION_SERVICE=http://${QUESTION_SERVICE_NAME}:${QUESTION_EXPRESS_PORT}
118143
- FRONTEND_PORT=${FRONTEND_PORT}
119144
depends_on:
120145
user-service:
121146
condition: service_healthy
122147
restart: true
148+
question-service:
149+
condition: service_healthy
150+
restart: true
123151
networks:
124152
- user-api-network
125153
- question-api-network

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)