3-Tier Architecture Deployment with Docker: Frontend, Backend, and Database_Image Optimization (3)

·

2 min read

In this post, we'll cover the setup of the frontend, backend, and database services, focusing on creating efficient Docker images.

Traffic Flow

Frontend (Next.js)

Dockerfile


FROM node:18-alpine as builder
WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci # Install dependencies.
COPY . .
RUN npm run build

FROM node:18-alpine as runner
WORKDIR /app
COPY --from=builder /app .
EXPOSE 3000
ENTRYPOINT ["npm", "start"]
  • Multi-Stage Build: Builds the app in the builder stage, copies only necessary files to the runner stage.

  • Base Image: node:18-alpine for a lightweight Node.js environment.

  • Expose Port: Opens port 3000 for web traffic.

Backend (Spring)

Initial Dockerfile

FROM openjdk:17-oracle
COPY ./build/libs/app.jar app.jar
ENTRYPOINT ["java", "-jar", "-Xmx512M", "-Dspring.profiles.active=main", "app.jar"]
  • Base Image: openjdk:17-oracle for Oracle JDK 17.

  • Copy JAR: Copies the built JAR file into the image.

  • Entry Point: Runs the JAR with specific JVM options.

Optimized Dockerfile

# Build Stage
FROM gradle:8.7.0-jdk17 AS build
COPY --chown=gradle:gradle . /home/gradle/src
WORKDIR /home/gradle/src
RUN gradle build --no-daemon --stacktrace

# Final Stage
FROM openjdk:17-jdk-alpine
COPY --from=build /home/gradle/src/build/libs/*.jar app.jar
ENV TZ Asia/Seoul
CMD ["java", "-jar", "-Xmx512M", "-Dspring.profiles.active=main", "app.jar"]
  • Multi-Stage Build: Builds the app in the first stage, runs it in the second.

  • Base Image: openjdk:17-jdk-alpine for a lightweight JDK.

  • Optimized for Size: Uses Alpine-based images to reduce size.

Database (MongoDB)

Dockerfile

FROM mongo:4
COPY init-mongo.js /docker-entrypoint-initdb.d/

init-mongo.js

db = db.getSiblingDB('appdb');
db.createCollection("collection1");
db.createCollection("collection2");
db.collection1.insertMany([
    { name: "example1", value: "data1" },
    { name: "example2", value: "data2" }
]);
db.collection2.insertMany([
    { name: "example3", value: "data3" },
    { name: "example4", value: "data4" }
]);
  • MongoDB Initialization: Sets up the database, creates collections, and inserts sample data.

Next Steps

In the next post, we'll dive into monitoring the 3-tier architecture