DevOps, 배포

[Docker] Docker 시작하기

킹형준 2025. 2. 26. 23:04

Docker란

Docker는 애플리케이션을 "컨테이너" 라는 가벼운 가상화 환경에서 실행할 수 있도록 해주는 컨테이너 기반의 가상화 플랫폼이다. 애플리케이션을 개발하거나 실행할 때 다른 컴퓨터에서 실행하면 환경이 달라지는 게 너무 많으므로(OS, SDK 등) 매 환경마다 이 설정을 하는 데 엄청나 노력이 들기 때문에 도커를 통해 애플리케이션과 해당 애플리케이션이 필요로 하는 모든 라이브러리, 설정, 종속성 등을 하나의 "Image"로 묶어 도커만 있으면 어떤 환경에서도 애플리케이션을 동일하게 실행할 수 있다. VM은 내 컴퓨터 위에 OS 하나 자체를 올리는 가상화 기술이라면, Docker는 Host의 커널을 공유하며, 그 위에 "컨테이너" 에 올려 여러 애플리케이션을 실행할 수 있다. "이미지"는 애플리케이션을 실행하기 위한 환경(OS, SDK 등)을 정의하는 일종의 틀이고, "컨테이너"는 해당 이미지를 실행하고 있는 기계라고 생각하면 될 듯 하다.

 

 

 

Spring Boot 애플리케이션 Docker에 올려보기!

https://github.com/brothergiven/spring_ex

 

GitHub - brothergiven/spring_ex: 백엔드 개발 전체 라이프사이클 실습

백엔드 개발 전체 라이프사이클 실습. Contribute to brothergiven/spring_ex development by creating an account on GitHub.

github.com

 

Docker를 사용하여 위 레포지토리의 Spring Boot 애플리케이션을 실행시켜보자.

 

Dockerfile 작성

Dockerfile은 해당 프로젝트를 Dockerizing하기 위한 간단한 Instruction을 작성하는 파일이다. 해당 Dockerfile이 작성된 디렉토리에서 build 명령어를 입력하면 이미지가 빌드되고, 해당 이미지는 Dockerfile의 Instruction을 따르게 된다.

 

Dockerfile을 이용하여 애플리케이션을 실행시키는 과정은 빌드, 실행의 두 단계로 나눌 수 있다. command line에 docker build를 입력하면 이미지와 함께 애플리케이션이 빌드되고, docker run을 입력하면 컨테이너가 실행됨과 동시에 애플리케이션이 실행되는 것이 일반적이다.

 

Dockerfile에서 주로 사용되는 명령어들은 아래와 같다.

- FROM <이미지 이름>:<태그> : Docker 이미지를 생성할 때 기본이 되는 베이스 이미지로, 주로 OS와 언어 SDK, -Framework 환경을 지정한다.

- WORKDIR <디렉토리명> : 베이스 이미지를 가져온 후 가상환경에서 명령어가 실행될 작업 디렉터리를 설정함.

- COPY <호스트 경로> <컨테이너 경로> : 로컬의 파일 또는 디렉터리를 가상환경으로 그대로 복사한다. 

- ADD <소스> <대상> : COPY와 유사하지만, URL 다운로드와 압축 파일 자동 해제 기능을 제공한다. 원격 파일 다운로드시에 주로 사용.

- RUN <명령어> : 이미지 빌드 시 실행할 명령어 지정. 컨테이너 실행 시에는 다시 실행되지 않음.

- ENTRYPOINT ["실행 파일", "인수1", "인수2"] : 컨테이너의 메인 프로세스 지정.

- ENV <변수명> <값> : 환경변수 지정. 

- EXPOSE <포트번호> : 컨테이너 내부의 포트 번호를 외부에 노출.

 

Docker build vs. Docker run?

Dockerfile을 작성했다면 해당 dockerfile이 작성된 디렉토리에서 docker build 명령어를 입력하면 애플리케이션을 빌드하고, 필요한 라이브러리를 설치하며, 최종 실행 파일을 이미지에 포함시킬 수 있으며 빌드된 이미지는 docker run 명령어와 함께 컨테이너로 실행시킬 수 있다. "이미지"와 "컨테이너"의 차이는 위에서 언급하였으니 생략하자.

 

이미지를 빌드하는것과 컨테이너를 실행시키는 과정은 그 느낌이 조금은 다르다. 단순히 Java로 작성된 Spring Boot Application을 생각해보면, IDE에서 초록색 Run 버튼을 누르는 방법도 있지만 gradle 또는 maven으로 명령어를 써서 빌드 후에 빌드된 jar 파일을 java 명령어로 실행시키는 게 가장 전형적이다. 

 

이런 과정을 가상환경에서 docker 이미지의 빌드와 동시에 또는 docker 컨테이너의 실행과 동시에 일어나도록 하는 것이 Dockerfile의 존재 이유이고 Dockerizing을 하더라도 빌드와 실행의 두 단계는 나뉘어져서 진행된다. 따라서 우리는 Dockerfile을 docker build, docker run의 명령어 단계를 나누어서 각 단계에 어떤 작업을 실행할지를 나누어 줘야한다. 

 

하지만 빌드 시에 문제가 발생할 수 있는게, 빌드를 하고 나서 그 환경에서 그대로 실행파일을 돌리게 되면 운영 환경 컨테이너에 빌드에 필요한 소스코드, 라이브러리, 빌드 도구 등의 파일들이 함께 올라가 있는 상태이므로 더 무겁고, 중요한 파일의 경우 공격의 위협에 노출될 수 있다는 것이다. 따라서 빌드 시의 환경과 실행 시의 환경을 나누기 위해서 docker image build 단계를 두 단계로 나누는 멀티 스테이지 빌드의 개념이 등장하게 되었다.

 

멀티 스테이지 빌드의 최대 특징은 싱글 스테이지 빌드(빌드와 실행이 같은 환경에서 실행되었다고 가정)에서는 빌드와 실행이 동시에 일어나므로 빌드에 필요한 다양한 파일들(소스코드, 라이브러리, 빌드 도구 등)도 함께 컨테이너 위에 올라가있어야 하는데, 멀티 스테이지 빌드는 빌드 후에 실행파일 만을 컨테이너에 올려서 크기도 줄이고, 보안도 강화할 수 있다는 것이다.

 

멀티 스테이지 빌드를 위한 Dockerfile

이런 식으로 도커파일에 AS 명령어와 --from 명령어를 사용해서 단계를 나눌 수 있고, 이전 단계에서 실행 파일만 복사하면 실행 단계와 빌드 단계를 나누어서 진행할 수 있다!

 

확인해보자

- 빌드

docker build -t thief .

 

-t thief : 해당 이미지의 이름을 "thief" 으로 지정. 

. : 현재 디렉토리에 있는 Dockerfile 사용.

 

 

- 실행

 

docker run -d -p 8080:8080 --name thief-container thief

 

-d : detached mode, 백그라운드에서 컨테이너 실행

-p 8080:8080 : 호스트의 포트와 컨테이너의 포트 연결

--name thief-container : 컨테이너 이름 지정

thief : 실행시킬 이미지.

 

 

실행 결과

 

Docker 실습 성공!

'DevOps, 배포' 카테고리의 다른 글

[DevOps] AWS EC2에 Docker 올리기 with Docker Compose  (0) 2025.02.28
[AWS] AWS EC2 시작하기  (0) 2025.02.25