
Docker는 애플리케이션을 신속하게 구축, 테스트 및 배포할 수 있는 소프트웨어 플랫폼이다. Docker는 소프트웨어를 컨테이너라는 표준화된 유닛으로 패키징하며, 이 컨테이너에는 라이브러리, 시스템 도구, 코드, 런타임 등 소프트웨어를 실행하는 데 필요한 모든 것이 포함되어 있다. Docker를 사용하면 환경에 구애받지 않고 애플리케이션을 신속하게 배포 및 확장할 수 있으며 코드가 문제없이 실행할 수 있다.
Docker의 장점
1. 의존성 문제를 해결해준다
어떤 애플리케이션은, 해당 애플리케이션을 실행하기 위해 반드시 어떤 환경이 구축되어 있어야 한다.

예를 들어 우리는 이와 같이 어떤 프로그램(A) 실행에 다른 프로그램(B)이 반드시 필요한 경우, "프로그램 A는 프로그램 B에 의존 관계를 가지고 있다"라고 말할 수 있다.
또한 A라는 프로그램과 B라는 프로그램이, php라는 프로그램에 대해 의존 관계를 가질 때에, 특정 php 버전을 요구하는 경우가 생길 수 있다.
A는 php v6를 요구하지만 B는 php v7을 요구할 때 일반적으로 한 컴퓨터에 여러 버전의 동일한 애플리케이션이 설치되지 않으므로, 이 경우에는 php의 의존 관계를 가지고 있는 다른 두 애플리케이션 중에 하나는 제대로 된 실행을 보장할 수 없으며 이런 상황을 우리는
"의존성이 충돌한다" 라고 말한다.
컨테이너 기술은 바로 이 문제를 해결한다. 컨테이너 기술은 애플리케이션을 컨테이너 내에 구성하기 때문에 컨테이너에서 실행 중인 애플리케이션은 어떠한 의존성도 공유하지 않아 각자의 고유의 의존성을 포함하고 있다는 말이다.

이는 각 컨테이너가 철저하게 실행 환경이 격리되어 있기 때문에 가능한 것이다.
컨테이너는 뭘 격리할까?
- 프로세스
특정 컨테이너에서 작동하는 프로세스는 기본적으로 그 컨테이너 안에서만 액세스할 수 있다.
컨테이너 안에서 실행되는 프로세스는 다른 컨테이너의 프로세스에게 영향을 줄 수 없다.
- 네트워크
기본으로 컨테이너 하나에 하나의 IP 주소가 할당되어 있다.
- 파일 시스템
컨테이너 안에서 사용되는 파일 시스템은 구획화되어 있으므로 해당 컨테이너에서의 명령이나 파일 등의 액세스를 제한할 수 있다.
Docker의 장점
2. 개발과 배포 환경을 일치시킨다
개발팀의 문제
Node.js나 Python 등을 이용하여 웹 서비스를 개발하는 개발팀을 생각해보자.
여러 개발자가 하나의 애플리케이션을 만들기 위해, 보통 비슷한 개발 환경을 구축하기 마련이다.
특정 버전 이상의 Node.js, 특정 버전의 MySQL 등을 개발자 각자가 본인의 운영체제에 설치하고, 그 후에 개발을 진행하지만 보통의 경우 그 과정이 빠르게 진행되지 않는다.
애플리케이션을 실행시키기 위해 OS나 Node.js나 Python과 같은 런타임 환경의 버전을 얼추 비슷하게 맞춰야 하는 것은 물론이고, 시스템 환경 변수를 애플리케이션에 맞게 구성해야 제대로 작동하는 경우도 종종 볼 수 있다.
다음은 공식 문서에 있는 우분투에 PostgreSQL을 설치하는 과정이다.
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt-get update
sudo apt-get -y install postgresql
반면에, CentOS에서 PostgreSQL을 설치하려면 다음과 같은 과정을 거친다.
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
sudo dnf -qy module disable postgresql
sudo dnf install -y postgresql14-server
sudo /usr/pgsql-14/bin/postgresql-14-setup initdb
sudo systemctl enable postgresql-14
sudo systemctl start postgresql-14
이러한 과정 중에 발생하는 사소한 실수나 사전 설치 항목의 부재는 문제 해결에 많은 시간을 소모하게 하며 특히 새로운 프로젝트에 투입되는 개발자의 경우, 그저 애플리케이션을 돌리고 싶었을 뿐인데, 그 길까지 가는 과정이 매우 험난하다.
도커는 이러한 문제를 해결해주며 도커가 실행 중이라면, 어떠한 운영체제든 상관없이 다음 명령어로 즉시 PostgreSQL을 설치하고 실행할 수 있다.
docker run --name postgres -e POSTGRES_PASSWORD=mysecret -d postgres
지금은 단일 소프트웨어 패키지 하나의 사례를 들었지만, 애플리케이션 구성 자체가 컨테이너화 되면 (이때 보통 Docker Compose라는 툴을 이용한다) YAML 파일 하나 + 명령어 하나로 모든 애플리케이션 실행 환경 구성이 완료되는 기적을 볼 수 있다.
docker-compose up
즉, OS에 상관없이 즉시 애플리케이션 실행 환경을 만들 수 있고 개발을 컨테이너 위에서 진행할 경우, 모든 개발팀이 동일한 환경 하에 개발을 진행할 수 있다.
배포 시의 문제
앞서 설명한 실행 및 개발 환경의 일치 이슈는 서비스 배포 환경에서도 동일하게 적용될 수 있다. 웹 서비스의 배포란 "어떤 애플리케이션이 특정 런타임 환경 위에서 실행되고, 사용자에게 이를 제공한다"는 것인데, 이는 앞서 말한 실행 환경 구성과 본질적으로 다를 것이 없기 때문이다. 그저 서비스를 인터넷상에 공개적으로 노출하느냐, 내 컴퓨터 상에서 프라이빗하게 작동하느냐의 차이일 뿐이다.
그래서 이제는 배포의 패러다임이 달라졌다. 서버에 파일 하나하나를 업로드하는 방식은 이전의 방식이라고 볼 수 있다. 서버도 이제는 컨테이너에 담긴 애플리케이션을 실행하는 방식으로 서비스를 제공한다.
따라서 Amazon Web Service의 EC2 상에 도커를 설치하거나, 또는 좀 더 편리하게 도커 컨테이너를 EC2 서버에서 실행할 수 있게 하는 서비스인 ECS를 이용하여 보다 쉽게 애플리케이션을 배포할 수 있다.

Docker의 장점
3. 수평 확장을 쉽게 해주며 각 서버에 새로운 내용을 배포하기 쉽게 해 준다.
우리가 매일같이 사용하는 글로벌 웹 서비스는 전 세계인들이 사용하므로 그 트래픽이 어마어마하다. 예를 들어, 지금 이 시간에도 전 세계의 수많은 사람들이 google.com 에 접속할 텐데, 수많은 사람들이 검색 서버라는 단 하나의 컴퓨터에 접속은 불가능하다.
서비스 제공자들은 이러한 트래픽 분산을 위해 프록시 서버를 운영하며, 프록시 서버는 여러 대의 동일한 검색 서버 중 한 군데를 이용할 수 있도록 돕는다. (이러한 서버를 리버스 프록시의 한 종류인 '로드 밸런서'라고 부른다)

컨테이너 기술의 가장 큰 장점은 실행 환경의 일치이다. 더 많은 트래픽으로 인한 서버 증설에 컨테이너 기술은 아주 활발하게 이용되고 있으며 동일한 애플리케이션 구성(이미지)을 바탕으로 새로운 서버에 해당 애플리케이션을 컨테이너로 실행하고, 로드 밸런서에 이 서버를 추가하기만 하면 된다. (심지어 AWS는 서버를 만들고 삭제하는 일을 자동으로 해줍니다!)
이러한 기술을 응용하여, 새로운 버전의 애플리케이션을 여러 서버 중 몇 대에만 운영하여 테스트하는 방법도 가능하다. 이를 통해 새 버전의 애플리케이션에서 발생할 수 있는 문제들을 미리 확인하고, 이러한 문제가 사용자 전체에게 영향을 끼치지 않도록 만들 수도 있다.

Docker 핵심 키워드
컨테이너
애플리케이션이 의존성, 네트워크 환경, 파일 시스템에 구애받지 않고, 도커라는 기술 위에 실행될 수 있도록 만든 애플리케이션 상자이다.
이미지
실행되는 모든 컨테이너는 이미지로부터 생성되며 이미지는 애플리케이션 및 애플리케이션 구성을 함께 담아놓은 템플릿으로, 이를 이용해 즉시 컨테이너를 만들 수 있다.
이미지를 이용해 여러 개의 컨테이너를 생성할 수 있으며 이를 이용해 앞서 설명한 애플리케이션의 수평 확장이 가능하다.
이미지는 기본 이미지(base image)로부터 (마치 git을 사용하는 것처럼) 변경 사항을 추가/커밋해서 또 다른 이미지를 만들 수도 있다.
예를 들어 node.js로 작성된 애플리케이션을 이미지로 만들고 싶은 경우, nodejs 이미지를 기본 이미지로 삼고 내가 만든 애플리케이션을 추가해 넣고, 이미지화할 수 있다.
레지스트리
이미지는 레지스트리에 저장된다. 대표적인 이미지 레지스트리로는 Docker Hub, Amazon ECR이 있습니다. 도커 CLI에서 이미지를 이용해 컨테이너를 생성할 때, 호스트 컴퓨터에 이미지가 존재하지 않는다면, 기본 레지스트리(Docker Hub)로부터 다운로드 받게 된다.
컨테이너와 가상머신(VM)의 비교
컨테이너 기술과 가상 머신은 둘 다 프로세스, 네트워크, 파일 시스템을 격리할 수 있다는 장점을 공유하지만 둘의 작동원리는 많이 다르다.
VM을 사용해본 경험이 있다면, VM을 만들고 실행하는 과정이 많은 컴퓨팅 자원을 필요로 한다는 점을 체감했을 것이다. 이에 비해, 도커는 한 호스트 컴퓨터에 여러 개의 컨테이너를 띄워도 크게 컴퓨터에 무리가 가지 않는다.
또 하나의 특징은, Docker Hub Registry를 통해 이미지를 살펴보면, 도커 이미지는 (운영체제 이미지도 존재하지만) 보통 애플리케이션 단위로 만들어져 있음을 알 수 있다. 반면 VM을 사용하기 위해서는 해당 VM 위에 운영체제(OS, Operating System)를 설치해야 하는 과정을 반드시 거치게 되어 있다.

컨테이너 기술과 VM의 작동 원리

왼쪽의 VM의 구성 요소에 OS가 존재하는데 비해, 오른쪽의 도커 컨테이너에는 OS를 포함하고 있지 않다. 다만, 도커라는 플랫폼 위에 컨테이너들이 올라가 있고, 그 아래 호스트 OS가 존재한다.
이를 통해, 각 컨테이너는 호스트 OS의 커널(시스템 콜과 같이 OS의 핵심 기능을 구현한 프로그램)을 공유하고 있음을 짐작할 수 있다.
도커는 애플리케이션을 컨테이너화해서 실행하는 데에 주 목적이 있으므로, 특별히 컨테이너에 OS를 올려서 사용하지 않으며 호스트 OS의 입장에서 컨테이너 하나는 프로세스 하나에 불과하다.
컨테이너에 OS를 올리지 않는데, Docker Hub에 존재하는 각종 OS 이미지는 무엇일까?
잘 알려진 리눅스 배포판인 우분투, CentOS 등은 결국 동일한 리눅스 커널 위에서 만들어진 것이다. 각자가 고유의 디렉토리 구조, 패키지 시스템(apt, yum), 쉘(bash, zsh) 등을 사용했을 뿐이다. OS 이미지는 컨테이너 내 애플리케이션 구성의 편의를 위해 존재하는 이미지이며 우분투, CentOS 이미지를 사용한다고 해도 결코 컨테이너에 커널 수준의 OS가 올라가지 않는다.
하이퍼바이저는 VM을 생성하고 구동하는 소프트웨어를 의미합니다. 하이퍼바이저에도 유형이 다양하게 존재하지만, 지금은 일단 VMware, VirtualBox 와 같은 프로그램이 하이퍼바이저라는 것 정도만 알아도 충분하다.
윈도우나 macOS용 도커를 살펴보면 컨테이너 안쪽은 리눅스로 작동됩니다. 윈도우나 macOS는 리눅스가 아닌데, 어떻게 컨테이너 안에서 리눅스 기반으로 작동하는 것일까?
윈도우나 macOS는 근본적으로 리눅스 커널을 쓰고 있지 않으므로, 해당 운영체제의 경우 리눅스 커널을 VM의 형태로 실행시키는 하이퍼바이저(Hyper-V, LinuxKit, HyperKit)를 자체적으로 구동합니다. 윈도우용 또는 macOS용 도커는 하이퍼바이저 위의 리눅스 커널을 사용하는 것이다. 보다 자세한 내용은 각자의 하이퍼바이저 설명 문서를 참고하세요.
한가지 재미있는 것은, 윈도우용 도커는 윈도우 커널을 사용한 윈도우 전용 컨테이너를 실행할 수 있는 기능을 제공합니다. 컨테이너는 커널을 공유하므로, 윈도우 커널을 사용하는 컨테이너는 리눅스용 도커에서 사용할 수 없습니다.
도커 이용하기
docker/whalesay
docker/whalesay 라는 이미지로 예제를 실습하며 먼저 제공된 이미지를 읽을 수 있어야 한다.

docker/whalesay는 레지스트리 계정, 레포지토리 이름, 태그 세 가지 정보로 구성되어 있다.
- 레지스트리(Registry)
- Docker Hub : https://hub.docker.com/
- 도커 이미지를 관리하는 공간이다.
- 특별히 다른 것을 지정하지 않는다면, 도커 허브(Docker Hub)를 기본 레지스트리로 설정한다.
- 레지스트리는 Docker Hub, Private Docker Hub, 회사 내부용 레지스트리 등으로 나뉠 수 있다.
- 레포지토리(Repository)
- 레지스트리 내에 도커 이미지가 저장되는 공간이다.
- 이미지 이름이 사용되기도 한다.
- GitHub의 레포지토리와 유사하게 생각하면 된다.
- 태그(Tag)
- 같은 이미지라고 할지라도 버전 별로 안의 내용이 조금은 다를 수 있다.
- 해당 이미지를 설명하는 버전 정보를 주로 입력한다.
- 특별히 다른 것을 지정하지 않는다면 latest 태그를 붙인 이미지를 가져온다.
docker/whalesay:latest 라는 문장을 다시 읽어보면, 다음와 같이 읽을 수 있다.
- Docker Hub라는 레지스트리에서
- docker라는 유저가 등록한 whalesay 이미지 혹은 레포지토리에서
- latest 태그를 가진 이미지
사용할 이미지를 확인했으니, 사용하는 방법을 알아보자.
Docker Hub는 Docker Image를 찾거나, Docker Image의 사용방법을 확인할 때 사용할 수 있다.
Docker Example 수행하기 : docker/whalesay

docker image pull docker/whalesay:latest
docker/whalesay의 최신 이미지를 받아옵니다.
docker pull docker/whalesay
docker/whalesay를 받아옵니다.

docker image ls
docker image 조회

그 후 받아온 이미지를 실행합니다. (이미지 → 컨테이너)

docker container run --name 컨테이너_이름 docker/whalesay:latest cowsay boo
컨테이너_이름을 이름으로 갖는 컨테이너를 실행합니다.
- {container} run
- 컨테이너를 실행한다.
- [OPTIONS]
- --name : 컨테이너의 이름을 할당한다.
- [COMMAND]
- command는 초기 컨테이너 실행 시 수행되는 명령어이다.
- cowsay : 컨테이너 실행 시 cowsay 명령어를 호출이며 node를 호출하듯 이용합니다.
- [ARG..]
- boo : COMMAND인 cowsay에 넘겨질 파라미터이다.

docker container ps -a
모든 컨테이너의 목록보기

docker container rm 컨테이너_이름
컨테이너 삭제

# docker image 의 용량 확인
docker image ls
# docker/whalesay 이미지 지우기
docker image rm docker/whalesay


이미지를 받아와 컨테이너로 실행하고, 컨테이너와 관련된 리소스를 삭제하는 작업까지 이번에는 세 가지 작업을 한 번에 실행해 보겠다.
docker container run --name 컨테이너_이름 --rm docker/whalesay cowsay boo
- {container} run : 컨테이너를 실행합니다. 이미지가 없다면 이미지를 받아온 뒤(pull) 실행합니다.
- --rm : 컨테이너를 일회성으로 실행합니다. 컨테이너가 중지되거나 종료될 때, 컨테이너와 관련된 리소스를 모두 제거합니다.
Docker Example 수행하기 : danielkraic/asciiquarium
docker container run -it --rm danielkraic/asciiquarium:latest
#danielkraic라는 사람이 올린 이미지 asciiquarium 를 일회성으로 실행합니다.
- -it : -i, -t 를 동시에 사용한 옵션이다. 사용자와 컨테이너 간에 인터렉션(interaction)이 필요하다면 이 옵션을 사용한다. 이 예제에서는 출력되는 화면을 사용자가 지속적으로 보기 위해서 사용하였다. 예를 들어 Python 명령이 필요하거나 추가로 다른 입력을 받는다면, 이 옵션을 지정한 뒤 사용한다.

- container는 ctrl + c 로 종료할 수 있다.
Docker 컨테이너에 파일을 복사하기
앞선 내용에서는 사용할 모든 파일이 하나의 이미지에 구성되어 있고, 그 이미지를 사용하는 방법을 학습했다. 그러나 게임 서버, 웹 서버와 같이 여러분이 사용할 도구가 도커 이미지에 모두 구성되어 있지 않은 경우도 있다.
예를 들면
- 웹 서버는 도커 컨테이너로 실행
- 웹 서버를 구성하는 파일은 직접 만들거나 가져온 파일 구성
- 장점
- 서버에 문제가 생기는 것을 호스트와 별개로 파악할 수 있음
- 문제가 생긴 서버를 끄고, 마치 공장 초기화를 하듯 도커 이미지로 서버를 재구동할 수 있음
로컬에 있는 파일과 도커 이미지를 연결하는 방법은 CP(Copy) 를 이용하는 방법과 Docker Volume 기능을 이용하는 방법으로 나뉜다.
- CP(Copy) : 호스트와 컨테이너 사이에 파일을 복사(Copy)
- Volume : 호스트와 컨테이너 사이에 공간을 마운트(Mount)
마운트는 저장 공간을 다른 장치에서 접근할 수 있도록 경로를 허용해서, 하나의 저장 공간을 이용하는 것처럼 보이게 하는 작업을 말한다.
httpd 웹 서버
게임 서버 파일은 codestates/pacman-canvas git 저장소에서 확인할 수 있으며 서버를 위한 동작, 그림, 사운드 파일이 모두 있고 웹서버에 업로드하여 사용한다.
사용할 도커 이미지는 httpd(http daemon)이며 httpd는 Apache HTTP Server를 실행할 수 있는 오픈소스 웹 서버 소프트웨어이며 /usr/local/apache2/htdocs/ 경로에 웹 서버와 관련된 파일들이 저장되어 있다면, 해당 파일을 기반으로 웹 서버가 실행되도록 한다.
먼저, git에서 pacman 서버파일을 클론한 후 docker container run 명령어로 httpd 를 실행한다.
docker container run --name 컨테이너_이름 -p 818:80 httpd
- -p 옵션은 로컬호스트의 포트와 컨테이너의 포트를 연결하는 것이며 818포트가 로컬호스트의 포트고, 80번은 컨테이너의 포트다.
- httpd 는 일정 시간 연결 기록이 없으면, 서버 가동이 중지되니 실행 중이던 도커 컨테이너가 중지되었다면, 다시 실행하면 된다.
- 터미널에서 명령어를 입력했을 때, 터미널의 작동이 중단된 것처럼 보여도 정상적인 상태이므로 터미널을 종료하지 말고, 다른 터미널 창을 열어 계속 진행한다.
- -d 옵션을 사용하면 백그라운드에서 실행하게 해준다.


--?-- 127.0.0.1 과 localhost 를 이용하면 로컬 컴퓨터의 IP 주소로 redirecting 할 수 있습니다. 또, DNS 설정으로 인해 localhost 로 접속이 안 되고 127.0.0.1 만 접속이 될 수 있습니다
서버가 열린 것을 확인 후 새로운 터미널을 열어 docker container cp 명령어를 입력해 로컬호스트에 있는 파일을 컨테이너에 전달한다.
docker container cp ./ 컨테이너_이름:/usr/local/apache2/htdocs/
- docker container cp 명령은 앞 경로의 파일을 뒤 경로에 복사합니다.
- 위의 명령어를 로컬 터미널에서 실행할 때, 위치는 pacman-canvas 디렉토리여야 합니다.
위 명령어로 pacman-canvas의 파일이 컨터이너의 /usr/local/apache2/htdocs/로 복사되어서 해당 파일이 서버에 돌아가는 모습이다.

컨테이너를 다룰 때, 제대로 되지 않는다면 docker exec -it 컨테이너_이름 bash 명령어를 통해 컨테이너 내부 터미널로 접속할 수 있다.

Docker 이미지 만들기
이번에는 앞서 만들어 본 Docker Container를 이미지 파일로 변환해볼거다. 이미지로 만들어 놓을 때의 장점은 다음과 같다.
- 이전에 작업했던 내용을 다시 한 번 수행하지 않아도 됨
- 배포 및 관리가 유용
다음에서 이미지를 만드는 방식 두 가지를 설명한다.
1. 구동한 Docker Container를 이미지로 만드는 방법
docker container commit 컨테이너_이름 my_pacman:1.0
docker container commit 명령을 이용해 구동안 컨테이너를 커밋하면 이미지(my_pacman)이 만들어진다.

그 후 생성된 이미지를 컨테이너로 실행한다.
docker run --name new -p 900:80 my_pacman:1.0


2. Docker Image 빌드를 위한 파일인 Dockerfile 로 만드는 방법
- Dockerfile 공식 문서
- Dockerfile 을 만들고, Dockerfile 대로 이미지를 build 하는 방법입니다.
- Dockerfile 은 이미지 파일의 설명서라고 생각하면 좋다.
FROM httpd:2.4 # 베이스 이미지를 httpd:2.4 로 사용합니다.
COPY ./ /usr/local/apache2/htdocs/ # 호스트의 현재 경로에 있는 파일을 생성할 이미지 /usr/local/apache2/htdocs/ 에 복사합니다.
#[코드] 현재 경로에 있는 파일(./)을 생성할 이미지 경로(/usr/~/htdocs)에 복사하는 명령의 Dockerfile 소스 코드입니다.

그 후 docker build 명령으로 Dockerfile을 도커 이미지 파일을 생성합니다.
# --tag 는 name:tag 형식으로 이미지를 생성할 수 있습니다.
# 지정한 경로에 있는 Dockerfile을 찾아서 빌드합니다.
docker build --tag my_pacman:2.0 . # "."을 명령어에 꼭 포함해야 합니다!


그 후 이미지를 컨테이너로 실행 시키면 된다.
docker run --name #컨테이너이름 -p 901:80 이미지:태그
#컨테이너이름에 이미지:태그를 로컬 901포트, 도커 80포트으로 실행한다


Part 1 - 한 개의 Docker Image를 다루는 방식 연습
Quiz 1: 브라우저 속 게임 화면의 특정 단어를 확인하세요.
- 이미지는 sebcontents/part1을 이용해야 합니다. 태그는 latest 입니다.
- sebcontents/part1은 아파치 웹 서버 이미지(httpd)를 기반으로 commit된 새로운 이미지 입니다.
- Docker Hub에 저장되어 있는 이미지를 사용하는 경우, repository에 작성된 안내 사항을 확인하는 습관을 들이는 것이 중요합니다.
- sebcontents/part1 이미지의 repository로 이동하여 안내 사항을 참고하고, 컨테이너를 생성합니다.
- 컨테이너를 통해 space 게임을 실행해보세요. 소스 코드는 https://github.com/codestates/SpaceInvaders에 있습니다.
- 게임 실행 후 다음 그림의 빨간 박스에 들어갈 단어가 무엇인지 확인하세요. Quiz 1의 정답입니다.
먼저 컨테이너에서 실행시킬 게임 파일을 클론한 후 sebcontents/part1의 이미지를 pull 한다.

그 후 pull한 이미지를 컨테이너로 실행 시킨다.


그 후 클론한 게임 파일을 컨테이너에 httpd 경로를 지정해준뒤 복사해넣는다.


그럼 정상적으로 실행되고 퀴즈의 답은 "Lives" 이다.
Quiz 2: 컨테이너 속 txt 파일 안에 있는 단어를 확인하세요.
- docker exec 명령어를 이용해 실습을 진행합니다.
- 컨테이너_이름 부분에는 quiz1 실습 과정에서 사용한 컨테이너의 이름을 입력하면 됩니다.
- 터미널을 열어 다음 명령어를 입력합니다.
docker exec -it 컨테이너_이름 bash
- 접속에 성공하면, 다음 과정을 순서대로 진행합니다.
- cd / 명령어를 입력하여 루트 디렉토리로 이동합니다.[커맨드] 루트 폴더로 이동합니다.
- ls 명령어를 입력하여 루트 디렉토리에 data 폴더가 존재하는지 확인합니다.[커맨드] data 폴더를 확인합니다.
- data 폴더로 이동하여 ls 명령어를 입력합니다. quiz2.txt 파일이 존재하는지 확인합니다.
- 명령어 apt update 와 apt install nano 를 입력해 nano 텍스트 에디터를 설치합니다.
- nano quiz2.txt 명령어를 입력해 quiz2.txt 파일 안에 적힌 단어를 확인합니다. Quiz 2의 정답입니다.
- 컨테이너 터미널은 exit명령어를 통해 종료할 수 있습니다.


퀴즈의 정답은 "Kimcoding" 이다.
Part 2 - 두 개의 Docker Image를 다루는 방식 연습
이번 실습에는 두 개의 이미지를 사용합니다.
- nginx 이미지를 기반으로 한 sebcontents/client 이미지를 이용하여 client 컨테이너를 생성합니다.
- node 이미지를 기반으로 한 sebcontents/server 이미지를 이용하여 server 컨테이너를 생성합니다.

- 이번 실습에서는 localhost 의 8080 번 포트로 접속하면, sebcontents/client 이미지를 이용해 배포한 client 컨테이너의 80 번 포트로 연결됩니다.
- 위 그림은 매우 간략하게 표현되어 있습니다. 도커 네트워크에 대해서 좀 더 궁금하시다면 docker network, docker bridge 를 검색해 더 많은 정보를 찾을 수 있습니다.
docker-compose CLI
- Docker compose docs
- [주의] Ubuntu 운영체제를 통해 실습을 진행한다면, 모든 명령어 앞에 sudo 명령어를 붙여야 합니다.
docker-compose up # -d 옵션을 함께 사용하면, 컨테이너를 백그라운드로 실행할 수 있습니다.
#docker-compose.yaml에 정의된 이미지를 컨테이너로 실행합니다.
docker-compose down
#docker-compose.yaml에 정의된 이미지를 이용해 실행된 컨테이너를 종료합니다.
docker-compose up {특정 이미지}
#특정 이미지만 컨테이너로 실행합니다.
두 개 이상의 도커 컨테이너를 연결하는 docker-compose를 사용해 보겠습니다.
- 다음의 설명에 따라 docker-compose.yaml 파일을 생성하세요.
- 소스 코드는 이미 작성되어 있습니다.
- docker-compose up -d을 통해 컨테이너를 구동하세요.
- 결과를 localhost:8080 혹은 127.0.0.1:8080 에서 확인하세요.
Quiz 3 : client와 server를 동시에 구동해 로그인 후 나타나는 단어를 확인하세요.
- docker-compose.yaml
- yaml, yml은 같은 확장자입니다.
- 하나의 docker-compose에서 관리되는 컨테이너끼리는 동일한 docker network에서 구동됩니다.
- docker run 명령과 다르게 docker-compose 파일 안에서 기본 network가 사용됩니다.
먼저 docker-compose.yaml 혹은 docker-compose.yml 파일을 위의 소스를 그대로 붙여넣어 생성합니다. 파일을 생성할 때 터미널의 위치는 무관합니다.

그 후 yaml 파일이 있는 위치에서 docker-compose up -d명령어를 통해 yaml 파일을 실행합니다.

브라우저에서 localhost:8080 혹은 127.0.0.1:8080 에서 실행된 client 화면을 확인한 후, 로그인 합니다. 로그인 정보는 브라우저 화면을 확인하세요.

로그인 후 나오는 단어를 확인하세요. Quiz 3의 정답입니다.
정답은 "노트북" 이다.
Advanced (optional)
Advanced 실습을 통해 다음 개념을 학습합니다.
- Volume
- 환경 변수 설정하기
도커에는 volume이라는 개념이 있습니다. 아래의 레퍼런스를 참조해 볼륨이라는 개념을 학습하고, 다음 가이드를 따라 실습을 진행해 보세요.
먼저 docker-compose.yaml 혹은 docker-compose.yml 파일을 다음의 내용을 그대로 붙여넣어 생성합니다. 파일을 생성할 때 터미널의 위치는 무관합니다.

- Docker Hub의 mysql 이미지의 description 을 잘 읽고, 환경 변수 설정과 사용 방법을 학습하세요.
docker-compose를 통해 컨테이너가 제대로 실행되었다면 로컬의 yaml 파일이 위치한 곳에 volumefolder 라는 디렉토리를 확인할 수 있습니다. volumefolder 디렉토리 속에 임의의 텍스트 파일 하나를 생성합니다.



docker exec -it server sh 명령어를 통해 server 컨테이너 터미널로 접속한 후, 컨테이너 터미널에서 cd /data 명령어를 입력해 data 디렉토리로 이동합니다.
server 컨테이너의 /data위치에 2번 과정에서 여러분이 로컬에서 생성했던 임의의 텍스트 파일이 존재하는지 확인합니다.

'TIL' 카테고리의 다른 글
| 30일차 docker, yaml (0) | 2022.05.30 |
|---|---|
| 29일차 docker (0) | 2022.05.30 |
| 27일차 aws (0) | 2022.05.30 |
| 26일차 aws (0) | 2022.05.23 |
| 25일차 AWS (0) | 2022.05.22 |