도커의 꽃이라고 할 수 있는 도커파일에 대해 알아보고 어떤 명령어가 있는지 어떻게 사용하는지 알아보도록 하겠다.
Dockerfile이란 도커 이미지를 작성할 때 실행시키는 스크립트 파일이다.
Dockerfile 작성하기
내 user에 들어가서 dockerfile을 작성해보겠다.
vi 에디터를 통해 간단히 도커파일 커맨드를 적어보자.
파일 이름은 무조건 Dockerfile로 저장해야 한다. dockerfile.txt 이런거 안된다.
FROM httpd
COPY ./webapp /usr/local/apache2/htdocs
CMD ["httpd-foreground"]
FROM
- 기본이 될 이미지 지정. Dockerfile의 첫 번째 명령어로 사용되며 이후의 명령어들은 모두 이 기본 이미지 위에서 실행된다.
COPY
- 로컬 파일 시스템에서 Docker 컨테이너의 파일 시스템으로 파일이나 디렉토리를 복사한다. 빌드 컨텍스트에서 파일을 컨테이너 이미지로 복사하는 데 사용된다.
- 이 명령어에선 ./webapp 디렉토리내용을 /usr/local/apache2/htdocs 에 복사하라는 의미 를 가진다.
CMD
- 컨테이너가 시작될 때 실행될 명령어를 지정한다. Dockerfile 내에서 단 한 번만 사용 가능하다.
- 여러 개의 CMD를 입력해도 맨 마지막 CMD만 유효하다.
COPY는 -v (volume)과의 차이가 있다.
-v는 run 옵션 중 하나이다. COPY는 복사이고 -v는 링크를 거는 것이므로 COPY파일은 수정해도 원본이 바뀌지 않지만 -v로 지정된 파일을 컨테이너에서 수정하게 된다면 HOST에 있는 원본 파일이 수정된다.
리눅스의 하드링크 소프트링크를 생각하면 된다.
Dockerfile 빌드하기
docker build -t [생성할이미지명]:[태그명] [dockerfile위치(경로)]
docker build -t webserver ./
docker build 명령어는 Dockerfile을 사용하여 Docker 이미지를 빌드하는 용도로 사용한다.
-t 옵션은 빌드된 이미지에 태그를 지정하는 데 사용된다.
태그를 지정함으로써 이미지를 쉽게 식별할 수 있다.
Dockerfile을 통해 빌드한 이미지는 docker images 명령어를 통해 확인할 수 있다.
다음으로 배울 명령어는 WORKDIR와 ADD, ENTRYPOINT이다.
FROM openjdk:11-jdk-slim
WORKDIR /app
COPY build/aws-v3-0.0.3.jar ./application.jar
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=dev", "application.jar"]
#CMD ["--server.port=8080"]
aws -v3-0.0.3.jar은 메타코딩 유튜브님의 깃허브에서 가져왔다.
https://github.com/codingspecialist/aws-v3
GitHub - codingspecialist/aws-v3: elastic bean stalk
elastic bean stalk. Contribute to codingspecialist/aws-v3 development by creating an account on GitHub.
github.com
다운받을 때는 release 브랜치로 바꾼 후 경로에 잘 추가해주면 된다.
각설하고 명령어를 소개하겠다.
WORKDIR
- Docker 이미지 빌드 과정에서 작업 디렉토리를 설정한다. 이후의 명령어들은 모두 이 디렉토리에서 실행된다.
- 사용자가 터미널로 접근 했을 경우에도 /app 디렉토리로 바로 접근되게 만든다.
- WORKDIR /app은 모든 작업 디렉토리를 /app으로 설정한다는 뜻이다.
ADD
- ADD 명령어는 호스트 시스템의 파일이나 디렉토리를 이미지에 추가하거나 URL에서 파일을 다운로드하여 추가한다.
- COPY와 유사하나 .zip 파일도 자동으로 압축 해제하는 기능이 있다.
- 압축파일을 푼 상태로 추가하고 싶다면 ADD를 쓰면 된다.
ENTRYPOINT
- 컨테이너가 시작될 때 실행할 명령어를 설정한다.
- CMD와 비슷하나 ENTRYPOINT로 설정된 명령어는 항상 실행된다.
- 파라미터로 넘겨받은 것들을 합쳐서 컨테이너 실행 시 실행시킨다.
- Dockerfile을 빌드해서 컨테이너가 실행되면 java-jar-Dspring.profiles.active=dev.application.jar 명령어가 /app 디렉토리에서 자동으로 실행되는 것이다.
- CMD는 ENTRYPOINT의 파라미터로 넘겨지기도 한다.
예를 들자면
CMD ["--server.port=3000"]
이렇게 해놓아도
docker run -d -p 9097:5000 java-server --server.port=5000
컨테이너를 실행할 때 위와 같이 실행시키면 --server.port=5000 으로 실행된다. (Dockerfile에 있는 CMD 대체)
무조건 실행되어야 할 것들은 ENTRYPOINT로 실행하면 되고 run 할 때마다 바꿀 수 있는 것들은 CMD로 설정하는 정도의 차이라고 생각하면 될 것 같다.
만약 ENTRYPOINT가 있는 상태에서 Dockerfile에 CMD를 추가하면?
간단한 예시를 들어보자.
docker run -d -p 9097:8081 java-server1:0
현재는 Dockerfile의 CMD 명령어가 없는 상태에서 spring.profile.active=dev가 실행되어 자동으로 8081이 기본포트로 잡힌다. ENTRYPOINT로 -Dspring.profiles.active=dev를 설정하였기 때문이다.
여기서 CMD를 추가해보자.
FROM openjdk:11-jdk-slim
WORKDIR /app
COPY build/aws-v3-0.0.3.jar ./application.jar
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=dev", "application.jar"]
CMD ["--server.port=8080"]
이렇게 되면 8080포트가 잡힌다.
마지막에 --server.port=8080명령어가 실행되었기 때문이다.
그런데 Dockerfile에 CMD가 있다 하더라도 run 옵션에서 포트를 다른 것으로 추가하면 이것이 CMD 명령어를 대체하게 된다.
docker run -d -p 9097:8800 java-server:1.0 --server.port=8800
이렇게 하게 되면 8800번으로 tomcat이 실행된다.
마지막으로 Dockerfile의 RUN에 대해 알아보자.
RUN 명령어는 Dockerfile에서 리눅스의 명령어를 실행하고 싶을 때 사용한다. 먼저 도커파일을 작성해보자.
FROM ubuntu
RUN apt-get update
RUN apt-get install -y nginx
WORKDIR /var/www/html
COPY ./webapp/index.html ./index.nginx-debian.html
ENTRYPOINT ["nginx", "-g", "daemon off;"]
FROM ubuntu
- ubuntu를 base로 해서 처음부터 설치하는 방식으로 실습했다.
RUN apt-get update
RUN apt-get install -y nginx
- 컨테이너 실행될 때 리눅스 명령어 실행.
- RUN apt-get update apt-get은 패키지 관리 도구를 사용하여 패키지를 업데이트하고 설치하는 데 사용.
- RUN apt-get install -y nginx은 nginx 웹 서버 설치.
WORKDIR /var/www/html
- 작업 디렉토리를 /var/www/html로 설정.
COPY ./webapp/index.html ./index.nginx-debian.html
- HOST내용물을 CONTAINER로 복사한다.
- (호스트)./webapp/index.html → (컨테이너) /var/www/html/index.nginx-debian.html 로 복사한다.
ENTRYPOINT ["nginx", "-g", "daemon off;"]
- 컨테이너가 시작될 때 Nginx 웹 서버를 포그라운드 모드로 실행하도록한다.
- 데몬 모드라는 것은 원래 백그라운드로 실행하라는 것인데 이것을 -g "daemon off; 를 통해 꺼둔 것이다.
- nginx를 백그라운드로 실행하면 컨테이너가 실행하자마자 죽어버리기 때문이다.(더 이상 실행할 명령어가 없다고 판단)
이제 작성된 Dockerfile을 기반으로 이미지를 빌드하자
docker build -t nginx-server:2.0 ./
docker build -t [생성할이미지명][생성할태그] [Dockerfile 위치] 이 기본 형태이다.
여기선 Docker 이미지 빌드를 실행하는 docker build 명령어와 태그 지정할 때 쓰이는 -t,
생성할 이미지명인 nginx-server, 생성할 태그인 2.0, 경로인 ./을 사용했다.(./은 현재 위치의 디렉토리를 의미하는 상대 경로)
docker images를 통해 이미지 생성이 되었는지 확인하고
docker run -d -p 8080:80 nginx-server:2.0으로 빌드된 이미지를 실행하면
이렇게 실행 완료된 결과를 확인할 수 있다.
다음 시간엔 docker-compose에 대해 자세히 알아보겠다.
'가상화 > Docker' 카테고리의 다른 글
[docker] Volume 옵션으로 폴더 연결하기 (32) | 2024.07.19 |
---|---|
[docker] exec 명령어 (33) | 2024.07.11 |
[docker] dit 옵션과 attach (27) | 2024.07.09 |
포트포워딩 알아보기 (feat. Docker) (52) | 2024.06.26 |
도커(Docker)란? (61) | 2024.06.11 |