[Docker] 도커 기초 명령어 익히기

개요top

지난 글에서 도커(Docker)에 대해 간단히 소개하고 우분투 리눅스에 도커를 설치하는 방법을 공부했습니다.

[Docker] 도커 소개와 우분투에 Docker CE 설치하기

이번에는 원격 저장소에 있는 도커 이미지를 받아서 사용하는 방법을 살펴보기로 합니다. 다만, 윈도우 OS 환경에서 도커를 설치하고 연습해봅니다. 그 외에 기본적은 내용은 맥이나 리눅스와 같습니다.

1. 윈도우에 도커 설치하기top

윈도우 사용자를 위한 도커 설치 방법을 설명합니다. Mac도 대동소이 하니 문서를 참고하세요.

윈도우에서는 도커를 사용하기 위해 아래 2가지 중 한가지 방법을 선택합니다.

이 둘 중에 하나를 자신의 OS 환경에 맞게 설치하시길 바랍니다.

1.1 Docker Desktop 실행하기

윈도우 프로페셔널인 경우는 Docker Deskop을 설치합니다. 아마도 OS를 다시 실행해야 설치가 끝날 것입니다.

귀여운 도커 테스크탑 아이콘이 나오면 실행하시면 됩니다.

도커가 실행중이라면 화면 오른쪽 하단에 도커 실행 아이콘을 볼 수 있을 겁니다.

이 상태에서 cmd창에 들어갑니다. 명령 프롬프트 상에서 도커 명령어 중 버전을 확인하는 docker version을 실행합니다.

위 화면처럼 나온다면 제대로 설치된 것입니다.

1.2 Docker Quickstart Terminal 실행하기 – 도커 툴박스의 경우

윈도우 홈 OS인 경우에는 Docker Toolbox를 설치합니다. 구버전이고 비추천이지만 어쩔 수 없는 경우에는 사용해야 합니다.

실행하면 다음처럼 2개의 실행 아이콘이 있습니다. Kitematic은 도커를 쉽게 사용할 수 있도록 도와주는 UI 도구 정도로 보시면 됩니다. 이것은 사용하지 않습니다. 여기서는 Docker Quickstart Terminal만 사용합니다.

보시면 리눅스와 비슷한 환경이 보입니다. 여기서 바로 도커 명령어들을 실행해 볼 수 있습니다. 아래처럼 버전을 확인해 봅니다.

Docker Desktop과는 다른 환경이지만 지금부터 설명하는 내용은 동일하게 적용됩니다.

2. Hello world 로 도커 맛보기top

도커는 도커 허브를 통해 공용 도커 이미지 저장소를 지원해줍니다. 여기에는 다양한 이미지가 올라와 있습니다. 우리도 도커 허브에 이미지를 만들어서 올리고 공유할 수 있습니다. 지금은 이미지를 만드는 것이 아닌 이미 생성된 이미지로 도커 사용법을 익혀보겠습니다. 사용할 이미지는 hello-world입니다.

2.1 원격 저장소에서 로컬 저장소로 도커 이미지 가져오기 – pull 명령

도커 허브(원격 저장소)에서 Hello World 도커 이미지를 가져와서 로컬 저장소에 저장하겠습니다. docker pull hello-world를 입력하시고 실행하세요.

$ docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:2557e3c07ed1e38f26e389462d03ed943586f744621577a99efb77324b0fe535
Status: Downloaded newer image for hello-world:latest

tag가 latest이기 때문에 pull 명령을 실행할 때마다 새로운 이미지가 있으면 대체될 것입니다.

2.2 로컬 저장소의 이미지 리스트 확인 – images 명령

로컬에 이미지가 등록되었는지 확인하기 위해 docker images 명령을 실행하세요.

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              fce289e99eb9        6 weeks ago         1.84kB

로컬 저장소(Repository)에 이미지 ID fce289e99eb9로 잘 등록되었음을 확인할 수 있습니다.

2.3 컨테이너 등록과 실행 중인지 확인 – run 명령

로컬에 등록된 이미지를 컨테이너로 생성해 실행해 보겠습니다. docker run hello-worlddocker run hello-world:latest로 실행해 보세요. 참고로 이미지 명 뒤에 붙은 latest는 태그입니다.

$ docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

Hello form Docker! 가 선명하게 찍혔습니다.

이렇게 run 명령으로 hello-world 이미지가 컨테이너로 만들어지고 실행되었습니다.

참고로 run 명령은 원래 pull 명령도 포합니다. 본연의 이미지로 컨테이너를 생성해 실행하는 것외에 로컬 저장소에 해당 이미지가 없으면 원격 저장소에서 찾아 있으면 pull 명령을 먼저 합니다.

2.4 컨테이너 리스트 보기 – ps 명령

run 명령은 컨테이너를 만들고 실행합니다. ps 명령은 등록된 컨테이너 리스트를 보여줍니다. 옵션 -a를 붙이면 실행, 중지된 컨테이너 전부 보여줍니다. 안붙이면 실행중인 컨테이너만 보여줍니다.

$ docker ps -a
CONTAINER ID  IMAGE       COMMAND  CREATED        STATUS                   PORTS NAMES
6d234d1376bb  hello-world "/hello" 36 seconds ago Exited (0) 36 seconds ago      zealous_sammet

컨테이너 리스트를 통해 hello-world 이미지를 기반으로한 컨테이너가 만들어졌음을 확인할 수 있습니다. 상태는 중지된 상태(Exited)이고 이름은 zealous_sammet으로 되어 있습니다. 이름은 run 명령시 자동으로 붙은 겁니다.

이름을 정하고 싶다면 docker run –name=hello hello-world처럼 –name옵션을 붙이면 됩니다.

$ docker run --name hello hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

ps 명령으로 컨테이너 리스트를 확인해 보겠습니다.

$ docker ps -a
CONTAINER ID IMAGE       COMMAND  CREATED           STATUS                   PORTS NAMES
21f3bb4dd477 hello-world "/hello" 28 seconds ago    Exited (0) 29 seconds ago      hello
6d234d1376bb hello-world "/hello" About an hour ago Exited (0) About an hour ago   zealous_sammet

2개의 컨테이너가 등록되어 있습니다. run 명령은 컨테이너 이름이 중복되지 않는 이상 같은 이미지더라도 새롭게 컨테이너를 생성합니다. 만약 같은 이름으로 run 명령을 수행하면 다음처럼 이미 존재하는 이름으로 실행할 수 없습니다.

$ docker run --name hello hello-world
C:\Program Files\Docker Toolbox\docker.exe: Error response from daemon: Conflict. The container name "/hello" is already in use by container "21f3bb4dd477c401315d473548a57f7c835f7190c39642cd237018bec882d945". You have to remove (or rename) that container to be able to reuse that name.
See 'C:\Program Files\Docker Toolbox\docker.exe run --help'.

2.5 컨테이너 삭제하기 – rm

2개 중 한 개의 컨테이너는 삭제해보겠습니다.

컨테이너를 지우는 명령은 rm입니다. rm 뒤에는 컨테이너 이름이나 컨테이너 ID 중 하나를 주시면 됩니다.

$ docker rm zealous_sammet
zealous_sammet

참고로 컨테이너 삭제는 해당 컨테이너가 중지되었을 때만 가능합니다. Hello-world 컨테이너는 실행 즉시 중지가 되므로 바로 삭제가 가능합니다.

이제 ps 명령으로 잘 지워졌는지 다시 확인해 보겠습니다.

$ docker ps -a
CONTAINER ID IMAGE       COMMAND  CREATED        STATUS                    PORTS NAMES
21f3bb4dd477 hello-world "/hello" 12 minutes ago Exited (0) 12 minutes ago       hello

예상대로 1개의 컨테이너만 남았습니다.

2.6 이미지 삭제하기 – rmi

이미지는 해당 이미지로부터 만들어진 컨테이너가 모두 삭제되어 있어야 삭제가 가능합니다. 그러므로 rm 명령으로 나머지 컨테이너도 삭제합니다. 이번에는 컨테이너 ID로 삭제해 보겠습니다.

$ docker rm 21f3bb4dd477
21f3bb4dd477

모든 hello-world 이미지 기반으로 만들어진 컨테이너를 삭제했으므로 이미지도 삭제할 수 있게 되었습니다. 이미지 삭제 명령은 rmi입니다.

$ docker rmi hello-world
Untagged: hello-world:latest
Untagged: hello-world@sha256:2557e3c07ed1e38f26e389462d03ed943586f744621577a99efb77324b0fe535
Deleted: sha256:fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e
Deleted: sha256:af0b15c8625bb1938f1d7b17081031f649fd14e6b233688eea3c5483994a66a3

images 명령으로 로컬 저장소에 있는 이미지 리스트가 비어 있음을 확인할 수 있습니다.

$ docker images
REPOSITORY   TAG  IMAGE ID   CREATED  SIZE

간단하게 도커 명령어를 익혀봤습니다. 이제 조금 더 실용적인 내용으로 전개해 보겠습니다.

3. Nginx로 도커 익히기top

도커 허브에서는 Nginx 이미지도 올라와 있습니다. 기존에 있는 이미지로 어떻게 활용할 수 있나 간단하게 살펴보는 것이기에 찬찬히 따라해보시면 쉽게 할 수 있을겁니다.

3.1 Nginx 컨테이너 실행하기

run 명령으로 nginx 이미지를 pull 받아 로컬 저장소에 등록하고 컨테이너로 등록해 실행하겠습니다. 아래 처럼 docker run -d -p 8080:80 –name my-nginx nginx 로 실행하세요.

$ docker run -d -p 8080:80 --name my-nginx nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
6ae821421a7d: Pull complete
da4474e5966c: Pull complete
eb2aec2b9c9f: Pull complete
Digest: sha256:dd2d0ac3fff2f007d99e033b64854be0941e19a2ad51f174d9240dda20d9f534
Status: Downloaded newer image for nginx:latest
de093d1975641e7df7e8ff6c15d76462fc56a04e88e759e11ce54f7796d965e5

사용한 run 명령은 docker run [옵션] [이미지명] 형태로 사용되었습니다. 이미지는 nginx를 가져왔고 사용한 옵션에 대해서 설명합니다.

  • -d :컨테이너를 백그라운드로 실행하고 컨테이너 ID를 출력합니다. 안붙이면 실행 후, Ctrl+C 해야 빠져나올 수 있는데, 이러면 컨테이너가 중지됩니다. 그래서 기본적으로 붙입니다.
  • -p 8080:80 : 포트번호를 바인딩 합니다. 여기서 앞 8080은 외부에 노출되는 포트번호이고 뒤에 80은 내부에서 쓰는 포트입니다. 그러므로 http://locathost:8080 으로 접속하면 됩니다. -p 옵션은 여러개 줄 수 있습니다.
  • –name my-nginx: 컨테이너의 이름을 지정하는 옵션입니다. 여기서는 my-nginx로 지정했습니다.
  • -v : 여기서는 사용하지 않았지만 중요한 옵션이 이 볼륨 지정 옵션입니다. 만약 -v /D/nginx/html:/usr/share/nginx/html 옵션을 줬다면, 앞 /D/nginx/html은 현재 호스트의 볼륨(D:드라이브에 /nginx/html 폴더)을 의미하며 뒤에 /usr/share/nginx/html는 컨테이너의 볼륨을 의미합니다. 나중에 컨테이너가 삭제되더라도 이렇게 지정된 볼륨은 삭제되지 않으며 새로운 컨테이너를 실행할 때 똑같은 옵션을 주면 호스트 볼륨에 지정된 경로로 바인딩되므로 중요한 컨테이너와 생명주기가 다른 컨텐츠는 이런식으로 볼륨지정해서 관리하면 되겠습니다. -v 옵션은 여러개 줄 수 있습니다. 이를 지정하면 잘 안되는데, 그것은 도커가 해당 호스트의 볼륨에 대한 접근권한이 없기 때문입니다. 접근권한을 주려면 Docker for Windows: Sharing Host Volumes 링크를 참고하세요.

3.2 브라우저에서 Nginx 실행 상태 확인

윈도우 환경의 경우 도커 툴박스를 설치한 경우는 웹브라우저에서 http://192.168.99.100:8080/ 에서 확인할 수 있습니다. Docker for Windows를 설치하신 경우는 http://localhost:8080 으로 확인할 수 있습니다.

아래처럼 보인다면 성공한 것입니다.

ps 명령으로 STATUS를 보면 40초 전에 실행되었음을 보여줍니다.

$ docker ps
CONTAINER ID   IMAGE  COMMAND         CREATED       STATUS         PORTS                  NAMES
df30973c59fe   nginx  "nginx -g 'da…" 8 minutes ago Up 40 seconds  0.0.0.0:8080->80/tcp   my-nginx

3.3 Nginx 컨테이너 중지 – stop

도커 명령 stop은 실행중인 컨테이너를 중지해 줍니다. docker stop [컨테이너ID 또는 이름]으로 합니다.

$ docker stop my-nginx
my-nginx

$ docker ps -a
CONTAINER ID  IMAGE  COMMAND     CREATED      STATUS            PORTS  NAMES
df30973c59fe  nginx  "nginx …" 7 minutes ago  Exited (0) 10 se..       my-nginx

ps 명령으로 중지된 상태까지 확인했습니다.

3.4 Nginx 컨테이너 실행 – start

컨테이너 실행 명령은 start입니다.

$ docker start my-nginx
my-nginx

$ docker ps
CONTAINER ID   IMAGE  COMMAND         CREATED       STATUS        PORTS                  NAMES
df30973c59fe   nginx  "nginx -g 'da…" 8 minutes ago Up 8 seconds  0.0.0.0:8080->80/tcp   my-nginx

3.5 Nginx 컨테이너 재실행 – restart

재실행은 restart 명령으로 합니다.

$ docker restart my-nginx
my-nginx

3.6 Nginx 컨테이너 접근하기 – exec

exec 명령은 실행중인 컨테이너에 접근할 수 있도록 합니다. 아래 코드는 echo “Hello world”를 컨테이너 내에서 실행하도록 합니다.

$ docker exec my-nginx echo "Hello World"
Hello World

호스트에서 실행한 것이 아니라 my-nginx 컨테이너에서 실행한 것입니다.

컨테이너에서 ls 명령을 써보겠습니다.

$ docker exec my-nginx ls /usr/share/nginx/html
50x.html index.html

컨테이너의 웹루트인 /usr/share/nginx/html 내부를 조회해 봤습니다.
이 리스트 중 index.html를 cat으로 보겠습니다.

$ docker exec my-nginx cat /usr/share/nginx/html/index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

이제 컨테이너의 Bash 셸로 접근해 보겠습니다.

$ docker exec -i -t  my-nginx /bin/bash
root@df30973c59fe:/#

컨테이너의 Bash 셸로 접근했습니다. 참고로 옵션 -i는 표준 입력(stdin)을 활성화합니다. 그리고 -t는 TTY 모드(pseudo-TTY)를 사용합니다. Bash를 사용하려면 이 옵션을 설정해야 합니다. 결국 컨테이너의 Bash 환경을 쓰려면 -i와 -t 옵션은 기본으로 써야 합니다.

컨테이너의 Bash 셸에 들어왔으니 몇가지 리눅스 명령을 써보겠습니다.

컨테이너를 업데이트 합니다.

# apt-get update
Get:1 http://security-cdn.debian.org/debian-security stretch/updates InRelease [94.3 kB]
Get:4 http://security-cdn.debian.org/debian-security stretch/updates/main amd64 Packages [473 kB]
Ign:2 http://cdn-fastly.deb.debian.org/debian stretch InRelease
Get:3 http://cdn-fastly.deb.debian.org/debian stretch-updates InRelease [91.0 kB]
Get:5 http://cdn-fastly.deb.debian.org/debian stretch Release [118 kB]
Get:6 http://cdn-fastly.deb.debian.org/debian stretch-updates/main amd64 Packages [7748 B]
Get:7 http://cdn-fastly.deb.debian.org/debian stretch Release.gpg [2434 B]
Get:8 http://cdn-fastly.deb.debian.org/debian stretch/main amd64 Packages [7084 kB]
Fetched 7871 kB in 4s (1705 kB/s)
Reading package lists... Done

그리고 ps 명령을 쓰기 위해 procps를 설치하세요.

# apt-get install procps
Reading package lists... Done
Building dependency tree
Reading state information... Done
.....
Processing triggers for libc-bin (2.24-11+deb9u3) ...

이제 ps 명령으로 실행중인 프로세스 목록을 볼 수 있습니다.

#  ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:00 nginx: master process nginx -g daemon off;
    6 ?        S      0:00 nginx: worker process
   27 pts/0    Ss     0:00 /bin/bash
  272 pts/0    R+     0:00 ps ax

현재 실행중인 컨테이너는 PID 1입니다. 그리고 nginx가 PID 6으로 실행중입니다. 우리가 호스트에서 docker exec로 Bash 셸에 접근했기 때문에 PID 27에 /bin/bash도 실행중입니다. 금방 ps ax를 실행해서 PID 272도 잡혔네요.

nginx 첫화면을 수정하기 위해 vim 에디터를 설치합니다.

# apt-get install -y vim

설치후 vim으로 index.html을 수정합니다. 내용 중에 Thank you for using nginx.This is docker container!!!!로 바꿔보겠습니다.

# vim /usr/share/nginx/html/index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>This is docker container!!!!</em></p>
</body>
</html>

웹브라우저에서 다시 확인해보세요.

4. 도커 이미지 생성하기top

다양한 도커 명령을 실행해보고 익혀봤습니다. 도커가 어떻게 동작하는지 감을 익혔을 것이라 생각합니다. 지금부터는 도커 이미지를 직접 만드는 방법을 다룹니다.

4.1 컨테이너로 새로운 이미지 생성 – commit

이전에 exec명령으로 컨테이너 Bash 셸에 접근해서 update하고 vim 및 procps등을 설치했습니다. 컨테이너 실행 후 이렇게 변경된 사항을 확인하는 명령은 diff입니다.

$ docker diff my-nginx 
C /var/cache/ldconfig
C /var/cache/ldconfig/aux-cache
C /var/cache/nginx
A /var/cache/nginx/client_temp
A /var/cache/nginx/fastcgi_temp
A /var/cache/nginx/proxy_temp
A /var/cache/nginx/scgi_temp
A /var/cache/nginx/uwsgi_temp
C /bin
A /bin/ps
.....

만약 이렇게 변경된 컨네이너를 기반으로 이미지를 만들면 이것으로 생성되어 실행되는 컨테이너는 vim과 ps 명령을 바로 사용할 수 있게 됩니다. 컨테이너 변경사항을 이미지 파일로 생성하는 명령은 commit 입니다.

$ docker commit -a "jidolstar@bsidesoft.com" -m "updated" my-nginx my-nginx:1.0
sha256:69c25785fcf1e36012b78f08c0ee7cffe964b78f37622ce161e720e0f214f4b0

$ docker images
REPOSITORY   TAG      IMAGE ID      CREATED         SIZE
my-nginx     1.0      69c25785fcf1  19 seconds ago  157MB
nginx        latest   f09fe80eb0e7  12 days ago     109MB

어떤가요? 바로 생성합니다. commit 명령에서 -a와 -m 옵션은 각각 커밋한 사용자와 로그 메시지에 해당합니다.

기존 실행중인 컨테이너는 종료시키고 새로운 이미지로 컨테이너를 실행하겠습니다.

$ docker stop my-nginx
$ docker run -d -p 8080:80 --name my-nginx2 my-nginx:1.0
0da326fdcd5a9fa9cfe555c37414d805b4e291ae39b9f2451e34cf519c4adfe9

$ docker ps
CONTAINER ID  IMAGE         COMMAND       CREATED        TATUS       PORTS                  NAMES
0da326fdcd5a  my-nginx:1.0  "nginx -g...  2 seconds ago  Up 1 second 0.0.0.0:8080->80/tcp   my-nginx2

새롭게 시작하는 컨테이너 이름은 my-nginx2입니다.
이제 이 컨테이너에서 ps 명령을 실행해 보겠습니다.

$ docker exec my-nginx2 ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:00 nginx: master process nginx -g daemon off;
    6 ?        S      0:00 nginx: worker process
    7 ?        Rs     0:00 ps ax

아주 잘 됩니다. 컨테이너로 이미지를 생성하는 방법을 알아보았습니다.

4.2 Dockerfile 로 이미지 생성 – build

Dockerfile은 도커의 이미지 설정 파일입니다. Dockerfile에 설정된 것대로 이미지가 만들어집니다. Dockerfile에 대한 자세한 설명은 다음 문서를 참고하세요.

Dockerfile reference

Dockerfile을 만들어보기 전에 작업 디렉토리를 만들겠습니다. 왜냐하면 mkdir로 디렉토리를 만들려고 하거나 vim 으로 파일을 만드는 경우 권한 문제로 안되기 때문입니다. 그러므로 권한을 가진 작업 폴더를 먼저 생성해야 합니다.

만약 D:드라이브가 있다면 파일 탐색기에서 D:/dockerOutput 폴더를 하나 만듭니다. 그리고 dockerOutput 선택 후 오른쪽 마우스 버튼을 눌러 속성으로 들어갑니다. 여기에서 “보안”탭으로 들어가 접속중인 사용자의 권한을 모두 지정합니다.

이제 터미널로 가서 D:/dockerOutput 으로 이동합니다.

$ cd /d/dockerOutput 

$ pwd 
/d/dockerOutput  

이 디렉토리에서는 마음대로 파일을 만들고 삭제가 가능합니다.

여기에 아까 만드려고 했던 Dockerfile를 vim으로 만들어 보겠습니다(vim 사용법 설명은 생략하겠습니다).

$ vim Dockerfile

FROM nginx

RUN apt-get update
RUN apt-get install -y procps
RUN apt-get install -y vim

이 Dockerfile은 nginx 이미지를 기반으로 만들되, apt-get으로 update, install을 합니다. 앞서 우리가 도커의 Bash 셸에서 직접 타이핑으로 했던 명령들입니다.

이 Dockerfile을 기반으로 이미지를 생성해 보겠습니다.

$ docker build -t my-nginx-image .

뒤에 점(.)을 잊지 마셔야 합니다. 이미지 명을 my-nginx-image로 했습니다. 태그를 넣지 않았기 때문에 기본 태그는 latest로 설정됩니다. 이 명령을 실행하면 Dockerfile의 지침에 따라 nginx 이미지를 받고 RUN에 지정된 명령을 하나씩 실행한 뒤, 이미지가 생성됩니다. 생성된 이미지를 확인해 보겠습니다.

$ docker images
REPOSITORY      TAG      IMAGE ID      CREATED        SIZE
my-nginx-image  latest   a114a574d1b2  6 seconds ago  158MB
...(생략)

이제 이 이미지를 컨테이너로 실행해 보겠습니다. 같은 포트를 쓰는 이미 실행중인 컨테이너가 있으면 stop 명령으로 중지하셔야 합니다.

$ docker run -d -p 8080:80 --name my-nginx3 my-nginx-image
0f2b37070b11187b3ac0b2e1e0aad6ede89396ce8ac21f939449ec022468114f

새롭게 시작하는 컨테이너 이름은 my-nginx3입니다. 이제 이 컨테이너에서 ps 명령을 실행해 보겠습니다.

$ docker exec my-nginx3 ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:00 nginx: master process nginx -g daemon off;
    6 ?        S      0:00 nginx: worker process
    7 ?        Rs     0:00 ps ax

잘 실행됩니다. Dockerfile로 이미지를 생성하는 방법을 알아봤습니다.

결론top

도커의 기본적인 명령을 이해하고 도커가 어떻게 동작하는지 살펴보았습니다. 그리고 이미지를 생성/실행하는 방법도 직접 해보았습니다.

도커에는 여기서 설명하지 않은 또 다른 명령도 많이 있습니다. docker –help를 해보시면 어떤 명령어와 옵션들이 있는지 볼 수 있으므로 참고하십시오.

$ docker --help
Flag shorthand -h has been deprecated, please use --help

Usage:  docker COMMAND

A self-sufficient runtime for containers

Options:
      --config string      Location of client config files (default
                           "C:\\Users\\user\\.docker")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket(s) to connect to
  -l, --log-level string   Set the logging level
                           ("debug"|"info"|"warn"|"error"|"fatal")
                           (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA (default
                           "C:\\Users\\user\\.docker\\machine\\machines\\default\\ca.pem")
      --tlscert string     Path to TLS certificate file (default
                           "C:\\Users\\user\\.docker\\machine\\machines\\default\\cert.pem")
      --tlskey string      Path to TLS key file (default
                           "C:\\Users\\user\\.docker\\machine\\machines\\default\\key.pem")
      --tlsverify          Use TLS and verify the remote (default true)
  -v, --version            Print version information and quit

Management Commands:
  config      Manage Docker configs
  container   Manage containers
  image       Manage images
  network     Manage networks
  node        Manage Swarm nodes
  plugin      Manage plugins
  secret      Manage Docker secrets
  service     Manage services
  swarm       Manage Swarm
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  build       Build an image from a Dockerfile
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  images      List images
  import      Import the contents from a tarball to create a filesystem image
  info        Display system-wide information
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  login       Log in to a Docker registry
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes

Run 'docker COMMAND --help' for more information on a command.

이번에 다룬 내용은 도커 기초를 다뤘을 뿐이며 실무적으로 쓰기에는 부족합니다. 다음 글부터는 조금 더 실무에서 쓸 수 있는 내용을 담아보겠습니다.