5.1 이미지를 생성하는 방법
5.1.1 컨테이너로 이미지를 생성
개발한 애플리케이션을 컨테이너화 할 때 가장 먼저 정석적인 방법은 아래와 같다.
1, 아무것도 존재하지 않는 이미지(우분투, CentOS 등)로 컨테이너를 생성
2.애플리케이션을 위한 환경을 설치하고 소스코드 등을 복사해 잘 동작하는 것을 확인
3.컨테이너를 이미지로 커밋

이 방법을 사용하면 애플리케이션이 동작하는 환경을 구성하기 위해 하나 하나 수작업으로 패키지 설치하고, 소스코드를 깃(Git)에서 복제하거나 호스트에서 복사해야한다.
이를 하면 직접 컨테이너에서 애플리케이션을 구동해보고 이미지로 커밋하기 때문에 이미지의 동작을 보장할 수 있다는 점이 있다.
5.1.2 Dockerfile로 이미지를 생성
Dockerfile을 사용하면 직접 컨테이너를 생성하고 이미지로 커밋해야 하는 번거로움을 덜 수 있을 뿐만 아니라 깃과 같은 개발 도구를 통해 애플리케이션의 빌드 및 배포를 자동화할 수 있다.
어떻게 해야하는가?

5.1.1의 과정을 손쉽게 기록하고 수행할 수 있는 빌드(build) 명령어를 제공한다.
그리고 완성된 이미지를 생성하기 위해 컨테이너에 설치하는 패키지, 추가해야 하는 소스코드, 실행해야 하는 명령어와 쉘 스크립트 등을 하나의 파일에 기록해두면 도커는 이 파일을 읽어 컨테이너에서 작업을 수행한 뒤 이미지로 만들어낸다.
여기서, 이러한 작업을 기록한 파일의 이름을 Dockerfile 이라 하며, 빌드 명령어는 Dockerfile을 읽어 이미지를 생성하게 된다.
5.1.3 도커 허브에 올려져 있는 Dockerfile 이미지를 사용해 빌드
배포되는 이미지를 신뢰할 수 없거나 직접 이미지를 생성해서 사용하고 싶다면 도커 허브에 올려져 있는 Dockerfile로 빌드하는 것도 하나의 방법이다.
실제로 도커 허브에 올려져 있는 대부분의 이미지는 Dockerfile을 함께 제공하고 있기 때문이다.
여기서 확인이 가능하다. https://hub.docker.com/_/ubuntu
하지만 애플리케이션을 컨테이너화하기 위한 장기적인 시점에서 본다면 Dockerfile을 작성하는 것은 이미지를 생성하는 방법을 기록하는 것 뿐만 아니라 이미지의 빌드, 배포 측면에서도 매우 유리하다.
애플리케이션에 필요한 패키지 설치 등을 명확히 할 수 있고, 이미지 생성을 자동화 할 수 있으며, 쉽게 배포 할 수 있기 때문이다.
5.2 Dockerfile 작성
Dockerfile에는 컨테이너에서 수행해야 할 작업을 명시한다.
이 작업을 위해서 Dockerfile에서 쓰이는 명령어를 알아 둘 필요가 있다.
1. 디렉터리 파일 생성
mkdir hellojs(디렉토리 이름)
2.컨테이너 파일 소스 작성하기
#vi hello.js
const http = require('http');
const os = require('os');
console.log("Test server starting...");
var handler = function(request, response){
console.log("Received request from " + request.connection.remoteAddress);
response.writeHead(200);
response.end("Container Hostname: " + os.hostname() + "\n");
};
var www = http.creatServer(handler);
www.listen(8080);
3. Dockerfile 소스 작성하기
#vi Dockerfile
FROM ubuntu:18.04
LABEL maintainer="JY LEE <jy@gmail.com>"
# install apache
RUN apt-get update \
&& apt-get install -y apache2
RUN echo "TEST WEB" > /var/www/html/index.html
EXPOSE 80
CMD ["/usr/sbin/apache2ctl", "-DFOREGROUND"]
1) 도커 엔진은 Dockerfile을 읽어 들일 때 기본적으로 현재 디렉토리에 있는 Dockerfile이라는 이름을 가진 파일을 선택한다.
2) 이미지 빌드할 때 컨텍스트(Context)때문에, Dockerfile은 빈 디렉터리에 저장하는 것이 좋다.
3) Dockerfile은 한 줄이 하나의 명령어가 되고, 명령어를 명시한 뒤에 옵션을 추가하는 방식이다.
4) 명령어를 소문자로 표기해도 상관은 없지만 일반적으로 대문자로 표기한다.
5) Dockerfile의 명령어는 위에서 아래로 한 줄씩 차례대로 실행된다.
6) Dockerfile에 사용되는 명령어
FROM)
- 생성할 이미지의 베이스가 될 이미지를 뜻한다.
- Dockerfile을 작성할 때 반드시 한 번 이상 입력해야 한다.
- 이미지 이름의 포맷은 docker run 명령어에서 이미지 이름을 사용했을 때와 같다.
- 사용하려는 이미지가 도커에 없다면 자동으로 pull한다.
MAINTAINER)
- 이미지를 생성한 개발자의 정보를 나타낸다.
- 일반적으로 Dockerfile을 작성한 사람과 연락할 수 있는 이메일 등을 입력한다.
- docker 1.13.0 버전 이후로는 사용하지 않는다. 대신 LABEL로 교체해 표현 할 수 있다.
LABEL)
- 이미지에 메타데이터를 추가한다.
- 메타데이터는 '키:값'의 형태로 저장되며, 여러 개의 메타데이터가 저장될 수 있다.
- 추가된 메타데이터는 DOCKER inspect 명령어로 이미지의 정보를 구해서 확인할 수 있다.
RUN)
- 이미지를 만들기 위해 컨테이너 내부에서 명령어를 실행한다.
- 해당 예제에서는 apt-get update와 apt-get install apache2 명령어를 실행하기 때문에 아파치 웹 서버가 설치된 이미지가 생성된다.
-RUN 명령어를 아래와 같이 작성할 수 있다.
RUN apt-get update
RUN apt-get install apache2 -y
만약 이와 같이 작성하면 '-y' 옵션을 쓸 수 있는데, 이 옵션은 Dockerfile을 이미지로 빌드하는 과정에서는 별도의 입력이 불가능하기 때문에 해당 명령어를 설치할 것인지 선택하는 Y/N을 YES로 설정해야한다. 설정하지 않으면 build 명령어는 이를 오류로 간주하고 빌드를 종료한다.
EXPOSE)
- Dockerfile의 빌드로 생성된 이미지에서 노출할 포트를 설정한다.
- 단, EXPOSE를 설정한 이미지로 컨테이너를 생성했다고 해서 반드시 이 포트가 호스트의 포트와 바인딩되는 것은 아니다. 다만 80번 포트를 사용할 것임을 나타내는 것 뿐이다.
- EXPOSE는 컨테이너를 생성하는 run 명령어에서 모든 노출된 컨테이너의 포트를 호스트에 퍼블리시(Publish)하는 -p 플래그(flag)와 함께 사용된다.
ADD)
- 파일을 이미지에 추가한다.
- 추가하는 파일은 Dockerfile이 위치한 디렉터리인 컨텍스트(Context)에서 가져온다.
- Dockerfile이 위치한 디렉터리에서 파일을 가져온다.
- Dockerfile이 위치한 디렉터리에서 "TEST WEB"이 /var/www/html/index.html 디렉터리에 추가되고 출력된다.
- ADD 명령어는 JSON 배열의 형태로 ["추가할 파일 이름", .... "컨테이너에 추가될 위치"]와 같이 사용이 가능하다. 추가할 파일명은 여러개 지정이 가능하며, 마지막 배열의 원소는 컨테이너에 추가될 위치이다.
CMD)
- 컨테이너가 시작될 때마다 실행할 명령어(커맨드)를 설정하며, Dockerfile에서 한번만 사용할 수 있다.
- Dockerfile에 CMD를 명시함으로써 이미지에 apachectl -DFOREGROUND라는 커맨드를 내장하면 컨테이너를 생성할 때 별도의 커맨드를 입력하지 않아도 이미지에 내장된 apachectl- DFOREGROUND 커맨드가 적용되어 컨테이너가 시작될 떄 자동으로 아파치 웹 서버가 실행될 것이다.
- 아파치 웹 서버는 하나의 터미널을 차지하는 포그라운드 모드로 실행되기 때문에 -d 옵션을 사용해 detached 모드로 컨테이너를 생성해야 한다. 즉, CMD는 run 명령어의 이미지 이름 뒤에 입력하는 커맨드와 같은 역할을 한다. docker run 명령어에서 커맨드 명령줄 인자를 입력하면 Dockerfile에서 사용한 CMD의 명령어는 run의 커맨드로 덮어쓰인다.
5.3 Docker build
앞에 만든 Dockerfile을 빌드해 보자.
빌드 명령어는 다음과 같다.
guru@docker-ubuntu:~/webserver$ docker build -t webserver:v1 .
build 명령어 끝에는 Dockerfile이 저장된 경로를 입력한다.
일반적으로 로컬에 저장된 Dockerfile을 사용하지만 외부 URL로부터 Dockerfile의 내용을 가져와 빌드할 수 있다.
이 예시에서는 로컬에 Dockerfile을 저장했으므로 .(현재 디렉터리)를 입력했다.
최종적으로 webserver이라는 이름의 이미지가 생성된다.
다음 명령어를 통해 생성된 이미지로 컨테이너를 실행한다.
guru@docker-ubuntu:~/webserver$ docker run -d -p 80:80 --name web webserver:v1
3471ab4e7ae342702ba6bfd4b24dc79d3317ae0f45b139b70a8a0b5417d299bd
<옵션>
-d: 백그라운드
-p: 포트 설정, 이미지에 설정된 EXPOSE의 모든 포트를 호스트에 연결하도록 설정한다.
해당 예시는 Dockerfile에 EXPOSE를 80번으로 설정했으므로, 이는 이미지에 '컨테이너의 80번 포트를 사용한다'는 것을 의미한다. 개발자는 이미지가 실제로 사용될 때 어떤 포트가 사용돼야 하는지를 명시할 수 있다. 이미지를 사용하는 입장에서는 컨테이너의 애플리케이션이 컨테이너 내부에서 어떤 포트를 사용하는 지 알 수 있게 된다.
docker port 컨테이너 이름 or docker ps 명령어로 컨테이너와 연결된 호스트의 포트를 확인할 수 있다. 확인한 호스트의 IP와 이 포트로 컨테이너의 웹 서버에 접근 할 수 있다.
-t: 생성될 이미지의 이름 설정
(만약, -t 옵션을 사용하지 않는다면 16진수 형태의 이름으로 이미지가 저장되므로 가급적이면 -t 옵션을 사용하는 것이 좋다.)
5.4 build 과정
- 이후 다른 포스트로 추가
5.5 기타 Dockerfile 명령어
- 이후 다른 포스트로 추가
5.6 Dockerfile로 빌드할 때 주의할 점
- 하나의 명령어를 '\'(역슬래시)로 나눠서 가독성을 높일 수 있도록 작성하는 것이 좋다.
RUN apt-get update \
&& apt-get install -y apache2
- '.dockerignore 파일'을 작성해 불필요한 파일을 빌드 컨텍스트에 포함하지 않는 것이 있다.
- 빌드 캐시를 이용해 기존에 사용했던 이미지 레이어를 재사용하는 방법이 있다.
- 이미지 레이어 수를 최소화하는 것이 좋다. 그러기 위해서는 다음과 같이 하나의 명령어를 '&&' 연결해서 작성하면 된다.
FROM ubuntu:14.04
RUN mkdir /test && \
fallocate -l 100m /test/dummy && \
rm /test/dummy
'Cloud Dev > Docker' 카테고리의 다른 글
| 4. Docker Container 기초 사용법 (0) | 2022.04.11 |
|---|---|
| 3. 도커 컨테이너(Docker Container) (0) | 2022.04.11 |
| 2. 도커 이미지(Docker image) (0) | 2022.04.11 |
| 1. Docker (0) | 2022.04.11 |