본문 바로가기
TIL&WIL

250109 TIL- Docker

by 나노다 2025. 1. 8.

도커란?

"어플리케이션을 패키징하는 툴"

컨테이너라 불리는 하나의 작은 소프트웨어 유닛 안에 

우리의 어플리케이션과 그에 필요한 시스템 툴, 환경 설정, 모든 디펜던시들을 하나로 묶어서

(런타임 환경에 필요한 모든 것들을 묶어서)

다른 서버, 다른 pc 어디든 쉽게 배포하고 안정적으로 구동할 수 있게 도와주는 툴

 

컨테이너는 운영체제를 포함하지 않기 때문에 가볍다!!

대신에, 컨테이너가 구동되기 위해선 컨테이너 엔진이 필요하고,

이 엔진이 컨테이너가 실행되는 호스트의 운영체제에 접근해 필요한 것들을 처리해줌!

이 컨테이너 엔진 중 하나가 바로 도커 엔진!


활용 방법

1. Dockerfile 만들기

Dockerfile은 컨테이너를 만들기 위한 설명서, 레시피 같은 파일

들어가는 정보들은 아래와 같다!!

  • Copy Files : 어플리케이션을 구동하기 위한 필수적인 파일들엔 무엇이 있는지
  • Install dependencies : 어떤 프레임워크나 라이브러리를 설치해야하는지 (외부 디펜던시)
  • Set environment variables : 필요한 환경 변수에 대한 설정
  • Run setup scripts : 어떻게 구동할지에 대한 스크립트

2. Image 만들기

작성한 Dockerfile을 바탕으로 이미지를 만들 수 있음!!

이미지 안에는 우리 어플리케이션을 실행하는 데에 필요한 코드, 런타임 환경,

시스템 툴, 시스템 라이브러리 등 모든 세팅들이 포함돼 있음!! 

실행되고 있는 어플리케이션의 상태를 스냅샷해서 보관해두는 느낌!!

한 번 만든 이미지는 더 이상 변경할 수 없음!! 사진 한 번 찍으면 그 자체를 편집할 순 없잖수?

3. Container 만들기

컨테이너는 잘 캡쳐해둔 어플리케이션의 Image를 이용해 그 어플리케이션을 실제로 구동하도록 함!!

컨테이너에서는 파일도 새로 만들 수 있고, 수정도 할 수 있고,

개별 컨테이너 당 시스템 설정도 달리 할 수 있음!! 이러한 변경 사항은 이미지엔 전혀 영향 없음!!

이미지는 클래스, 컨테이너는 인스턴스!!


Shipping Container

이미지를 배포하고 공유하는 방법!!

  1. Build : 내 로컬 머신에서 이미지를 생성하고
  2. Push : 깃허브 같은 Container Registry에 이미지를 배포한다!!
  3. Pull : 그럼 이 이미지가 필요한 다른 호스트에서 이 이미지를 가져와서 그대로 실행하면 됨!! 

물론 이미지를 받아오는 쪽에서도 컨테이너 엔진이 설치돼있어야 함!!

public으로 배포하는 사이트
docker hub / RED HAT Quay.io / GitHub Packages 등이 있고, 주로 docker hub가 활발히 쓰임!!
private로 배포하는 사이트
aws / Google Cloud / Microsoft Azure 등등, 기업 내부 등에서 공유하는 경우!

Docker 실습!!

1) Dockerfile 작성하기

# 처음엔 항상 FROM으로 시작해, 베이스가 될 이미지를 설정함
# <사용할 베이스> : <버전> - <리눅스환경의 버전>
FROM node:16-alpine

# 이미지 파일 안에서 어떤 디렉토리에 우리의 어플리케이션을 복사해올 건지 지정
# WORKDIR은 디렉토리를 이동하는 cd와 유사한 명령어!
WORKDIR /app

# 이제 root 디렉토리의 app에 위치하게 됐고,
# app 디렉토리에 어플리케이션에 필요한 파일들을 복사해올 것임!!
# 변경이 덜 되는 녀석부터 먼저 가져올 것이기 때문에, package.json을 먼저!
COPY package.json package-lock.json ./

# 이제 app 디렉토리에 package.json이 생겼으니,
# 어플리케이션에서 활용하는 라이브러리들을 설치할 수 있음!!
# 따라서 npm install을 하면 되는데, 여기서 npm ci를 하는 이유는?!
# 전자는 설치 시점에서 가장 최신 버전의 라이브러리를 받아 옴!!
# 예를 들어 나는 개발 당시 express 3버전을 활용했는디,
# 다른 호스트가 컨테이너를 실행할 땐 5버전까지 나왔다면
# 5버전이 설치돼버려 예기치 않은 오류가 생길 수 있다는 것!!
# 반면 npm ci를 하면 package-lock.json에 명시된 개발 당시 버전 정보까지 조회해 설치한다!!
RUN npm ci

# 이제 소스 코드 파일을 복사해오면 준비 끗
COPY index.js .

# 이제 실행을 할 건데, "node"라는 이미지를 쓸 거고,
# 이 어플리케이션의 파일 중 "index.js"란 파일을 실행하셔요 란 의미다!!
ENTRYPOINT [ "node", "index.js" ]

 

2) Image 생성하기

만든 DockerFile을 바탕으로 이미지를 생성할 거고, 먼저 터미널에가서 다음과 같은 명령어를 입력해준다!!

docker build -f DockerFile -t fun-doker .
  • docker : 도커에 관련된 명령어들을 실행하기 위한 명찰!
  • build : Dockerfile로 새 Image를 생성해달란 명령어!
  • -f : point to a Dockerfile, 실행할 Dockerfile의 파일명을 적는 곳!! 혼란스러우니 익숙해질 때까진 Dockerfile로 고정해서 연습하자!!
  • -t : name the image, 생성할 Image의 태그명을 적는 곳!! Image에 내 맘대로 이름을 지어줄 수 있다!!
  • . : build context, 여긴 실행할 Dockerfile의 상대 경로를 기입하는 곳인디, 실습 파일 기준 최상위 디렉토리에 있는지라 그냥 온점만 찍혀 있다... 다른 상황을 만나게 된다면 꼭꼭 터미널의 현 디렉토리 기준 상대 경로로 올바른 Dockerfile에 찾아가주자!!

build 명령어를 실행한 이후 터미널의 내역을 확인해보면,

이런 식으로 Dockerfile에 작성해준 명령어들이 순차적으로 실행됐음을 확인할 수 있다!!

Build한 Image는 내 로컬 환경에 저장되는데, 이를 확인해보고 싶다면 다음과 같은 명령어를 입력하면 된다!!

docker images

그러면 내 로컬 환경에 보관 중인 Image들의 목록을 확인할 수 있게 된다!!

아까 -t 로 부여해준 이름인 fun-doker가 잘 지어진 게 보인다!!

이 이름은 이후에 이 Image를 공유할 때도 활용하게 됨!!

또 build할 때 따로 Image의 버전을 명시해주지 않았기 때문에, TAG는 가장 최신 버전이란 뜻의 latest가 된 모습!!

 

3) Container 실행하기

이제 만든 Image를 바탕으로 Container를 만들어 볼 거다!! 이런 명령어를 입력해보면 된다!!

docker run -d -p 8080:8080 fun-doker
  • run : Container를 실행시키겠다는 명령어
  • -d : detached, 이 속성을 넣지 않으면, 터미널이 종료되면 Container도 종료된다!! 실습 파일 기준 백엔드 프로젝트기 때문에, 터미널과 상관없이 Container가 백그라운드에서 계속 동작해야하므로 추가!!
  • -p : port publishing, 호스트 장치의 포트와 Container의 포트를 연결해주는 속성!! 콜론 기준 앞의 번호가 호스트의 포트 번호고, 뒤의 번호가 Container의 포트 번호임!!
  • fun-doker : 어떤 Image를 기반으로 Container를 만들 것인지, Image의 이름을 적어주면 된다!! c가 빠진 오타를 놓치지 말자...

Container를 실행했다면 현재 실행 중인 Container들의 목록을 확인해보도록 하자!!

docker ps

이렇게 입력하면 현재 동작 중인 Container들의 목록이 나오고,

docker ps -a

이렇게 -a 속성을 넣으면 동작 여부와 상관없이 전체 Container의 목록을 확인할 수 있다!!

참고로 마지막의 NAMES는 Container의 이름인데, 따로 지정해주지 않으면 저런 식으로 docker에서 작명해준다!!

또 만약 실행 중인 Container에 무슨 일이 일어나고 있는지 확인하고 싶다면,

docker logs f78ca8136241

이 명령어를 입력하면 된다!! logs 다음의 정체 모를 녀석은 바로 저기 위 CONTAINER ID를 입력해주는 곳!!

이런 식으로 터미널에서 log를 확인해보거나, docker desktop 프로그램에서 직접 log를 확인해볼 수도 있다!!

여기 Inspect나 Stats 등 다른 탭에서 현재 Container의 세부 상황도 열람할 수 있으며,

Exec 탭에선 직접 콘솔을 입력하는 등의 조작도 가능!!

 

도커 자주 사용하는 명령어 모음
https://www.yalco.kr/36_docker/
도커 공식 문서
https://docs.docker.com/reference/dockerfile/
공식에서 내려주는 올바른 사용 지침
https://docs.docker.com/build/building/best-practices/#dockerfile-instructions