Docker가 필요한 이유
환경이 다르면 결과도 달라지기 때문이다.
개발자 PC: Windows / Mac
서버 환경: Linux
라이브러리 버전, 패키지 충돌, 환경 변수 차이
DB, 포트, 경로 설정 문제
Docker는 동일한 환경에서 언제나 같은 결과를 보장하기 위해 존재한다.
기존 방식: 가상 머신(VM)
예전에는 가상 머신(Virtual Machine) 을 사용했다.
OS 위에 또 다른 OS를 실행
완전히 분리된 환경
문제점
VM 1개당 OS 1개 필요
부팅 시간 느림
CPU / RAM / 디스크 낭비 큼
컨테이너(Container)는 뭐가 다를까?
| 구분 | 가상 머신(VM) | 컨테이너(Container) |
|---|---|---|
| 구조 | OS 위에 또 다른 OS | OS 커널 공유 |
| 실행 단위 | OS 단위 | 애플리케이션 단위 |
| 부팅 속도 | 느림 (수 분) | 매우 빠름 (수 초) |
| 용량 | 수 GB | 수백 MB |
| 자원 사용 | 많음 | 효율적 |
VM: 컴퓨터 안에 또 다른 컴퓨터
컨테이너: 하나의 컴퓨터에서 앱만 격리 실행
컨테이너가 빠른 이유
OS를 새로 부팅하지 않음
호스트 OS의 커널을 그대로 사용
필요한 실행 환경만 로드
요약
필요한 환경만 꺼내 쓰기 때문에 빠르고 가볍다.
Docker의 핵심 개념
실행 환경을 정의한 설계도
OS, 라이브러리, 애플리케이션, 설정 포함
특징
이미지는 실행되지 않음
하나의 이미지로 여러 컨테이너 생성 가능
비유
이미지를 실제로 실행한 결과물
독립된 실행 공간
가볍고 빠르게 생성 / 삭제 가능
특징
서로 간섭하지 않음
필요할 때 만들고 버릴 수 있음
실행 중인 애플리케이션이 여기서 동작
비유
사람마다 다른 개발 환경 문제 해결
OS 상관없이 동일한 실행 보장
환경 설정을 자동화
예시
Windows / Mac / Linux 상관 없음
환경 변수 차이 없음
Ubuntu 설치 필요 없음
WSL2, VM 설치 없이도 실행 가능
Docker Hub
Docker Hub는 이미지 저장소이다.
GitHub = 코드 저장소
Docker Hub = 실행 환경(이미지) 저장소
특징
전 세계 개발자가 만든 이미지 공유
공식 이미지 다수 제공
예시 이미지
redis
mysql
kafka
elasticsearch
비유
기본 사용 흐름
Docker 전체 흐름
Docker는 깨끗한 실행 환경을 이미지로 정의하고,
그 이미지를 컨테이너로 실행하여
어디서든 동일한 결과를 보장하는 기술이다.
Docker Hub에서 Redis 실행하기 (실습 TIL)
docker search redis
Docker Hub는 전 세계 개발자들이 공유하는 도커 이미지 저장소
OFFICIAL 표시가 있는 이미지는 Redis 공식 팀이 배포한 신뢰 가능한 이미지
포인트
docker pull redis:latest
pull : Docker Hub에서 이미지를 로컬로 다운로드
latest : Redis의 최신 버전 태그
다운로드된 이미지 확인
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest b5d3b2e6f64e 2 weeks ago 117MB
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 주소: 컴퓨터(서버)의 주소
포트 번호: 그 컴퓨터 안에서 실행 중인 프로그램의 출입구
비유
대표적인 포트 예시
80 : 웹 서버
3306 : MySQL
6379 : Redis
Docker에서의 포트 매핑
-p [호스트 포트]:[컨테이너 포트]
docker run -d -p 6379:6379 redis:latest
docker run -d -p 8000:6379 redis:latest
실행 중인 Redis 컨테이너 접근하기
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>
실습 정리 한 줄 요약
Docker Hub에서 Redis 이미지를 내려받아
컨테이너로 실행하고,
포트 매핑을 통해 외부에서 Redis에 접근했다.
Docker로 MySQL 8.0 실행하기
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 컨테이너 생성 및 실행
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
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:
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 실행하기
FROM eclipse-temurin:21-jdk
COPY build/libs/*.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
EXPOSE 8080
Dockerfile 설명
포인트
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 구성 요소 설명
서비스 구성
depends_on
depends_on:
- mysql
networks:
- spring-net
포인트
mysql → 컨테이너 이름이자 호스트 이름
Spring에서 localhost ❌
jdbc:mysql://mysql:3306/nbcam (컨테이너 내부 기준)
볼륨(Volume)
volumes:
- mysql_data:/var/lib/mysql
없다면?
환경 변수(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)
Spring ↔ MySQL 컨테이너 통신은
“같은 네트워크 내부 통신”
→ 호스트 포트(3307)가 아니라 컨테이너 포트(3306)를 사용
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/nbcam
docker-compose 실행
docker compose up -d
실행 확인
docker ps
mysql-compose, spring-compose 두 컨테이너가 실행 중이면 정상
8080 포트로 Spring Boot 접근 가능
요약
Dockerfile로 Spring Boot를 이미지화하고,
docker-compose로 MySQL과 함께 실행하여
멀티 컨테이너 환경을 한 번에 구성했다.
중요한 이유 (실무 관점)
로컬 ↔ 서버 환경 차이 제거
DB + 애플리케이션 한 번에 실행
팀원 누구나 docker compose up 한 줄로 환경 구성
운영 환경과 거의 동일한 구조
개념 정리를 하는데 너무 너무 어렵다 반복적으로 시도해보면서 체득하려고 노력해야겠다..(;´д`)ゞ
(;´д`)ゞ 좀 더 정진할 수 있도록 해주세요.(;´д`)ゞ