본문 바로가기

Development/Web

Docker 포트포워딩과 드라이브 연결

들어가며

이번에는 도커 컨테이너의 네트워크와 드라이브를 설정하는 방법에 대해서 정리해보았다. 이 글을 이해하려면 웹 서비스의 전체적인 동작 원리, 포트포워딩 등의 사전 지식이 필요하다. 본 개발일지에는 사전 지식에 필요한 내용도 일부 정리해놓았으나, 이해가 되지 않는다면 관련 영상이나 글을 통해 학습하길 바란다.

Port Forwarding

일반적인 웹 서버가 동작하는 방식은 아래 그림과 같이 나타낼 수 있다.

위 그림을 설명하자면, 클라이언트가 test.com:80/index.html을 요청하면 서버 PC에 설치된 Apache에 지정된 파일 경로에서 index.html을 찾아 클라이언트에게 보내주는 것이다. 반면, 도커 컨테이너로 동작하는 웹 서버도 위의 그림과 유사하긴 하나, 호스트와 컨테이너 간 포트를 연결해주는 포트포워딩을 해주어야 한다.

컨테이너를 실행할 때 아래 명령어와 같이 '-p 옵션을 추가로 입력하면, 호스트의 포트와 컨테이너의 포트를 연결할 수 있다.

$ docker run -p {host port}:{container port} {image}

이해를 돕기 위해 한 가지 예를 들어보자. 클라이언트가 호스트의 2000번 포트로 웹 페이지를 요청했을 때, 이를 컨테이너의 80번 포트와 연결하려는 경우 아래와 같이 입력하면 된다.

$ docker run --name test -p 2000:80 httpd

위 예시의 httpd 이미지는 기본 포트가 80포트로 설정되어 있기 때문에 컨테이너의 80 포트와 연결해주었다. 이처럼 이미지마다 기본으로 정해진 포트가 다를 수 있기 때문에 docker hub에서 해당 이미지에 대한 설명을 읽어보아야 한다.

컨테이너 제어

위의 명령어를 실행해서 호스트의 2000번 포트와 httpd 이미지가 실행되는 컨테이너의 80번 포트를 연결하고, http://localhost:2000로 접속해보자. 컨테이너가 정상적으로 실행 중이라면 'It works!'라는 문구가 웹 브라우저에 나타날 것이다. 이번에는 직접 컨테이너에 저장된 index.html 파일을 수정하는 방법에 대해서 알아보자.

컨테이너 쉘 연결

명령어를 통해 컨테이너를 직접 제어하기 위한 기본 명령어는 아래와 같다.

$ docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

먼저, 위의 예시를 통해 실행한 컨테이너의 pwd(print working directory)를 출력해보면 아래와 같다.

$ docker exec test pwd
/usr/local/apache2

이번에는 컨테이너의 파일 목록을 확인해보면 아래와 같다.

$ docker exec test ls
bin
build
cgi-bin
conf
error
htdocs
icons
include
logs
modules

컨테이너를 직접 제어할 때마다 위의 명령어를 사용해야 한다면 매우 번거로울텐데, 다행히도 아래 명령어를 사용하여 컨테이너에 직접 접속할 수 있다. 정확히 말하자면, 컨테이너의 쉘을 통해 컨테이너에 직접 접속한 것과 같은 기능을 사용할 수 있는 것이다.

$ docker exec test /bin/bash

위의 명령어를 실행하면 아무런 일도 일어나지 않는 것을 확인할 수 있는데, 이는 컨테이너의 쉘과 연결한 이후에 추가로 실행할 명령어가 없어 연결이 끊어졌기 때문이다. 따라서, 아래와 같이 위의 명령어에 '-it' 옵션을 추가하면 쉘을 지속시킬 수 있다.

$ docker exec -it test /bin/bash

'-it' 옵션은 '--interactive' 옵션과 --tty옵션을 결합한 것으로, 각각의 의미는 아래와 같다.

Option Description
--interactive, -i Keep STDIN open even if not attached
--tty, -t Allocate a pseudo-TTY

컨테이너 쉘과의 연결을 종료하고 싶다면, 아래 명령어를 입력하면 된다.

# exit

index.html 직접 수정

docker hub에서 httpd 이미지의 설명을 보면 /usr/local/apache2/htdocs/에 index.html 파일이 위치하고 있음을 알 수 있다.

FROM httpd:2.4
COPY ./public-html/ /usr/local/apache2/htdocs/

그렇다면 컨테이너에서 위에서 알아낸 경로에 접속하여 index.html을 수정하면 되지 않겠는가? 다시 아래 명령어를 입력하여 컨테이너의 bash에 접속하고, 위의 경로로 이동한 후 index.html이 있는지 확인해보자.

$ docker exec -it test /bin/bash

root@391d4b555a8a:/usr/local/apache2# cd /usr/local/apache2/htdocs
root@391d4b555a8a:/usr/local/apache2/htdocs# ls -al
total 16
drwxr-xr-x 2 root     root     4096 Jan 26 08:38 .
drwxr-xr-x 1 www-data www-data 4096 Jan 26 08:38 ..
-rw-r--r-- 1      504 staff      45 Jun 11  2007 index.html

이제 vim이나 nano 에디터로 index.html를 수정해보자.

root@391d4b555a8a:/usr/local/apache2/htdocs# vi index.html
bash: vi: command not found

root@391d4b555a8a:/usr/local/apache2/htdocs# nano index.html
bash: nano: command not found

위의 결과를 보면 현재 컨테이너에 에디터가 설치되지 않은 것을 확인할 수 있다. 이와 같이 컨테이너에는 당장 사용하지 않는 불필요한 소프트웨어는 설치되어 있지 않는 것을 알 수 있으며, 컨테이너의 '낮은 용량'이라는 특성으로 최대한의 성능을 발휘할 수 있는 것이다. 하지만, 실습을 위해 index.html을 수정해야 하니, 아래와 같이 입력하여 apt로 nano 에디터를 설치하도록 하자.

root@391d4b555a8a:/usr/local/apache2/htdocs# apt update
root@391d4b555a8a:/usr/local/apache2/htdocs# apt install nano -y

설치가 다 되었다면 nano 에디터로 index.html을 열고, 'Hello, Docker!'로 수정한다.

root@391d4b555a8a:/usr/local/apache2/htdocs# nano index.html

nano 에디터로 수정한 index.html을 저장하려면 키보드에서 ctrl + xyEnter 순으로 누르면 된다. 그리고 http://localhost:2000로 접속 또는 새로고침하면, 'It works!'가 'Hello, Docker!'로 변경된 것을 확인할 수 있다.

드라이브 연결

위에서는 컨테이너의 index.html 파일을 직접 수정하였는데, VScode 등의 에디터를 사용하지 못할 뿐더러 그러한 에디터를 컨테이너에 별도로 설치해야 하므로 매우 비효율적이고, 불편함을 느꼈을 것이다. 또한, 컨테이너 내부의 파일을 직접 수정하는 경우 해당 컨테이너가 의도치 않은 삭제, 시스템 상의 문제로 인해 사라졌을 때, 그 파일 정보를 더 이상 가져올 수 없는 위험성도 존재한다. 이와 같은 상황에 대비할 수 있는 방법이 있는데, 그것은 바로 호스트의 드라이브와 컨테이너의 드라이브를 연결하는 것이다. 이러한 방법을 도입하면, 컨테이너가 사라져도 호스트에 파일이 그대로 남아있으므로 비교적 안전한 개발이 가능하다. 먼저, 바탕화면에 docker 폴더를 생성하고, docker 폴더 안에 test 폴더를 생성한 후 index.html을 생성하여 적절하게 코드를 수정한다.

<!-- C:/Users/CHOEWY/Desktop/docker/test/index.html -->

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Docker Tutoruals</title>
</head>
<body>
    <h1>This is Host Drive!</h1>
</body>
</html>

명령 프롬프트에 아래와 같이 입력하여 docker 폴더와 컨테이너의 드라이브를 연결한다.

$ docker run --name test -p 2000:80 -v C:\Users\CHOEWY\Desktop\docker\test:/usr/local/apache2/htdocs/ httpd

컨테이너가 실행되면 http://localhost:2000으로 접속해보자. 그러면, 자신이 작성한 웹 페이지가 나타나는 것을 확인할 수 있다.

마치며

여기까지, 도커 기초 지식에 해당하는 내용을 정리해보았다. 이어서 도커 이미지를 만들고, Docker Hub에 commit 하는 내용에 대해서 정리해보겠다.