Skip to content

Commit ee41fd4

Browse files
github-actions[bot]tofikwestMarfuen
authored
[dev] [tofikwest] tofik/docker-build-updates (#1931)
* feat(api): add multi-stage Docker build configuration and docker-compose * chore(api): add comment for local testing in docker-compose file --------- Co-authored-by: Tofik Hasanov <[email protected]> Co-authored-by: Mariano Fuentes <[email protected]>
1 parent 912f418 commit ee41fd4

File tree

3 files changed

+175
-0
lines changed

3 files changed

+175
-0
lines changed

apps/api/Dockerfile.multistage

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# =============================================================================
2+
# STAGE 1: Dependencies - Install workspace dependencies
3+
# =============================================================================
4+
FROM oven/bun:1.2.8 AS deps
5+
6+
WORKDIR /app
7+
8+
# Copy root workspace config
9+
COPY package.json bun.lock ./
10+
11+
# Copy all workspace package.json files
12+
COPY packages/db/package.json ./packages/db/
13+
COPY packages/utils/package.json ./packages/utils/
14+
COPY packages/integration-platform/package.json ./packages/integration-platform/
15+
COPY packages/tsconfig/package.json ./packages/tsconfig/
16+
17+
# Copy API package.json
18+
COPY apps/api/package.json ./apps/api/
19+
20+
# Install all dependencies (including workspace deps)
21+
RUN bun install
22+
23+
# =============================================================================
24+
# STAGE 2: Builder - Build workspace packages and NestJS app
25+
# =============================================================================
26+
FROM deps AS builder
27+
28+
WORKDIR /app
29+
30+
# Copy workspace packages source
31+
COPY packages/db ./packages/db
32+
COPY packages/utils ./packages/utils
33+
COPY packages/integration-platform ./packages/integration-platform
34+
COPY packages/tsconfig ./packages/tsconfig
35+
36+
# Copy API source
37+
COPY apps/api ./apps/api
38+
39+
# Bring in node_modules from deps stage
40+
COPY --from=deps /app/node_modules ./node_modules
41+
42+
# Build workspace packages
43+
RUN cd packages/db && bun run build && cd ../..
44+
RUN cd packages/integration-platform && bun run build && cd ../..
45+
46+
# Generate Prisma client for API (copy schema and generate)
47+
RUN cd packages/db && node scripts/combine-schemas.js && cd ../..
48+
RUN cp packages/db/dist/schema.prisma apps/api/prisma/schema.prisma
49+
RUN cd apps/api && bunx prisma generate
50+
51+
# Build NestJS application
52+
RUN cd apps/api && bun run build
53+
54+
# =============================================================================
55+
# STAGE 3: Production Runtime
56+
# =============================================================================
57+
FROM node:20-alpine AS production
58+
59+
WORKDIR /app
60+
61+
# Install runtime dependencies
62+
RUN apk add --no-cache wget libc6-compat openssl
63+
64+
# Copy built NestJS app
65+
COPY --from=builder /app/apps/api/dist ./dist
66+
67+
# Copy prisma files
68+
COPY --from=builder /app/apps/api/prisma ./prisma
69+
70+
# Copy package.json (for any runtime needs)
71+
COPY --from=builder /app/apps/api/package.json ./package.json
72+
73+
# Copy workspace packages that are referenced by node_modules symlinks
74+
COPY --from=builder /app/packages/db ./packages/db
75+
COPY --from=builder /app/packages/utils ./packages/utils
76+
COPY --from=builder /app/packages/integration-platform ./packages/integration-platform
77+
COPY --from=builder /app/packages/tsconfig ./packages/tsconfig
78+
79+
# Copy production node_modules (includes symlinks to workspace packages above)
80+
COPY --from=builder /app/node_modules ./node_modules
81+
82+
# Set production environment
83+
ENV NODE_ENV=production
84+
ENV PORT=3333
85+
86+
# Install Prisma CLI and regenerate client in production stage
87+
RUN npm install -g [email protected] && \
88+
prisma generate --schema=./prisma/schema.prisma
89+
90+
# Create non-root user
91+
RUN addgroup --system nestjs && adduser --system --ingroup nestjs nestjs \
92+
&& chown -R nestjs:nestjs /app
93+
94+
USER nestjs
95+
96+
EXPOSE 3333
97+
98+
# Health check
99+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
100+
CMD wget --no-verbose --tries=1 --spider http://localhost:3333/v1/health || exit 1
101+
102+
# Start the application
103+
CMD ["node", "dist/src/main.js"]
104+

apps/api/buildspec.multistage.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
version: 0.2
2+
3+
# Simplified buildspec that uses multi stage Docker build
4+
# al building happens inside Docker - CodeBuild just orchestrates ECR/ECS
5+
6+
phases:
7+
pre_build:
8+
commands:
9+
- echo "Logging in to Amazon ECR..."
10+
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
11+
- COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
12+
- IMAGE_TAG=${COMMIT_HASH:=latest}
13+
14+
build:
15+
commands:
16+
- echo "Building Docker image with multi-stage build..."
17+
- cd apps/api
18+
- docker build \
19+
--build-arg BUILDKIT_INLINE_CACHE=1 \
20+
--target production \
21+
-f Dockerfile.multistage \
22+
-t $ECR_REPOSITORY_URI:$IMAGE_TAG \
23+
../..
24+
- docker tag $ECR_REPOSITORY_URI:$IMAGE_TAG $ECR_REPOSITORY_URI:latest
25+
26+
post_build:
27+
commands:
28+
- echo "Pushing images to ECR..."
29+
- docker push $ECR_REPOSITORY_URI:$IMAGE_TAG
30+
- docker push $ECR_REPOSITORY_URI:latest
31+
- echo "Updating ECS service..."
32+
- aws ecs update-service --cluster $ECS_CLUSTER_NAME --service $ECS_SERVICE_NAME --force-new-deployment
33+
- 'printf "[{\"name\":\"%s-container\",\"imageUri\":\"%s\"}]" api $ECR_REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json'
34+
35+
cache:
36+
paths:
37+
- '/root/.docker/buildx/cache/**/*'
38+
39+
artifacts:
40+
files:
41+
- imagedefinitions.json
42+
name: ${APP_NAME}-build
43+

apps/api/docker-compose.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# FOR TESTING LOCALY ONLY
2+
version: '3.8'
3+
4+
services:
5+
api:
6+
build:
7+
context: ../..
8+
dockerfile: apps/api/Dockerfile.multistage
9+
target: production
10+
container_name: comp-api-test
11+
ports:
12+
- "3333:3333"
13+
environment:
14+
- NODE_ENV=production
15+
- PORT=3333
16+
env_file:
17+
- .env
18+
19+
healthcheck:
20+
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3333/v1/health"]
21+
interval: 30s
22+
timeout: 3s
23+
retries: 3
24+
start_period: 5s
25+
26+
restart: unless-stopped
27+
28+

0 commit comments

Comments
 (0)