Gom3rye
Dockerfile (앱 빌드, Private Registry) 본문
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를 지정해서 빌드하면 된다.
→ 다시 RUN을 수행한다.docker build --no-cache -t webapp:4.0 .
파이썬 장고 애플리케이션 빌드하기
- 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
- push할 이미지를 생성
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 |