본문 바로가기
Docker :

[DUAS] Dockerfile, Distroless 빌드 - 배포

by 밍코딩코 2025. 6. 13.

gradle, docker, distroless

SpringBoot

1. 개발중인 프로젝트 초기 빌드

./gradlew bootJar

 

build/libs/*.jar 파일 생성

 

2. Dockerfile

프로젝트 루트 폴더에 Dockerfile 생성

# 1단계: 빌드 (JDK 필요)
FROM eclipse-temurin:21-jdk AS builder
WORKDIR /app
COPY . .
RUN ./gradlew bootJar

# 2단계: 런타임 (Distroless)
FROM gcr.io/distroless/java21-debian12
WORKDIR /app
COPY --from=builder /app/build/libs/*.jar app.jar

# JVM 옵션은 필요에 따라 조정
ENTRYPOINT ["java","-jar","app.jar"]

 

  • 빌드 스테이지 : jdk
  • 런타임 스테이지 : Distroless로 최적화, 불필요한 레이어 쉘 제거

3. 빌드 및 실행

docker build -t myapp:latest .
docker run -d -p 8080:8080 --name myapp myapp:latest

 

docker containers에 추가됨

 

4. yml 분리

application.yml 파일 분리 : application.yml, application-dev.yml, application-prod.yml

# application.yml

spring:
  application:
    name: admin_server
#dev

dev 값들 ...
#prod .env 환경 변수로 값들 지정

spring:
  datasource:
    driver-class-name: org.postgresql.Driver
    url: ${SPRING_DATASOURCE_URL}
    username: ${SPRING_DATASOURCE_USERNAME}
    password: ${SPRING_DATASOURCE_PASSWORD}

  jpa:
    properties:
      hibernate:
        jdbc:
          time_zone: Asia/Seoul
      hibernate.allow_update_agent_connection_release: true

  servlet:
    multipart:
      max-file-size: ${SERVLET_MULTIPART_MAX_FILE_SIZE}
      max-request-size: ${SERVLET_MULTIPART_MAX_REQUEST_SIZE}

logging:
  level:
    org.springframework: INFO
    org.hibernate: INFO

server:
  port: ${SERVER_PORT}
  servlet:
    context-path: /
  tomcat:
    remoteip:
      remote-ip-header: X-Forwarded-For

storage:
  url: ${STORAGE_URL}
  bucket: ${STORAGE_BUCKET}

crypto:
  aes-key: "${CRYPTO_AES_KEY}"

 

.env

SPRING_PROFILES_ACTIVE=prod
SPRING_DATASOURCE_URL=
SPRING_DATASOURCE_USERNAME=
SPRING_DATASOURCE_PASSWORD=
JPA_HIBERNATE_DDL_AUTO=
SERVLET_MULTIPART_MAX_FILE_SIZE=
SERVLET_MULTIPART_MAX_REQUEST_SIZE=
SERVER_PORT=
STORAGE_URL=
STORAGE_BUCKET=
CRYPTO_AES_KEY=

 

 

추가 고려사항

1. 무중단 배포 - Blue/Green, Rolling Update 활용

2. yml에 postgresql ip 주소 내 로컬 ip로 변경

3. Dockerignore

 

task dockerBuild 

로컬에서 도커 이미지 생성

task dockerBuild(type: Exec) {
    group = 'docker'
    description = 'Build Docker image'
    commandLine 'docker', 'build', '-t', 'project-name', '--platform', 'linux/amd64', '.'
}

 

task dockerDeploy

빌드한 이미지를 서버에 전송하고 로드

task dockerDeploy(type: Exec) {
    group = 'docker'
    description = 'Deploy Docker image'
    commandLine 'sh', '-c', 'docker save project-name | zstd -T0 | ssh dlup-manage "unzstd | docker load"'
}

 

배포 과정

IntelliJ

./gradlew dockerBuild -> ./gradlew dockerDeploy

 

VSCode

- store server : npm run docker:build:dev -> npm run docker:deploy:dev

 

terminal

~/.ssh

ssh project-name 접속

docker images 이미지

docker rmi IMAGEID : 이전 이미지 삭제

docker ps -a : 현재 떠있는 컨테이너 확인

docker kill containerID

docker rm containerID : 컨테이너 삭제

cd dliup-manage : ssh 내부 배포할 경로로 이동 (관리자 페이지 배포할때는 하나 더 진입해서 docker run)

dev : history에서 docker run -d --env-file .env -p ip:ip --name name project-name:latest (dev배포)

 

container migration

ssh 접속 상태에서

docker ps

docker exec -it ContainerID /bin/bash

root@ID:/app# npx prisma migrate deploy

 

마이그레이션 후 컨테이너 내리고 다시 올리기

 

STORE PG 승인

store 프로젝트 sites/../env.production에 PG AUTH KEY, PG AUTH TAIL, PG SHOP ID 수정 

'Docker :' 카테고리의 다른 글

[DLU] docker, ssh  (2) 2025.06.10