자바 스프링 부트 개념 정리(Docker)

제이 용·2025년 12월 17일

Docker

  • Docker는 애플리케이션과 실행 환경을 하나로 묶어
  • 어디서 실행하든 동일하게 동작하도록 만들어주는 컨테이너 기술이다.

코드뿐만 아니라 실행에 필요한 OS, 라이브러리, 설정까지 함께 패키징하여

“내 컴퓨터에서는 되는데?” 문제를 해결해준다.


요약

  • Docker = 실행 환경을 통째로 포장하는 기술

Docker가 필요한 이유

  • 환경이 다르면 결과도 달라지기 때문이다.

  • 개발자 PC: Windows / Mac

  • 서버 환경: Linux

  • 라이브러리 버전, 패키지 충돌, 환경 변수 차이

  • DB, 포트, 경로 설정 문제

같은 코드인데도 실행 결과가 달라지는 문제가 빈번하게 발생한다.

  • Docker는 동일한 환경에서 언제나 같은 결과를 보장하기 위해 존재한다.

  • 기존 방식: 가상 머신(VM)

    • 예전에는 가상 머신(Virtual Machine) 을 사용했다.

    • OS 위에 또 다른 OS를 실행

    • 완전히 분리된 환경

하지만 무겁고 느리며 자원 소모가 큼

  • 문제점

    • VM 1개당 OS 1개 필요

    • 부팅 시간 느림

    • CPU / RAM / 디스크 낭비 큼


컨테이너(Container)는 뭐가 다를까?

  • 컨테이너는 운영체제를 새로 띄우지 않는다.

호스트 OS의 커널을 공유하고

애플리케이션 실행에 필요한 것만 격리해서 실행한다.

  • VM vs Container 비교
구분가상 머신(VM)컨테이너(Container)
구조OS 위에 또 다른 OSOS 커널 공유
실행 단위OS 단위애플리케이션 단위
부팅 속도느림 (수 분)매우 빠름 (수 초)
용량수 GB수백 MB
자원 사용많음효율적
  • VM: 컴퓨터 안에 또 다른 컴퓨터

  • 컨테이너: 하나의 컴퓨터에서 앱만 격리 실행


컨테이너가 빠른 이유

  • OS를 새로 부팅하지 않음

  • 호스트 OS의 커널을 그대로 사용

  • 필요한 실행 환경만 로드

요약

필요한 환경만 꺼내 쓰기 때문에 빠르고 가볍다.


Docker의 핵심 개념

Image (이미지)

  • 실행 환경을 정의한 설계도

  • OS, 라이브러리, 애플리케이션, 설정 포함

읽기 전용(Immutable)

  • 특징

    • 이미지는 실행되지 않음

    • 하나의 이미지로 여러 컨테이너 생성 가능

  • 비유

    • 이미지 = 붕어빵 틀

Container (컨테이너)

  • 이미지를 실제로 실행한 결과물

  • 독립된 실행 공간

  • 가볍고 빠르게 생성 / 삭제 가능

  • 특징

    • 서로 간섭하지 않음

    • 필요할 때 만들고 버릴 수 있음

    • 실행 중인 애플리케이션이 여기서 동작

  • 비유

    • 컨테이너 = 붕어빵
    • (같은 틀로 원하는 만큼 생성 가능)

컨테이너 하나 = 포맷된 깨끗한 컴퓨터 1대


컨테이너를 사용하는 이유

  • 사람마다 다른 개발 환경 문제 해결

  • OS 상관없이 동일한 실행 보장

  • 환경 설정을 자동화

  • 예시

    • Windows / Mac / Linux 상관 없음

    • 환경 변수 차이 없음

    • Ubuntu 설치 필요 없음

    • WSL2, VM 설치 없이도 실행 가능

이미지 하나로 모든 설정이 자동 구성


Docker Hub

  • Docker Hub는 이미지 저장소이다.

  • GitHub = 코드 저장소

  • Docker Hub = 실행 환경(이미지) 저장소

  • 특징

    • 전 세계 개발자가 만든 이미지 공유

    • 공식 이미지 다수 제공

  • 예시 이미지

    • redis

    • mysql

    • kafka

    • elasticsearch

  • 비유

    • Docker Hub = 붕어빵 틀 창고
  • 기본 사용 흐름

    • search → pull → run

Docker 전체 흐름

Docker는 깨끗한 실행 환경을 이미지로 정의하고,

그 이미지를 컨테이너로 실행하여

어디서든 동일한 결과를 보장하는 기술이다.


Docker Hub에서 Redis 실행하기 (실습 TIL)

  • Docker Hub에서 Redis 이미지 검색
docker search redis
  • Docker Hub는 전 세계 개발자들이 공유하는 도커 이미지 저장소

  • OFFICIAL 표시가 있는 이미지는 Redis 공식 팀이 배포한 신뢰 가능한 이미지

  • 포인트

    • 실무에서는 가급적 OFFICIAL 이미지를 사용한다.

  • Redis 이미지 다운로드 (pull)
docker pull redis:latest
  • pull : Docker Hub에서 이미지를 로컬로 다운로드

  • latest : Redis의 최신 버전 태그

  • 다운로드된 이미지 확인

docker images
  • 출력 예시:
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
redis        latest    b5d3b2e6f64e   2 weeks ago    117MB

Redis 실행 환경이 이미지 형태로 내 컴퓨터에 저장됨


  • Redis 컨테이너 실행
docker run -d -p 6379:6379 --name redis-container redis:latest
  • 옵션 설명
-d	백그라운드(detached) 실행
-p 6379:6379	호스트 ↔ 컨테이너 포트 매핑
--name redis-container	컨테이너 이름 지정
redis:latest	실행할 이미지
  • Redis 설치

  • 실행 환경 구성

  • Redis 서버 실행

    • 이 모두가 자동으로 완료됨

  • 컨테이너 실행 상태 확인
docker ps
  • 출력 예시:
CONTAINER ID   IMAGE          STATUS          PORTS
a12b3c4d5e6f   redis:latest   Up 5 seconds    0.0.0.0:6379->6379/tcp
  • 확인 포인트

    • STATUS 가 Up → 정상 실행 중

    • 6379->6379 → 외부에서 Redis 접근 가능

5. Port(포트)

  • 포트는 한 컴퓨터 안에서 프로그램을 구분하는 번호

  • IP 주소: 컴퓨터(서버)의 주소

  • 포트 번호: 그 컴퓨터 안에서 실행 중인 프로그램의 출입구

  • 비유

    • IP = 건물 주소
    • Port = 건물 안의 문 번호
  • 대표적인 포트 예시

    • 80 : 웹 서버

    • 3306 : MySQL

    • 6379 : Redis


Docker에서의 포트 매핑

컨테이너는 외부와 격리된 공간이기 때문에

외부에서 접근하려면 포트를 연결해야 한다.

-p [호스트 포트]:[컨테이너 포트]
  • 예시 1
docker run -d -p 6379:6379 redis:latest
  • 왼쪽 6379 내 컴퓨터(호스트) 포트
  • 오른쪽 6379 컨테이너 내부 Redis 포트

호스트 6379 → 컨테이너 6379 연결

  • 예시 2
docker run -d -p 8000:6379 redis:latest

호스트 8000 포트로 접근하면 컨테이너 내부의 Redis(6379)로 연결됨


실행 중인 Redis 컨테이너 접근하기

  • 컨테이너 ID 확인
docker ps

a12b3c4d5e6f   redis:latest   Up 30 seconds
  • 컨테이너 내부 접속
docker exec -it a12b3c4d5e6f bash
  • docker exec : 실행 중인 컨테이너에 명령 실행

  • -it : 터미널 입출력 모드

  • a12b3c4d5e6f : 컨테이너 ID (앞자리만 가능)

  • bash : Bash 쉘 실행

  • 접속 성공 시:

root@a12b3c4d5e6f:/data#

이제 컨테이너 내부 환경


Redis CLI 실행

redis-cli
  • 정상 접속 시:
127.0.0.1:6379>

Redis 서버에 직접 명령어 입력 가능

실습 정리 한 줄 요약

Docker Hub에서 Redis 이미지를 내려받아

컨테이너로 실행하고,

포트 매핑을 통해 외부에서 Redis에 접근했다.


Docker로 MySQL 8.0 실행하기

  • MySQL 이미지 다운로드
docker pull mysql:8.0
  • pull : Docker Hub에서 이미지 다운로드

  • mysql:8.0 : MySQL 8.0 버전 이미지

  • MySQL 8.0은 현재 가장 널리 사용되는 안정적인 LTS 버전

  • 이미지 다운로드 확인

docker images
  • 출력 예시:
REPOSITORY   TAG   IMAGE ID       CREATED        SIZE
mysql        8.0   9b51f5e3c789   2 weeks ago    595MB

MySQL 실행에 필요한 환경이 이미지로 준비됨

MySQL 컨테이너 생성 및 실행

로컬 환경에서 기존 MySQL이 3306 포트를 사용 중이기 때문에 컨테이너는 3307 포트로 매핑하여 실행한다.

docker run -d \
  --name mysql-docker \
  -e MYSQL_ROOT_PASSWORD=1234 \
  -e MYSQL_DATABASE=nbcam \
  -p 3307:3306 \
  mysql:8.0
  • -d : 백그라운드 실행

  • --name mysql-docker : 컨테이너 이름 지정

  • -e MYSQL_ROOT_PASSWORD=1234 : MySQL root 계정 비밀번호 설정

  • -e MYSQL_DATABASE=nbcam : 컨테이너 시작 시 DB 자동 생성

  • -p 3307:3306 : 호스트 포트 → 컨테이너 포트 매핑

  • mysql:8.0 : 실행할 이미지

  • 포트 구조 설명

    • 호스트(내 컴퓨터): 3307

    • 컨테이너(MySQL 내부): 3306

외부에서는 3307로 접속하지만, 컨테이너 내부 MySQL은 기본 포트인 3306을 그대로 사용


MySQL 컨테이너 실행 상태 확인

docker ps
  • 출력 예시:
CONTAINER ID   IMAGE       STATUS          PORTS
b1c3d5e7f9a1   mysql:8.0   Up 10 seconds   0.0.0.0:3307->3306/tcp
  • 확인 포인트

    • STATUS : Up → 정상 실행

    • PORTS : 3307->3306 → 포트 매핑 성공

    • 외부 접근 가능 포트: 3307


Spring Boot와 Docker MySQL 연결

Spring Boot 프로젝트의 application.yml에서

Docker MySQL 컨테이너 포트(3307)로 연결 설정을 한다.

spring:
  datasource:
    url: jdbc:mysql://localhost:3307/nbcam
    username: root
    password: 1234
    driver-class-name: com.mysql.cj.jdbc.Driver
  • 설정 포인트

    • localhost:3307 → 호스트 포트 기준

    • nbcam → 컨테이너 실행 시 자동 생성된 DB

    • Docker를 사용해도 Spring 설정 방식은 기존과 동일

요약

Docker로 MySQL 8.0 이미지를 실행하고,

포트 매핑을 통해 로컬 환경과 충돌 없이

Spring Boot에서 안정적으로 DB를 연결했다.


Redis + MySQL 핵심

DB도 설치가 아닌 실행의 개념으로 관리 가능

포트 충돌 문제를 Docker로 깔끔하게 해결

개발 환경을 언제든지 삭제 / 재생성 가능

팀원 간 DB 환경 차이를 제거


Dockerfile & Docker Compose로 Spring Boot 실행하기

Dockerfile (Spring Boot 이미지 빌드)

FROM eclipse-temurin:21-jdk
COPY build/libs/*.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
EXPOSE 8080
  • Dockerfile 설명

    • FROM eclipse-temurin:21-jdk : JDK 21 기반 이미지 사용
    • COPY build/libs/*.jar app.jar : 빌드된 jar 파일 복사
    • ENTRYPOINT : 컨테이너 시작 시 실행할 명령
    • EXPOSE 8080 : 애플리케이션 포트 명시
  • 포인트

    • Spring Boot 애플리케이션을 컨테이너 이미지로 패키징

    • build/libs/*.jar → Gradle 빌드 결과 자동 매칭

  • jar 생성 명령

./gradlew bootJar

docker-compose.yml 생성

version: '3.8'

services:
  mysql:
    image: mysql:8.0
    container_name: mysql-compose
    environment:
      MYSQL_ROOT_PASSWORD: 1234
      MYSQL_DATABASE: nbcam
    ports:
      - "3307:3306"
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - spring-net

  spring:
    build: .
    container_name: spring-compose
    depends_on:
      - mysql
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3307/nbcam
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: 1234
    ports:
      - "8080:8080"
    networks:
      - spring-net

volumes:
  mysql_data:

networks:
  spring-net:

docker-compose 구성 요소 설명

  • 서비스 구성

    • mysql : MySQL 8.0 컨테이너
    • spring : Dockerfile 기반 Spring Boot 애플리케이션
  • depends_on

depends_on:
  - mysql

Spring 컨테이너가 MySQL 컨테이너 이후에 실행

단, DB “준비 완료”까지 보장하진 않음 (실무에서는 healthcheck 추가)


  • Docker 네트워크
networks:
  - spring-net

컨테이너는 기본적으로 서로 격리되어 있음

같은 네트워크에 포함되면 서비스 이름으로 통신 가능

  • 포인트

    • mysql → 컨테이너 이름이자 호스트 이름

    • Spring에서 localhost ❌

    • jdbc:mysql://mysql:3306/nbcam (컨테이너 내부 기준)

  • 볼륨(Volume)

volumes:
  - mysql_data:/var/lib/mysql

MySQL 데이터 디렉토리와 볼륨 연결

컨테이너 삭제/재시작해도 DB 데이터 유지

  • 없다면?

    • 컨테이너 삭제 시 DB 데이터 전부 날아감

  • 환경 변수(Environment)

environment:
  SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3307/nbcam
  SPRING_DATASOURCE_USERNAME: root
  SPRING_DATASOURCE_PASSWORD: 1234
  • Spring Boot 설정을 application.yml 대신 주입

  • 환경별 설정 분리 가능 (local / dev / prod)


포트 관련 핵심 정리 (중요)

  • MySQL 컨테이너 내부 : 3306
  • MySQL 컨테이너 간 통신 : 3306
  • 호스트 접근용 : 3307

Spring ↔ MySQL 컨테이너 통신은

“같은 네트워크 내부 통신”

→ 호스트 포트(3307)가 아니라 컨테이너 포트(3306)를 사용

  • 실무 기준 권장:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/nbcam

(3307은 내 PC에서 접근할 때만 필요)


docker-compose 실행

docker compose up -d
  • up : compose 파일 기준으로 컨테이너 실행
  • -d : 백그라운드 실행

실행 확인

docker ps
  • mysql-compose, spring-compose 두 컨테이너가 실행 중이면 정상

  • 8080 포트로 Spring Boot 접근 가능


요약

Dockerfile로 Spring Boot를 이미지화하고,

docker-compose로 MySQL과 함께 실행하여

멀티 컨테이너 환경을 한 번에 구성했다.

  • 중요한 이유 (실무 관점)

    • 로컬 ↔ 서버 환경 차이 제거

    • DB + 애플리케이션 한 번에 실행

    • 팀원 누구나 docker compose up 한 줄로 환경 구성

    • 운영 환경과 거의 동일한 구조


개념 정리를 하는데 너무 너무 어렵다 반복적으로 시도해보면서 체득하려고 노력해야겠다..(;´д`)ゞ

2개의 댓글

comment-user-thumbnail
2025년 12월 17일

(;´д`)ゞ 좀 더 정진할 수 있도록 해주세요.(;´д`)ゞ

1개의 답글