Docker 는 Go언어로 작성된 리눅스 컨테이너 기반으로 하는 오픈 소스 컨테이너화 플랫폼
→ 이를 통해, 개발자는 어플리케이션을 컨테이너로 패키징할 수 있다.
→ Docker 0.9버전부터는 직접 개발한 libcontainer 컨테이너를 사용
기본적으로 개발자가 단일 API를 통한 업무 절감 자동화 & 간단한 명령을 통해,
컨테이너를 빌드/배치/실행/업데이트/중지할 수 있도록 해주는 툴킷
Docker 를 사용하지 않고도 컨테이너를 구축할 수 있으나
Docker 플랫폼을 이용하면, 컨테이너를 보다 쉽고/간편하고/안전하게 빌드/배치/관리할 수 있다.
"legacy" 는 사전적으로 "유산" 이라는 뜻이다.
이와 같은 맥락으로
IT 에서 "legacy" 는 "프로그래밍 언어, 플랫폼, 기술 등...에서 과거로 부터 물려 내려온 것들" 을 의미한다.
→ 대부분의 기업들은 중요한 업무를 처리하는 레거시 응용프로그램들과 데이터베이스를 가지고 있다.
예를 들면
회사에서 'visual studio 2015' 를 쓰고 있는데, 'visual studio 2019' 가 새로 나왔다.
이 때, 'visual studio 2019' 에 맞게 코드를 버전업 시켜야 할 경우, 'visual studio 2015'를 legacy라고 부른다.
어플리케이션은 모든 환경에서 동일하나, 각 환경의 서버의 OS 나 그 위에 올라가 있는 미들웨어 프로그램들은 동일하지 않다.
(의존성 문제, 제품 자체가 달라 생기는 문제 등...)
때문에,
개발자 개인 PC 에서는 어플리케이션이 정상 작동하는데, 테스트환경에서는 오류가 발생하는 문제가 발생할 수 있다.
→ 프로덕션 환경을 기준으로 다른 환경을 맞춘다고 해도, 여전히 문제가 발생한다.
(어떤 문제? 무겁다. 이식과 확장에 불리하다. 관리가 복잡하다 등...)
개선되고 완벽한 이식성
LXC 컨테이너
종종 시스템 특정 구성을 참조
Docker 컨테이너
데스크탑, 데이터 센터 및 클라우드 환경에서 수정 없이 실행된다
보다 경량의 중량과 보다 미세한 업데이트
LXC 컨테이너
다수의 프로세스를 단일 컨테이너 내에서 결합
Docker 컨테이너
각 컨테이너에서 오직 하나의 프로세스만 실행
→ 업데이트나 수리를 위해, 해당 파트 中 하나를 중지하는 동안에도 계속 실행될 수 있는 애플리케이션을 빌드 가능
자동화된 컨테이너 작성
Docker 컨테이너
애플리케이션 소스 코드를 기반으로 컨테이너를 자동으로 빌드
컨테이너 버전화
Docker 컨테이너
컨테이너 이미지의 버전을 추적,
이전 버전으로 롤백,
버전을 빌드한 사용자와 빌드 방법을 추적
단, 심지어 이는 기존 버전과 새 버전 사이의 델타만 업로드 가능
컨테이너 재사용
특히 새 컨테이너를 빌드하기 위한 템플릿처럼, 기존 컨테이너는 기본 이미지로 사용 가능
공유 컨테이너 라이브러리
개발자는 수천 개의 사용자가 기여한 컨테이너를 포함하는 오픈 소스 레지스트리에 액세스 가능
향상된 컴퓨터의 성능을 더욱 효율적으로 사용하기 위해 가상화 기술이 많이 등장했다.
그러나
서버 관리자 입장에서는 이런 가상화 기술의 CPU사용률은 10%대 밖에 되지 않아 서버의 리소스 낭비가 돼버린다.
그렇다고 모든 서비스를 한 서버 안에 올린다면, 안정성에 문제가 생길 수 있다.
→ 그래서, 안정성을 높이며 + 리소스도 최대한 활용 = 서버 가상화
예시 : 가상화 플랫폼 VM (OS가상화)
가상화 기술 中 하나
어플리케이션 소스 코드를 임의의 환경에서
해당 코드의 실행에 필요한 OS 라이브러리 및 종속 항목과 결합하는
실행 가능한 표준 컴포넌트
대표적으로 LXC (Linux Container) 가 있다.
(기존 OS 를 가상화시키던 것과 달리) 컨테이너는 OS 레벨의 가상화로 프로세스를 격리시켜 동작하는 방식
VM 과는 달리, 전체 OS 인스턴스와 하이퍼바이저의 페이로드(payload)를 전달하지 않는다.
→ 오직 코드 실행에 필요한 OS 프로세스와 종속 항목만 포함
컨테이너 크기는 메가바이트(MB) 단위로 측정된다.(일부 VM 의 경우는 GB 단위)
→ 하드웨어 용량을 보다 잘 활용. 구동 시간이 보다 빠름
즉, Docker 와 VM 의 비교를 말한다.
리소스 격리성을 제공하여,
어플리케이션마다 다른 컴퓨터에서 실행되는 것처럼 IP 나 PORT 등...을 다르게 설정할 수 있다.
컨테이너 기술
Docker의 기반 기술은 리눅스 컨테이너 기술이다. (LXC)
Docker는 애플리케이션 단위 가상화를 한다.
Docker는 각각의 애플리케이션의 격리성을 제공한다.
Docker는 필요한 부분만 격리가 되어있고 나머지는 공유하기 때문에 가상 머신 보다 훨씬 가볍다. (호스트 OS 공유, 이미지 레이어 공유)
Docker는 호스트 OS의 자원을 공유한다.
Docker는 가상 머신만큼 견고한 격리성을 제공하지는 않는다.
Docker는 리눅스의 컨테이너를 이용한 기술로, OS 위에 다른 OS를 실행하는것이 아니므로 가상 머신보다 좋은 성능을 낼 수 있다.
Docker는 컨테이너의 관점에서 개발자와 사용자 커뮤니티를 중심으로 혜택을 제공하는 데 있다.
EC2에서도 OS 단위 가상화를 하고 있다. => EC2에 도커를 올려서 사용도 가능하다. => 게스트 OS 위에 Docker 위에 컨테이너 올라가는 모양이다.
가상머신
VM에는 VirtualBox, VMware 등이 있다.
VM은 OS 단위 가상화를 한다.
VM은 애플리케이션에 대한 환경 격리성을 중심으로 제공한다.
VM은 개발 환경이나 사용 환경을 이미지로 저장하고, 호스트 OS 위에 게스트 OS를 올리는 방식이다.
VM은 컴퓨터의 하드웨어 자체를 가상화 시키기 때문에 컨테이너보다 가상 머신이 훨씬 무겁다.
한 서버의 여러 OS 를 가상화하여 사용 (OS 가상화)
Host OS 위에 + 가상화를 시키기 위한 Hypervisor 엔진 위에 + Guest OS 를 올려 사용
→ 가상화된 하드웨어 위에 OS가 올라가는 형태
→ 거의 완벽하게 Host와 분리된다.
장점
단점 : OS 위에 + OS를 올리기 때문에, 무겁고 느리다.
컨테이너 방식으로 프로세스를 격리시켜 동작 (컨테이너 기반 가상화)
Docker 엔진 위에 + Application 실행에 필요한 Bin(= Binary, 바이너리, 이진코드, 텍스트형식이 아닌 실행 파일 or 이미지 파일)만 올라가게 된다.
(Bin = Binary 바이너리 = 이진코드 = 텍스트형식이 아닌 실행 파일 or 이미지 파일)
Host OS + Docker 엔진 위에서 바로 동작하며, Host의 커널을 공유
→ 커널을 공유하게 되면, I/O 처리가 쉽게 되어 성능의 효율 ↑
(I/O 처리 : 입출력 처리. (컴퓨터는 크게 연산, 입출력 처리 2가지를 한다))
컨테이너를 사용하는 것 : 가상 머신을 생성하는 것이 아니라, Host OS 가 사용하는 자원을 분리하여 여러 환경을 만들 수 있도록 하는 것
장점
컨테이너를 실행할 수 있는 실행파일, 설정 값들을 가지고 있는 것
Image 를 컨테이너에 담고 실행을 시킨다면, 해당 프로세스가 동작
Docker Image 를 Pull받기 위한 url 을 적지 않으면, default 로 Docker Hub에서 Image를 pull 받게되고
url 을 적어준다면, 사설 저장소에서 이미지를 받을 수 있다.
ubuntu 이미지
를 만들기 위해서 → Layer A,B,C 가 들어간다.
nginx 이미지
를 만들기 위해서 → 이미 Layer A,B,C 로 만들어진 ubuntu 이미지를 베이스 이미지로 사용하여, 여기에 nginx 만 더한다.
web app 이미지
를 만들기 위해서 → 이미 만들어진 nginx 베이스 이미지에 web app을 올려 이미지를 만든다.(ubuntu 이미지에 nginx를 올리고 web app을 올리는 것이 X)
Docker Image들을 저장하고 배포
많은 회사들은 Docker Hub를 통해 소프트웨어를 배포 (GitHub와 동일하게 생각해도 무관)
우린 Docker hub에서 image를 pull하여 간단하게 컨테이너에 넣어 사용 가능
→ 만약 배포판이 없다면? 배포판 보다 더욱 보완하고 싶다면? 그럴때 사용 할 수 있는 것이 Docker Fille 다.
$ vim Dockerfile
FROM ubuntu:14.04
# app 디렉토리 생성
RUN mkdir -p /app
#Docker 이미지 내부에서 RUN, CMD, ENTRYPOINT의 명령이 실행될 디렉터리를 설정합니다.
WORKDIR /app
# 현재 디렉터리에 있는 파일들을 이미지 내부 /app 디렉터리에 추가함
ADD . /app
RUN apt-get update
RUN apt-get install apache2
RUN service apache2 start
VOLUME ["/data", "/var/log/httpd"]
# 하기 포트를 외부로 노출합니다.
EXPOSE 80
# 쉘을 사용하지 않고 컨테이너가 시작되었을 때 logbackup 스크립트를 실행
CMD ["/app/log.backup.sh"]
:wq!
이미지 생성 출발점
이미지를 구성하기 위한 명령어들을 작성하여, 이미지를 구성 가능
→ 즉, "Docker File을 읽을 수만 있다면, 해당 이미지가 어떻게 구성되어 있는지도 알 수 있다."
Docker Image 를 만들기 위한 설정 파일
→ 명령어를 토대로 Docker File을 작성하면 설정된 내용대로 Docker Image를 만들 수 있다.
주의!
FROM
MAINTAINER
RUN
VOLUME
CMD
WORKDIR
EXPOSE
$ vim dockerignore
node_modules
npm-debug.log
Dockerfile*
docker-compose*
.dockerignore
.git
.gitignore
README.md
LICENSE
.vscode
:wq!
$ docker build -t [만들고싶은 이미지 이름]
해당 명령어는 반드시 DockerFile 경로에서 입력해야 힌다.
Docker 설치
1) Docker 설치
$ curl -fsSL https://get.docker.com/ | sudo sh
$ service docker start
$ docker version
2) Docker Image Pull 받기
$ docker pull [Image Name]
Docker 이미지 내역은 Docker Hub 에서 확인 할 수 있다.
※ DockerHub 에서 Official 이 공식 배포 버전
※ Version 명시가 없을시 latest(최신버전)으로 Pull
※ Image 앞에 Url이 없을경우 default 로 DockerHub에서 pull 사설 레지스트리에서 받을시 앞에 Url 작성
3) Docker Image list 확인
$ docker images
## 다음과 같이 이미지가 만들어진다.
REPOSITORY TAG IMAGE ID CREATED SIZE
docker-example 0.0.1 378107e4a39d 3 hours ago 454MB
4) Docker Image 삭제하기
$ docker rmi [이미지 이름]
※ 이미지 삭제 시, 뒤에 버전까지 명시 해야한다.
※ 버전 생략 시, latest 최신 버전으로 삭제
5) Docker Image Push 하기
$ docker push [레지스트리url/이미지:버전]
6) Docker Image로 컨테이너 실행시키기
$ docker run <옵션> <이미지 이름, ID> <명령> <매개 변수>
7) Docker List 확인 [컨테이너]
$ docker ps (실행중인 컨테이너만 확인)
$ docker ps - a (종료된 컨테이너까지 확인)
CONTAINER ID IMAGE COMMAND ..... PORTS NAMES
08d9361ea25f eclipse-mosquitto "/docker-entrypoint.…" ..... 0.0.0.0:1883->1883/tcp jovial_wright
8) Docker 컨테이너 log 확인
$ docker logs –f [컨테이너 이름]
9) Docker 컨테이너 내부 디렉토리 들어가기
$ docker exec -i -t [컨테이너 이름] bash
10) Docker 컨테이너 종료
$ docker kill [컨테이너이름]
11) Docker 종료된 컨테이너 실행시키기
$ docker start [컨테이너이름]
12) Docker 컨테이너 삭제
$ docker rm [컨테이너이름]
Make Open SSL
$ mkdir -p /data/certs
$ openssl req \
-newkey rsa:4096 -nodes -sha256 -keyout ~/data/certs/server.key \
-x509 -days 36500 -out ~/data/certs/server.crt
Docker Registry에 접속 할 장비들 설정
1) 접속할 장비들에 server.crt 파일 복사
$ mkdir -p /etc/docker/certs.d/docker-registry.khj93tistory.com
$ cp /data/certs/server.crt /etc/docker/certs.d/docker-registry.khj93tistory.com:5000/server.crt
2) 접속할 장비들에 hosts 등록 (localhost일 경우 127.0.0.1)
$ vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 docker-registry.kh93tistory.com
:wq!
Docker Registry Image Pull / Start
$ docker pull registry
$ docker run -d -p 5000:5000 --restart=always --name docker-registry -v /data/certs:/certs -e
REGISTRY_HTTP_TLS_CERTIFICATE=/certs/server.crt -e REGISTRY_HTTP_TLS_KEY=/certs/server.key -v /data/certs/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry
Docker 실행 및 종료 명령어들은 script 로 만들어 한 곳에 모아두면 손쉽게 start/stop 가능
Docker Registry Image Push
$ docker push docker-registry.kh93tistory.com:5000/[Image Name]:[tag]
Docker Image 의 실행 중인 라이브 인스턴스
사용자는 이들과 상호 작용 가능
관리자는 docker 명령을 사용하여, 자체 설정과 조건을 알맞게 조정 가능
Docker Hub 는 Github 처럼 remote 저장소를 활용할 수 있는 곳이다.
로그인 → Create Repository → Repository 를 생성
repository명 설정 → public → create
"Docker 를 사용해서 서비스를 운영한다."는 것은 "애플리케이션들을 컨테이너화(Containerizing)했다."는 뜻
어플리케이션에 필요한 미들웨어도 컨테이너로 받아서 사용
어플리케이션에 필요한 모든 요소들을 컨테이너로 받고,
Docker-compose, Docker Swarm, Kubernetes 등...을 이용해서 관리할 수 있다.
애플리케이션을 컨테이너화 했을 때, 개발과 배포의 흐름이 간단해져서 빠르게 진행될 수 있다.
서버의 운영체제나 미들웨어의 의존성에 대해 걱정할 필요없이,
Docker 만 설치되어 있다면 모든 것이 해결된다.
spring initializr 에서 다음과 같은 설정으로 SpringBoot Application 을 생성
바탕 화면에 해당 프로젝트 파일을 저장할 폴더 생성
프로젝트의 기본 구조
DockerController
@RestController
public class DockerController {
@GetMapping("/")
public ResponseEntity<String> hello(){
return ResponseEntity.ok("Hello Docker-Spring World!");
}
}
DemoApplication 실행
@SpringBootApplication
public class DemoApplication {
public static void main (string[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
localhost:8080 로 연결이 잘 되는지 확인
1) http://localhost:8080/ 로 접속
2) 다음과 같은 메시지가 뜬다면 성공
Jar 파일은 여러 개의 클래스 파일들과 관련 리소스 및 메타 데이터를 하나의 파일로 모아서, 배포를 위해 만들어진 소프트웨어 패키지 파일 포맷이다.
(Jar 은 zip으로 이루어진 압축 파일)
Gradle 로 들어가기
Tasks → build → bootjar 클릭하기
bootjar 를 클릭하면, 프로젝트 폴더 → build → libs 에 jar 파일이 만들어진다.
Jar 파일이 있는 곳에 Dockerfile 을 만든다.
# 기반이 되는 이미지를 의미 → jdk 버전을 명시해주면 된다.
# jdk11 버전을 이용해서, Docker 를 올리겠다.
FROM openjdk:11-jdk
# 컨테이너 내에서 사용할 수 있는 변수를 지정 → JAR 파일의 위치를 환경변수의 형태로 선언
# JAR_FILE 변수를 정의
# 프로젝트를 빌드할 시, build/libs/xxxx.jar 의 형태로 jar file이 생성되고, 그 파일의 위치를 변수로 저장하는 것
# 기본적으로 jar file이 2개이기 때문에 이름을 특정해야함
ARG JAR_FILE=./build/libs/DevopsTestKotlin-0.0.1-SNAPSHOT.jar
# JAR 파일 메인 디렉토리에 복사
# 프로젝트의 jar 파일 위치를 참조하여 jar 파일을 가져와서(ARG의 JAR_FILE 변수), 컨테이너의 루트 디렉토리에 app.jar의 이름으로 복사
COPY ${JAR_FILE} app.jar
# 시스템 진입점(컨테이너가 시작됐을 떄 실행할 스크립트) 정의
# Docker파일이 Docker엔진을 통해서 컨테이너로 올라갈 때, Docker 컨테이너의 시스템 진입점이 어디인지를 선언
# java -jar 명령어를 이용해서, 컨테이너의 루트에 위치한 app.jar을 실행하라.
ENTRYPOINT ["java","-jar","/app.jar"]
git commit and push 를 통해, ec2에 코드 옮겨주기
터미널 → jar 파일 (cd build/libs 명령어로도 갈 수 있다)
Image 생성 (한 칸 띄고 점을 찍어주는 것에 주의!)
docker build -t [도커허브ID/레포지토리 이름] .
Image 생성됐는지 확인
docker images
만든 repository에 push
docker push [도커 허브 ID/레포지토리명]
docker run <도커이미지명> 을 통해, container 를 실행시킬 수 있다.
단, 여기서 8080포트로 진입은 불가능하다.
→ 이미지 기반으로 만든 컨테이너 안에서의 8080포트 이지, localhost의 8080포트를 사용하는 것이 아니기 때문.
이를 해결하기 위해서는 Port Mapping (포트 맵핑)이 필요
docker run -p 8080:8080 dockertestimg 로 컨테이너의 Port 를 호스트 시스템의 Port 에 바인딩해준다.
확인 하기
EC2 생성
ec2 업데이트 & git 설치
# ec2 업데이트
sudo yum update -y
# git 설치하기
sudo yum install git
jdk를 설치
# aws coreetto 다운로드
sudo curl -L https://corretto.aws/downloads/latest/amazon-corretto-11-x64-linux-jdk.rpm -o jdk11.rpm
# jdk11 설치
sudo yum localinstall jdk11.rpm -y
# jdk version 선택
sudo /usr/sbin/alternatives --config java
# java 버전 확인
java --version
# 다운받은 설치키트 제거
rm -rf jdk11.rpm
java --version 을 통해, 환경설정이 제대로 됐는지 확인
openjdk 11.0.15 2022-04-19 LTS
OpenJDK Runtime Environment Corretto-11.0.15.9.1 (build 11.0.15+9-LTS)
OpenJDK 64-Bit Server VM Corretto-11.0.15.9.1 (build 11.0.15+9-LTS, mixed mode)
이렇게 뜬다면 성공한 것
Docker 의 버전 확인
sudo yum install docker
# 잘 설치가 되었는지 확인
sudo docker --version
Docker version 20.10.7, build f0df350
이렇게 뜬다면 정상
docker-compose를 설치
sudo curl -L "https://github.com/docker/compose/releases/download/1.28.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker-compose 의 버전 확인
docker-compose --version
docker-compose version 1.28.2, build 67630359
이렇게 뜬다면 정상
docker-compose.yml을 프로젝트의 루트 디렉토리에 생성하고, 다음과 같이 작성
version: "3"
services:
web:
# nginx 이미지의 경우, 인바운드로 들어오는 80번 포트를 docker container 내부에 꽂히는 80번 포트로 포워딩해주는 기능을 수행
# Http 요청을 nginx 내부로 그대로 흘릴 것이다.
image: nginx
ports:
- 80:80
# volumes 를 통해서, ec2 에 있는 nginx 설정 파일을 컨테이너의 /etc/nginx/conf.d 폴더로 옮겨서 실행
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
# nginx가 실행되는 시점은 spring 이 컨테이너로 올라간 다음에 올리겠다.
depends_on:
- spring
# 현재 디렉토리에 있는 Docker image 를 빌드시키고, 8080번 포트로 인바운드 들어오는 신호를 컨테이너 내부의 8080번 포트로 그대로 꽂아주겠다.
spring:
build: .
ports:
- 8080:8080
nginx 의 설정 파일인 conf.d 를 작성
1) nginx/conf.d 폴더 내부에 app.conf를 생성
mkdir nginx
mkdir nginx/conf.d
cd nginx/conf.d
sudo vim app.conf
2) app.conf 에는 다음과 같이 작성
server {
# nginx 이 외부의 80번 포트의 신호를 읽어낸다.
listen 80;
access_log off;
location / {
proxy_pass http://spring:8080; # 신호를 pass 시킬때는 spring의 8080번 포트로 포워딩시켜서 패스시킨다.
proxy_set_header Host $host:$server_port;
# proxy에 header를 채우는 코드
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
이렇게 포워딩 된 신호는 spring 입장에서는 인바운드에 해당하므로,
위에서 '4. docker-compose.yml' 을 작성한대로 spring 은 그에 해당하는 신호를 8080번 포트로 포워딩시켜서 container 내부로 꽂아버린다.
프로젝트 빌드시키기
# gradlew의 권한 변경
sudo chmod + ./gradlew
# 빌드
./gradlew build
docker 실행
sudo systemctl start docker
docker가 정상적으로 동작하고 있는지 확인
systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
Active: active (running) since 수 2022-04-20 17:48:42 UTC; 51s ago
Docs: https://docs.docker.com
Process: 3380 ExecStartPre=/usr/libexec/docker/docker-setup-runtimes.sh (code=exited, status=0/SUCCESS)
Process: 3379 ExecStartPre=/bin/mkdir -p /run/docker (code=exited, status=0/SUCCESS)
Main PID: 3384 (dockerd)
Tasks: 8
Memory: 119.3M
CGroup: /system.slice/docker.service
└─3384 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --default-ulimit nofile=32768:65536
이렇게 뜬다면 정상
docker-compose 를 통해서, 프로젝트 올리기
# docker-compose를 백그라운드에서 동작시키기
docker-compose up --build -d
Building with native build. Learn about native build in Compose here: https://docs.docker.com/go/compose-native-build/
Creating network "order-example-kotlin_default" with the default driver
Building spring
Sending build context to Docker daemon 45.52MB
Step 1/4 : FROM openjdk:11-jdk
11-jdk: Pulling from library/openjdk
6aefca2dc61d: Pulling fs layer
967757d56527: Pulling fs layer
c357e2c68cb3: Pulling fs layer
c766e27afb21: Pulling fs layer
a747e81e6111: Pulling fs layer
2859d18181fd: Pulling fs layer
3c6d59134c80: Pulling fs layer
c766e27afb21: Waiting
a747e81e6111: Waiting
3c6d59134c80: Waiting
2859d18181fd: Waiting
c357e2c68cb3: Verifying Checksum
c357e2c68cb3: Download complete
967757d56527: Verifying Checksum
967757d56527: Download complete
6aefca2dc61d: Verifying Checksum
6aefca2dc61d: Download complete
a747e81e6111: Verifying Checksum
a747e81e6111: Download complete
2859d18181fd: Verifying Checksum
2859d18181fd: Download complete
c766e27afb21: Verifying Checksum
c766e27afb21: Download complete
3c6d59134c80: Verifying Checksum
3c6d59134c80: Download complete
6aefca2dc61d: Pull complete
967757d56527: Pull complete
c357e2c68cb3: Pull complete
c766e27afb21: Pull complete
a747e81e6111: Pull complete
2859d18181fd: Pull complete
3c6d59134c80: Pull complete
Digest: sha256:95b2daeb07a18121a4309a053ff99aa741888528e5da068beef36db092a03e25
Status: Downloaded newer image for openjdk:11-jdk
---> e67a33049aa6
Step 2/4 : ARG JAR_FILE=./build/libs/DevopsTestKotlin-0.0.1-SNAPSHOT.jar
---> Running in a1ebd6481830
Removing intermediate container a1ebd6481830
---> e448756e884e
Step 3/4 : COPY ${JAR_FILE} app.jar
---> 1c1a9cfead2f
Step 4/4 : ENTRYPOINT ["java","-jar","/app.jar"]
---> Running in 7dfbfc10fc7e
Removing intermediate container 7dfbfc10fc7e
---> e1bfd62d0398
Successfully built e1bfd62d0398
Successfully tagged order-example-kotlin_spring:latest
Pulling web (nginx:)...
latest: Pulling from library/nginx
1fe172e4850f: Pull complete
35c195f487df: Pull complete
213b9b16f495: Pull complete
a8172d9e19b9: Pull complete
f5eee2cb2150: Pull complete
93e404ba8667: Pull complete
Digest: sha256:694f2ecdb88498325d70dbcb4016e90ab47b5a8e6cd97aaeec53f71f62536f99
Status: Downloaded newer image for nginx:latest
Creating order-example-kotlin_spring_1 ... done
Creating order-example-kotlin_web_1 ... done
정상적으로 동작하고 있는지 확인
참고: [Docker] Docker의 개념 및 핵심 설명
참고: [Docker] Docker File을 이용하여 Docker Image만들기
참고: [Docker] Private Docker Registry 구축하기
참고: [Docker] Docker 설치부터 실행까지 기본 사용법 정리
참고: Docker
참고: 레거시(legacy)란?
참고: Docker란 무엇인가? 왜 사용할까?
참고: 도커(Docker)란? – 필요성
참고: [Docker] Spring 프로젝트를 Docker를 이용해서 배포해봅시다
참고: Spring Boot, Dockerfile로 이미지 생성, 배포하기
참고: [Docker] - (3) 도커를 사용하여 간단한 SpringBoot 어플 실행하기
참고: [Docker] 스프링부트를 docker 이미지를 통해서 AWS EC2에 배포하기(DockerHub)
참고: Spring Boot + Docker로 배포하기
참고: Docker - 도커에 Spring Boot(Gradle) 구축하기
참고: [Docker] - Spring Boot 애플리케이션을 Docker 이미지로 빌드후 실행해보기