위 사진과 같이 프로젝트 하위에 Dockerfile 이라는 파일을 생성하고 아래 내용을 작성합니다.
FROM openjdk:8-jdk-alpine
// FROM amazoncorretto:11 ==> amazon corretto 11 사용할 경우
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
// ENTRYPOINT ["java","-jar","-Dspring.profiles.active=prod","/app.jar"]
// => 설정파일을 분리해서 사용할 때
// java -jar -Dspring.profiles.active=prod app.jar
위 코드에 대한 설명을 간략히 나타내면 다음과 같습니다.
FROM amazoncorretto:11
위의 커맨드는, Docker를 올릴 때 jdk11 버전을 이용해서 올리겠다라고 선언하는 커맨드입니다.
ARG JAR_FILE=build/libs/*.jar
위의 커맨드는, JAR 파일의 위치를 환경변수의 형태로 선언하는 것입니다. 프로젝트를 빌드하게되면 build/libs/xxxx.jar 의 형태로 jar file이 생성이 되어있을텐데요, 그 파일의 위치를 변수로 저장하는 것입니다.
COPY ${JAR_FILE} app.jar
위의 커맨드는, 프로젝트의 jar 파일 위치를 참조하여 jar 파일을 가져와서 컨테이너의 루트 디렉토리에 app.jar의 이름으로 복사하는 커맨드입니다.
ENTRYPOINT ["java","-jar","/app.jar"]
위의 커맨드는, 도커파일이 도커엔진을 통해서 컨테이너로 올라갈 때, 도커 컨테이너의 시스템 진입점이 어디인지를 선언하는 커맨드입니다.
위의 커맨드에서는, java -jar 명령어를 이용해서 컨테이너의 루트에 위치한 app.jar을 실행하라는 뜻의 커맨드입니다
Mac , Android Studio 환경에서 터미널로 앱 빌드를 하고 싶으면
./gradlew build
위와 같은 명령어로 빌드를 실행할 수 있다.
bash: ./gradlew: Permission denied
그러나 위와 같이 Permission denied 가 발생하면
chmod +x gradlew
⚠️ chmod +x gradlew 를 터미널에 입력 한 후, 다시 ./gradlew build 를 실행하면 빌드가 되는 것을 확인 할 수 있다.
(gradlew 빌드 실패시 명령창에 나온 주소 클릭하면 원인을 알 수 있어 원인제거 하면 빌드 성공)
그러면 libs에 jar파일이 두개 생성됨을 알 수 있다.
애플 M1의 경우 도커 이미지로 빌드할 때 --platform 옵션을 사용해야 한다.
이 문제는 깃허브에 자세히 나와있다.
애플 M1의 경우 아래와 같이 입력하면 성공
// gradle
docker build --build-arg DEPENDENCY=build/dependency -t 도커허브 ID/Repository --platform linux/amd64 .
// maven
docker build -t 도커허브 ID/Repository --platform linux/amd64 .
docker build --build-arg DEPENDENCY=build/dependency -t jeonghyewon/searchgym --platform linux/amd64 .
위에서 생성한 docker image 파일을 Docker Hub에 push를 해줍니다.
push 명령어는 docker hub의 Repository에 보면 확인할 수 있다.
docker push jeonghyewon/searchgym
만약 위와 같이 denied: requested access to the resource is denied 라는 문구가 나오면 로그인을 해주어야 한다.
docker login
도커 아이디로 로그인에 성공하면 다시 푸시 명령어를 입력한다.
docker login 명령어를 통해 로그인을 한 뒤 다시 push하면 정상적으로 push가 되고, docker hub의 Repository에
새로운 TAG(latest)가 생성된 걸 확인할 수 있습니다.
생성부분은 생략 ~~ 합니다
이제 우리는 SSH 로 EC2 인스턴스 서버에 접속할 수 있다.
하지만 위에서 본 것처럼 매번 ssh -i {키 페어 파일} {ubuntu}@{탄력적 IP}
를 입력해야 합니다.
일일히 기억하기도 귀찮고 타이핑도 번거롭기 때문에 호스트로 등록해서 쉽게 접속할 수 있도록 변경해본다.
우선 키 페어 파일을 ~/.ssh/
로 복사
$ cp my-key.pem ~/.ssh/
키 페어 파일의 권한을 변경
$ chmod 600 my-key.pem
~/.ssh/
디렉터리에 config
파일을 생성해서 다음과 같이 입력한다.
이미 파일이 존재한다면 맨 아래에 입력하면 된다.
User 는 우분투를 선택했다면 ubuntu 고 그 외에는 전부 ec2-user .
$ vi ~/.ssh/config
# 아래는 파일 내용# ssh -i {키 페어 파일} {유저 이름}@{탄력적 IP}
Host {원하는 호스트 이름}
User {유저 이름}
HostName {탄력적 IP}
IdentityFile {키 페어 파일 위치}
도커 설치
$ sudo yum install docker
## yum 안되면 apt 로 설치 하기
도커 실행
$ sudo systemctl start docker
입력했을 때
아래와 같이 에러 발생시
ubuntu@ip-172-31-2-147:~$ sudo systemctl start docker
Failed to start docker.service: Unit docker.service not found.
curl -sSL https://get.docker.com/ | sh
으로 다시 설치해준다. 설치 후 다시 도커 실행 명령어 실행
$ sudo systemctl start docker
그 다음에 docker가 정상적으로 동작하고있는지 확인해봅시다.
$ systemctl status docker
도커 허브에 존재하는 이미지 파일 pull
$ sudo docker pull jeonghyewon/searchgym
도커 이미지를 통해 스프링 부트 애플리케이션 배포(실행)
$ sudo docker run -p 8080:8080 jeonghyewon/searchgym
했는데 에러발생!!!!!
해당 컨테이너를 restart 했을 때 에러 발생 (docker 가 정상적으로 종료되지 않아 발생한 에러인 듯)
포트가 이미 할당되어 있어서 발생한 에러로 해당 포트를 사용 중인지 확인
lsof -i :포트번호 # 해당 포트 번호
강제종료 시키기
kill -9 [PID]
다시 도커 이미지를 통해 스프링 부트 애플리케이션 배포(실행)
sudo docker run -p 8080:8080 jeonghyewon/searchgym
그 다음에 docker가 정상적으로 동작하고있는지 확인해봅시다.
$ systemctl status docker
도커 이미지를 통해 스프링 부트 애플리케이션이 정상적으로 실행이 된다.
최종적으로 AWS의 IP로 접속해보거나 도메인으로 접속하면 정상적으로 배포가 된 걸 확인할 수 있다.
Docker를 이용하여 EC2 서버에 배포하는 방법은 다음과 같다.
AWS EC2 콘솔에 접속하여 인스턴스를 생성합니다.
생성한 인스턴스에 SSH로 접속하여 필요한 설정들을 진행합니다. (예: 보안 그룹 설정, 패키지 업데이트, Docker 설치 등)
AWS EC2 인스턴스에 SSH로 접속하여, Docker 이미지를 pull합니다.
Docker 이미지를 이용하여 컨테이너를 실행합니다.
(예: docker run -p <호스트 포트>:<컨테이너 포트> <ECR 주소>/<이미지명>:<태그>)
위와 같은 방법으로 Docker를 이용하여 EC2 서버에 배포할 수 있.