이번 프로젝트를 진행하는데 백엔드와 CI/CD 파트를 맡게 되었다. 고로 스프링부트로 프로젝트를 만든다음 배포를 하게되었는데 그때의 과정을 기록하면 추후에 프로젝트를 다시 할때 도움이 될까 하여 기록하게 되었다.
일단 스프링부트로 내가 만든 프로젝트가 잘 동작하는지를 확인했고 이제 배포만 하면 되었다
고로 먼저 나의 스프링 파일을 Docker Container로 만들어야한다. 컨테이너로 만들기 위해서는 먼저 Dockerfile을 작성해야한다.
FROM openjdk:17-alpine
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
저 같은 경우에는 자바17에서 작업을 하여 openjdk:17로 적었습니다. 이 과정에서 뒤에 붙는 alpine이 있었는데 이것은 alpine linux는 경량화를 추구하면서 보안을 강화한 이미지로 꼭 필요한 라이브러리와 시스템 데몬이 포함되어 있기 때문에 일반적인 OS이미지에 비해서 그 사이즈가 매우작다.
[출처: https://bcho.tistory.com/1356 [조대협의 블로그:티스토리]]
조금더 다양한 openjdk를 가져오고 싶다면 아래의
https://hub.docker.com/_/openjdk 를 접속해서 슬림버전을 가져오는것이 제일 좋을 것 이다.
고로 이 도커파일의 의미는
openjdk:17 버전의 환경 구성
build 되는 시점에 JAR_FILE 경로에 jar 파일 생성
JAR_FILE을 app.jar에 복사후 jar 파일 실행 명령
[출처: https://9keyyyy.tistory.com/39 [9keyyy]]
그럼 이제 도커파일로 Build를 해보겠습니다
docker build --platform linux/amd64 -t {DOCKER_REPO} .
나의 환경은 macOS이기 때문에 앞에 --platform을 이용하여 리눅스환경임을 알려주었다.
이렇게 빌드를 하게 되면
이런식으로 빌드가 된 것을 알 수 있습니다.
빌드를 했으면 이제
docker push {DOCKER_REPO}
이렇게 푸쉬를 하게 되면
푸쉬가 되는것을 확인할 수 있습니다. 저는 이미 해놔서 저렇게 레이어가 이미 있다고 뜨네요 ㅎㅎ
그럼 이렇게 도커가 잘 푸쉬가 되는것을 확인했으니 이제 서버에서 잘 땡겨올 수 있는지 확인해 보겠습니다
ssh -i "{key_name}.pem" ec2-user@ec2-{ip_address}.ap-northeast-2.compute.amazonaws.com
위의 명령어로 접속하면 본인의 서버에 접속할 수 가 있는데요
여기서 '@'앞에 있는 ec2-user같은 경우는 이제 리눅스 환경의 서버를 만들었기 때문에 root user가 ec2-user가 됩니다. ubuntu환경에서는 ubuntu가 루트 사용자라고 합니다. (추후에 github action에서도 써야함)
이렇게 서버에 접속을 하면 일단 우리가 실행할 도커나 도커 컴포즈를 설치해야합니다
[출처: https://mangkyu.tistory.com/196[MangKyu's Diary:티스토리]]
위의 블로그에서 정말 잘 정리를 해주었습니다.
간단하게 정리해보자면
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo groupadd docker
sudo usermod -aG docker $USER
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
아래의 명령어들을 실행하면 도커와 도커 컴포즈가 설치가 됩니다
docker-compose --version
의 명령어를 쳤을때
docker-compose version 1.29.2, build 5becea4c
출처: https://mangkyu.tistory.com/196 [MangKyu's Diary:티스토리]
가 나오면 된다고 합니다. 자세한 내용은 위의 블로그에서 확인하시면 될 것 같습니다.
이제 설치가 완료가 되었기 때문에 저희의 컨테이너를
sudo docker pull ${DOCKER_REPO}
명령어로 ec2에서 가져온다음에
version: '3'
services:
{service_name}:
container_name: service
image: {DOCKER_REPO}
expose:
- 8080
ports:
- "8080:8080"
이런식으로 작성한 도커 컴포즈 파일을
docker-compose up
명령어를 통해 실행을 시키면 됩니다. 그러면 저희가 만든 스프링부트 파일이 실행이 될 것 입니다!
참고로 docker-compose.yaml 파일을 작성할때
nodeapp: # <- 서비스명
image: "tsutomu/nodeapp" # <- 사용하는Docker이미지명(이후에 빌드한다)
container_name: "nodeapp" # <- 컨테이너명. 지정하지 않은 경우에Docker compose로 임의로 결정된다.
working_dir: "/usr/src/app" # <- 컨테이너 내의 워킹 디렉토리. docker run커맨드의 -w/--workdir에 상당한다.
ports: # <- Expose할 포트. docker run커맨드의 -p/--publish에 상응한다.
- "10080:10080"
volumes: # <- Bind mount하는 디렉토리. volume. docker run커맨드의 -v/--volume에 상당한다.
- "$PWD/app-server/src:/usr/src/app"
links: # <- 다른 컨테이너와 접속할 때의 컨테이너명. docker run 커맨드의 -link에 해당한다.
- "noderedis"
noderedis:
image: "redis:3" # <- 이미지ID와 tag
container_name: "noderedis"
출처: https://engineer-mole.tistory.com/221 [매일 꾸준히, 더 깊이:티스토리]
[출처 : https://engineer-mole.tistory.com/221 [매일 꾸준히, 더 깊이:티스토리]][출처 : https://seosh817.tistory.com/387]]
위 블로그들이나 공식 사이트를 참고하는게 좋습니다.
version -> 최신 버전 사용
services:
container_1:
image: `` //쓰일 이미지 설정. 이미지가 도커에 없으면 허브에서 내려 받음
container_2:
image: ```
-> 다른 서비스에서 서비스명만으로 접근 가능하게 한다
-> 환경변수 지정
-> 명령어 설정
-> 의존 관계 -> 명시된 컨테이너가 먼저 생성되고 실행된다!
-> 포트 설정
-> 정해진 도커파일에서 이미지를 빌드해서 서비스 컨테이너 생성
-> 다른 yaml파일이나 현재 파일에서 서비스 속성 상속 받도록 한다
자세한 내용은 https://seosh817.tistory.com/387 에서 확인하시면 됩니다.