코딩/sparta TIL

TIL 60 : Docker란 2

americanoallday 2025. 5. 19. 12:55

🐳 도커란?

💡 한 줄 정의:

도커는 애플리케이션을 실행하기 위한 모든 환경(코드, 라이브러리, 설정 등)을 하나로 묶어서 ‘컨테이너’라는 형태로 실행할 수 있게 해주는 도구입니다.

 

 

🎁 비유로 이해해보자: “도시락(컨테이너)”

  • 당신이 요리를 만들어서 다른 사람에게 전달한다고 해봐요.
  • 전에는 냄비, 접시, 불, 재료, 조리법 전부 전달해야 했어요. (이게 기존 서버 환경)
  • 하지만 도커는 완성된 도시락처럼 요리와 필요한 모든 것을 깔끔하게 포장해서 누구에게나 똑같이 전달할 수 있어요.
  • 심지어 받는 사람이 가스레인지든 전자레인지든 상관없이 잘 먹을 수 있도록 되어 있어요.

즉, 도커는 앱이 동작하는 환경 전체를 ‘도시락 컨테이너’에 담아서 어디서든 똑같이 실행할 수 있도록 해줘요.

 

 

🔩 도커의 주요 개념

용어 설명 비유
이미지 (Image) 컨테이너를 만들기 위한 설계도, 스냅샷 도시락 레시피
컨테이너 (Container) 이미지로부터 만들어진 실제 실행 환경 도시락 실제 음식
Dockerfile 이미지를 만들기 위한 명령어 모음 요리 순서 정리한 종이
도커 엔진 (Docker Engine) 도커 컨테이너를 실제로 실행하는 프로그램 조리도구 및 배달 시스템
docker-compose 여러 컨테이너를 한꺼번에 실행시키는 도구 도시락 여러 개 한 번에 만들고 배달하기

 


💻 왜 도커를 쓰는가?

상황 도커의 장점
“내 PC에선 되는데, 서버에선 왜 안 돼?” 개발 환경을 완전히 동일하게 만들 수 있음
“설치가 너무 복잡해요…” 필요한 환경을 한 줄로 실행 가능 (docker run, docker-compose up)
“여러 서비스를 동시에 돌려야 해요.” 컨테이너로 각 서비스를 분리, 독립 실행
“배포가 어렵고 시간이 오래 걸려요” 한 번 이미지 만들면 어디서든 실행 가능

 

🧪 예: Spring Boot + MySQL 도커 실행

# MySQL 실행
docker run -e MYSQL_ROOT_PASSWORD=1234 -p 3306:3306 --name my-mysql -d mysql:8

# Spring Boot 도커 이미지 빌드
docker build -t my-spring-app .

# Spring Boot 앱 실행
docker run -p 8080:8080 --name spring-container --link my-mysql:mysql my-spring-app

 

 

Spring Boot + MySQL 프로젝트를 도커로 실행하는 기본 흐름

📦 목표는 도커로 내 앱과 DB를 컨테이너로 띄우는 것!

 

✅ 전제

  • 이미 Spring Boot 코드는 만들어져 있고
  • application.properties 또는 application.yml에서 MySQL을 사용 중이다.

 

예시:

# application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=1234
spring.jpa.hibernate.ddl-auto=update

 

🪛 Step 1. Dockerfile 만들기

루트 디렉토리에 Dockerfile 생성:

# 베이스 이미지
FROM openjdk:17
# jar 복사
COPY build/libs/myapp-0.0.1-SNAPSHOT.jar app.jar
# 실행
ENTRYPOINT ["java", "-jar", "app.jar"]
Gradle 기준: build/libs/에 빌드된 jar가 있어야 함.
./gradlew build 먼저 실행하고 myapp-0.0.1-SNAPSHOT.jar 이름은 실제 파일명에 맞춰 바꾸세요.

 

 

🧩 Step 2. docker-compose.yml 만들기

 

docker-compose.yml을 루트에 생성:

version: "3.8"
services:
  mysql:
    image: mysql:8
    container_name: my-mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: 1234
      MYSQL_DATABASE: mydb
    ports:
      - "3306:3306"

  spring-app:
    build: .
    container_name: my-spring-app
    ports:
      - "8080:8080"
    depends_on:
      - mysql
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/mydb
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: 1234
🔥 핵심 포인트: localhost가 아니라 mysql이라는 도커 서비스 이름을 사용해야 연결돼요.

 

📝 Step 3. application.properties 수정

아래처럼 바꾸세요 (환경변수를 우선 적용하기 위해):

spring.datasource.url=${SPRING_DATASOURCE_URL}
spring.datasource.username=${SPRING_DATASOURCE_USERNAME}
spring.datasource.password=${SPRING_DATASOURCE_PASSWORD}
spring.jpa.hibernate.ddl-auto=update

 

 

▶️ Step 4. 실행

  1. jar 빌드
./gradlew build

 

  1. 도커 실행
docker-compose up --build

 

 

✅ 성공하면?

  • http://localhost:8080에서 Spring Boot 앱 접속 가능
  • mysql 컨테이너 안에서 DB 자동 생성
  • 도커로 앱+DB 동시에 실행

 

🛠️ 디렉토리 구조 예시

my-spring-project/
├── build/
├── src/
├── build.gradle
├── Dockerfile
├── docker-compose.yml
└── application.properties

 

 

Docker VS AWS

🔍 핵심 차이 요약

구분 Docker AWS
무엇인가요? 애플리케이션을 포장해서 실행하는 기술 (컨테이너) 클라우드에서 서버, DB, 스토리지 등을 제공하는 플랫폼
역할 앱이 어디서든 잘 돌아가게 만드는 도구 앱을 돌릴 컴퓨터, 네트워크, 저장공간을 제공
주로 하는 일 앱을 컨테이너로 감싸고 실행 감싼 앱을 실행시킬 서버/인프라를 제공
비유 도시락 요리하는 법 도시락 배달할 집, 배달원, 배달차 제공

 

📦 예를 들어서

당신이 Spring Boot + MySQL 프로젝트를 만들었을 때:

  • Docker:
    → 코드를 패키징해서 하나의 컨테이너로 만듦
    → “이 앱이 어디서든 똑같이 실행되게 해줘!”
  • AWS:
    → EC2(서버), RDS(DB), S3(파일저장소) 같은 리소스 제공
    → “이 앱을 돌릴 컴퓨터랑 인터넷이 필요해!”

 

 

🧩 둘은 같이 쓰이는 경우가 많음

예: AWS에서 Docker 쓰기

작업 도구
Spring Boot 코드 작성 로컬 PC
Docker로 이미지 만들기 docker build
AWS에 배포 EC2, ECS, ECR, RDS 사용
MySQL은? AWS RDS로 구성하거나 Docker로 같이 배포

 

 

🎯 결론

질문
Docker가 AWS를 대체하나요? ❌ 아니요. Docker는 앱 실행 방식, AWS는 인프라
AWS에서 Docker 안 써도 되나요? ⭕ 가능하지만, Docker 쓰면 배포가 훨씬 편해짐
Docker 없이도 앱 배포할 수 있나요? ⭕ 직접 서버에 코드 올리면 가능 (전통 방식)
둘 다 써야 하나요? ✅ 대개 Docker로 만들고 AWS에 배포하는 게 요즘 트렌드입니다

 

 

“도커에서 실행한 MySQL이나 Redis는 어디에 저장되는가?”

 

 

🔍 기본 원칙

도커에서 실행한 DB(MySQL, Redis)는 기본적으로 컨테이너 안에 저장돼요. 즉, 로컬 PC 안에 있지만, 도커 컨테이너 속에 격리되어 있는 공간입니다.

 

 

📦 예시 상황

docker run --name my-redis -p 6379:6379 -d redis

 

  • 이건 로컬 PC의 도커 엔진이 redis를 컨테이너로 실행한 것
  • Redis는 데이터 파일을 컨테이너 내부에 저장
  • 따라서 컨테이너를 docker stop, docker rm 하면 데이터도 같이 사라짐!

 

🧱 그럼 진짜 저장하고 싶으면?

 볼륨(Volume) 또는 바인드 마운트를 써야 합니다.

docker run -v /my/local/dir:/data --name my-redis redis

 

  • 이건 Redis의 내부 경로(/data)를 로컬 PC의 실제 폴더(/my/local/dir)와 연결함
  • 이렇게 하면 컨테이너가 꺼지거나 삭제돼도 데이터는 로컬에 남음

 

📂 Docker Compose 예시 (Redis)

services:
  redis:
    image: redis
    container_name: redis-container
    ports:
      - "6379:6379"
    volumes:
      - ./redis-data:/data

 

  • ./redis-data 폴더에 Redis 데이터가 실제로 저장됨
  • 이건 로컬 PC의 폴더이기 때문에 다른 컨테이너가 죽어도 데이터 유지 가능

 

📌 요약

질문 답변
도커에서 실행한 MySQL/Redis는 로컬인가요? ✅ 로컬 맞지만, 컨테이너 안의 가상 공간이에요
그럼 꺼지면 사라져요? ❌ 기본 설정에선 사라짐
데이터 유지하려면? volume 또는 bind mount를 사용해서 로컬 디스크와 연결해야 함
클라우드 DB랑 차이는요? 클라우드는 원격 저장소이고, 도커는 로컬 PC에서 실행되는 개발용 또는 테스트용 환경에 가까움

 

 

  1. Redis는 꼭 도커로만 써야 하는가?
  2. Redis의 저장 구조를 텍스트 기반 그림으로 표현

 

✅ 1. Redis는 도커 전용이 아니다!

실행 방식 설명
로컬 설치 내 PC에 직접 Redis를 설치해서 실행 가능 (brew install redis 등)
도커 실행 도커 컨테이너로 Redis를 띄워서 격리된 상태로 실행
원격 서버 접속 AWS, Azure, Redis Cloud 같은 외부 Redis 서버에 접속 가능
🔥 즉, Redis는 “도커로만 써야 하는 구조”가 절대 아닙니다. 도커는 단지 편하게 실행하려는 방법 중 하나일 뿐이에요.

 


 

✅ 2. Redis 저장 구조 (텍스트 그림 설명)

Redis는 기본적으로 메모리 기반인데, 옵션에 따라 디스크에도 저장할 수 있어요.

대표적인 저장 방식은 2가지예요:

 

🔹 1. RDB (Snapshot)

+------------------+
|      Redis       |    ← 메모리에서 실행
+--------+---------+
         |
         |  (주기적으로 전체 스냅샷 저장)
         v
+-----------------------------+
| dump.rdb (디스크 파일)         |
+-----------------------------+

 

  • 설정: save 900 1 같은 규칙
  • 서버가 꺼졌다 켜질 때, 이 파일에서 복원함

 

🔹 2. AOF (Append Only File)

+------------------+
|      Redis       |
+--------+---------+
         |
         | (명령어를 하나씩 기록)
         v
+-----------------------------+
| appendonly.aof              |
+-----------------------------+

 

  • 실시간으로 쓰기 명령을 계속 디스크에 기록
  • 가장 안전하지만 느릴 수 있음

 

🔹 도커로 실행하면?

📦 도커 컨테이너 내부 구조
---------------------------
| /data/dump.rdb           |
| /data/appendonly.aof     |
---------------------------

컨테이너가 사라지면 /data/도 사라짐 😱

그래서 이렇게 연결해야 함:

🖥️ 로컬 PC 파일 시스템
-------------------------------
| ./redis-data/dump.rdb       |
| ./redis-data/appendonly.aof |
-------------------------------
           ▲
           |
     [volume mount]
           |
           ▼
  📦 컨테이너의 /data 폴더

 

예시 명령어:

docker run -d \
  -v ./redis-data:/data \
  -p 6379:6379 \
  redis \
  redis-server --appendonly yes

 

🧠 정리 요약

질문 답변
Redis는 도커 전용인가요? ❌ 로컬 설치나 클라우드에서도 가능
도커 Redis는 저장되나요? 기본 저장소는 컨테이너 내부 (/data)
저장하려면? -v 옵션으로 로컬 디렉토리랑 연결해야 함
저장 방식 종류? ✅ RDB (스냅샷), ✅ AOF (명령어 로그)

 

'코딩 > sparta TIL' 카테고리의 다른 글

스프링에서 캐시 저장하는 방법  (2) 2025.05.19
DB vs 캐시, 로컬 캐시 vs 리모트 캐시 차이  (0) 2025.05.19
TIL 59 : Docker 란  (1) 2025.05.19
Redis란  (1) 2025.05.18
TIL 58 : Resolver(리졸버)란? - 다시 공부  (2) 2025.05.15