[작성일: 2023. 09. 10]
AWS ec2 배포를 해보고 이번에는 Docker + ec2 배포를 했다.
ec2 배포는 엄청난 실패와 반복을 겪고 명령어까지 다 외워버린 상태이기 때문에 따로 기록은 하지 않았지만 Docker는 기록을 해보려고 한다.
사전 준비물
- AWS EC2 인스턴스 세팅 (https://aws.amazon.com/ko)
- Docker Hub 회원가입 및 리포지토리 생성 (https://hub.docker.com)
배포 과정(요약)
- Dockerfile을 build 해서 docker image 파일을 생성한다.
- docker image 파일을 docker hub에 push 한다.
- 서버(AWS EC2)에서 docker hub에 존재하는 docker image 파일을 pull로 받아온다.
- docker run 명령어를 통해 docker image 파일을 실행한다.
Dockerfile 생성
우선 인텔리제이 프로젝트 제일 상단 루트에 Dockerfile을 만든다. src가 아니라 build.gradle이랑 같은 위치에 만들어주면 된다.
Dockerfile을 만들면 확장 프르그램을 설치하라고 뜨는데 설치해주고 나면 이미지 생성이 가능해진다.
그다음 Dockerfile에 도커 이미지를 생성하는 설정을 작성해 주면 된다.
FROM openjdk:17-jdk
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
- FROM openjdk:17-jdk : 기본 이미지로 openjdk:17-jdk를 사용하겠다는 의미로 OpenJDK17 버전의 Java Development Kit이 포함된 이미지이다.
- ARG JAR_FILE=build/libs/*.jar
- ARG : Dockerfile 안에서 사용할 변수를 정의한다.
- JAR_FILE이라는 변수를 build/libs/*. jar로 초기화한다.
- Java 애플리케이션의 JAR 파일 경로를 가리킨다.
- COPY ${JAR_FILE} app.jar
- COPY 명령어는 파일이나 디렉터리를 이미지에 추가한다.
- ${JAR_FILE}은 이전에 정의한 JAR 파일의 경로를 의미한다.
- 이미지 내의 app.jar로 복사하고 이미지 내에서 애플리케이션은 app.jar라는 이름으로 접근할 수 있게 된다.
- ENTRYPOINT ["java", "-jar", "app.jar"]
- ENTRYPOINT는 도커 컨테이너가 시작될 때 실행할 명령어를 설정한다.
- java -jar app.jar 명령어가 실행되어 app.jar파일이 시작되게 된다.
작성이 완료되었다면 gradle clean ➡️ build 후 git에 push 한다.
이후 과정은 AWS EC2 배포할 때와 같다. AWS 서버 접속 후 git clone을 하고 ./gradlew build까지만 진행한다.
Docker Image 만들기
git clone까지 하고 나서 리포지토리로 이동한다.
docker build -t 도커아이디/도커 리포지토리 이름 .
// 예시
docker build -t username/repository:tag .
- -t
- --tag를 의미하며 이 옵션은 이미지에 이름과 태그를 부여하는데 사용된다.
- username/repository는 이미지의 이름이고 :tag는 해당 이미지의 버전, 상태를 나타낸다.
- -t 옵션을 사용하지 않으면 Docker는 자동으로 임시 이름을 부여한다.
- .
- docker build 명령어의 마지막에 있는 .는 Dockerfile이 있는 현재 디렉토리를 가리킨다.
- Docker는 이 위치에서 Dockerfile을 찾아 이미지를 빌드하는데 사용한다.
- 이미지 태그의 중요성
- 태그는 특정 이미지의 버전 또는 상태를 구분한데 사용한다.
- 예를 들어 애플리케이션의 여러 버전들을 Docker 이미지로 만들었다면 각 버전에 대한 이미지에 다른 태그를 부여하여 구분할 수 있다.
- :latest는 특별한 태그로, 특정 태그 없이 이미지를 빌드하거나 가져올 때 사용되는 기본값이다.
이미지가 잘 생성됐는지 확인하려면 docker images 명령어로 확인할 수 있다. (docker hub에서도 확인 가능!)
기타 명령어
- Push : docker login ➡️ docker push 도커아이디/리포지토리 이름
- 푸시하기 전 도커에 로그인을 해야 한다.
- 이미지 생성 후 바로 Hub에 push 하지 말고 이미지가 올바르게 작동하는지 로컬에서 테스트해 보는 것도 좋다.
- Pull : docker pull 도커아이디/리포지토리 이름
Docker 실행하기
docker run -d -p 8080:8080 도커아이디/리포지토리:이미지 이름
// 예시
docker run -d -p 8080:8080 dockerId/hello:latest
- -d
- --detach를 의미한다.
- 컨테이너를 백그라운드에서 실행하도록 한다.
- 컨테이너가 실행되는 동안 터미널이나 명령 프롬프트에 출력되는 로그를 보여주지 않고 새로운 커맨드 라인 프롬프트를 반환한다.
- -p
- --publish를 의미한다.
- 호스트의 포트와 컨테이너의 포트를 연결(바인딩)한다.
- -p 8080:8080은 호스트의 8080 포트와 컨테이너의 8080 포트를 연결한다는 뜻이다.
- 이를 통해 외부에서 컨테이너의 서비스에 액세스 할 수 있게 된다.
여기까지 됐다면 AWS ip로 접속할 수 있게 된다.
배포는 개발의 마지막 단계지만 가장 까다롭고 복잡한 부분 중 하나라고 생각한다.
처음에는 설정(특히 DB...)이나 명령어에 익숙하지 않아 어려움도 많고 수많은 build 실패가 있었지만 반복적인 연습을 통해 점차 익숙해졌고 지금은 명령어를 다 외워버렸다. 많은 시도 끝에 배포 고비를 쉽게 넘길 수 있었던 거 같다.