
첫 프로젝트를 마무리 지으며 느꼈던 점은 실제 서비스를 사용자가 이용하고 이에 대해 피드백 받을 수 있었다면, 더 값진 경험을 할 수 있지 않았을까라는 아쉬움이 남았습니다.
웹이든 앱이든 사용자가 서비스를 사용할 수 없다면 학습 목적 이외에 서비스로서 큰 가치가 없습니다.
따라서, 서비스 운영에 있어서 배포는 필수이며 서버 백엔드 개발자라 하더라도, 기본적인 인프라 구축 및 운영에 대해 이해하고 구축할 수 있어야겠구나 라고 생각했습니다.
현재 프로젝트의 프론트가 구현되어 있지 않기 때문에 도커와 도커 컴포즈를 활용하여 서버측만 배포를 하고, README.md에 서버를 경험하기 위한 방식에 대해 정의할까 합니다.
Docker 개념에 대해 조금 더 자세히 알아보겠습니다.
도커 개념 관련 포스팅

도커는 "컨테이너 기반의 오픈소스 가상화 플랫폼" 입니다.
기존에 하나의 물리적인 서버에서는 1개의 OS가 올라가고, 1개의 태스크를 수행했습니다. 하지만, 가상화를 사용하게 되면 하나의 서버 위에 여러 개의 OS를 사용할 수 있게됩니다. 이를 통해서, 필요한 물리적 서버가 줄어들게 되면서 비용 절감, 여러 운영체제를 운영함으로써 유연성 향상 등의 장점으로 인해 가상화 플랫폼을 많이 사용합니다.
일반적으로 컨테이너는 선박이 화물을 수송할 때, 사용되는 박스 정도로 이해할 수 있습니다. 서버에서 사용되는 컨테이너도 역할이 비슷합니다. 다양한 프로그램 또는 실행 환경을 "컨테이너" 라는 개념으로 추상화하고 동일하게 제공하여 프로그램의 배포 및 관리를 단순하게 수행하도록 해줍니다. 어떤 프로그램이라도 추상화가 가능하고, 이를 어떤 환경에서도 동일하게 실행할 수 있도록 해줍니다.

컨테이너란 프로세스가 독립적으로 실행될 수 있는 환경을 제공하는 "가상화 기술" 을 말합니다. 즉, 가상화 기술 중 하나입니다.
기존의 가상화 방식은 주로 "OS 가상화" 방식이었습니다.
OS 가상화
VMware 또는 VirtualBox와 같은 가상머신은 호스트 OS 위에 게스트 OS 전체를 가상화하여 사용하는 방식을 말합니다.
해당 방식은 여러가지 OS를 가상화할 수 있고 비교적 사용법이 간단하지만, 무겁고 느려서 운영환경에서 사용하기 어렵습니다.
이러한 상황을 개선하기 위해서 "CPU 가상화" 기술을 이용한 KVM 과 반가상화 방식의 Xen이 등장합니다. 이는 게스트 OS가 필요하긴 하지만, 호스트 OS 전체를 가상화 하는 방식이 아니였기 때문에 OS_가상화에 비해서 성능이 향상되었습니다.
하지만, 이러한 가상화 방식은 성능 문제로 인해 사용이 어려웠고, 이를 개선하기 위해 프로세스를 격리하는 방식 이 등장합니다.
Linux에서는 해당 방식을 "Linux Container" 라고 하며, 메모리는 프로세스가 필요한 만큼만 사용되므로 가볍고 빠르다는 장점이 있습니다. 이는 도커 컨테이너의 origin 입니다.
하나의 서버 내 여러개의 컨테이너를 실행하면 서로 영향을 미치지 않고 독립적으로 실행되며, 가벼운 VM을 사용하는 느낌을 줍니다.

도커에서 가장 중요한 개념 중 하나인 "이미지"라는 개념이 있습니다.
이미지는 컨테이너 실행에 필요한 파일과 설정값 등을 포함하고 있는 것으로 상태값을 가지지 않고 변하지 않습니다.(Immutable) 컨테이너는 이미지를 실행한 상태를 의미하며, 변하는 값은 컨테이너에 저장됩니다.
하나의 이미지로 복수의 컨테이너를 생성할 수 있고 컨테이너의 상태가 바뀌거나 컨테이너가 삭제되더라도 이미지는 변하지 않고 그대로 남아있습니다. 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 추가적인 의존성이 필요없습니다.
즉, 새로운 서버를 추가하기 위해서는 이미지를 다운받고 컨테이너로 실행만 해주면 됩니다.
도커 이미지는 DockerHub에 등록하거나 Docker Registry 저장소를 직접 만들어서 관리할 수 있습니다.
저장방식 관련 Docker 공식 사이트 설명 정리
도커 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 일반적으로 용량이 수백 메가바이트에 달합니다. 처음 이미지를 다운로드 받을 때에는 크게 부담되지 않지만, 기존 이미지에 파일이 추가되어 업데이트가 필요할 때, 수백 메가바이트를 다시 다운받게 되면 매우 비효율적일 수 밖에 없습니다.
도커는 이러한 문제를 해결하기 위해서 레이어(Layer) 라는 개념을 사용하고 "유니온 파일 시스템"을 이용하여 여러 개의 레이어를 하나의 파일 시스템으로 사용할 수 있게 해줍니다.이미지는 여러 개의 읽기 전용(ReadOnly) 레이어로 구성되고 파일이 추가되거나 수정 시 새로운 레이어가 생성됩니다.
예를 들면, Layer A + Layer B + Layer C로 구성된 ubuntu라는 이미지가 존재할 때, nginx 이미지를 추가해야하는 경우, ubuntu에 nginx라는 레이어가 추가된 새로운 이미지를 생성하며, mysql 이라는 레이어를 추가할 경우, nginx 레이어에 mysql 레이어를 합친 mysql 이미지가 생성됩니다.
이러한 구조에서는 DB를 다른 이미지로 변경할 때, mysql 레이어만 oracle 레이어로 변경만 해주면 되기 때문에 효율적으로 관리할 수 있습니다.
컨테이너를 생성 시에도 레이어 방식을 사용하는데 기존의 이미지 레이어들에 읽기/쓰기(read-write) 레이어를 추가합니다. 이미지 레이어를 그대로 사용하면서 컨테이너가 실행 중에 생성하는 파일이나 변경된 내용은 읽기/쓰기 레이어에 저장하면 되므로 여러 개의 컨테이너를 생성하더라도 최소한의 용량으로 관리가 가능합니다.
이미지는 url 방식으로 관리하며 태그를 붙일 수 있습니다. 예를 들면, ubuntu 14.04 이미지는 docker.io/library/ubuntu:14.04 이고 이를 생략한 것입니다. 이러한 방식은 사용자의 이해를 쉽게 해주고 편리하게 사용할 수 있도록 제공해줍니다.
도커 이미지를 만들기 위해 Dockerfile 이라는 파일에 자체 DSL(Domain-Specific Language) 언어를 사용하여 이미지 생성 과정을 정의해줍니다. 이러한 문법은 간단하여 사용이 편리합니다.
도커 이미지의 용량은 보통 수백 메가바이트로 기가바이트를 넘는 경우도 있습니다. 이렇게 큰 용량의 이미지를 서버에 저장하고 관리하는 것은 쉽지 않은데 도커는 DockerHuub를 통해 공개 이미지를 무료로 관리해줍니다.