1. Dockerfile
내 프로그램을 이미지로 만들어두면, 아무 컴퓨터에서나 그걸 내려받아서 매우 쉽게 실행할 수 있다고 했습니다. 이미지를 만들고 싶으면,
- 코드짠거 근처에다가
Dockerfile을 하나 만들고 - 이미지에 뭘 넣을지 작성하고
- 그 다음에 같은 곳에서 터미널을 열어서
docker build 명령어를 입력하면 이미지가 하나 생성됩니다.
Dockerfile에 넣을 수 있는 것들은 다음과 같다.
- 어떤 OS를 설치할건지
- 어떤 프로그램을 설치할건지
- 어떤 터미널 명령어를 실행할건지
- 내 컴퓨터에 있던 파일을 어디에 집어넣을 것인지
그래서 내 프로그램을 돌리고 싶으면, 무슨 짓을 차례로 해야하는지 Dockerfile에 전부 적어놓으면 됩니다.
e.g. 저번에 만들어둔 Node.js 서버를 이미지에 담아서 실행하고 싶으면,
- OS 하나 설치하고
- nodejs설치하고
npm install express터미널에 입력하고- 서버 코드 작성하고,
node server.js터미널에 입력
이렇게 Dockerfile에 작성하고 이미지 생성하면 끝입니다. 그래서 이걸 Dockerfile 문법으로 번역해봅시다.
1.1 FROM 명령어
어떤 OS환경에서 내 프로그램을 실행할지부터 정해야하는데 그건 FROM으로 정할 수 있습니다. 그래서 Dockerfile은 항상 FROM부터 시작합니다. FROM 뒤에 어떤 OS를 설치해서 시작할건지 정하면 되는데, 그건 Docker hub에서 찾아오면 됩니다.

e.g. 윈도우 설치하고 싶으면 windows 검색해서 그거 기재하면 되고,
- 리눅스 OS 설치하고 싶으면 (ubuntu, devian, redhat, alpine) 이런거 검색해서 기재하면 됩니다.
- 보통은 리눅스가 서버비가 덜 들기 때문에 리눅스를 씁니다.
- 그래서 위 사진에서 ubuntu 검색하면 저런 버전들이 있다고 뜨는데,
FROM ubuntu:25.04이런 식으로 Dockerfile에 기입하면 ubuntu 25버전이 설치된 채로 시작가능합니다.

▲ 아니면 아예 리눅스 + Node.js 함께 설치된걸 이미 만들어둔 사람들이 있기 때문에 그거 설치하셔도 됩니다.
-
node 검색해보면 되고 파이썬, 자바도 마찬가지로 검색해보면 리눅스와 셋트로 제공해주는 이미지들이 많습니다.
-
그래서 위 사진 검색결과에 나온 대로
FROM node:22-alpine를 기재하면,- Node.js 22버전과 alpine 리눅스 OS가 설치된 채로 시작할 수 있습니다.
-
cf.
slim은 devian 리눅스에서 필요없는거 지운거고,alpine은 용량이 가장 작은 리눅스라서 보통 선호됩니다
1# Dockerfile2FROM node:20-slim
원래 내가 쓰던 Node.js 버전 쓰는게 좋습니다. cf. 지금 쓴건 정확히는 OS를 설치한다기보다 OS가 이미 설치된 이미지를 가져와서 그 이미지 위에서 시작한다는 뜻입니다. 근데 그게 그거임.
💡 cf, 바이너리로 컴파일한 파일만 돌리면 되는 경우엔, OS 설치가 딱히 필요없을 수 있는데,
1FROM scratch그럴 땐 빈 도화지에서 시작하라고 이런걸 쓰기도 합니다.
1.2 RUN 명령어
그 다음에 npm install express 이런걸 해서 라이브러리를 설치했는데,
이걸 똑같이 하라고 하고 싶으면 Dockerfile에서 RUN 명령어 뒤에 적으면 됩니다.
1FROM node:20-slim2RUN npm install express
RUN npm install express하면 RUN 뒤에 있는걸 터미널 명령어처럼 실행해줍니다.
RUN은 여러번 써도 됩니다.- 근데 이러면 문제가 설치할 라이브러리가 100개 있으면 100줄 써야하고,
- 또 최신 버전 express 라이브러리를 설치해주기 때문에 귀찮아질 수 있습니다.
그래서 어떻게 설치하냐면, 내가 쓰던 package.json 파일을 먼저 똑같이 복사해오고,
- 그 다음에
npm install만 입력하면, package.json에 기록되어있던 라이브러리를 그대로 설치해주는 기능이 있기 때문에 그걸 사용해봅시다.- cf.
package.json은 설치된 라이브러리가 기록되어있는 파일입니다.
1.3 COPY 명령어
그래서 내 컴퓨터에 있던 파일을 이미지로 복사하려면, COPY 명령어 쓰면 되겠습니다.
아무거나 복사 가능합니다. 지금은 package.json 파일을 복사해봅시다.
1COPY 내컴퓨터파일경로 이미지내부파일경로
COPY 명령어 뒤에는 경로 2개를 적을 수 있는데, 왼쪽에는 내컴퓨터 폴더경로, 오른쪽에는 이미지 어디로 옮길건지 정하면 됩니다.
1FROM node:20-slim2COPY . .
마침표는 현재 경로라는 뜻이기 때문에,
Dockerfile 현재경로 옆에 있던 모든 파일과 폴더들을 가상컴퓨터 현재경로로 복사해달라는 뜻입니다.
그러면 소스코드도 전부 복사되어서 편하겠군요.
1// .dockerignore2.git3Dockerfile4node_modules
근데 이러면 node_modules같은 라이브러리 소스코드도 복사해줄텐데 굳이 그건 복사할 필요는 없습니다.
복사하기 싫은 파일이 있으면, .dockerignore 파일 만들어서 파일이나 폴더경로 기재해두면 됩니다.
1.4 WORKDIR 명령어
근데 파일 카피하기 전에 폴더 이동을 좀 해보도록 합시다.
왜냐면 이미지 기본 경로에 옮기면, 파일이 좀 많으면 더러울 수 있으니까,
/app 같은 폴더 하나 만들어서 거기로 이동하라고 합시다.
1FROM node:20-slim2WORKDIR /app # /app폴더로 이동하라는 뜻 (cd 명령어랑 비슷)3COPY . .
쉽게하려면 WORKDIR /app 이러면 됩니다.
그러면 현재 작업경로를 /app 폴더로 바꿔주고, /app 폴더가 없으면 하나 만들어줍니다.
터미널 명령어 중에 cd와 비슷한 역할입니다.
1.5 다시 RUN 명령어
그 다음에 npm install을 터미널에서 입력하면 package.json에 기재된 라이브러리가 설치된다고 했으니까,
npm install하라고 명령을 줘봅시다.
1FROM node:20-slim2WORKDIR /app3COPY . .4RUN ["npm", "install"]
RUN npm install 이렇게 써도 되는데 대괄호치는게 더 안정적인 방식입니다.
- 괄호 안치면
/bin/sh -c npm install이라는 명령어가 실행이 되는데 - 이게 뭐냐면 내 OS에 기본적으로 설치된 shell을 이용해서 실행하라는 소리입니다.
- 그래서
shell이라는 프로그램과 거기서 제공하는&& ||이런 명령어가 필요하면 괄호없이 쓰면 되는데 - 하지만
shell기능이 필요없거나 OS마다shell이 서로 다를 수 있기 때문에 불안하면 대괄호를 씁시다.
1.6 CMD 명령어
그럼 이제 마지막으로 node server.js 입력하면 파일이 실행되고 그러면 웹서버가 실행됩니다.
그래서 Dockerfile에도 그거 하라고 작성하면 되는데, RUN node server.js 하면 될 것 같은데,
하지만 보통 마지막 명령어는 RUN 말고 CMD 뒤에 적습니다.
1FROM node:20-slim2WORKDIR /app3COPY . .4RUN ["npm", "install"]5CMD ["node", "server.js"]
CMD 대신에 ENTRYPOINT라고 적을 수도 있는데 차이점은 사소합니다.
💡 CMD vs ENTRYPOINT
나중에 내 이미지를 실행할 때 멋있게 터미널에서 실행하고 싶으면,
1docker run 이미지명입력하면 되는데 근데 뒤에 몰래 명령어를 추가할 수 있습니다.
1docker run 이미지명 node server1.js그러면 Dockerfile 내의
CMD부분이node server1.js로 덮어쓰기가 되어서 실행됩니다. 그래서 매번 다른 명령어로 실행하고 싶으면,CMD사용하면 덮어쓰기 편리해집니다.
CMD말고ENTRYPOINT를 쓰면 기능은 비슷하지만 덮어쓰기가 살짝 어려워집니다. 이상한 명령어를 써야 덮어쓰기가 되기 때문에, 어떻게 보면ENTRYPOINT쓰면 좀 더 안정적이라고 보면 되겠습니다.실은 섞어서 써도 됩니다. 변경원하지 않는 부분은
ENTRYPOINT에 넣고, 변경원하는 부분은CMD넣고 그러셔도 됩니다.1# ...생략2ENTRYPOINT ["node"]3CMD ["server.js"]e.g. 이런 식으로 적어두면, 앞으로 이미지 실행할 때
docker run 이미지명 server1.js이렇게 실행하면
node server1.js라는 커맨드가 마지막에 실행됩니다.- 그래서
docker run할 때마다 일부 명령어만 가변적으로 덮어쓰기 하고 싶을 때 이런 식으로 써도 되겠습니다.- 지금은 쓸데없으니까 아무거나 씁시다.
1.7 EXPOSE 명령어
1FROM node:20-slim2WORKDIR /app3COPY . .4RUN ["npm", "install"]5EXPOSE 8080 # 8080포트를 열어서 쓰겠다고 메모하는 용도6CMD ["node", "server.js"]
EXPOSE 명령어 뒤에 8080 이런 식으로 포트번호를 기재할 수 있습니다.
포트가 뭐냐면 “컴퓨터에 뚫린 구멍”입니다.
이게 뚫려있어야 외부 사람들이 내 컴퓨터로 접속이 가능해서 웹서버 운영하는 컴퓨터도 포트를 하나 뚫어줘야합니다.
그래서 코드짤 때 8080 이런 포트를 뚫으라고 코드짜놨습니다.
그래서 이미지 돌릴 컴퓨터에도 8080 포트를 오픈하라고 해야하는데, 그건 이미지 실행할 때 명령줄 수 있습니다.
근데 위처럼 EXPOSE 8080 이런걸 작성해놓으면 나중에 포트 오픈하라고 명령줄 때 약간 편리합니다.
그래서 편의를 위해 쓰는 메모같은 개념입니다. 없어도 상관은 없음.
2. 이미지 만들려면 docker build
1docker build -t 이미지이름:태그 .
Dockerfile 작성했으면 이걸 바탕으로 이미지를 하나 만들어달라고 명령내릴 수 있습니다.
작업폴더에서 터미널 열어서 입력해봅시다.
- 이미지 이름은 맘대로 작명합시다.
- 태그도 맘대로 작명합시다.
태그는 “버전”이랑 비슷하게 취급하면 됩니다. - 마침표 자리에는
Dockerfile 경로입력하면 되는데,마침표는 “현재경로”라는 뜻입니다. - cf.
docker desktop또는docker engine이 실행되고 있어야 이거 명령어도 사용가능합니다.
아무튼 그럼 입력하면 커스텀 이미지가 생성됩니다.
이미지 확인은 docker desktop 들어가보거나, 터미널에 docker images 입력해봅시다.
2.1 이미지 실행하기
만든 이미지 실행 잘 되나 확인해봅시다.
재생버튼 누르거나 docker run 명령어입력하면 되는데, 근데 포트 부분에 8080을 기입해서 실행해봅시다.

▲ 누가 내 컴퓨터 8080번 포트로 들어오면, 가상 컴퓨터의 8080번 포트로 연결하라는 뜻입니다.
뭔 소리인지는 네트워크 시간에 자세히 알아봅시다.
터미널을 사용할 것이면 docker run -p 8080:8080 이미지명:태그명 입력합시다.
아무튼 브라우저 켜서 localhost:8080으로 들어가보면 웹서버를 만날 수 있습니다.
이게 나만의 커스텀 이미지를 만들고 실행하는 법 끝입니다.
이제 이 이미지를 다른 컴퓨터로 보내서 실행만 하면 그게 배포 아니겠습니까.
💡
localhost가 뭐냐면 “내 컴퓨터로 접속하라”는 뜻입니다.
💡 실은
docker init명령어 입력하면,Dockerfile을 약간 자동완성 해주기 때문에, 거기서 필요한거 수정해서 쓰는 방법도 좋습니다.