Dockerfile 활용해 이미지 직접 만들기

  • Dockerfile이란?

Docker 이미지를 만들게 해주는 파일.

 

  • FROM : 베이스 이미지 생성

FROM은 베이스 이미지를 생성하는 역할을 한다.

Docker 컨테이너를 특정 초기 이미지를 기반으로 추가적인 셋팅을 할 수 있다.

여기서 예기한 '특정 초기 이미지'가 곧 베이스 이미지이다.

 

사용법

# 문법
FROM [이미지명]
FROM [이미지명]:[태그명]

 

  • [실습] FROM : 베이스 이미지 생성

  1. Dockerfile 만들기

# JDK 17
FROM openjdk:17-jdk
  1. Dockerfile을 기반으로 이미지 만들기

docker build -t my-jdk17-server .
  1. 이미지를 기반으로 컨테이너 띄우기

docker run -d my-jdk17-server
  1. 컨테이너 조회하기

docker ps # 실행되고 있는 컨테이너가 없다.
docker ps -a # 확인해보니 컨테이너가 종료되어 있다. 

Docker의 컨테이너는 내부적으로 필요한 명령을 다 수행하면 컨테이너가 저절로 종료된다.

  1. 컨테이너 내부로 들어가서 jdk가 잘 깔렸는지 확인해보기

종료된 컨테이너에 들어가서 디버깅하고 싶을때

FROM openjdk:17-jdk

ENTRYPOINT ["/bin/bash", "-c", "sleep 500"] # 500초 동안 시스템을 일시정지 시키는 명령어
docker build -t my-jdk17-server . # 이미지 빌드
docker run -d my-jdk17-server # 컨테이너 실행
docker ps # 실행 중인 컨테이너 조회
docker exec -it [컨테이너 ID] bash # 컨테이너 접속

java -version # JDK 설치되어 있는 지 확인

 

  • COPY : 파일 복사( 이동 )

# 문법
COPY [호스트 컴퓨터에 있는 복사할 파일의 경로] [컨테이너에서 파일이 위치할 경로]

# 예시
COPY app.txt /app.txt

 -- 와일드 카드 사용해보기

FROM ubuntu

COPY *.txt /text-files/

ENTRYPOINT ["/bin/bash", "-c", "sleep 500"] # 디버깅용 코드

 -- .dockerignore 사용해보기

.dockerignore

readme.txt

 Dockerfile

FROM ubuntu

COPY ./ /

ENTRYPOINT ["/bin/bash", "-c", "sleep 500"] # 디버깅용 코드

--> readme.txt만 복사가 안된다.

 

  • ENTRYPOINT : 컨테이너가 시작할때 실행되는 명령어

# 문법
ENTRYPOINT [명령문...]

# 예시
ENTRYPOINT ["node", "dist/main.js"]

예제

FROM ubuntu

ENTRYPOINT ["/bin/bash", "-c", "echo hello"]
 docker build -t my-server .
 docker run -d my-server
 docker ps -a
 docker logs [Container ID]

 

  • [실습] 백엔드 프로젝트(Spring Boot) 를 Docker로 실행시키기

AppController

@RestController
public class AppController {
  @GetMapping("/")
  public String home() {
    return "Hello, World!";
  }
}

Dockerfile

FROM openjdk:17-jdk

COPY build/libs/*SNAPSHOT.jar app.jar

ENTRYPOINT ["java", "-jar", "/app.jar"]
# Spring Boot 프로젝트 빌드하기
./gradlew clean build
# Dockerfile을 바탕으로 이미지 빌드하기
docker build -t hello-server .
# 이미지가 잘 생성됐는 지 확인하기
docker image ls
# 생성한 이미지를 컨테이너로 실행시켜보기
docker run -d -p 8080:8080 hello-server
# 컨테이너 잘 실행되고 있는 지 확인하기
docker ps

 

  • RUN: 이미지를 생성하는 과정에서 사용할 명령문 실행

RUN 은 이미지 생성 과정에서 명령어를 실행시켜야 할 때 사용한다.

# 문법
RUN [명령문]

# 예시
RUN npm install

 

RUN 과 ENTRYPOINT

RUN은 '이미지 생성 과정'에서 필요한 명령어를 실행시킬 때 사용하고,

ENTRYPOINT는 생성된 이미지를 기반으로 컨테이너를 생성한 직후에 명령어를 실행시킬 때 사용한다.

 

[예제]

미니 컴퓨터 환경이 ubuntu로 구성되었으면 좋겠고 git이 깔려있으면 좋겠다고 가정하자. 이런 환경을 구성하기 위해

Dockerfile 을 활용해 ubuntu, git이 깔려있는 이미지를 만들면 된다.

 

Dockerfile

FROM ubuntu

RUN apt update && apt install -y git

ENTRYPOINT ["/bin/bash", "-c", "sleep 500"]

이미지 빌드 및 컨테이너 실행

docker build -t my-server .
docker run -d my-server
docker exec -it [Container ID] bash

git -v # 컨테이너 내에 git이 잘 설치됐는 지 확인

 

  • WORKDIR : 작업 디렉토리를 지정

작업 디렉토리를 지정해주는 이유는 컨테이너 내부의 폴더를 깔끔하게 관리하기 위해서이며

컨테이너도 미니 컴퓨터와 같기 때문에 Dockerfile을 통해 생성되는 파일들을 특정 폴더에 정리해두는 것이 추후에 관리가 쉽다.

만약에 WORKDIR을 쓰지 않으면 내부에 존재하는 기존 파일들과 뒤섞여버린다.

 

# 문법
WORKDIR [작업 디렉토리로 사용할 절대 경로]

# 예시
WORKDIR /usr/src/app

 

예제

  1. app.txt

    ,

    src

    ,

    config.json

    파일 만들기

  2. Dockerfile 만들어서 이미지 생성 및 컨테이너 실행

- - WORKDIR 을 안 썼을 때 파일이 어떻게 구성되는 지 먼저 확인

 

Dockerfile

FROM ubuntu

COPY ./ ./

ENTRYPOINT ["/bin/bash", "-c", "sleep 500"] # 디버깅용 코드
 docker build -t my-server .
 docker run -d my-server
 docker exec -it [Container ID] bash

 ls

 

-- WORKDIR 을 썼을 때 파일이 어떻게 구성되는 지 확인

 

Dockerfile

FROM ubuntu

WORKDIR /my-dir

COPY ./ ./

ENTRYPOINT ["/bin/bash", "-c", "sleep 500"]
 docker build -t my-server .
 docker run -d my-server
 docker exec -it [Container ID] bash

 ls

 

  • EXPOSE : 컨테이너 내부에서 사용 중인 포트를 문서화

EXPOSE 는 컨테이너 내부에서 어떤 포트에 프로그램이 실행되는 지를 문서화하는 역할만 한다.

 

# 문법
EXPOSE [포트 번호]

# 예시
EXPOSE 3000

 

[실습]

  • 백엔드 프로젝트(Next.js)를 Docker로 실행

  1. Next.js 프로젝트 만들기

# Nest CLI 설치
 npm i -g @nestjs/cli

# nest new {프로젝트명}
 nest new my-server
  1. Dockerfile 작성

FROM node

WORKDIR /app

COPY . .

RUN npm install

RUN npm run build

EXPOSE 3000

ENTRYPOINT [ "node", "dist/main.js" ]
  1. .dockerignore 작성

node_modules
  1. Dockerfile을 바탕으로 이미지 빌드 및 컨테이너 실행

docker build -t my-server .

docker image ls

docker run -d -p 3000:3000 my-server

docker ps

 

  • 웹 프론트엔드 프로젝트(Next.js)를 Docker로 배포하기

  1. Next.js 프로젝트 만들기

npx create-next-app@latest
  1. Dockerfile 작성하기

FROM node:20-alpine

WORKDIR /app

COPY . .

RUN npm install

RUN npm run build

EXPOSE 3000

ENTRYPOINT [ "npm", "run", "start" ]
  1. .dockerignore 작성

node_modules
  1. Dockerfile로 이미지 빌드 및 컨테이너 실행

docker build -t my-web-server .

docker image ls

docker run -d -p 80:3000 my-web-server

docker ps

 

  • 웹 프론트엔드 프로젝트(HTML, css, Nginx)를 Docker로 배포하기

  1. HTML, css 파일 만들기

index.html

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <h1>My Web Page</h1>
</body>
</html>

주의) Nginx의 기본 설정에 의하면 메인 페이지(첫 페이지)의 파일명을 index.html 이라고 지어야 한다.

style.css

* {
  color: blue;
}
  1. Dockerfile 작성

FROM nginx 
COPY ./ /usr/share/nginx/html
  1. Dockerfile로 이미지 빌드 및 컨테이너 실행

docker build -t my-web-server .

docker image ls

docker run -d -p 80:80 my-web-server

docker ps

 

 

댓글을 작성해보세요.

채널톡 아이콘