도커는 컨테이너 기반 가상화 플랫폼으로, 어떤 프로그램을 외부 환경과 격리시켜 구동할 수 있게 해주는 SW이다.
즉 버전이나 os 상관 없이 언제 어디서나 구동할 수 있도록 해주는 기특한 녀석이라고 할 수 있다.
여기서 컨테이너란 os 상에 논리적인 영역을 구축하고, 앱이 작동하는데 필요한 요소들을 모아 별도의 서버처럼 동작하는 실행환경이다. 앱과 그 실행에 필요한 모든 것들을 하나의 패키지로 묶은, 말 그래도 '컨테이너'와 똑같은 개념이다.

다만 도커는 리눅스 기반이기 때문에 기본적으로 리눅스가 아닌 곳에서 리눅스 환경으로 작성된 앱을 가동하기 위한 서비스이고, 그 외의 다른 크로스플랫폼 예를 들어 window에서 작성된 파일을 macOS에서 돌리고 이런 건 안된다.
docker {대상}{커맨드}{옵션}{인자}
명령어는 그때 그때 찾아가면서 사용하면 된다. 주로 build, run이나 stop, ls, push, pull 등을 많이 사용하게 될 것....
때문에 이미지 레이어는 하나만 있어도 되고, 여러 환경에서 이미지를 가져다가 컨테이너를 생성할 수 있는 것이다.
도커의 핵심 철학인
"Build Once, Run Anywhere"
을 실현하기 위해선 결국 앱 실행 환경을 이미지에 잘 반영하는 것이 중요할 것이다. 이를 위해 우리는 Dockerfile을 아주 잘 작성해야 한다!
Dockerfile은 도커 이미지를 생성하기 위한 스크립트 파일로, 앱 실행 환경을 어떻게 이미지로 만들지 정의하는 일종의 '명세서' 역할을 수행한다.
사용자는 여러 키워드를 통해 빌드를 용이하게 할 수 있다. 대표적으로:
등의 키워드들이 사용된다.
이제 실제로 배포를 해볼 것이다! AWS EC2는 미리 생성했다고 가정하고 진행한다.

gradle-build-bootjar를 더블클릭하여 jar 파일을 생성해준다.

이런식으로 .jar 파일이 스냅샷 형식으로 생기게 된다.
jar는 java 앱을 배포하기 위한 패키지 파일 포맷으로, .class파일 및 메타데이터, 의존성 파일 또한 포함한다.
참고로 SNAPSHOT은 gradle에서 개발 중인 버전을 나타내는 식별자이고, 앞의 0.0.1은 버전 번호를 말한다.

jar파일을 생성했으면 프로젝트 루트 디렉토리에 Dockerfile 파일을 생성해준다. 대부분의 IDE는 자동으로 이를 인식한다.
# 빌드 스테이지
FROM gradle:7.6-jdk17 AS build
WORKDIR /app
COPY . /app
RUN gradle build --no-daemon -x test
# 실행 스테이지
FROM openjdk:17-jdk-slim
# 빌드된 JAR 파일 복사
COPY --from=build /app/build/libs/*.jar app.jar
# 포트 설정
EXPOSE 8080
# 실행 명령
ENTRYPOINT ["java", "-jar", "app.jar"]
필자의 경우 이렇게 작성했다.
이제 작성된 Dockerfile로 이미지를 빌드해보자.
우선 터미널을 켜고 Dockerfile이 있는 프로젝트 루트 디렉토리로 이동한 후
docker build -t devkev00/sbb .
devkev00에는 본인의 도커 아이디, sbb 부분에는 본인의 프로젝트명 or 서비스명을 입력하면 된다. 뒤에 . 을 붙이는 이유는 현재 디렉토리의 Dockerfile을 기반으로 빌드하겠다는 뜻으로, 아까 cd를 해주지 않았다면 뒤에 파일 경로를 입력해줘야 한다.

요런 식으로 빌드가 이루어진다.
우리는 빌드한 이미지를 ec2 서버가 있는 ubuntu에서 갖다 써야 한다. 때문에 이 이미지를 리모트 저장소인 Docker Hub로 푸시해두자.
docker push devkev00/sbb
마찬가지로 각자 id와 서비스명을 넣어주면 된다.

필자는 이미 한번 올린 레이어로 다시 푸시 했기 때문에 레이어가 이미 존재한다고 뜬다. 처음 푸시한다면 5개 전부 pushed가 뜰 것이다.

도커 공식 FE인 Docker Desktop에서 방금 푸시한 이미지를 확인할 수 있다.
이제 서버 컴퓨터에서 이미지를 받아와서 run 하면 끝난다 !!
그 전에 ubuntu에 Docker를 설치해주자.
// 시스템 패키지 업데이트
sudo apt upgrade -y
// 도커 설치에 필요한 패키지 설치
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
// 도커 공식 GPG 키 추가
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
// 도커 저장소 추가
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
// 패키지 목록 업데이트
sudo apt update
// 도커 설치
sudo apt install -y docker-ce docker-ce-cli containerd.io
// 도커 시작
sudo systemctl start docker
// (선택) 부팅 시 자동 시작 설정
(sudo systemctl enable docker)
// (선택) 현재 사용자를 도커 그룹에 추가 -> 권한 부여
(sudo usermod -aG docker $USER)
명령어가 매우 많지만 외울 필요는 없다. 다만 도커 저장소를 추가하는 이유는 이렇게 해야 도커가 최신 버전으로 업데이트 될 때마다 apt update 등의 명령어로 손쉽게 최신화할 수 있기 때문이다(해당 경로에서 받아온다). 또한 GPG 키는 일종의 보안 절차이다. 이게 있어야 설치하는 패키지가 실제 도커 공식 저장소에서 온 것인지 알 수 있다.
설치 후
docker --version
명령어를 입력했을 때 버전 정보가 뜨면 잘 설치된 것이다.
이제 아까 전에 푸시한 이미지를 pull 해오자!
sudo docker pull devkev00/sbb
이렇게 하면....

이런 오류가 뜨는데, 이는 m1, m2칩을 사용하는 애플 실리콘 제품에서 빌드된 docker 이미지가 ec2의 cpu 아키텍쳐와 호환되지 않아서 발생하는 오류이다. 이를 해결하기 위해 로컬에서 다시 멀티 아키텍쳐 이미지로 빌드해서 푸시해야 한다 (후...)
docker buildx create --use
docker buildx build --platform linux/amd64,linux/arm64 -t devkev00/sbb --push .
마찬가지로 외울 필요는 없다... 이것도 언젠가 해결되겠지...?

뭔가 엄청나게 빌드 후 푸시까지 진행되는 중... 다 하고 나서 다시 pull을 해보면

마찬가지로 필자는 전에 했기 때문에 이미 존재한다는 상태 메시지도 뜨는데, 처음이라면 Pull complete가 전체적으로 뜰 것이다.

성공적으로 pull을 받아 왔으니 8080포트로 run을 해주고, sudo docker ps 명령어를 입력해보면 잘 실행되고 있음을 확인할 수 있다.

이제 본인의 ec2 퍼블릭 IPv4 주소:8080으로 접속하면 접속이 잘 되는 것을 확인할 수 있다. 이후에 nginx로 도메인을 적용하고, https까지 적용하면 배포가 끝나게 된다!

sudo docker stop {컨테이너ID} 명령어로 배포 중인 컨테이너를 중지할 수도 있다!