Dockfile

snooby·2022년 7월 28일
2

🐳 kubernetes

목록 보기
3/63
post-thumbnail

1. Dockfile을 쓰는 이유

  • base image 파일로 수정된 image 만드는 일련의 과정들을 정리해 놓은 파일
  • docker는 dockerfile을 이용해서 쉽게 이미지를 반복해서 만들 수 있다.

2. 작성 방법

#FROM
# 베이스 이미지를 지정합니다. 반드시 지정해야 하며 어떤 이미지도 베이스 이미지가 될 수 있습니다.
# tag는 될 수 있으면 latest(기본값)보다 구체적인 버전(16.04등)을 지정하는 것이 좋습니다.
# 이미 만들어진 다양한 베이스 이미지는 Docker hub에서 확인할 수 있습니다.
# FROM <image>:<tag>
FROM ubuntu:16.04
 
 
#MAINTAINER
# Dockerfile을 관리하는 사람의 이름 또는 이메일 정보를 적습니다. 빌드에 딱히 영향을 주지는 않습니다.
# MAINTAINER <name>
MAINTAINER jinwkon.kim@ahnlab.com
 
 
#COPY
# 파일이나 디렉토리를 이미지로 복사합니다. 일반적으로 소스를 복사하는 데 사용합니다. target디렉토리가 없다면 자동으로 생성합니다.
# COPY <src>... <dest>
COPY . /usr/src/app
 
 
#ADD
# COPY명령어와 매우 유사하나 몇가지 추가 기능이 있습니다. src에 파일 대신 URL을 입력할 수 있고 src에 압축 파일을 입력하는 경우 자동으로 압축을 해제하면서 복사됩니다.
# ADD <src>... <dest>
ADD . /usr/src/app
 
 
#RUN
# 가장 많이 사용하는 구문입니다. 명령어를 그대로 실행합니다. 내부적으로 /bin/sh -c 뒤에 명령어를 실행하는 방식입니다.
# RUN <command>
# RUN ["executable", "param1", "param2"]
RUN bundle install
 
 
#CMD
# 도커 컨테이너가 실행되었을 때 실행되는 명령어를 정의합니다.
# 빌드할 때는 실행되지 않으며 여러 개의 CMD가 존재할 경우 가장 마지막 CMD만 실행됩니다.
# 한꺼번에 여러 개의 프로그램을 실행하고 싶은 경우에는 run.sh파일을 작성하여 데몬으로 실행하거나 supervisord나 forego와 같은 여러 개의 프로그램을 실행하는 프로그램을 사용합니다.
#CMD ["executable","param1","param2"]
#CMD command param1 param2
CMD bundle exec ruby app.rb
 
 
#WORKDIR
# RUN, CMD, ADD, COPY등이 이루어질 기본 디렉토리를 설정합니다.
# 각 명령어의 현재 디렉토리는 한 줄 한 줄마다 초기화되기 때문에 RUN cd /path를 하더라도 다음 명령어에선 다시 위치가 초기화 됩니다.
# 같은 디렉토리에서 계속 작업하기 위해서 WORKDIR을 사용합니다.
WORKDIR /path/to/workdir
 
#EXPOSE
# 도커 컨테이너가 실행되었을 때 요청을 기다리고 있는(Listen) 포트를 지정합니다. 여러개의 포트를 지정할 수 있습니다.
# EXPOSE <port> [<port>...]
EXPOSE 4567
 
 
#VOLUME
# 컨테이너 외부에 파일시스템을 마운트 할 때 사용합니다. 반드시 지정하지 않아도 마운트 할 수 있지만, 기본적으로 지정하는 것이 좋습니다.
VOLUME ["/data"]
 
 
#ENV
# 컨테이너에서 사용할 환경변수를 지정합니다. 컨테이너를 실행할 때 -e옵션을 사용하면 기존 값을 오버라이딩 하게 됩니다.
# ENV <key> <value>
# ENV <key>=<value> ...
ENV DB_URL mysql

3. 예제

node.js server를 띄워보자

1) node.js 파일 생성

# 폴더 생성 이도
mkdir docker-study && cd docker-study

# node.js 초기 세팅
npm init
# package.json 생성되었는지 확인 
ls

# express 세팅
npm i express
  • package.json start 내용 수정
{
  "name": "docker-study",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.1"
  }
}
  • index.js 생성 후 작성
'use strict';

const os = require('os');
const express = require('express');

// 상수
const PORT = 9090;
const HOST = '0.0.0.0';

// 앱
const app = express();
app.get('/', (req, res) => {
  res.send(`Your app is running on Host : ${os.hostname()}\r\n`);
});

app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);
  • index.js 실행
npm start
  • localhost:9090 접속

2) 도커 이미지 생성

  • dockerfile 생성
FROM node:12

# 앱 디렉터리 생성
WORKDIR /usr/src/app

# 앱 의존성 설치
# 가능한 경우(npm@5+) package.json과 package-lock.json을 모두 복사하기 위해
# 와일드카드를 사용
COPY package*.json ./

RUN npm install
# 프로덕션을 위한 코드를 빌드하는 경우
# RUN npm ci --only=production

# 앱 소스 추가
COPY . .

EXPOSE 8080
CMD [ "node", "index.js" ]
  • WORKDIR는 RUN, CMD, ENTRYPOINT, COPY, ADD 명령어들은 다 이 WORKDIR에서 실행WORKDIR로 지정한 경로의 폴더가 없다면 생성됨.
  • COPY package*.json ./는 Dockerfile이 있는 위치에서 package로 시작하는 json 파일들을 전부 다 WORKDIR로 복사
  • RUN npm install은 WORKDIR에서 npm install을 실행
  • package*.json이 있는 상태에서 npm install을 실행하면 그 안에 있는 내용을 보고 필요한 패키지들을 node_modules 폴더에 설치해요. 설치한 패키지들이 많으면 이 폴더가 커질 수 있는데 도커 이미지 사이즈를 최대한 작게 하기 위해 이미지를 만들 때 부터 넣어놓지 않고 컨테이너를 생성할 때 패키지 설치를 하게 .
  • EXPOSE 9090은 이 도커 이미지로 만든 컨테이너가 기본적으로 9090포트를 열고있다고 도커에게 알려줌.
  • .dockerignore 생성
node_modules
npm-debug.log
# 로컬에 있는 node_modules라는 폴더를 이미지로 복사해서 덮어쓰지 않게 하고 npm-debug.log 파일도 이미지 파일 안으로 복사되는 것을 막음.
  • 도커 이미지 생성
docker build . -t bell.coco/node-web-app:1.0.0

# 이미지 확인
docker image ls

3) 도커 컨테이너 생성

docker run -d -p <내가원하는포트>:9090 위에서 생성한 이미지 repository:tag
docker ps

접속 결과

profile
DevOps 🐥

0개의 댓글