Gom3rye

Dockerfile (앱 빌드, Private Registry) 본문

현대 오토에버 클라우드 스쿨

Dockerfile (앱 빌드, Private Registry)

Gom3rye 2025. 6. 20. 17:38

Dockerfile 작성 시 유의 사항

  • docker build 명령을 통해 Dockerfile에 작성한 명령을 순서대로 읽으면서 처리하고 자동으로 이미지를 생성하는데 이미지 빌드는 사용자와의 대화식 처리가 아니라 자동화된 빌드이다.
  • 따라서 패키지를 설치할 때 -y 옵션을 이용해서 대화식으로 설치하지 않고 자동으로 설치하도록 해야 한다.

Python 이미지 빌드

  • Dockerfile 만들어서 우분투에 python 설치
FROM ubuntu:20.04 # 우분투 버전 명시
RUN apt update
RUN apt install -y python 
  • 이미지 빌드
docker build -t mypython:1.0 .
  • 파일명이 Dockerfile이 아니거나 다른 디렉토리에 있는 도커 파일을 빌드할 때는 -f 옵션을 이용해서 경로를 직접 설정해야 한다.
  • 아래 경우는 appimage 폴더 안에 파일명이 dockerfile으로 있어서 -f 없이도 .appimage 경로 붙여줘서 -f 없이도 가능한 것이다.

→ dockerfile이 현재 경로에 없으면 경로를 명시해줘야 한다.

 

이미지 빌드 과정

  • Docker 이미지는 Dockerfile의 명령어 단위로 읽기 전용 레이어를 생성해서 최종 이미지로 생성한다.
  • Dockerfile 작성
FROM ubuntu:20.04

RUN apt update
RUN apt install -y nginx
RUN apt install -y curl
RUN echo 'Docker Container Application' > /var/www/html/index.html

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
  • 이미지 빌드 (현재 디렉토리에 있는 경우)
docker build -t webapp:1.0 .
  • 도커 파일을 다시 빌드
    • 캐시를 이용하므로 빌드 과정이 바로 끝남
docker build -t webapp:2.0 .
  • 도커 파일 명령어 순서를 바꾼 후 다시 빌드
    • 순서가 바뀐 곳부터 다시 빌드하므로 똑같이 시간 걸림 (바로 끝나지 않음)
FROM ubuntu:20.04

RUN apt update
RUN apt install -y curl
RUN apt install -y nginx
RUN echo 'Docker Container Application' > /var/www/html/index.html

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
docker build -t webapp:3.0 .
  • 빌드 캐시
    • docker build는 빌드 속도 향상을 위해서 실행 중간에 있는 이미지 캐시를 이용한다.
    • 기본적으로 첫 번째 빌드 과정에서 단계별로 캐시를 생성하고 이 빌드 캐시는 동일한 이미지 작업으로 제한된다.
    • 빌드 과정에서 캐시를 사용하지 않고자 하는 경우 --no-cache를 지정해서 빌드하면 된다.
    docker build --no-cache -t webapp:4.0 .
    
    → 다시 RUN을 수행한다.

파이썬 장고 애플리케이션 빌드하기

  • django 실행 명령어
python manage.py runserver 서버IP:포트번호
  • pip 설치
sudo apt install -y python3-pip
  • 가상 환경 패키지 설치
sudo apt install -y python3.12-venv
  • 가상 환경 생성
python3 -m venv ./myvenv
  • 가상환경 활성화
    • 윈도우: myvenv/Scripts.activate
    • 리눅스: source myvenv/bin/activate

  • Django 설치 및 실행
pip install django
django-admin startproject dockerdjango

  • Django 서버 실행
cd dockerdjango
python manage.py runserver

  • 라이브러리의 의존성을 파일로 내보내기
pip freeze > requirements.txt
  • Dockerfile 작성
FROM python
RUN apt update
WORKDIR /usr/src/app
COPY requirements.txt ./    
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]  
  • 이미지 빌드
docker build -t dockerdjango .

  • 컨테이너를 만들어서 실행
docker run --name dockerdjango -p 8000:8000 -d dockerdjango

Spring Boot 프로젝트 이미지 생성

  • Spring Boot 프로젝트 생성
  • 프로젝트가 존재하는 디렉토리로 커서를 이동
  • 프로젝트를 빌드해서 실행 가능한 jar 파일을 생성
./gradlew clean build
  • root 디렉토리에 Dockerfile 작성
FROM amazonecorretto:17 # 자바 가져오기 (java 21버전을 쓴다면 :21로)
CMD ["./mvnw", "clean", "package"]
ARG JAR_FILE=target/*.jar
COPY ./build/libs/*.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]

Node 프로젝트 이미지 빌드

  • Node 설치
# nvm 다운로드 및 설치
curl -o- <https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh> | bash

# 변경된 내용 적용
source ~/.bashrc

# Node.js 다운로드 및 설치
nvm install 22

# Node.js 버전 확인
node -v # v22.16.0
nvm current # v22.16.0

# npm 버전 확인
npm -v # 10.9.2

  • package.json 의 scripts 부분 수정
{
  "name": "sample",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "node app.js"
  },
  "author": "",
  "license": "ISC",
  "description": ""
}
  • app.js 파일을 생성하고 작성
const express = require('express')
const app = express()
app.set('port', process.env.PORT || 3000);
app.get("/", (req, res) => {
        res.send("Hello Express")
})
app.listen(app.get('port'), () => {
        console.log(app.get('port'), 'port ready')
})  
  • express 모듈 설치 후 실행
npm install express
npm start

  • Dockerfile 작성
FROM node
RUN mkdir -p /app
WORKDIR /app
ADD . /app
RUN npm install
EXPOSE 3000 80
CMD ["npm", "start"] 
  • 이미지 빌드
docker build -t nodeapp .

  • 컨테이너 생성
docker run -d -p 3000:3000 --name dockernode nodeapp

다양한 방법의 Dockerfile 작성

ADD 명령어는 자동 압축 해제 기능이 존재한다.

  • 압축된 파일을 ADD 명령으로 삽입하면 압축이 해제되서 디렉토리에 들어간다.
    • 확인
    git clone https://github.com/brayanlee/webapp.git
    cd webapp
    ls

  • 현재 디렉토리에 dockerfiles 디렉토리 생성
vi dockerfiles/Dockerfile
FROM ubuntu:latest

RUN apt update
RUN apt install -y curl
RUN apt install -y vim

ADD webapp.tar.gz /var/www/html

WORKDIR /var/www/html

EXPOSE 80

CMD /usr/sbin/apachectl -D FOREGROUND
  • 이미지 빌드
docker build -t webapp:5.0 -f ./dockerfiles/Dockerfile .
  • 실행
docker run -dit -p 8008:80 --name webapp5 webapp:5.0

→ 포트포워딩 하면 docker 이미지 볼 수 있다.

  • 컨테이너 들어가서 실행
    • add할 때 압축된 것을 넣었지만 들어가서 확인해보니 압축이 풀려있다.
docker exec -it webapp5 bash

이미지 용량 줄이기

  • apt를 이용한 패키지 업데이트와 설치 시 남게 되는 캐시를 제거하여 생성되는 이미지의 용량을 줄일 수 있다.
  • apt clean
    • 설치에 사용한 패키지 라이브러리, 임시 파일, 오래된 파일을 삭제를 하는데 autoclean을 사용하면 더 이상 설치되어 있지 않은 패키지들의 .deb 파일들까지 삭제한다.
  • apt autoremove
    • 다른 패키지의 종속성을 충족시키기 위해 자동으로 설치된 패키지 삭제
  • rm -rfv /tmp/ /var/lib/apt/lists/ /var/tmp/***
    • apt와 연관된 캐시 파일을 모두 삭제

실습

  • index.html 파일 작성
FROM ubuntu

RUN apt update
RUN apt install -y apache2

WORKDIR /var/www/html
ADD index.html .
EXPOSE 80
CMD apachectl -D FOREGROUND
  • 이미지 빌드
docker build -t webapp6 .
  • Dockerfile 수정
FROM ubuntu

RUN apt update
RUN apt install -y apache2
RUN apt clean -y
RUN apt autoremove -y
RUN rm -rfv /var/lib/apt/lists/* /tmp/* /var/tmp/*

WORKDIR /var/www/html
ADD index.html .
EXPOSE 80
CMD apachectl -D FOREGROUND
  • 이미지 빌드
docker build -t webapp7 .

→ 지금은 차이 없지만 설치한 게 많아지면 clean, autoremove, rm을 작성한 이미지의 용량이 더 줄어든다.

다단계 빌드

빌드를 여러 단계로 나누어 빌드하는 것

  • 각 빌드 단계는 FROM 명령으로 시작하며 필요한 경우 빌드 단계에 AS 파라미터를 이용해서 이름을 붙일 수 있다.
  • 빌드가 여러 단계로 나누어져 있지만 최종 산출물은 마지막 단계의 내용물을 담은 도커 이미지이다.
  • 각 빌드 단계는 독립적으로 실행되지만 앞 단계에서 만들어진 디렉토리나 파일을 복사할 수는 있다.
  • go 애플리케이션의 경우 다단계 빌드를 하게 되면 이미지 크기가 많이 줄어든다.
    • go lang 설치
    sudo apt update
    sudo apt install golang
    # 확인
    go version
    
    • go 소스 파일 작성 (main.go)
    package main
    import(
    		"fmt"
    		"os"
    )
    
    func main(){
    		fmt.Fprintln(os.Stdout, "Go Go Go")
    }
    

  • Dockerfile 생성
FROM golang:1.15-alpine3.12 AS gobuilder-stage

WORKDIR /usr/src/goapp
COPY main.go .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /usr/local/bin/gostart

FROM scratch AS runtime-stage
COPY --from=gobuilder-stage /usr/local/bin/gostart /usr/local/bin/gostart
CMD ["/usr/local/bin/gostart"]
  • 이미지 빌드
docker build -t goapp:1.0 .
docker run --name goapp-deploy goapp:1.0
  • 만약 안되면 로그 확인
docker logs goapp-deploy

Private Registry

이미지를 외부에 공개하지 않고 내부에서만 사용할 목적으로 구성하는 이미지 저장소

  • 도커 허브에서 프라이빗 레지스트리 구성을 위한 이미지를 제공하는데 단순 텍스트 방식만 지원하기 때문에 웹 기반의 검색을 하려면 GUI 인터페이스를 제공하는 다른 컨테이너와 결합해서 사용한다.
  • 레지스트리를 생성
docker run -d --name registry -p 5000:5000 registry:2
  • 5000번 사용 포트포워딩 하고 접속해보면 현재는 아무것도 없는 것을 확인할 수 있음
  • GUI까지 연결하고 싶으면 하나의 레지스트리 더 써야 한다.
docker run -dit -p 8080:8080 --name registry-web --link registry -e REGISTRY_URL=http://10.0.2.101:5000 -e REGISTRY_NAME=10.0.2.101:5000 --restart=always hyper/docker-registry-web
  • Private Registry 사용
    • push할 이미지를 생성
      • 레지스트리이름/이미지이름:태크 형태로 이름이 만들어져야 한다.
    docker image tag goapp:1.0 10.0.2.101:5000/goapp:1.0
    
    • push
    docker push 10.0.2.101:5000/goapp:1.0
    
    • 기본적으로 도커는 HTTPS를 지원한다. → HTTP 서버를 사용하고자 하는 경우에는 설정을 수정해 주어야 한다.
      • 이 설정은 deamon.json 이라는 파일에 있다.
      • sudo vi /etc/docker/daemon.json
    {
            "builder":{
                    "gc":{
                            "defaultKeepStorage": "20GB",
                            "enabled": true
                    }
            },
            "experimental": false,
            "insecure-registries":["10.0.2.101:5000"]
    } 
    
    • 도커를 재시작
    systemctl restart docker
    
    • private 레지스트리 컨테이너 다시 시작
    docker start registry
    
728x90
반응형

'현대 오토에버 클라우드 스쿨' 카테고리의 다른 글

Dockerfile  (1) 2025.06.19
Volume  (1) 2025.06.18
Docker 명령어  (0) 2025.06.17
현대 오토에버 클라우드 교육 참여 소감  (0) 2025.06.17
Docker 명령어  (0) 2025.06.16