Easy to understand

[Docker][Summary] 본문

===너의과학===/Infra] Docker & Kubernetes

[Docker][Summary]

Homo knowledgian 2024. 9. 15. 13:53
728x90
반응형

01-01_FCND]


01-02_JOC]


01-03_Why is Docker?] : 일반적인 software 사용을 위한 설치과정에서 격는 어려움이 존재한다

- 일반적으로 software를 설치하기 위해서는 아래와 같은 절차가 필요하다
- 그리고 설치과정에는 에러를 마주할 가능성이 있고, 이를 해결하기 위해서는 상당히 시간과 비용이 필요할 수 있다
- 도커는 이러한 문제에 대한 해결책을 제시한다

02 - flow-01_03
03 - why-01_03


01-04_What is Docker?] : Docker를 왜 사용하지를 알았고, 그럼 Docker는 뭐하는 놈인가?

- Docker는 Docker 생태계를 말하며, Docker를 사용한다는 것은 생태계가 제공하는 여러 utilities를 사용하고 있다는 것을 말한다
- Docker를 통해, 최종적으로 생성된 container는 Image로부터 생성된 하나의 프로그램이다

04 - redis-01_04
05 - what-01_04


01-05_Dcoker for Mac/Windows]

- Docker를 사용하기 위해서, Docker Client가 필요하고 각 PC 운영체제에 맞게 설치해야 한다
- Docker Client(Docker CLI)는 원하는 Docker 명령을 실행시키도록 도와주는 Tools이다

05 - docker cli-01_05


01-06_Installing Docker on macOS]


01-07_Installing Docker with WSL on Windows 10/11]


01-08_Installing Docker on Linux]


01-09_Using the Docker Client]

- docker client를 설치했다면, docker 명령어를 docker server로 전달할 수 있다
- docker version : version명령으로 server 정보를 확인할 수 있다, Server는 linux/arm64를 사용하고 있다걸 확인할 수 있다

➜  ~ docker version
Client:
 Cloud integration: v1.0.35+desktop.10
 Version:           25.0.2
 API version:       1.44
 Go version:        go1.21.6
 Git commit:        29cf629
 Built:             Thu Feb  1 00:18:45 2024
 OS/Arch:           darwin/arm64
 Context:           desktop-linux

Server: Docker Desktop 4.27.1 (136059)
 Engine:
  Version:          25.0.2
  API version:      1.44 (minimum version 1.24)
  Go version:       go1.21.6
  Git commit:       fce6e0c
  Built:            Thu Feb  1 00:23:21 2024
  OS/Arch:          linux/arm64
  Experimental:     false
 containerd:
  Version:          1.6.28
  GitCommit:        ae07eda36dd25f8a1b98dfbf587313b99c0190bb
 runc:
  Version:          1.1.12
  GitCommit:        v1.1.12-0-g51d5e94
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
➜  ~

- $ docker run hello-world 명령시 어떠한 일이 일어날까?
>> Docker Server가 Image Cache에 저장된 image 존재유무를 확인하고, 없다면 Docker Hub에서 가져온다

08 - flow-01_09


01-10_But Really...What's a Container]

- container의 동작 원리를 알기 위해서, Operating System에 대해 어느 정도 이해가 필요하다
- 대부분의 OS는 Kernel을 가지고 있는데, kernel은 모든 programs이 HW 컴퓨터 자원(CPU, Memory, Hard Dist etc...)에 대한 사용 권한을 매니징하는 역할을 수행한다
- 예를 들어, NodeJS program이 Hard Disk에 특정 내용을 저장하고 싶다는 System Call을 통해 Kernel에 Hard Disk로 접근 요청을 해야 한다
 

09 - kernel-01_10

- 다른 예로, Python v2를 사용하는 Chrome과 Python v3를 사용하는 NodeJS가 있는데, Hard Disk에 접근은 v2만 가능한 상황이다
- 어떻게 이 문제를 해결해야 하나?

10 - kernel-01_10

- HW(Hard Disk)를 namespacing을 사용해야 하는데, Segment를 분리해서 연결시켜야 한다
- 이를 통해 Chrome은 V2에 접근하게 하고, NodeJS는 V3에 접근하게 한다

11 - isolate-01_10

 
- 결국, 하나의 장비에서 Chrome과 NodeJS가 운영될 수 있다

12 - route-01_10

- Namespacing이란 process(program)당 Isolated된 HW를 할당받아 사용하게 만드는 걸 말한다
- Control Groups(cgroups)이란 process(program)당 자원의 사용이 제한되어 동시에 사용이 불가한 자원으로 포트가 이에 해당한다
 

13 - separate-01_10

- 그리하여, 아래 점선으로 표기된 부분은 Chrome이 Isolated된 영역을 이용하는 모습을 보여준다
 

14 - container-01_10

- 좀 더 구체화한 모습은 아래와 같다

15 - container-01_10

- 실제적으로, Chome을 실행하는 Container가 있다고 했을 때
- 아래 그림과 같이, [FS Snapshot]이 Hard Disk로 Copy되고 Chrome 프로그램이 실행된다.

16 - cont to image-01_10


01-11_How's Docker Running on Your Computer]

- docker client를 설치했고, container를 실행시켰다는 것은 Linux Virtual Machine에서 process(container)가 run한다는 의미다

17 - stack-01_11


02-12_Docker Run in Detail]

- Docker Container를 실행하기
- $ docker run <image name>
- Image에 정의된 "hello-world"라는 binary가 Linux-Virtual-Machine에 있는 hard disk 저장되고, binary가 실행된다
- 여기서, Default Command가 실행된 것이다
- Container에 process가 looping하지 않은 process는 exit(종료)되고, looping하는 process는 up(running)상태로 남는다

01 - run-02_12
02 - scratch-02_12


02-13_Overriding Default Commands]

- 기본 명령어를 지정하는 방법이 있다
- $ docker run <image name> <command>
- Startup Command가 <command>로 지정된다

 

03 - override-02_13

 
 

04 - busybox-02_13


02-14_Listing Running Containers]

- container(process) 리스트를 보여준다
- $ docker ps :  status가 up으로 running 상태의 container를 보여준다
- $ docker ps -a : 모든 상태의 container를 보여준다

05 - ps-02_14


02-15_Container Lifecycle]

- container(process) 리스트를 봤는데, 왜 shutdown(exit)되는가?
- 먼저, docker run 은 docker create(container 생성) + docker start(container 실행)을 의미한다
- container가 생성되고 startup command로 process가 끝나면 container(process)가 shutdown된다
- $ docker start -a <container id> :  -a는 Attach STDOUT/STDERR and forward signals

➜  ~ docker create hello-world
d617efa3c329824b2a171472b71bcf1eefca05a76201c770d0280aa3a8460105
➜  ~ docker start -a d617efa3c329824b2a171472b71bcf1eefca05a76201c770d0280aa3a8460105

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.
    (arm64v8)
 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/

➜  ~

 

06 - start-02_15

 

07 - create-02_15


02-16_Restarting Stopped Container]

- $ docker run busybox echo hi there 로 container를 생성했다
- 해당 container는 exited 상태이고, 다시 실행을 위해 $ docker start <container id> 명령으로 재실행이 가능하다
- $ docker start -a <container id>로 STDOUT을 볼 수 있다
- $ docker start -a <container id> echo bye there은 start 사용법상 여러 <container id>가 나열되어야 한다

➜  ~ docker run busybox echo hi there
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
835f85a6d665: Pull complete 
Digest: sha256:c230832bd3b0be59a6c47ed64294f9ce71e91b327957920b6929a0caa8353140
Status: Downloaded newer image for busybox:latest
hi there
➜  ~ docker ps -a
CONTAINER ID   IMAGE     COMMAND           CREATED         STATUS                     PORTS     NAMES
a8da300f416a   busybox   "echo hi there"   5 seconds ago   Exited (0) 4 seconds ago             focused_varahamihira
➜  ~ docker start a8da300f416a
a8da300f416a
➜  ~ docker start -a a8da300f416a
hi there
➜  ~ docker start -a a8da300f416a echo bye there
you cannot start and attach multiple containers at once
➜  ~ docker start --help

Usage:  docker start [OPTIONS] CONTAINER [CONTAINER...]

Start one or more stopped containers

Aliases:
  docker container start, docker start

Options:
  -a, --attach               Attach STDOUT/STDERR and forward signals
      --detach-keys string   Override the key sequence for detaching a container
  -i, --interactive          Attach container's STDIN
➜  ~

02-17_Removing Stopped Container]

- $ docker system prune : 불필요한 container, image, cache, network 등을  삭제한다
- docker 작업을 마치고, 추가 작업이 없는 경우 자원을 낭비하지 않도록 해당 명령을 수행하자

➜  ~ docker system prune
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all dangling images
  - unused build cache

Are you sure you want to continue? [y/N] y
Deleted Containers:
5ec79aa7b10d6e4660bafe74a9a97b8412c18d45f24dc5b0fd2d287ce70abed3
a8da300f416ac1a930c00177c37ac360c78cde9bb67f8692dda9ec78d654975b

Total reclaimed space: 0B
➜  ~

02-18_Retrieving Log Output]

- $ docker logs <container id> : Fetch the logs of a container

08 - logs-02_18

➜  ~ docker create busybox echo hi there
932b3a005c553eeb6c941cd31850c76c80f7888222f114feb37a771d1c8d9fca
➜  ~ docker start 932b3a005c553eeb6c941cd31850c76c80f7888222f114feb37a771d1c8d9fca
932b3a005c553eeb6c941cd31850c76c80f7888222f114feb37a771d1c8d9fca
➜  ~ docker logs 932b3a005c553eeb6c941cd31850c76c80f7888222f114feb37a771d1c8d9fca
hi there
➜  ~ docker start 932b3a005c553eeb6c941cd31850c76c80f7888222f114feb37a771d1c8d9fca
932b3a005c553eeb6c941cd31850c76c80f7888222f114feb37a771d1c8d9fca
➜  ~ docker logs 932b3a005c553eeb6c941cd31850c76c80f7888222f114feb37a771d1c8d9fca 
hi there
hi there
➜  ~

02-19_Stopping Containers]

- 계속 Status: UP(running) 중인 container를 중지시키는 방법

09 - stop kill-02_19
10 - signals-02_19
11 - kill-02_19


02-20_Multi-Command Containers]

- redis-server가 돌고 있는 container에 외부에서 redis-cli를 실행해도 바로 container 내 redis-server와 연결할 수 없다

12 - attach-02_20


02-21_Executing Commands in Running Containers]

- 그렇다면, redis-server가 Status:UP(running)인 container에 명령을 실행시킬 수 있다
- $ docker exec -it <container id> <command>

13 - exec-02_21
14 - attach-02_21

➜  ~ docker run redis
Unable to find image 'redis:latest' locally
latest: Pulling from library/redis
92c3b3500be6: Pull complete 
631720f833ee: Pull complete 
704a08909867: Pull complete 
090311ee98f0: Pull complete 
50eb2e3e87d6: Pull complete 
4a05d8378bf0: Pull complete 
4f4fb700ef54: Pull complete 
713e6192e133: Pull complete 
Digest: sha256:eadf354977d428e347d93046bb1a5569d701e8deb68f090215534a99dbcb23b9
Status: Downloaded newer image for redis:latest
1:C 18 Sep 2024 11:22:16.175 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 18 Sep 2024 11:22:16.175 * Redis version=7.4.0, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 18 Sep 2024 11:22:16.175 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
1:M 18 Sep 2024 11:22:16.175 * monotonic clock: POSIX clock_gettime
1:M 18 Sep 2024 11:22:16.176 * Running mode=standalone, port=6379.
1:M 18 Sep 2024 11:22:16.176 * Server initialized
1:M 18 Sep 2024 11:22:16.176 * Ready to accept connections tcp

^Z
[1]  + 13309 suspended  docker run redis
➜  ~ docker ps -a
CONTAINER ID   IMAGE     COMMAND                   CREATED          STATUS                      PORTS      NAMES
882dfc420465   redis     "docker-entrypoint.s…"   26 seconds ago   Up 24 seconds               6379/tcp   thirsty_elgamal
➜  ~ docker exec -it 882dfc420465 redis-cli
127.0.0.1:6379> set myvalue 5
OK
127.0.0.1:6379> get myvalue
"5"
127.0.0.1:6379>

02-22_The Purpose of the IT Flag]

- $ docker exec -it에서 이 flag들의 의미는?
- -i : terminal을 통해 process와 STDIN를 전달하고, STDOUT STDERR를 받는다
- -t : Allocate a pseudo-TTY (보기 좋게 표시해준다)

15 -stdin-02_22


02-23_Getting a Command Prompt in a Container]

- 매번 container에 exec로 명령을 수행할 필요없이, shell command로 container에 접근해 명령을 수행할 있다

16 - shell-02_23

➜  ~ docker ps -a
CONTAINER ID   IMAGE     COMMAND                   CREATED          STATUS                      PORTS      NAMES
882dfc420465   redis     "docker-entrypoint.s…"   11 minutes ago   Up 10 minutes               6379/tcp   thirsty_elgamal
932b3a005c55   busybox   "echo hi there"           41 minutes ago   Exited (0) 41 minutes ago              sad_rubin
➜  ~ docker exec -it 882dfc420465 bash
root@882dfc420465:/data# redis-cli 
127.0.0.1:6379> get myvalue
"5"
127.0.0.1:6379>

02-24_Starting with a Shell]

- container를 실행할때, shell이 FS snapshot에 있는 경우 바로 실행시킬 수 있다
- $ docker run -it busybox sh

➜  ~ docker run -it busybox sh
/ # ls
bin    dev    etc    home   lib    lib64  proc   root   sys    tmp    usr    var
/ #

17 - fs-02_24


02-25_Container Isolation]

- 생성된 container는 Isolated 상태로 서로 영향을 주지 않는 독립 공간이다

➜  ~ docker ps -a
CONTAINER ID   IMAGE     COMMAND                   CREATED          STATUS                      PORTS      NAMES
3ec31ad00755   busybox   "sh"                      13 seconds ago   Up 13 seconds                          hardcore_gould
1632d24b635e   busybox   "sh"                      7 minutes ago    Up 7 minutes                           sweet_dewdney
➜  ~ 

[CONTAINER ID : 3ec31ad00755]
/ # ps -ef
PID   USER     TIME  COMMAND
    1 root      0:00 sh
   10 root      0:00 ps -ef
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:03  
          inet addr:172.17.0.3  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:65535  Metric:1
          RX packets:13 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1006 (1006.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # ls
bin    dev    etc    home   lib    lib64  proc   root   sys    tmp    usr    var
/ # touch con3ec31ad00755
/ # ls
bin              dev              home             lib64            root             tmp              var
con3ec31ad00755  etc              lib              proc             sys              usr
/ # 

[CONTAINER ID : 1632d24b635e]
/ # ps -ef
PID   USER     TIME  COMMAND
    1 root      0:00 sh
    8 root      0:00 ps -ef
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:04  
          inet addr:172.17.0.4  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:65535  Metric:1
          RX packets:10 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:796 (796.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # ls
bin    dev    etc    home   lib    lib64  proc   root   sys    tmp    usr    var
/ # touch con1632d24b635e
/ # ls
bin              dev              home             lib64            root             tmp              var
con1632d24b635e  etc              lib              proc             sys              usr
/ #

03-26_Creating Docker Images]

- 지금까지 다른 engineer가 만든 이미지를 사용했고, 우리가 원하는 이미지를 만들기 위해서는 Dockerfile을 만들어야 한다

01 - images-03_26

- Dockerfile을 build하면 Docker Client가 Docker Server로 Dockerfile에 맞는 Image를 생성한다

02 - dockerfile-03_26

- Dockerfile은 보통 다음과 같은 Flow로 작성한다

03 - base-03_26


03-27_BfDD]


03-28_Building a Dockerfile]

- redis-server 를 만들어 보겠다

# Specify a base image : Use an existing docker image as a base
FROM alpine

# Run some commands to install additional programs : Download and install a dependency
RUN apk add --update redis

# Specify a command to run on container startup : Tell the image what to do when it starts as a container
CMD ["redis-server"]

- Dockerfile로 이미지 만들기

➜  redis-image sudo docker build .
[+] Building 6.3s (7/7) FINISHED                                                                                         docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                                                     0.0s
 => => transferring dockerfile: 358B                                                                                                     0.0s
 => [internal] load metadata for docker.io/library/alpine:latest                                                                         3.5s
 => [auth] library/alpine:pull token for registry-1.docker.io                                                                            0.0s
 => [internal] load .dockerignore                                                                                                        0.0s
 => => transferring context: 2B                                                                                                          0.0s
 => [1/2] FROM docker.io/library/alpine:latest@sha256:beefdbd8a1da6d2915566fde36db9db0b524eb737fc57cd1367effd16dc0d06d                   0.0s
 => => resolve docker.io/library/alpine:latest@sha256:beefdbd8a1da6d2915566fde36db9db0b524eb737fc57cd1367effd16dc0d06d                   0.0s
 => => sha256:beefdbd8a1da6d2915566fde36db9db0b524eb737fc57cd1367effd16dc0d06d 1.85kB / 1.85kB                                           0.0s
 => => sha256:9cee2b382fe2412cd77d5d437d15a93da8de373813621f2e4d406e3df0cf0e7c 528B / 528B                                               0.0s
 => => sha256:c157a85ed455142fd79bff5dce951fd5f5b0d0c6e45e6f54cfd0c4e2bdec587b 1.49kB / 1.49kB                                           0.0s
 => [2/2] RUN apk add --update redis                                                                                                     2.7s
 => exporting to image                                                                                                                   0.0s
 => => exporting layers                                                                                                                  0.0s
 => => writing image sha256:f396f6ca44e6b28c049339480b6c532de62948335996eab74a715b3099f3d9f9                                             0.0s
                                                                                                                                              
View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/swr131jc1gwyhtycv5bybvv6d                                    

Whats Next?
  View a summary of image vulnerabilities and recommendations → docker scout quickview
➜  redis-image docker images
REPOSITORY                                                                                     TAG       IMAGE ID       CREATED          SIZE
<none>                                                                                         <none>    f396f6ca44e6   11 seconds ago   15.5MB
➜  redis-image docker run f396f6ca44e6
1:C 18 Sep 2024 15:05:01.471 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 18 Sep 2024 15:05:01.471 * Redis version=7.2.5, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 18 Sep 2024 15:05:01.471 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
1:M 18 Sep 2024 15:05:01.471 * monotonic clock: POSIX clock_gettime
1:M 18 Sep 2024 15:05:01.472 * Running mode=standalone, port=6379.
1:M 18 Sep 2024 15:05:01.472 * Server initialized
1:M 18 Sep 2024 15:05:01.472 * Ready to accept connections tcp


➜  .docker docker ps -a
CONTAINER ID   IMAGE                                                                                          COMMAND                   CREATED          STATUS                        PORTS     NAMES
0f3709b6c900   f396f6ca44e6                                                                                   "redis-server"            23 seconds ago   Up 22 seconds                           zealous_allen
➜  .docker

03-29_Dockerfile Teardown]

- Dockerfile을 분석해보자


03-30_What's a Base Image?]

- dockerfile에서 base image는 software를 설치(구축) 및 실행하기 위한 환경이다

06 - imagine-03_30
07 - why alpine-03_30
08 - dfile-03_30


03-31_The Build Process in Detail]

- Dockerfile의 명령어 실행마다 이미지가 생성되고, 생성된 이미지에 다음 단계의 명령이 실행되어 새로운 이미지가 만들어진다

09 - base-03_31


03-32_A Brief Recap]

10 - process-03_32


03-33_Rebuilds with Cache]

- Dockerfile의 명령어 실행마다 이미지가 생성되고, 생성된 이미지 캐시에 저장되어 빌드시 여러번 이미지 생성하지 않고 재사용한다

11 - cache-03_33


03-34_Tagging an Image]

- custom 이미지에 tag를 달아 image 이름을 지정할 수 있다
- Docker ID를 앞에 붙여, custom image 이름을 지정할 수 있고, Docker ID가 없다면 공식 public 이미지로 간주된다

12 - tag-03_34

 

13 - tag anatomy-03_34


03-35_Quick Note for Windows Users]


03-36_Manual Image Generation with Docker Commit]

- container로 image를 만들수 있다
- container를 실행하고, container 내부에서 추가작업(RUN, 설치)를 한 후 image로 만들 수 있다
- docker commit -c 'CMD ["~~~"]' <container id>
- 새로운 이미지가 생성된다

14 - commit-03_36


04-37_Project Outline]

- 이번엔 NodeJS web app을 만들어 보자
- 중간에 발생할 수 있는 오류를 수정하는 과정도 알아본다

01 - app-04_37
02 - steps-04_37


04-38_Node Server Setup]

- NodeJS Express 서버 세팅을 한다 (동일한 파일 경로에 아래 두 파일이 위치한다)
- package.json

{
    "dependencies": {
        "express": "*"
    },
    "scripts": {
        "start": "node index.js"
    }
}

- index.js

const express = require('express');

const app = express();

app.get('/', (req, res) => {
    res.send('Hi there');
});

app.listen(8080, () => {
    console.log('Listening on port 8080');
})

 


04-39_Reminder on Buildkit]

더보기

As mentioned earlier, Buildkit will hide away much of its progress which is something the legacy builder did not do. In the upcoming lectures will be discussing some output that will be quickly hidden by default. To see this output, you will want to pass the progress flag to the build command:

docker build --progress=plain .

Additionally, you can pass the no-cache flag to disable any caching:

docker build --no-cache --progress=plain .

Note - Do not try to use the no-cache flag with Lecture 47 Minimizing Cache Busting

Disabling Buildkit to match course output

To disable Buildkit, you can just pass the following variable to the build command:

DOCKER_BUILDKIT=0 docker build .


04-40_A Few Planned Errors]

- NodeJS Apps을 실행시키기 위한 과정을 살펴보면 다음과 같다
- 먼저 npm install로 dependency를 설치해야 한다
- 그 다음 서버를 실행시키기 위해 npm start 명령을 실행한다

03 - node apps-04_40

- 이전에 만들었던 Dockerfile 개념과 비교해서 살펴 보자

04 - commands-04_40

- 앞서 만들었던 package.json, index.js파일과 같은 위치에 Dockerfile을 만들어보자

# Specify a base image
FROM alpine

# Install some dependencies
RUN npm install

# Default command
CMD [ "npm", "start" ]

- image를 빌드하는 과정에서 npm 바이너리(실행 명령)이 없다는 에러에 마주한다

➜  simpleweb docker build .
[+] Building 1.9s (6/6) FINISHED                                                                    docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                                0.0s
 => => transferring dockerfile: 195B                                                                                0.0s
 => [internal] load metadata for docker.io/library/alpine:latest                                                    1.7s
 => [auth] library/alpine:pull token for registry-1.docker.io                                                       0.0s
 => [internal] load .dockerignore                                                                                   0.0s
 => => transferring context: 2B                                                                                     0.0s
 => CACHED [1/2] FROM docker.io/library/alpine:latest@sha256:beefdbd8a1da6d2915566fde36db9db0b524eb737fc57cd1367ef  0.0s
 => ERROR [2/2] RUN npm install                                                                                     0.1s
------                                                                                                                   
 > [2/2] RUN npm install:
0.115 /bin/sh: npm: not found
------
Dockerfile:5
--------------------
   3 |     
   4 |     # Install some dependencies
   5 | >>> RUN npm install
   6 |     
   7 |     # Default command
--------------------
ERROR: failed to solve: process "/bin/sh -c npm install" did not complete successfully: exit code: 127

View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/y37k6xse64ks5ldbe86rye1lp
➜  simpleweb

04-41_Base Image Issues]

- Alpine Image에는 매우 기본적인 리눅스 또는 유닉스 프로그램만 존재한다
- 그래서 위 에러를 통해, npm 프로그램이 Alpine Image에 없다는 걸 알 수 있다
- npm 프로그램 사용을 위해, 누가 npm 프로그램을 설치해 놓은 이미지를 사용하거나 alpine 이미지에 npm 프로그램을 설치한다

- 먼저 npm까지 설치한 image를 사용해보자
- node:14-alpine (14-alpine 버전을 명시해야 하고, 그렇지 않으면 다른 에러를 접하게 될 수 있습니다)

# Specify a base image
FROM node:14-alpine

# Install some dependencies
RUN npm install

# Default command
CMD [ "npm", "start" ]

- 수업에서는 npm install 진행시, package.json파일을 찾지 못한다고 나왔지만 현시점에 해보니 image는 만들어 졌다
- 하지만, image를 run으로 실행하니 package.json을 찾지 못한다고 나온다
- image 내부에 로컬에 있던, package.json과 index.js 파일은 없는 상태라서 그러하다

➜  simpleweb docker build .
[+] Building 9.1s (6/6) FINISHED                                                                                                                                   docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                                                                                               0.0s
 => => transferring dockerfile: 205B                                                                                                                                               0.0s
 => [internal] load metadata for docker.io/library/node:14-alpine                                                                                                                  2.0s
 => [internal] load .dockerignore                                                                                                                                                  0.0s
 => => transferring context: 2B                                                                                                                                                    0.0s
 => [1/2] FROM docker.io/library/node:14-alpine@sha256:434215b487a329c9e867202ff89e704d3a75e554822e07f3e0c0f9e606121b33                                                            6.1s
 => => resolve docker.io/library/node:14-alpine@sha256:434215b487a329c9e867202ff89e704d3a75e554822e07f3e0c0f9e606121b33                                                            0.0s
 => => sha256:4cf6a83c0e2af3c780abcda02cc33f9e812fdcb40b610ed1838281cc9ab94ec8 2.43MB / 2.43MB                                                                                     1.2s
...
 => => extracting sha256:4cf6a83c0e2af3c780abcda02cc33f9e812fdcb40b610ed1838281cc9ab94ec8                                                                                          0.0s
 => => extracting sha256:686172e40c38722891b4004f55f6447548c8367968ac523a612591e0d92f9db3                                                                                          0.0s
 => [2/2] RUN npm install                                                                                                                                                          0.8s
 => exporting to image                                                                                                                                                             0.1s 
 => => exporting layers                                                                                                                                                            0.1s 
 => => writing image sha256:f46f65def41dd2eb604f75c721b50ca3e4db3876d1aea9a050a5bbe036de6f28                                                                                       0.0s 
                                                                                                                                                                                        
View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/ihx9ejubm2xynaczdhucwxjg8                                                                              
                                                                                                                                                                                        
What s Next?
  View a summary of image vulnerabilities and recommendations → docker scout quickview
➜  simpleweb docker images
REPOSITORY                                                                                     TAG       IMAGE ID       CREATED         SIZE
<none>                                                                                         <none>    f46f65def41d   9 seconds ago   119MB
vsc-volume-bootstrap                                                                           latest    cfce4300fd5e   5 days ago      983MB
vsc-docker-kubernetes-basic-57eccdfb2c8ba37c05300e10cfb2a08e291b33c57345b2870c1283043d66ba45   latest    2a9fe4849080   13 days ago     1.11GB
redis                                                                                          latest    9fba7e5fadd5   8 weeks ago     140MB
busybox                                                                                        latest    7db2ddde018a   16 months ago   4.04MB
➜  simpleweb docker run f46f65def41d
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /package.json
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '/package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent 

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2024-09-23T15_09_27_201Z-debug.log
➜  simpleweb

04-42_A Few Missing Files]

- npm install 명령을 수행하기 위해서, package.json파일이 필요하다

- 하지만 package.json 파일은 로컬 환경엔 존재하지만 node:14-alpine image 내부엔 없다

06 - build-04_42


04-43_Copying Build Files]

- 로컬 환경에 있는 package.json과 index.js 파일을 container 내부로 복사하는 명령어를 알아보자

07 - copy-04_43

- 아래와 같이 Dockerfile에 COPY를 추가하자

08 - copy-04_43

- 그리고 실행해보면 node server가 8080 포트로 실행되었다

➜  simpleweb docker build .
[+] Building 11.8s (9/9) FINISHED                                                                                                                                                                                docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                                                                                                                                             0.0s
 => => transferring dockerfile: 216B                                                                                                                                                                                             0.0s
 => [internal] load metadata for docker.io/library/node:14-alpine                                                                                                                                                                2.5s
 => [auth] library/node:pull token for registry-1.docker.io                                                                                                                                                                      0.0s
 => [internal] load .dockerignore                                                                                                                                                                                                0.0s
 => => transferring context: 2B                                                                                                                                                                                                  0.0s
 => [internal] load build context                                                                                                                                                                                                0.0s
 => => transferring context: 672B                                                                                                                                                                                                0.0s
 => [1/3] FROM docker.io/library/node:14-alpine@sha256:434215b487a329c9e867202ff89e704d3a75e554822e07f3e0c0f9e606121b33                                                                                                          7.5s
 => => resolve docker.io/library/node:14-alpine@sha256:434215b487a329c9e867202ff89e704d3a75e554822e07f3e0c0f9e606121b33                                                                                                          0.0s
...
 => => extracting sha256:686172e40c38722891b4004f55f6447548c8367968ac523a612591e0d92f9db3                                                                                                                                        0.0s
 => [2/3] COPY ./ ./                                                                                                                                                                                                             0.1s
 => [3/3] RUN npm install                                                                                                                                                                                                        1.7s
 => exporting to image                                                                                                                                                                                                           0.0s
 => => exporting layers                                                                                                                                                                                                          0.0s
 => => writing image sha256:1d7801c67a8df399a1c7d9512bf88ffad74e4704960b135c86b425b3dd9119ce                                                                                                                                     0.0s

View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/t8s1mj3x3wbjupytijkvhcjj9

What's Next?
  View a summary of image vulnerabilities and recommendations → docker scout quickview
➜  simpleweb 
➜  simpleweb docker images
REPOSITORY                                                                                     TAG       IMAGE ID       CREATED         SIZE
<none>                                                                                         <none>    1d7801c67a8d   6 seconds ago   123MB                                                                                  latest    7db2ddde018a   16 months ago   4.04MB
➜  simpleweb docker run 1d7801c67a8d

> @ start /
> node index.js

Listening on port 8080

- 하지만 server 외부(browser, curl 등)에서 접속할 수 없다

09 - ports-04_43


04-44_Container Port Mapping]

- 외부에서 container와 통신하려면 port mapping을 해야 한다

10 - local-04_44

- port mapping하는 방법은 다음과 같다, 그리고 내부 컨테이너 포트는 node server가 실행 중인 8080 포트와 동일해야 한다

- 이제 localhost:39090로 node server와 통신할 수 있다


04-45_Specifying a Working Directory]

- 로컬에서 copy한 파일들은 container의 /에 복사했다

- 현재 기존 파일들과 겹치는 내용이 없지만 파일명이 겹칠 경우 치명적인 오류를 발생시킬 수 있다

- 그래서 작업 경로를 지정하는 절차가 필요하다

13 - workdir-04_45

- Dockerfile을 아래와 같이 수정하면, 작업 파일을 지정한 위치에 복사해 사용할 수 있고 위 언급한 치명적 오류를 예방할 수 있다

# Specify a base image
FROM node:14-alpine

WORKDIR /usr/app
# Install some dependencies
COPY ./ ./
RUN npm install

# Default command
CMD [ "npm", "start" ]

04-46_Unnecessary Rebuilds]

- 로컬의 index.js 파일이 변경되면, image를 다시 빌드해야하고 이때 npm install 역시 위 COPY 구분 실행간 변화로 재실행된다

- 하지만 npm install은 사실 재실행될 필요가 없다, 물론 package.json에 변화가 없다면 말이다
- 다음 장에서 npm installdl 재실행되지 않도록 Dockerfile을 변경해보겠다


04-47_Minimizing Cache Busting and Rebuilds]

- 먼저, package.json과 index.json 파일의 복사 시점을 따로 둬야한다

# Specify a base image
FROM node:14-alpine

WORKDIR /usr/app
# Install some dependencies
COPY ./package.json ./
RUN npm install
COPY ./ ./

# Default command
CMD [ "npm", "start" ]

 

- image를 build하고, 다시 또 build하면 전부 cache image를 사용하고, index.js만 변경 후 build하면, 두번째 COPY만 새로 image를 build한다

➜  simpleweb docker build -t yigongyikong/simpleweb .
[+] Building 0.8s (10/10) FINISHED                                                                                              docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                                                            0.0s
 => => transferring dockerfile: 256B                                                                                                            0.0s
 => [internal] load metadata for docker.io/library/node:14-alpine                                                                               0.7s
 => [internal] load .dockerignore                                                                                                               0.0s
 => => transferring context: 2B                                                                                                                 0.0s
 => [1/5] FROM docker.io/library/node:14-alpine@sha256:434215b487a329c9e867202ff89e704d3a75e554822e07f3e0c0f9e606121b33                         0.0s
 => [internal] load build context                                                                                                               0.0s
 => => transferring context: 202B                                                                                                               0.0s
 => CACHED [2/5] WORKDIR /usr/app                                                                                                               0.0s
 => CACHED [3/5] COPY ./package.json ./                                                                                                         0.0s
 => CACHED [4/5] RUN npm install                                                                                                                0.0s
 => CACHED [5/5] COPY ./ ./                                                                                                                     0.0s
 => exporting to image                                                                                                                          0.0s
 => => exporting layers                                                                                                                         0.0s
 => => writing image sha256:f882fcad462af39d55d68b519c042985748a1fcffb2f49efd5c4e92e1895ad74                                                    0.0s
 => => naming to docker.io/yigongyikong/simpleweb                                                                                               0.0s

View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/rwnbo5luh079b4hlasvuf6fyq

What's Next?
  View a summary of image vulnerabilities and recommendations → docker scout quickview
➜  simpleweb 
➜  simpleweb 
➜  simpleweb sudo docker build -t yigongyikong/simpleweb .
[+] Building 0.3s (10/10) FINISHED                                                                                              docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                                                            0.0s
 => => transferring dockerfile: 256B                                                                                                            0.0s
 => [internal] load metadata for docker.io/library/node:14-alpine                                                                               0.3s
 => [internal] load .dockerignore                                                                                                               0.0s
 => => transferring context: 2B                                                                                                                 0.0s
 => [1/5] FROM docker.io/library/node:14-alpine@sha256:434215b487a329c9e867202ff89e704d3a75e554822e07f3e0c0f9e606121b33                         0.0s
 => [internal] load build context                                                                                                               0.0s
 => => transferring context: 202B                                                                                                               0.0s
 => CACHED [2/5] WORKDIR /usr/app                                                                                                               0.0s
 => CACHED [3/5] COPY ./package.json ./                                                                                                         0.0s
 => CACHED [4/5] RUN npm install                                                                                                                0.0s
 => CACHED [5/5] COPY ./ ./                                                                                                                     0.0s
 => exporting to image                                                                                                                          0.0s
 => => exporting layers                                                                                                                         0.0s
 => => writing image sha256:f882fcad462af39d55d68b519c042985748a1fcffb2f49efd5c4e92e1895ad74                                                    0.0s
 => => naming to docker.io/yigongyikong/simpleweb                                                                                               0.0s

View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/uyu0va5ljckyh0v5iclisyt5t

What's Next?
  View a summary of image vulnerabilities and recommendations → docker scout quickview
➜  simpleweb 
➜  simpleweb 
➜  simpleweb sudo docker build -t yigongyikong/simpleweb .
[+] Building 0.8s (10/10) FINISHED                                                                                              docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                                                            0.0s
 => => transferring dockerfile: 256B                                                                                                            0.0s
 => [internal] load metadata for docker.io/library/node:14-alpine                                                                               0.7s
 => [internal] load .dockerignore                                                                                                               0.0s
 => => transferring context: 2B                                                                                                                 0.0s
 => [1/5] FROM docker.io/library/node:14-alpine@sha256:434215b487a329c9e867202ff89e704d3a75e554822e07f3e0c0f9e606121b33                         0.0s
 => [internal] load build context                                                                                                               0.0s
 => => transferring context: 420B                                                                                                               0.0s
 => CACHED [2/5] WORKDIR /usr/app                                                                                                               0.0s
 => CACHED [3/5] COPY ./package.json ./                                                                                                         0.0s
 => CACHED [4/5] RUN npm install                                                                                                                0.0s
 => [5/5] COPY ./ ./                                                                                                                            0.0s
 => exporting to image                                                                                                                          0.0s
 => => exporting layers                                                                                                                         0.0s
 => => writing image sha256:67f3c15880242962d7faaab28ddee1fc438b5042cf4b95dacbd30ccb8fb1cb6b                                                    0.0s
 => => naming to docker.io/yigongyikong/simpleweb                                                                                               0.0s

View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/zmrc922bb1dlldbeusl5pf9i5

What's Next?
  View a summary of image vuln

05-48_App Overview]

- 방문자수를 카운팅하는 서비스를 생각해보자

- CLIENT(browser) , NodeApp-container , Redis-container 를 사용할 것이다

- CLIENT(browser) : NodeApp에 접속해서 visits 값을 1 증가 후 보여준다

- NodeApp-container : NodeApp은 Redis-container에 visits값 불러온 후 1 증가 후 다시 Redis-container에 저장한다

- Redis-container : NodeApp의 제어에 따라 visits값을 불러오고 저장한다


05-49_App Server Starter Code]

- visits 폴더를 만들고 아래와 같이 NodeApp 코드를 작성한다

- package.json

{
    "dependencies": {
        "express": "*",
        "redis": "2.8.0"
    },
    "scripts": {
        "start": "node index.js"
    }
}

- index.js

const express = require('express');
const redis = require('redis');

const app = express();
const client = redis.createClient();
client.set('visits', 0);

app.get('/', (req, res) => {
    client.get('visits', (err, visits) => {
        res.send('Number of visits is ' + visits);
        client.set('visits', parseInt(visits) + 1);
    })
});

app.listen(8081, () => {
    console.log('Listening on port 8081');
})

05-50_Assembling a Dockerfile]

- 이제 Dockerfile을 위 package.json 그리고 index.js 파일과 동일한 위치에 만들어보자

FROM node:alpine

WORKDIR '/app'

COPY package.json .
RUN npm install
COPY . .

CMD [ "npm", "start"]

- 그리고 docker build를 통해 image를 생성하자

➜  visits docker build -t yigongyikong/visits .
Password:
[+] Building 17.2s (11/11) FINISHED                                                                                                                                                                              docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                                                                                                                                             0.0s
 => => transferring dockerfile: 175B                                                                                                                                                                                             0.0s
 => [internal] load metadata for docker.io/library/node:alpine                                                                                                                                                                   2.6s
 => [auth] library/node:pull token for registry-1.docker.io                                                                                                                                                                      0.0s
 => [internal] load .dockerignore                                                                                                                                                                                                0.0s
 => => transferring context: 2B                                                                                                                                                                                                  0.0s
 => [internal] load build context                                                                                                                                                                                                0.0s
 => => transferring context: 881B                                                                                                                                                                                                0.0s
 => [1/5] FROM docker.io/library/node:alpine@sha256:c9bb43423a6229aeddf3d16ae6aaa0ff71a0b2951ce18ec8fedb6f5d766cf286                                                                                                            10.9s
 => => resolve docker.io/library/node:alpine@sha256:c9bb43423a6229aeddf3d16ae6aaa0ff71a0b2951ce18ec8fedb6f5d766cf286                                                                                                             0.0s
...
 => => extracting sha256:7ef25b6a8abdfe58ef5eeca0675ab4de9da3ee01f94b6b06d3c92bc4d36cd0f4                                                                                                                                        0.0s
 => [2/5] WORKDIR /app                                                                                                                                                                                                           0.1s
 => [3/5] COPY package.json .                                                                                                                                                                                                    0.0s
 => [4/5] RUN npm install                                                                                                                                                                                                        3.5s
 => [5/5] COPY . .                                                                                                                                                                                                               0.0s
 => exporting to image                                                                                                                                                                                                           0.1s
 => => exporting layers                                                                                                                                                                                                          0.1s
 => => writing image sha256:7e699bb15ed724de00432f866893b4f896ec0fd6f5b9df65cc943922efec8016                                                                                                                                     0.0s
 => => naming to docker.io/yigongyikong/visits                                                                                                                                                                                   0.0s

View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/9f6d5g82b6svhclko8rb0ifv8

What's Next?
  View a summary of image vulnerabilities and recommendations → docker scout quickview
➜  visits

05-51_Introducing Docker Compose]

- docker run을 통해, build한 image를 실행시키면 문제가 발생한다

- NodeJS App이 연결할 Redis Server가 없기 때문이다

- 그렇다면, Redis Server를 container을 실행시킨 후, 재시도하면 어떻까?, 역시 동일하게 문제가 발생한다

- 왜냐하면 NodeJS App과 Redis Server는 isolated(절연된, 고립된) 상태로 서로 연동되지 않았기 때문이다

 

- 이처럼 여러개의 container를 연동하고자 하는 욕구가 존재하고, 이에 대한 해결책으로는 두 가지가 있다

- 첫번째는 docker cli로 Redis Server container의 port mapping을 설정해 실행하고, NodeJS App도 설정이 필요하다

- 두번째는 docker compose를 사용하는 것이다

- docker compose는 첫번째 방식인, 여러 docker cli 명령을 작성한 파일을 통해 실행시킬 수 있고, 여러 container도 동시 실행시킨다


05-52_Docker Compose File]

- 이제 docker compose file을 만들어 볼껀데, 파일명은 docker-compose.yml이다

- docker-compose.yml을 아래와 같이 작성해보았다

version: '3' # Here are the containers I want created:
services:
  redis-server:
    image: 'redis' # 'redis' image를 사용해 redis-server container를 만든다
  node-app:
    build: . # docker-compose.yml과 같은 위치에 Dockerfile을 사용해 image를 만든다
    ports:
      - "4001:8081" # port mapping으로 4001은 외부(browser 접속)용, 8081은 node app용 port

05-53_Networking with Docker Compose]

- redis-server와 node-app은 각각 실행되지만 같은 환경에서 isolated된 상태이기 때문에 port mapping을 할 필요가 없다

- 그렇다면 node-app은 어떻게 redis-server와 통신할 수 있을까?

- index.js 파일에 client 설정 부분을 아래와 같이 변경했다

- 원래 host에는 http://{ip or domain} 을 지정해야 하지만, docker-compose는 services name인 redis-server가 이를 대신해준다

const express = require('express');
const redis = require('redis');

const app = express();
const client = redis.createClient({
    host: 'redis-server',
    port: 6379
});
client.set('visits', 0);

app.get('/', (req, res) => {
    client.get('visits', (err, visits) => {
        res.send('Number of visits is ' + visits);
        client.set('visits', parseInt(visits) + 1);
    })
});

app.listen(8081, () => {
    console.log('Listening on port 8081');
})

05-54_Docker Compose Commands]

- 이제 docker-compose.yml 파일을 실행시켜야 한다

- 'docker-compose up' = 'docker run image'와 유사하게 container들을 설정에 맞게 실행시킨다

- 'docker-compose up --build' = 'docker build . / docker run image'와 같이 변경된 내용을 다시 build 후 실행시킨다

➜  visits docker-compose up
Password:
[+] Building 1.7s (11/11) FINISHED                                                                                                                                                                               docker:desktop-linux
 => [node-app internal] load build definition from Dockerfile                                                                                                                                                                    0.0s
 => => transferring dockerfile: 175B                                                                                                                                                                                             0.0s
 => [node-app internal] load metadata for docker.io/library/node:alpine                                                                                                                                                          1.7s
 => [node-app auth] library/node:pull token for registry-1.docker.io                                                                                                                                                             0.0s
 => [node-app internal] load .dockerignore                                                                                                                                                                                       0.0s
 => => transferring context: 2B                                                                                                                                                                                                  0.0s
 => [node-app 1/5] FROM docker.io/library/node:alpine@sha256:c9bb43423a6229aeddf3d16ae6aaa0ff71a0b2951ce18ec8fedb6f5d766cf286                                                                                                    0.0s
 => [node-app internal] load build context                                                                                                                                                                                       0.0s
 => => transferring context: 867B                                                                                                                                                                                                0.0s
 => CACHED [node-app 2/5] WORKDIR /app                                                                                                                                                                                           0.0s
 => CACHED [node-app 3/5] COPY package.json .                                                                                                                                                                                    0.0s
 => CACHED [node-app 4/5] RUN npm install                                                                                                                                                                                        0.0s
 => [node-app 5/5] COPY . .                                                                                                                                                                                                      0.0s
 => [node-app] exporting to image                                                                                                                                                                                                0.0s
 => => exporting layers                                                                                                                                                                                                          0.0s
 => => writing image sha256:b7ff75cffa8440d657f1c2d7c3552f991bf7483315e49d09e0a4ccf38c590974                                                                                                                                     0.0s
 => => naming to docker.io/library/visits-node-app                                                                                                                                                                               0.0s
[+] Running 3/1
 ✔ Network visits_default           Created                                                                                                                                                                                      0.0s 
 ✔ Container visits-node-app-1      Created                                                                                                                                                                                      0.1s 
 ✔ Container visits-redis-server-1  Created                                                                                                                                                                                      0.1s 
Attaching to node-app-1, redis-server-1
redis-server-1  | 1:C 25 Sep 2024 14:55:07.893 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis-server-1  | 1:C 25 Sep 2024 14:55:07.893 * Redis version=7.4.0, bits=64, commit=00000000, modified=0, pid=1, just started
redis-server-1  | 1:C 25 Sep 2024 14:55:07.893 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis-server-1  | 1:M 25 Sep 2024 14:55:07.893 * monotonic clock: POSIX clock_gettime
redis-server-1  | 1:M 25 Sep 2024 14:55:07.894 * Running mode=standalone, port=6379.
redis-server-1  | 1:M 25 Sep 2024 14:55:07.894 * Server initialized
redis-server-1  | 1:M 25 Sep 2024 14:55:07.895 * Ready to accept connections tcp
node-app-1      | 
node-app-1      | > start
node-app-1      | > node index.js
node-app-1      | 
node-app-1      | Listening on port 8081

^Z
[1]  + 16728 suspended  sudo docker-compose up


➜  visits docker ps -a
CONTAINER ID   IMAGE             COMMAND                   CREATED         STATUS         PORTS                    NAMES
c20b4eca0115   redis             "docker-entrypoint.s…"   3 minutes ago   Up 3 minutes   6379/tcp                 visits-redis-server-1
172c5ee3c320   visits-node-app   "docker-entrypoint.s…"   3 minutes ago   Up 3 minutes   0.0.0.0:4001->8081/tcp   visits-node-app-1
➜  visits docker-compose ls
NAME                STATUS              CONFIG FILES
visits              running(2)          /Users/.../projects/DockerTutor/ch05/visits/docker-compose.yml
➜  visits docker-compose down
[+] Running 3/3
 ✔ Container visits-redis-server-1  Removed                                                                                                                                                                                      0.2s 
 ✔ Container visits-node-app-1      Removed                                                                                                                                                                                      0.7s 
 ✔ Network visits_default           Removed                                                                                                                                                                                      0.1s 

[index.js 수정 후 재기동]
➜  visits docker-compose up --build
[+] Building 0.8s (10/10) FINISHED                                                                                                                                                                               docker:desktop-linux
 => [node-app internal] load build definition from Dockerfile                                                                                                                                                                    0.0s
 => => transferring dockerfile: 175B                                                                                                                                                                                             0.0s
 => [node-app internal] load metadata for docker.io/library/node:alpine                                                                                                                                                          0.8s
 => [node-app internal] load .dockerignore                                                                                                                                                                                       0.0s
 => => transferring context: 2B                                                                                                                                                                                                  0.0s
 => [node-app 1/5] FROM docker.io/library/node:alpine@sha256:c9bb43423a6229aeddf3d16ae6aaa0ff71a0b2951ce18ec8fedb6f5d766cf286                                                                                                    0.0s
 => [node-app internal] load build context                                                                                                                                                                                       0.0s
 => => transferring context: 744B                                                                                                                                                                                                0.0s
 => CACHED [node-app 2/5] WORKDIR /app                                                                                                                                                                                           0.0s
 => CACHED [node-app 3/5] COPY package.json .                                                                                                                                                                                    0.0s
 => CACHED [node-app 4/5] RUN npm install                                                                                                                                                                                        0.0s
 => [node-app 5/5] COPY . .                                                                                                                                                                                                      0.0s
 => [node-app] exporting to image                                                                                                                                                                                                0.0s
 => => exporting layers                                                                                                                                                                                                          0.0s
 => => writing image sha256:241139de0138b8697956ab678e4ba43b7ebed2fa1f32e0a3c0e882d47af93c40                                                                                                                                     0.0s
 => => naming to docker.io/library/visits-node-app                                                                                                                                                                               0.0s
[+] Running 3/0
 ✔ Network visits_default           Created                                                                                                                                                                                      0.0s 
 ✔ Container visits-node-app-1      Created                                                                                                                                                                                      0.0s 
 ✔ Container visits-redis-server-1  Created                                                                                                                                                                                      0.0s 
Attaching to node-app-1, redis-server-1
redis-server-1  | 1:C 25 Sep 2024 14:58:42.988 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis-server-1  | 1:C 25 Sep 2024 14:58:42.988 * Redis version=7.4.0, bits=64, commit=00000000, modified=0, pid=1, just started
redis-server-1  | 1:C 25 Sep 2024 14:58:42.988 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis-server-1  | 1:M 25 Sep 2024 14:58:42.988 * monotonic clock: POSIX clock_gettime
redis-server-1  | 1:M 25 Sep 2024 14:58:42.988 * Running mode=standalone, port=6379.
redis-server-1  | 1:M 25 Sep 2024 14:58:42.988 * Server initialized
redis-server-1  | 1:M 25 Sep 2024 14:58:42.988 * Ready to accept connections tcp
node-app-1      | 
node-app-1      | > start
node-app-1      | > node index.js
node-app-1      | 
node-app-1      | Listening on port 8081

05-55_Stopping Docker Compose Containers] 여기부터

- 백그라운드로 container를 실행할때, docker run -d <image> = docker-compose up -d 와 유사하게 실행할 수 있다

- container를 stop할 때는 docker-compose down으로 stop할 수 있다 


05-56_Container Maintenance with Compose]

- container 프로그램이 동작 중 중단될 가능성이 있는데 이러한 상황을 만들어보자

- index.js 파일을 아래와 같이 수정한다

const express = require('express');
const redis = require('redis');
const process = require('process');

const app = express();
const client = redis.createClient({
    host: 'redis-server',
    port: 6379
});
client.set('visits', 0);

app.get('/', (req, res) => {
    process.exit(0);
    client.get('visits', (err, visits) => {
        res.send('Number of visits is ' + visits);
        client.set('visits', parseInt(visits) + 2);
    })
});

app.listen(8081, () => {
    console.log('Listening on port 8081');
})

- docker-compose up

➜  visits docker-compose up --build
open /Users/johnnyji/.docker/buildx/current: permission denied
➜  visits sudo docker-compose up --build
Password:
[+] Building 2.0s (11/11) FINISHED                                                                             docker:desktop-linux
 => [node-app internal] load build definition from Dockerfile                                                                  0.0s
 => => transferring dockerfile: 175B                                                                                           0.0s
 => [node-app internal] load metadata for docker.io/library/node:alpine                                                        2.0s
 => [node-app auth] library/node:pull token for registry-1.docker.io                                                           0.0s
 => [node-app internal] load .dockerignore                                                                                     0.0s
 => => transferring context: 2B                                                                                                0.0s
 => [node-app 1/5] FROM docker.io/library/node:alpine@sha256:c9bb43423a6229aeddf3d16ae6aaa0ff71a0b2951ce18ec8fedb6f5d766cf286  0.0s
 => [node-app internal] load build context                                                                                     0.0s
 => => transferring context: 801B                                                                                              0.0s
 => CACHED [node-app 2/5] WORKDIR /app                                                                                         0.0s
 => CACHED [node-app 3/5] COPY package.json .                                                                                  0.0s
 => CACHED [node-app 4/5] RUN npm install                                                                                      0.0s
 => [node-app 5/5] COPY . .                                                                                                    0.0s
 => [node-app] exporting to image                                                                                              0.0s
 => => exporting layers                                                                                                        0.0s
 => => writing image sha256:3b6921cf3a9f572abda421b4fe36e95fc2065eec1e9789742b331aeeca2f7770                                   0.0s
 => => naming to docker.io/library/visits-node-app                                                                             0.0s
[+] Running 3/3
 ✔ Network visits_default           Created                                                                                    0.0s 
 ✔ Container visits-redis-server-1  Created                                                                                    0.0s 
 ✔ Container visits-node-app-1      Created                                                                                    0.0s 
Attaching to node-app-1, redis-server-1
redis-server-1  | 1:C 26 Sep 2024 14:31:25.988 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis-server-1  | 1:C 26 Sep 2024 14:31:25.988 * Redis version=7.4.0, bits=64, commit=00000000, modified=0, pid=1, just started
redis-server-1  | 1:C 26 Sep 2024 14:31:25.988 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis-server-1  | 1:M 26 Sep 2024 14:31:25.988 * monotonic clock: POSIX clock_gettime
redis-server-1  | 1:M 26 Sep 2024 14:31:25.989 * Running mode=standalone, port=6379.
redis-server-1  | 1:M 26 Sep 2024 14:31:25.989 * Server initialized
redis-server-1  | 1:M 26 Sep 2024 14:31:25.989 * Ready to accept connections tcp
node-app-1      | 
node-app-1      | > start
node-app-1      | > node index.js
node-app-1      | 
node-app-1      | Listening on port 8081
=> http://localhost:4001/ 로 접속하면 NodeJS Container가 꺼진다
node-app-1 exited with code 0

➜  visits docker ps -a
CONTAINER ID   IMAGE             COMMAND                   CREATED         STATUS                     PORTS      NAMES
2623a3a0c4f2   visits-node-app   "docker-entrypoint.s…"   3 minutes ago   Exited (0) 3 minutes ago              visits-node-app-1
2a4af8c71917   redis             "docker-entrypoint.s…"   3 minutes ago   Up 3 minutes               6379/tcp   visits-redis-server-1
➜  visits

05-57_Automatic Container Restarts]

- 재시작 정책으로 always를 추가하면, 예기치 못한 종료에도 재시작이 가능하다

version: '3'
services:
  redis-server:
    image: 'redis'
  node-app:
    restart: always
    build: .
    ports:
      - "4001:8081"

05-58_Container Status with Docker Compose]

- docker ps = docker-compose ps 유사하다, 다만 docker-compose.yml에 명시한 container의 상태만 보여준다


05-59_Visits Application Updated for Redis v4+]

const express = require("express");
const redis = require("redis");
 
const app = express();
const client = redis.createClient({
  url: "redis://redis-server:6379",
});
 
(async () => {
  await client.connect();
  await client.set("visits", 0);
})();
 
app.get("/", async (req, res) => {
  const visits = await client.get("visits");
  res.send("Number of visits " + visits);
  await client.set("visits", parseInt(visits) + 1);
});
 
app.listen(8081, () => {
  console.log("listening on port 8081");
});

 
 
 


 
 
 


 
 
 


 
 
 
 


~~

반응형
Comments