열심히 프로젝트를 만들었다면, 배포를 해야한다.
그걸 위해 Docker를 보자.
도커는 애플리케이션을 ‘컨테이너(container)’ 단위로 패키징하고 실행할 수 있게 해주는 플랫폼이다.
-> “어디서나 동일하게 동작하는 실행 환경”을 만들어 줌. (물론 가상으로)
(이미지를 기반으로 컨테이너 만들어서 실행하는거임)
도커를 사용하면 여러개의 os를 효율적으로 사용할 수 있는데, 구체적으로는 다음과 같은 장점이 있다.
도커 컨테이너에서의 프로그램 실행은 HOST OS 에서의 실행대비 성능저하가 없음.
도커는 가상머신과 달리 호스트 OS의 커널을 직접 사용함.
컨테이너는 프로세스 격리 기술을 사용하여 매우 가볍게 동작함.
시스템 자원을 효율적으로 사용하면서도 독립된 실행 환경을 제공함.
가상머신처럼 OS를 통째로 올리는 것이 아니라 필요한 부분만 격리하여 사용함.
그리고 애플리케이션 실행에 필요한 환경을 이미지라고 한다.
이미지 = 프로그램
이미지 실행 -> 도커 컨테이너 생성
= 프로그램 실행 -> 프로세스 생성
컨테이너 = 호스트 OS 위에서 격리된, 가상 OS 역할을 하는 프로세스 (앱+OS)
그럼 함 사용해보자. 물론 설치는 해야한다. 그리고 도커허브를 이용하면 다양한 이미지를 다운 받을 수 있다.
그리고 아래 명령어들은 이미지ID나 이름으로 실행 가능하다.
| 명령어 | 설명 |
|---|---|
docker pull 이미지명 | 이미지 다운로드 |
docker pull 이미지명:버전 | 특정 버전 다운로드 |
docker images | 다운받은 이미지 목록 확인 |
docker inspect 이미지명 | 이미지 정보 확인 |
docker rmi 이미지명:버전 | 이미지 삭제 |
| 명령어 | 설명 |
|---|---|
docker run 이미지명 | 포그라운드 실행 |
docker run -d 이미지명 | 백그라운드 실행 |
docker run --name 이름 이미지명 | 이름 지정해서 실행 |
docker ps -a | 실행/종료된 컨테이너 모두 확인 |
docker stop 컨테이너명 | 백그라운드 컨테이너 정지 |
docker start 컨테이너명 | 정지한 컨테이너 재시작 |
docker rm 컨테이너명 | 컨테이너 삭제 |
docker logs 컨테이너명 | 로그 확인 (-f 실시간, --timestamps 시간 표시) |
docker exec -it 컨테이너명 bash | 컨테이너 내부에서 대화형 사용(실행중) |
docker exec -run 컨테이너명 bash | 컨테이너 내부에서 대화형 사용(신규 실행) |
exit | 컨테이너에서 나가기 |
docker 명령어 --rm 컨테이너명 | 컨테이너가 실행 후 종료되어도 종료된 컨테이너가 목록에 남지 않음 |
추가 옵션
--rm : 종료 후 컨테이너 목록에 남기지 않음
-it : 컨테이너 안으로 들어가서 대화형 사용 (bash 등)
--entrypoint : 엔트리 포인트 재지정
엔트리 포인트 : 컨테이너는 실행 시 컨테이너 내의 여러 프로세스 중 엔트리 포인트에 지정된 걸 실행 함.
+)그리고 저거 해도 안되는 경우도 있는데, 그건 윈도우라 그럼. 그때는 앞에 winpty 하면 된다.
+) docker kill 컨테이너명 나 docker rm -f 컨테이너명 하면 바로 멈추고 삭제가 되긴함. 근데 권장 안함. 멈출 때 과정이 안될 수 있음..rm -f는 내부적으로 kill하고 삭제하는 거임
| 명령어 | 설명 |
|---|---|
docker run -p 호스트:컨테이너 | 포트 매핑 |
docker run -P 이미지명 | 컨테이너의 노출 포트를 호스트 임의 포트에 자동 매핑 |
docker run -e 환경변수명="값" 이미지명 env | 환경변수 지정 |
| 기능 | 명령어 |
|---|---|
| 호스트 → 컨테이너 파일 복사 | docker cp 호스트경로 컨테이너명:경로 |
| 컨테이너 → 호스트 파일 복사 | docker cp 컨테이너명:경로 호스트경로 |
| 디렉터리 바인드 마운트 | docker run -v 호스트경로:컨테이너경로 이미지명 |
+) 경로 끝에 /. 이거 붙여서 디렉터리 복사도 가능
바인드 마운트 = 호스트 - 컨테이너 간 디렉토리 연결
같은 컨테이너 내부: 자유롭게 통신 가능
다른 컨테이너: IP 주소 또는 컨테이너 이름으로 접근 가능
웹 서버일 경우: 웹루트 디렉터리에 파일 추가 → http://컨테이너주소/파일명 로 접근 가능
docker network create 네트워크명
| 항목 | 설명 |
|---|---|
| 기본 네트워크 | bridge (도커 설치 시 자동 생성, 게이트웨이: 172.17.0.1) |
| 사용자 정의 네트워크 | 이름 자유롭게 지정 가능 (예: common, 게이트웨이: 172.18.0.1) |
-> 컨테이너 간 DNS 이름 해석 가능 → 컨테이너명으로 통신 가능
docker network inspect 네트워크명 | less
docker run --network 네트워크명 이미지명
-p 옵션으로 호스트 포트 ↔ 컨테이너 포트 연결 후 접근 가능:http://호스트_IP:호스트포트/파일명
기본 브릿지 네트워크(bridge)의 역할:
컨테이너 내부 네트워크 ↔ 호스트 OS ↔ 외부 네트워크
외부 요청 흐름 예시:
외부 요청 (브라우저)
↓
호스트 OS 8080 포트
↓
docker 브릿지 네트워크 (172.17.0.1)
↓
컨테이너 내부 80 포트
문제: 호스트 IP는 환경마다 달라서 하드코딩이 불편
해결: host.docker.internal 사용
예시:
http://host.docker.internal:포트번호/파일명
-> 어떤 컨테이너에서도 호스트 접근이 편리하게 가능
Nginx는 포트번호나 도메인 이름을 기준으로 요청을 구분해 각각 다른 웹 애플리케이션에 전달할 수 있으며, 도커를 이용하면 이러한 환경을 손쉽게 재현하고 일관성 있게 관리할 수 있다.
이런 형태다. 참고로 nginx가 설정에 따라 포트 번호 보고 알맞은 사이트로 준다.
echo -e "
server {
listen 포트번호; # 이 서버 블록이 응답할 포트 번호
root /웹 앱 위치; # 실제 파일(html, js 등)이 있는 디렉터리
}
" > /etc/nginx/conf.d/vhost.conf
이렇게 하면 nginx 설정 가능.
도메인으로도 비슷하게 쓸 수 있다!
docker build -t 레포지토리명/이미지명:버전 .
| 옵션/부분 | 의미 |
|---|---|
-t | 태그(tag) 지정 |
레포지토리명/이미지명:버전 | 이미지 이름과 버전 지정 |
. | 현재 디렉터리 → Dockerfile과 빌드에 필요한 모든 파일 참조 |
-> 현재 디렉터리의 Dockerfile과 필요한 파일(HTML, 설정 파일 등)을 이용해 이미지 생성
+) 캐시 없이 빌드하기 : docker build -t myname/nginx:1 --no-cache .
-> 1/2/3/4/5 레이어에서 1이 가장 하위 일때, 3이 수정 되면 1,2는 캐시 재사용, 3,4,5만 재연산 -> 레이어 순서 중요함.
+) 레이어는 순차적으로 쌓이며 이전 레이어의 변경사항 포함
+) docker history 이미지명 → 이미지 레이어 구조 확인 가능
| 명령어 | 역할 |
|---|---|
FROM | 기본 이미지 레이어 지정 |
COPY | 파일 복사 레이어 생성 |
RUN | 명령어 실행 레이어 생성 |
| 구분 | Docker 볼륨 (Volume) | Bind Mount (호스트 경로 마운트) |
|---|---|---|
| 저장 위치 | Docker가 관리하는 영역 (/var/lib/docker/volumes/...) | 호스트의 특정 디렉터리 경로 지정 |
| 생성 방법 | docker volume create 혹은 -v volume_name:/container/path | -v /host/path:/container/path |
| 관리 | Docker가 볼륨을 생성·삭제·백업 관리 | 호스트가 직접 파일 시스템 관리 |
| 사용 목적 | 컨테이너 데이터 영구화, 여러 컨테이너 공유 | 호스트와 실시간 파일 공유, 개발용 코드 반영 |
| 장점 | 컨테이너 독립적, 안전, Docker CLI로 관리 편함 | 호스트 파일 바로 반영 가능, 개발 편리 |
| 단점 | 호스트에서 바로 접근 어려움 | 컨테이너 독립성 낮음, 실수로 호스트 파일 변경 가능 |
->
Volume: 운영 환경, 데이터 영구화, 안전, Docker 관리 중심
Bind Mount: 개발 환경, 호스트와 실시간 파일 공유, 편리하지만 운영엔 위험
컨테이너 여러개를 한번에 관리할 수 있게 해준다.
docker-compose.yml에 컨테이너 구성을 정의하여 각 컨테이너의 의존성, 네트워크, 볼륨 등을 선언적으로 관리한다.
주요 명령어
docker-compose up : 컨테이너들을 생성하고 시작
docker-compose up --build : 이미지를 다시 빌드하고 컨테이너 시작
docker-compose down : 컨테이너들을 중지하고 제거
만든 이미지는 도커 허브에 올릴 수 있다.
docker build -t 개인아이디/이름:태그 .
# (선택) tag 명령어 이미지 이름 추가하기 (가장 최신이라는 뜻)
docker tag 인아이디/이름:태그 인아이디/이름:latest
# 도커 로그인
docker login
# 이미지 푸시
docker push 개인아이디/이름:태그
# 도커허브 이미지 확인
docker images
# 확인
- https://hub.docker.com/r/개인아이디/이름