Docker - 원하는 서비스 이미지 만들고 배포하기

목표

도커 기반으로 서비스를 구성하고, docker hub에 배포하기

예시로 진행할 것은 우분투에서 flask 기반의 api 서비스인데, 어느 것이든 상관없음

과정 요약

  1. 서비스를 구성할 기반 이미지(OS 등)를 pull하고 컨테이너를 생성한다
  2. 컨테이너 레이어에 접속해서 내가 추가하길 원하는 서비스 코드를 추가한다
  3. commit으로 새로운 레이어가 쌓인 이미지를 만든다
  4. 배포한다 (docker hub를 이용한 배포, 이미지 파일을 이용한 직접 배포가 있다)

DockerFile을 이용하는 방법도 있는데, 내가 선호하지 않아서 패스.

이미지 만들기

기반 이미지 가져오기

우선 나는 ubuntu에서 flask를 이용한 api 서비스를 배포할 예정이라 ubuntu를 가져왔다.

당연히 기반 이미지가 꼭 쌩os일 필요는 없다. 다른 사람이 배포해둔 서비스를 가져와서 수정하는 것도 가능하다.

도커 특성상 단일 동작은 거의 바로 보장되는 반면 서비스 간 연계는 수정이 필요한 경우가 많아서 직접 고치는 경우도 많다

(메일서버를 구축할 때는 rainloop를 가져와서 쓰려다가 웹 연동에 버그가 있어서 직접 고쳐 썼다)

1
hhr-test@hhrtest:~$ docker pull ubuntu
1
2
3
hhr-test@hhrtest:~$ docker images
REPOSITORY                    TAG       IMAGE ID       CREATED       SIZE
ubuntu                        latest    54c9d81cbb44   1 hours ago   72.8MB

컨테이너 레이어에 접속해서 이미지 수정하기

container layer 에서 내가 원하는 서비스 환경을 구축해야 한다.

우선 container 생성 후 container layer에 접속.

1
hhr-test@hhrtest:~$ docker run -it ubuntu

나의 경우는 python을 이용한 api 서비스가 목적이기 때문에 이를 위한 환경 세팅을 해 주었다.

1
2
3
4
5
6
7
8
root@bf23e90770cd:/# apt update
...
root@bf23e90770cd:/# apt install -y software-properties-common
...
root@bf23e90770cd:/# add-apt-repository ppa:deadsnakes/ppa
...
root@bf23e90770cd:/# apt install python3-pip
...

그리고 기존에 만들어둔 서비스 코드를 옮겨야 하는데, 현재 컨테이너 레이어 세션을 종료하면 컨테이너가 종료되기 때문에 이를 유지한 채로 코드를 옮겨야 한다.

1
2
3
4
5
hhr-test@hhrtest:~/Desktop/etc$ docker ps
CONTAINER ID   IMAGE                         COMMAND                  CREATED          STATUS          PORTS                                       NAMES
bf23e90770cd   ubuntu                        "bash"                   55 seconds ago   Up 55 seconds                                               zealous_keller

hhr-test@hhrtest:~/Desktop$ docker cp myProject bf23e90770cd:home/myTest

그 뒤 프로젝트 requirements를 설치해 주었다.

1
2
3
4
5
root@bf23e90770cd:/home# ls
myTest
root@bf23e90770cd:/home# cd myTest
root@bf23e90770cd:/home# pip3 install -r requirements.txt
...

이미지 commit

1
2
3
4
5
6
7
8
9
10
11
hhr-test@hhrtest:~$ docker ps
CONTAINER ID   IMAGE           COMMAND   CREATED         STATUS         PORTS     NAMES
bf23e90770cd   ubuntu   "bash"    7 minutes ago   Up 7 minutes             zealous_keller

hhr-test@hhrtest:~$ docker commit bf23e90770cd my-web-service
sha256:323e60860fc44842c0a4484201dbb6da113e018c3b51c1879afcbbd8e65e6fd9

hhr-test@hhrtest:~$ docker images
REPOSITORY       TAG       IMAGE ID       CREATED       SIZE
my-web-service   latest    8c49521961a8   10 minutes ago   1.04GB
ubuntu           latest    54c9d81cbb44   2 hours ago   72.8MB

이미지 배포하기

docker hub 를 이용해 배포하는 일반적인 방법과,

인터넷이 되지 않는 환경이라거나 다른 이유로 인해 이미지 파일을 이용해 배포하는 방법이 있다.

1. Docker Hub 이용

https://hub.docker.com/

docker hub 계정이 필요하다. 가입 후 private repository 하나까지는 무료이며 이후로는 프로버전 결제를 해야 한다.

유출되면 안 되는 코드나 정보들이 이미지 내부에 있으면 public repository 에 배포할 수가 없어서 비추천 … private repository 를 애용하자.

로그인 - repository 생성 까지 완료해준 뒤

docker hub 계정으로 로컬에서 로그인을 해야 한다.

1
2
hhr-test@hhrtest:~$ docker login
...

그리고 이미지에 태그를 달고 push 해주면 끝.

1
2
3
4
5
6
7
8
hhr-test@hhrtest:~$ docker tag my-web-service syndrome5044/my-web-service:test
hhr-test@hhrtest:~$ docker push syndrome5044/my-web-service
Using default tag: latest
The push refers to repository [docker.io/syndrome5044/my-web-service]
8febd95ec042: Pushed
2acf1f2cce20: Pushed
448f179be62e: Pushed
36ffdceb4c77: Pushed

이후 docker hub 의 repository 페이지에 들어가보면 push 된 이미지를 확인할 수 있다.

2. 인트라넷 배포

우선 이미지를 파일로 export해야 한다.

export 명령어가 있긴 한데, 이건 이미지가 아닌 컨테이너를 파일로 저장하게 해 주는 명령어다.

이미지를 파일로 저장하기 위해서는 save 명령어를 이용한다.

1
2
3
hhr-test@hhrtest:~$ docker save -o my-web-service.tar my-web-service
hhr-test@hhrtest:~$ ls
my-web-service.tar

my-web-service.tar를 배포하면 되고, 이미지로 다시 변환하기 위해서는 load 명령어를 이용한다.

1
2
3
4
5
hhr-test@hhrtest:~$ docker load -i my-web-service.tar
Loaded image: my-web-service:latest
hhr-test@hhrtest:~$ docker images
REPOSITORY                    TAG       IMAGE ID       CREATED       SIZE
my-web-service                         latest    837213e00679   1 hours ago    515MB

끝-