|
| 1 | +# Use bind mounts |
| 2 | + |
| 3 | +[Part 4](/#/get-started/workshop/05_persisting_data)에서는 볼륨 마운트를 사용하여 데이터베이스의 데이터를 유지했습니다. 볼륨 마운트는 애플리케이션 데이터를 영구적으로 저장할 곳이 필요할 때 좋은 선택입니다. |
| 4 | + |
| 5 | +바인드 마운트는 호스트 파일시스템의 디렉토리를 컨테이너와 공유할 수 있게 해주는 또 다른 유형의 마운트입니다. 애플리케이션을 개발할 때, 바인드 마운트를 사용하여 소스 코드를 컨테이너에 마운트할 수 있습니다. 이렇게 하면 컨테이너는 파일을 저장하는 즉시, 코드에 대한 변경 사항을 볼 수 있습니다. 이는 파일 시스템 변경을 감시하고 이에 응답하는 프로세스를 컨테이너에서 실행할 수 있다는 뜻입니다. |
| 6 | + |
| 7 | +이 챕터에서는, 바인드 마운트와 [nodemon](https://npmjs.com/package/nodemon)이라는 도구를 사용하여 파일 변경을 감시하고, 애플리케이션을 자동으로 재시작하는 방법을 살펴보겠습니다. 대부분의 다른 언어와 프레임워크에도 이와 동등한 도구들이 있습니다. |
| 8 | + |
| 9 | +## Quick volume type comparisons |
| 10 | + |
| 11 | +다음은 `--mount`를 사용한 명명된(named) 볼륨과 바인드 마운트의 예시입니다: |
| 12 | + |
| 13 | +- 명명된(Named) 볼륨: `type=volume,src=my-volume,target=/usr/local/data` |
| 14 | +- 바인드 마운트: `type=bind,src=/path/to/data,target=/usr/local/data` |
| 15 | + |
| 16 | +다음 표는 볼륨 마운트와 바인드 마운트 사이의 주요 차이점을 보여줍니다. |
| 17 | + |
| 18 | +| 비교 항목 | **명명된(Named) 볼륨** | **바인드 마운트** | |
| 19 | +| -------------------------------- | ---------------------- | ----------------- | |
| 20 | +| 호스트 위치 | Docker가 선택 | 사용자가 결정 | |
| 21 | +| 새 볼륨에 컨테이너 콘텐츠 채우기 | 예 | 아니오 | |
| 22 | +| 볼륨 드라이버 지원 | 예 | 아니오 | |
| 23 | + |
| 24 | +## Trying out bind mounts |
| 25 | + |
| 26 | +애플리케이션 개발에 바인드 마운트를 어떻게 사용할 수 있는지 살펴보기 전에, 간단한 실험을 통해 바인드 마운트가 어떻게 작동하는지 실용적으로 이해해 보겠습니다. |
| 27 | + |
| 28 | +1. `getting-started-app` 디렉토리가 Docker Desktop의 파일 공유 설정에 정의된 디렉토리에 있는지 확인합니다. 이 설정은 컨테이너와 공유할 수 있는 파일시스템의 부분을 정의합니다. 설정에 액세스하는 방법에 대한 자세한 내용은 [파일 공유](https://docs.docker.com/desktop/settings-and-maintenance/settings/#file-sharing)를 참조하세요. |
| 29 | + |
| 30 | + > **Note** |
| 31 | + > |
| 32 | + > **파일 공유** 탭은 Hyper-V 모드에서만 사용할 수 있습니다. 파일은 WSL 2 모드와 Windows 컨테이너 모드에서 자동으로 공유되기 때문입니다. |
| 33 | +
|
| 34 | +2. 터미널을 열고 `getting-started-app` 디렉토리로 변경합니다. |
| 35 | + |
| 36 | +3. 바인드 마운트가 있는 `ubuntu` 컨테이너에서 `bash`를 시작하려면 다음 명령을 실행하세요: |
| 37 | + |
| 38 | + ```bash |
| 39 | + # Mac/Linux |
| 40 | + $ docker run -it --mount type=bind,src="$(pwd)",target=/src ubuntu bash |
| 41 | + |
| 42 | + # Windows (Command Prompt) |
| 43 | + $ docker run -it --mount "type=bind,src=%cd%,target=/src" ubuntu bash |
| 44 | + |
| 45 | + # Windows (PowerShell) |
| 46 | + $ docker run -it --mount "type=bind,src=$(pwd),target=/src" ubuntu bash |
| 47 | + |
| 48 | + # Windows (Git Bash) |
| 49 | + $ docker run -it --mount type=bind,src="/$(pwd)",target=/src ubuntu bash |
| 50 | + ``` |
| 51 | + |
| 52 | + `--mount type=bind` 옵션은 Docker에게 바인드 마운트를 생성하도록 지시합니다. 여기서 `src`는 호스트 머신의 현재 작업 디렉토리(`getting-started-app`)이고, `target`은 해당 디렉토리가 컨테이너 내부에 표시되어야 하는 위치(`/src`)입니다. |
| 53 | + |
| 54 | +4. 명령을 실행하면, Docker는 컨테이너 파일 시스템의 루트 디렉토리에서 대화형 `bash` 세션을 시작합니다. |
| 55 | + ```bash |
| 56 | + root@ac1237fad8db:/# pwd |
| 57 | + / |
| 58 | + root@ac1237fad8db:/# ls |
| 59 | + bin dev home media opt root sbin srv tmp var |
| 60 | + boot etc lib mnt proc run src sys usr |
| 61 | + ``` |
| 62 | +5. `src` 디렉토리로 변경합니다: |
| 63 | + |
| 64 | + ```bash |
| 65 | + cd /src |
| 66 | + ls |
| 67 | + ``` |
| 68 | + |
| 69 | + 이것은 컨테이너를 시작할 때 마운트한 디렉토리입니다. 이 디렉토리의 내용을 나열하면 호스트 시스템의 `getting-started-app` 디렉토리와 동일한 파일이 표시됩니다. |
| 70 | + |
| 71 | + ```bash |
| 72 | + root@ac1237fad8db:/# cd src |
| 73 | + root@ac1237fad8db:/src# ls |
| 74 | + Dockerfile node_modules package.json spec src yarn.lock |
| 75 | + ``` |
| 76 | + |
| 77 | +6. `myfile.txt`라는 새 파일을 생성합니다: |
| 78 | + |
| 79 | + ```bash |
| 80 | + root@ac1237fad8db:/src# touch myfile.txt |
| 81 | + root@ac1237fad8db:/src# ls |
| 82 | + Dockerfile myfile.txt node_modules package.json spec src yarn.lock |
| 83 | + ``` |
| 84 | + |
| 85 | +7. 호스트에서 `getting-started-app` 디렉토리를 열고 `myfile.txt` 파일이 디렉토리에 있는지 확인합니다. |
| 86 | + |
| 87 | + ```bash |
| 88 | + ├── getting-started-app/ |
| 89 | + │ ├── Dockerfile |
| 90 | + │ ├── myfile.txt |
| 91 | + │ ├── node_modules/ |
| 92 | + │ ├── package.json |
| 93 | + │ ├── spec/ |
| 94 | + │ ├── src/ |
| 95 | + │ └── yarn.lock |
| 96 | + ``` |
| 97 | + |
| 98 | +8. 호스트에서 `myfile.txt` 파일을 삭제합니다. |
| 99 | + |
| 100 | +9. 컨테이너에서 다시 한번 `app` 디렉토리의 내용을 나열합니다. 파일이 이제 사라진 것을 관찰하세요: |
| 101 | + |
| 102 | + ```bash |
| 103 | + root@ac1237fad8db:/src# ls |
| 104 | + Dockerfile node_modules package.json spec src yarn.lock |
| 105 | + ``` |
| 106 | + |
| 107 | +10. `Ctrl+D`로 대화형 컨테이너 세션을 중지합니다. |
| 108 | + |
| 109 | +바인드 마운트에 대한 간략한 소개는 여기까지입니다. 이 절차는 파일이 호스트와 컨테이너 간에 어떻게 공유되는지, 그리고 변경 사항이 양쪽에서 즉시 반영되는 방법을 보여주었습니다. 이제 소프트웨어 개발을 위해 바인드 마운트를 사용할 수 있습니다. |
| 110 | + |
| 111 | +## Development containers |
| 112 | + |
| 113 | +바인드 마운트는 로컬 개발 환경에서 일반적으로 사용됩니다. 장점은 개발 머신에 모든 빌드 도구와 환경을 설치할 필요가 없다는 것입니다. 단일 `docker run` 명령으로 Docker는 의존성과 도구를 가져옵니다. |
| 114 | + |
| 115 | +### Run your app in a development container |
| 116 | + |
| 117 | +이후 단계는 다음과 같은 작업을 수행하는 바인드 마운트가 있는 개발 컨테이너를 실행하는 방법을 설명합니다: |
| 118 | + |
| 119 | +- 소스 코드를 컨테이너에 마운트 |
| 120 | +- 모든 의존성 설치 |
| 121 | +- 파일 시스템 변경을 감시하기 위한 `nodemon` 시작 |
| 122 | + |
| 123 | +CLI 또는 Docker Desktop을 사용하여 바인드 마운트로 컨테이너를 실행할 수 있습니다. |
| 124 | + |
| 125 | +1. 현재 실행 중인 `getting-started` 컨테이너가 없는지 확인합니다. |
| 126 | + |
| 127 | +2. `getting-started-app` 디렉토리에서 다음 명령을 실행합니다: |
| 128 | + |
| 129 | + ```bash |
| 130 | + # Mac/Linux |
| 131 | + $ docker run -dp 127.0.0.1:3000:3000 \ |
| 132 | + -w /app --mount type=bind,src="$(pwd)",target=/app \ |
| 133 | + node:18-alpine \ |
| 134 | + sh -c "yarn install && yarn run dev" |
| 135 | + |
| 136 | + # Windows (Command Prompt) |
| 137 | + $ docker run -dp 127.0.0.1:3000:3000 ^ |
| 138 | + -w /app --mount "type=bind,src=%cd%,target=/app" ^ |
| 139 | + node:18-alpine ^ |
| 140 | + sh -c "yarn install && yarn run dev" |
| 141 | + |
| 142 | + # Windows (PowerShell) |
| 143 | + $ docker run -dp 127.0.0.1:3000:3000 ` |
| 144 | + -w /app -mount "type=bind,src=$pwd,target=/app" ` |
| 145 | + node:18-alpine ` |
| 146 | + sh -c "yarn install && yarn run dev" |
| 147 | +
|
| 148 | + # Windows (Git Bash) |
| 149 | + $ docker run -dp 127.0.0.1:3000:3000 \ |
| 150 | + -w //app --mount type=bind,src="/$(pwd)",target=/app \ |
| 151 | + node:18-alpine \ |
| 152 | + sh -c "yarn install && yarn run dev" |
| 153 | + ``` |
| 154 | + |
| 155 | + 다음은 명령의 세부 내용입니다: |
| 156 | + |
| 157 | + - `-dp 127.0.0.1:3000:3000` - 이전과 같습니다. 백그라운드(분리) 모드에서 실행하고 포트 매핑을 생성합니다. |
| 158 | + - `-w /app` - "작업 디렉토리" 또는 명령이 실행될 현재 디렉토리를 설정합니다. |
| 159 | + - `--mount type=bind,src="$(pwd)",target=/app` - 호스트의 현재 디렉토리를 컨테이너의 `/app` 디렉토리에 바인드 마운트합니다. |
| 160 | + - `node:18-alpine` - 앱의 기본 이미지입니다 |
| 161 | + - `sh -c "yarn install && yarn run dev"` - 명령어입니다. `sh`를 이용해 셸을 사용하여 명령을 시작하고 `yarn install`을 실행해 패키지들을 설치하고 `yarn run dev`를 실행해 개발 서버를 시작합니다. `package.json` 파일을 보면, `dev` 스크립트는 `nodemon`을 시작합니다. |
| 162 | + |
| 163 | +3. `docker logs <container-id>`를 사용하여 로그를 볼 수 있습니다. 다음과 같은 내용이 표시되면 준비가 된 것입니다 : |
| 164 | + |
| 165 | + ```bash |
| 166 | + nodemon -L src/index.js |
| 167 | + [nodemon] 2.0.20 |
| 168 | + [nodemon] to restart at any time, enter `rs` |
| 169 | + [nodemon] watching path(s): *.* |
| 170 | + [nodemon] watching extensions: js,mjs,json |
| 171 | + [nodemon] starting `node src/index.js` |
| 172 | + Using sqlite database at /etc/todos/todo.db |
| 173 | + Listening on port 3000 |
| 174 | + ``` |
| 175 | + |
| 176 | + 로그 보기를 종료하려면, `Ctrl+C`를 누르세요. |
| 177 | + |
| 178 | +### Develop your app with the development container |
| 179 | + |
| 180 | +호스트 머신에서 앱을 업데이트하고 컨테이너에 반영된 변경 사항을 확인하세요. |
| 181 | + |
| 182 | +1. `src/static/js/app.js` 파일에서, 109번째 줄에, "Add Item" 버튼의 텍스트를 "Add"로 간단하게 변경합니다 : |
| 183 | + |
| 184 | + ```javascript |
| 185 | + - {submitting ? 'Adding...' : 'Add Item'} |
| 186 | + + {submitting ? 'Adding...' : 'Add'} |
| 187 | + ``` |
| 188 | + |
| 189 | + 저장합니다. |
| 190 | + |
| 191 | +2. 웹 브라우저에서 페이지를 새로 고치면 바인드 마운트로 인해 변경 사항이 거의 즉시 반영되는 것을 볼 수 있습니다. Nodemon이 변경 사항을 감지하고 서버를 다시 시작합니다. Node 서버가 다시 시작되는 데 몇 초 정도 걸릴 수 있습니다. 오류가 발생하면, 몇 초 후에 새로 고침해 보세요. |
| 192 | +  |
| 193 | + |
| 194 | +3. 원하는 다른 변경 사항이 있으면 자유롭게 적용하세요. 파일을 변경하고 저장할 때마다 바인드 마운트로 인해 변경 사항이 컨테이너에 반영됩니다. Nodemon이 변경 사항을 감지하면, 컨테이너 내부의 앱을 자동으로 다시 시작합니다. 수정 작업이 완료되면 컨테이너를 중지하고 다음을 사용하여 새 이미지를 빌드합니다 |
| 195 | + |
| 196 | + ```bash |
| 197 | + $ docker build -t getting-started . |
| 198 | + ``` |
| 199 | + |
| 200 | +## Summary |
| 201 | + |
| 202 | +이 시점에서, 여러분은 데이터베이스를 유지할 수 있고 이미지를 다시 빌드하지 않고도 앱의 변경 사항을 개발하면서 확인할 수 있습니다. |
| 203 | +볼륨 마운트와 바인드 마운트 외에도, Docker는 보다 복잡하고 특수한 사용 사례를 처리하기 위해 다른 마운트 유형과 스토리지 드라이버도 지원합니다. |
| 204 | + |
| 205 | +관련 정보 : |
| 206 | + |
| 207 | +- [docker CLI reference](https://docs.docker.com/reference/cli/docker/) |
| 208 | +- [Manage data in Docker](https://docs.docker.com/storage/) |
| 209 | + |
| 210 | +## What next |
| 211 | + |
| 212 | +앱을 프로덕션을 위해 준비하려면 SQLite에서 작동하는 데이터베이스를 확장성이 좀 더 뛰어난 데이터베이스로 마이그레이션해야 합니다. 간편함을 위해, 관계형 데이터베이스를 계속 사용하고 애플리케이션을 MySQL로 전환하면 됩니다. 하지만, MySQL을 어떻게 실행해야 할까요? 컨테이너 간 통신을 어떻게 허용해야 할까요? 다음 섹션에서 자세히 알아보겠습니다. |
| 213 | + |
| 214 | +[Multi container apps](/#/get-started/workshop/07_multi_container) |
0 commit comments