프로젝트 진행하면서 배포를 직접할 일이 생겼다
보통 잘하는 팀장님이 배포 셋팅을 미리 해줘서 편하게 작업을 했었는데
막상 직접 하려니까 쉬우면 쉽고 어려우면 어려운 복잡한 일이었다
이 글은 도커와 AWS를 공부하면서 참고하기 위해 작성해보는
도커를 이용한 배포 과정, 그 중에서도 Dockerfile 에 대한 작성법이다
📝 Reference
📚 도커, 컨테이너 빌드 업! - 이현룡
📜 Dockerfile
어떠한 컨테이너를 위해 필요한 모든 설정을 기록한 파일
도커 파일을 빌드하면 이미지가 자동으로 생성된다
도커 파일을 통해 특정 컨테이너를 빌드하고 배포하기 위한 과정들을 자동화 할 수 있게 된다
💥 Dockerfile 작성 시 고려할 점
- 컨테이너 서비스의 장점인 경량 가상화 서비스를 지향하기 위해 최소한의 설정과 구성만을 사용
- Dockerfile 명령어 수와 도커 이미지 레이어 수는 동일하다
레이어 수가 늘어나면 빌드 시간이 길어지고 파일 용량이 커지게 된다
따라서 Dockerfile 명령어를 최적화 할 필요가 있다 - 하나의 어플리케이션은 하나의 컨테이너에 담아 결합성을 낮춘다
- Dockerfile은 명령어 단위로 캐싱이 일어난다
이것을 적극 활용하여 빌드 속도를 높힌다 - Dockerfile은 이미지 빌드를 시작하면 현재 위치 포함 하위 디렉토리의 모든 것들을 빌드한다
따라서 별도의 작업 디렉토리를 두어 독립된 환경에서 꼭 필요한 파일만 빌드한다
📚 Dockerfile 명령어 리스트
- FROM : 생성하려는 이미지의 베이스 이미지 지정, 반드시 입력해야함
ex) FROM ubuntu:20.04 - MAINTAINER : 보통 이미지를 빌드한 작성자의 이름 또는 이메일을 입력
ex) MAINTAINER gengminy <gengminy@github.com> - LABEL : 버전, 타이틀, 설명, 라이센스 등 메타 데이터를 입력, 여러 개 입력 가능
ex) LABEL description = 'my web service application' - RUN : 컨테이너 내부에서 실행할 명령어를 지정, 여러 개 입력 가능
ex1 shell 방식) RUN apt update
ex2 exec 방식) RUN ["bin/bash", "-c", "apt -y install nginx git vim curl"] - CMD : 컨테이너가 실행될 때 실행할 명령어, 하나만 입력 가능
ex1 shell 방식) CMD nginx -g deamon off
ex2 exec 방식) CMD ["python", "app.py"] - ENTRYPOINT : CMD 와 마찬가지로 생성된 이미지가 컨테이너로 실행될 때 사용
ex) ENTRYPOINT ["npm", "start"] - COPY : 호스트 환경의 파일이나 디렉토리를 이미지 내부로 복사할 때 사용
빌드 작업 디렉토리 외부 파일은 복사할 수 없다
ex) COPY index.html /usr/share/nginx/html - ADD : 호스트 환경의 파일이나 디렉토리를 이미지 내부로 복사하거나
해당 URL에서 다운로드, 또는 압축파일을 풀어서 추가한다
ex1) ADD index.html /usr/share/nginx/html
ex2) ADD http://dockerhub.com/example.tar.gz /app
ex3) ADD web.tar.gz /var/www/html - ENV : 이미지 내부에 환경 변수를 지정할 때 사용
ex) ENV JAVA_HOME /usr/lib/jvm/java-8-oracle - EXPOSE : 호스트 네트워크를 통해 컨테이너로 들어오는 트래픽을 listening 하기 위한 포트와 프로토콜 지정
ex1) EXPOSE 80
ex2) EXPOSE 8000/tcp - VOLUME : 호스트와 공유하기 위한 컨테이너 볼륨 지정
ex) VOLUME /etc/nginx - USER : 컨테이너 사용자 변경, 기본은 root
ex) USER gengminy - WORKDIR : 컨테이너에서 작업할 경로의 전환을 위한 명령어
ex) WORKDIR /app - ARG : docker build 시점에서 인자 값을 전달하기 위한 명령어
ex) ARG db_name ---> docker bulid --build-arg db_name=my_sql_server - ONBUILD : 현재 이미지가 다른 이미지의 기본 이미지(FROM)로 포함될 경우
다른 이미지가 빌드될 때 실행시킬 명령어 현재 이미지에서는 실행되지 않는다
ex) ONBUILD ADD source.tar.gz /usr/share/nginx - STOPSIGNAL : docker stop 명령어 입력 시 컨테이너에 전달될 signal 지정
ex) STOPSIGNAL SIGKILL - HEALTHCHECK : 컨테이너 프로세스 상태를 체크할 때 작성, 하나만 사용 가능
ex) HEALTHCHECK --interval={체크간격(초)} --timeout={타임아웃(초)} --retries={타임아웃회수} - SHELL : Dockerfile 내부에서 사용할 기본 쉘을 지정
ex) SHELL ["bin/bash", "-c"]
🔨 Dockerfile 직접 작성해보기 (Spring Boot Project)
📝 Dockerfile
FROM openjdk:11
EXPOSE 8000
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
FROM openjdk:11
- 베이스 이미지를 openjdk:11로 지정
EXPOSE 8000
- 8000번 포트를 listening (스프링 프로젝트의 기본 포트는 8080)
ARG JAR_FILE=build/libs/*.jar
- 스프링 프로젝트를 빌드할 때 나오는 결과물을 JAR_FILE 로 지정
COPY ${JAR_FILE} app.jar
- 빌드된 파일을을 app.jar 로 복사
ENTRYPOINT ["java", "-jar", "/app.jar"]
- 생성된 이미지를 컨테이너로 실행하는 시점에 app.jar 실행, 즉 컨테이너 실행과 동시에 서버를 실행함
🔨 스프링 프로젝트 Gradle 빌드
./gradlew build -x test
-x test : 테스트 없이 빌드하겠다는 의미
🚀 Dockerfile 빌드
docker build [플래그] 이미지명:[태그] 경로|URL|압축파일
- [플래그]
-t : tag를 지정하는 옵션
-f : Dockerfile 이외의 다른 파일명을 지정하는 옵션
--platform : 애플 M1의 경우 플랫폼을 linux/amd64 로 지정해주어야 빌드가 됨 - 이미지명:[태그]
생성할 이미지 이름 및 태그를 지정, 태그는 보통 버전 관리용으로 지정 - 경로 | URL | 압축파일
디렉토리 경로나 Dokerfile 이 포함된 깃허브 url, 또는 압축파일을 지정한다
📝 예시
docker build -t {username}/{imagename} .
반드시 마지막에 Dockerfile 의 경로를 표시해주어야 한다
여기서는 현재 디렉토리에 Dockerfile 이 있기 때문에 점을 찍는다
만약 Docker hub 에 이미지를 올릴 것이라면
반드시 {username} 에 본인의 유저 이름이 들어가야 한다
아니면 권한 거부가 일어날 것이다
혹시라도 docker deamon is not runnig 오류가 나온다면
docker desktop 을 실행하고 빌드하면 된다
🚀 Docker image push
빌드한 도커 이미지를 도커 허브에 푸시하는 과정이다
도커 허브 아이디가 없다면 만들어야 한다
docker login
docker login 명령어 실행 후
docker hub 에 로그인 한다
docker push {username}/{imagename}
리모트 레포지토리에 성공적으로 올라간 모습
나중에 배포 서버에서 도커 허브에 접근하여
이 이미지를 내려받으면 손쉽게 배포 세팅을 끝마칠 수 있다
배포 서버에서 도커 이미지 실행만 하면 되니까 얼마나 편한가
나중에 Github Action 이랑 연동하면
깃헙에 푸시 하자마자 도커 이미지 빌드 및 푸시까지 자동으로 해줄 수 있다
따라하면서 해보니까 꽤 재밌다
끝
'🏭 Infra > 🐳 Docker' 카테고리의 다른 글
[Docker] docker compose로 다중 컨테이너 연결 시 Connection to localhost:5432 refused 에러 (0) | 2022.08.07 |
---|---|
[Docker] docker compose 사용해서 다중 컨테이너 띄우기 (0) | 2022.08.07 |