Skip to content

Commit b12af4a

Browse files
committed
chore: update docker files
1 parent 81daac2 commit b12af4a

13 files changed

Lines changed: 614 additions & 526 deletions

File tree

.github/workflows/docker-build-manual.yaml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,20 @@ jobs:
2525
with:
2626
version: 9
2727

28-
- uses: actions/setup-node@v4
28+
- name: Setup Node.js
29+
uses: actions/setup-node@v4
2930
with:
3031
node-version: "22"
3132
cache: "pnpm"
3233
cache-dependency-path: "./backend/pnpm-lock.yaml"
33-
- run: pnpm install --frozen-lockfile
34-
- run: pnpm test
35-
env:
36-
CLIENT_URL: http://localhost:3000
34+
35+
- name: Install dependencies
36+
run: pnpm install --frozen-lockfile
37+
working-directory: ./backend
38+
39+
- name: Run Tests
40+
run: pnpm test
41+
working-directory: ./backend
3742

3843
backend:
3944
needs: test-backend

backend/Dockerfile

Lines changed: 13 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,45 @@
1-
# syntax=docker/dockerfile:1
2-
3-
# Comments are provided throughout this file to help you get started.
4-
# If you need more help, visit the Dockerfile reference guide at
5-
# https://docs.docker.com/go/dockerfile-reference/
6-
7-
# Want to help us make this template better? Share your feedback here: https://forms.gle/ybq9Krt8jtBL3iCk7
8-
9-
ARG NODE_VERSION=22.18.0
1+
ARG NODE_VERSION=24.11.0
102
ARG PNPM_VERSION=10.32.1
113

12-
################################################################################
13-
# Use node image for base image for all stages.
14-
FROM node:${NODE_VERSION}-alpine as base
4+
# =================== base stage ============================================
5+
FROM node:${NODE_VERSION}-alpine AS base
156

16-
# Set working directory for all build stages.
177
WORKDIR /usr/src/app
188

19-
# Install pnpm.
20-
RUN --mount=type=cache,target=/root/.npm \
21-
npm install -g pnpm@${PNPM_VERSION}
22-
23-
################################################################################
24-
# Create a stage for installing production dependecies.
9+
# =================== deps stage ============================================
2510
FROM base as deps
2611

27-
# Download dependencies as a separate step to take advantage of Docker's caching.
28-
# Leverage a cache mount to /root/.local/share/pnpm/store to speed up subsequent builds.
29-
# Leverage bind mounts to package.json and pnpm-lock.yaml to avoid having to copy them
30-
# into this layer.
12+
RUN --mount=type=cache,target=/root/.npm \
13+
npm install -g pnpm@${PNPM_VERSION}
14+
3115
RUN --mount=type=bind,source=package.json,target=package.json \
32-
--mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \
33-
--mount=type=cache,target=/root/.local/share/pnpm/store \
34-
pnpm install --prod --frozen-lockfile
16+
--mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \
17+
--mount=type=cache,target=/root/.local/share/pnpm/store \
18+
pnpm install --prod --frozen-lockfile
3519

36-
################################################################################
37-
# Create a stage for building the application.
20+
# =================== build stage ============================================
3821
FROM deps as build
3922

40-
# Download additional development dependencies before building, as some projects require
41-
# "devDependencies" to be installed to build. If you don't need this, remove this step.
4223
RUN --mount=type=bind,source=package.json,target=package.json \
4324
--mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \
4425
--mount=type=cache,target=/root/.local/share/pnpm/store \
4526
pnpm install --frozen-lockfile
4627

47-
# Copy the rest of the source files into the image.
4828
COPY . .
49-
# Run the build script.
5029
RUN pnpm run build
5130

52-
################################################################################
53-
# Create a new stage to run the application with minimal runtime dependencies
54-
# where the necessary files are copied from the build stage.
31+
# =================== final stage ============================================
5532
FROM base as final
5633

57-
# Use production node environment by default.
5834
ENV NODE_ENV production
5935

60-
# Run the application as a non-root user.
6136
USER node
6237

63-
# Copy package.json so that package manager commands can be used.
6438
COPY package.json .
6539

66-
# Copy the production dependencies from the deps stage and also
67-
# the built application from the build stage into the image.
6840
COPY --from=deps /usr/src/app/node_modules ./node_modules
6941
COPY --from=build /usr/src/app/dist ./dist
7042

71-
72-
# Expose the port that the application listens on.
7343
EXPOSE 3000
7444

75-
# Run the application.
76-
CMD ["pnpm", "run", "start"]
45+
CMD ["node", "./dist/src/server.js"]

backend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"scripts": {
88
"start": "node ./dist/src/server.js",
99
"watch": "tsc -w",
10-
"build": "tsc",
10+
"build": "tsc -p tsconfig.build.json",
1111
"dev": "concurrently \"tsc -w\" \"node --watch ./dist/src/server.js\"",
1212
"bun": "bun ./src/server.ts",
1313
"bun watch": "bun --watch ./src/server.ts",

backend/src/app.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ app.use(
1111
cors({
1212
origin: process.env.CLIENT_URL as string,
1313
credentials: true,
14+
maxAge: 7200,
1415
}),
1516
);
1617

backend/src/config/db.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ export default async function connectDB() {
77
logger.info({ message: "MongoDB connected" });
88
} catch (error) {
99
logger.error({ message: "Failed to connect to MongoDB", error });
10+
throw error;
1011
}
1112
}

backend/src/config/redis.config.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { Redis } from "ioredis";
22
import logger from "../utils/logger.utils.js";
33

4-
const redis = new Redis(process.env.REDIS_URL as string);
4+
const redis = new Redis(process.env.REDIS_URL as string, {
5+
connectTimeout: 10_000,
6+
maxRetriesPerRequest: 3,
7+
});
58

69
redis.on("connect", () => {
710
logger.info({ message: "Redis client connected" });

backend/src/server.ts

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,34 @@ import "dotenv/config";
22
import app from "./app.js";
33
import connectDB from "./config/db.config.js";
44
import logger from "./utils/logger.utils.js";
5+
import redis from "./config/redis.config.js";
6+
import mongoose from "mongoose";
57

6-
connectDB();
8+
async function startServer() {
9+
try {
10+
await connectDB();
711

8-
const port = process.env.PORT || 3000;
9-
app.listen(port, () => {
10-
logger.info(`Server running on Port ${port}`);
11-
});
12+
const port = process.env.PORT || 3000;
13+
const server = app.listen(port, () => {
14+
logger.info({ message: "Server running on Port", port });
15+
});
16+
17+
const shutdown = async (signal: string) => {
18+
logger.info({ message: "Closing connections...", signal });
19+
await redis.quit();
20+
await mongoose.connection.close();
21+
server.close(() => {
22+
logger.info({ message: "Server and DB connections closed." });
23+
process.exit(0);
24+
});
25+
};
26+
27+
process.on("SIGTERM", () => shutdown("SIGTERM"));
28+
process.on("SIGINT", () => shutdown("SIGINT"));
29+
} catch (error) {
30+
logger.error({ message: "Failed to start server", error });
31+
process.exit(1);
32+
}
33+
}
34+
35+
startServer();

backend/tests/integration/job/fetch.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ describe("GET /api/v1/jobs/:jobId", () => {
3333
it("should return 400 for invalid jobId parameter", async () => {
3434
vi.mocked(jwtUtils.verifyToken).mockReturnValue({ userId: "user-abc-123" } as any);
3535

36-
const response = await request(app).get("/api/v1/jobs/invalid-id").set("Authorization", "Bearer validsimulatedtoken");
36+
const response = await request(app)
37+
.get("/api/v1/jobs/invalid-id")
38+
.set("Authorization", "Bearer validsimulatedtoken");
3739

3840
expect(response.status).toBe(400);
3941
expect(response.body.message.length).toBeGreaterThan(0);

backend/tsconfig.build.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts", "tests"]
4+
}

docker-compose.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: "3.9"
2-
31
services:
42
mongodb:
53
image: mongo:6

0 commit comments

Comments
 (0)