Skip to content

TIL -2025-05-21 [도커파일을 활용한 배포 방법, MySQL Docker 컨테이너 실행, Spring Boot 환경변수 보안 관리 및 Docker 배포 시 .env 활용 방법, Docker 컨테이너화 배포실습 중 오류] #72

Description

@soheeGit

📌 도커파일을 활용한 배포 방법

1. 로컬에서 직접 실행 (개발/테스트용)

도커 파일로 이미지를 만든 후, 로컬 환경에서 직접 실행.

# 1. Dockerfile을 기준으로 이미지 생성
docker build -t my-app .

# 2. 컨테이너 실행
docker run -d -p 8080:80 --name my-app-container my-app
  • 빠르게 테스트 가능
  • CI/CD 없이 수동 배포
  • 운영 환경엔 적합하지 않음

2. Docker Hub / GHCR / ACR 등에 이미지 푸시 후 실행

이미지를 퍼블릭/프라이빗 레지스트리에 올리고, 다른 서버에서 pull 해서 실행.

# 1. 빌드
docker build -t my-app .

# 2. 태깅
docker tag my-app docker.io/yourid/my-app:latest

# 3. 푸시
docker push docker.io/yourid/my-app:latest

# 4. 다른 서버에서 pull & run
docker pull docker.io/yourid/my-app:latest
docker run -d -p 8080:80 yourid/my-app:latest
  • 서버 간 이미지 배포가 쉬움
  • CI/CD와 연계 가능

3. CI/CD + Docker 배포 (GitHub Actions / Jenkins 등)

CI 도구가 Dockerfile을 빌드하고, 배포 서버에 자동으로 푸시/실행.
예시 (GitHub Actions + EC2):

  • GitHub Actions로 Docker 이미지 빌드 → GHCR 업로드
  • EC2에 Jenkins 또는 SSH로 접속해 GHCR에서 pull → 실행
# GitHub Actions 예시
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: docker build -t ghcr.io/yourid/my-app:latest .
      - run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u yourid --password-stdin
      - run: docker push ghcr.io/yourid/my-app:latest
  • 자동화된 배포 가능
  • 프로덕션 환경에 적합
  • Nginx + HTTPS 연동도 가능

📌 MySQL Docker 컨테이너 실행

https://hub.docker.com/
https://hub.docker.com/_/mysql

# 1. MySQL 8.0 이미지 받기
docker pull mysql:8.0

# 2. 기존 mysql 컨테이너 종료 및 제거 (있다면)
docker rm -f mysql

# 3. 새 컨테이너 실행
docker run -d -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=1q2w3e4r mysql:8.0
# 4. 컨테이너 상태 확인
docker ps        # 실행 중인 컨테이너 확인
docker logs mysql  # 로그 확인
  • DBeaver로 연결
항목
Host localhost
Port 3306
User root
Password 1q2w3e4r
Database 필요시 생성 후 연결 (CREATE DATABASE ...)

아래와 같은 오류가 뜬다면

Image

아래와 같이 설정해주면 성공한다.

Image Image Image

newdb라는 database를 만들어준다.

Image
server:
  port: 8080 
spring:
  # JPA
  jpa:
    hibernate:
      ddl-auto: create 
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL8Dialect # MySQL
        show_sql: true
        format_sql: true
  # 데이터소스
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver # MySQL
    url: jdbc:mysql://localhost:3306/mydb?useSSL=false
    username: root
    password: 1q2w3e4r
  • 이런식으로 설정하면 내가 코드로 만들어두었던 Animal 테이블이 생성된 것을 볼 수 있다.
Image

데이터베이스까지 한번에 만들고 싶다면?

docker run -d -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=1q2w3e4r -e MYSQL_DATABASE=mydb mysql:8.0

볼륨(외부연결) 까지 추가하고 싶다면?

방법 1: 직접 경로 마운트

docker run -d -p 3306:3306 --name mysql -v ~/Development/workspace/docker/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=1q2w3e4r -e MYSQL_DATABASE=mydb mysql:8.0
  • 단, Mac에서는 권한 문제 발생할 수 있음 (Docker Desktop이 직접 파일을 쓰려고 할 때)
  • 일부 디렉토리는 Docker > Settings > File Sharing에 등록돼 있어야 사용 가능

방법 2: Docker 볼륨 사용 (권장)

# docker rm -f mysql
docker volume create mydb-data
docker run -d -p 3306:3306 --name mysql -v mydb-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=1q2w3e4r -e MYSQL_DATABASE=mydb mysql:8.0

Docker 네트워크 생성도 추가하고 싶다면?

# mydb-network라는 사용자 정의 네트워크를 생성
docker network create mydb-network
# docker rm -f mysql
docker run -d -p 3306:3306 --name mysql -v mydb-data:/var/lib/mysql --network mydb-network -e MYSQL_ROOT_PASSWORD=1q2w3e4r -e MYSQL_DATABASE=mydb mysql:8.0
# mydb-network 네트워크에 대한 자세한 정보를 JSON 형식으로 출력
docker network inspect mydb-network
# docker rm -f boot-container-v2
docker run -d -p 19898:8080 --name boot-container-v2 --network mydb-network --env-file .env boot-container:v2-arm
Image

📌 Spring Boot 환경변수 보안 관리 및 Docker 배포 시 .env 활용 방법

Spring Boot의 application-prod.yml 파일에는 민감한 정보(DB 연결 정보 등)가 있으므로,
이를 코드에서 직접 작성하지 않고, 외부 .env 파일을 통해 안전하게 주입하기 위함이다.

  1. application-prod.yml (코드에는 변수 이름만 남긴다)
server:
  port: 8080

spring:
  jpa:
    hibernate:
      ddl-auto: create
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL8Dialect
        show_sql: true
        format_sql: true
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: ${DB_URL}
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}
  1. .env 파일 (Docker나 docker-compose에서 환경변수 정의)
DB_URL=jdbc:mysql://localhost:3306/mydb?useSSL=false
DB_USERNAME=root
DB_PASSWORD=1q2w3e4r
  • Docker 컨테이너 실행 시 --env-file .env 또는 env_file:로 사용된다.
  1. Docker 또는 docker-compose에서 연동
  • Docker CLI
docker run -d \
  --env-file .env \
  -p 8080:8080 \
  your-springboot-image:latest
  • docker-compose.yml 예시
version: '3.8'
services:
  app:
    image: your-springboot-image:latest
    ports:
      - "8080:8080"
    env_file:
      - .env

❗️ Docker 컨테이너화 배포실습 중 오류

# Stage 1: Build
FROM eclipse-temurin:17-jdk-alpine AS build
WORKDIR /app

# 그래들 파일 복사 및 의존성 캐싱
COPY gradlew .
COPY gradle gradle
COPY build.gradle settings.gradle ./
RUN chmod +x ./gradlew

# 소스 코드 복사 및 빌드
COPY src src
RUN ./gradlew build -x test

# Stage 2: Runtime
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app

# 빌드 스테이지에서 JAR 파일만 복사
COPY --from=build /app/build/libs/*.jar app.jar

EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
docker build -t boot-container:v1 .
Image - eclipse-temurin:17-jdk-alpine 이미지를 불러올 수 없음

원인

  • eclipse-temurin:17-jdk-alpine 이미지는 현재 사용 중인 플랫폼(rancher-desktop, M2 칩) 에 맞는 이미지가 Docker Hub에 존재하지 않기 때문이다.
  • 특히 alpine 기반의 일부 Java 이미지들은 ARM64 (Apple Silicon) 플랫폼을 지원하지 않는 경우가 많다.
docker build -t boot-container:v1 . # 이전 명령어
docker build --platform linux/amd64 -t boot-container:v1 . # 플랫폼 관련 이슈 해결
  • 플랫폼 관련 이슈는 해결했지만, 무한 빌드 에러 발생

해결방법

  • Dockerfile 변경
# Stage 1: Build
FROM azul/zulu-openjdk:17-latest AS build
WORKDIR /app

# 그래들 파일 복사 및 의존성 캐싱
COPY gradlew .
COPY gradle gradle
COPY build.gradle settings.gradle ./
RUN chmod +x ./gradlew

# 소스 코드 복사 및 빌드
COPY src src
RUN ./gradlew build -x test

# Stage 2: Runtime
FROM azul/zulu-openjdk:17-latest
WORKDIR /app

# 빌드 스테이지에서 JAR 파일만 복사
COPY --from=build /app/build/libs/*.jar app.jar

EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
docker build -t boot-container:v1-arm -f ./Dockerfile-mac .
docker run -d -p 9898:8080 --name boot-container boot-container:v1-arm
Image

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions