본 내용은 Microsoft에서 제공하는 Docker 자습서 내용을 정리한 글입니다.
원문과 내용이 비슷하지만, Docker를 접하기에 아주 유용한 문서로 개인 학습 및 정보공유 차원에서 작성합니다.
지금까지는 단일 컨테이너 앱을 사용했습니다. 이제 애플리케이션 스택에 MySQL을 추가해 보겠습니다.
“MySQL은 어디서 실행되나요? 같은 컨테이너에 설치하나요, 아니면 별도로 실행하나요?”라는 질문을 받는 경우가 많습니다.
일반적으로 각 컨테이너에서 한 가지 작업을 잘 수행하는 것이 좋습니다. 다음과 같은 몇 가지 이유가 있습니다.
그 밖에 다른 이유도 있습니다. 따라서 애플리케이션을 다음과 같이 업데이트 하겠습니다.
네트워크 생성
$ docker network create todo-app
MySQL 컨테이너를 시작하고 네트워크에 연결함, 또한 DB를 초기화 하는데 사용할 몇 개의 환경 변수를 정의함
$ docker run -d \
--network todo-app --network-alias mysql \
-v todo-mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=todos \
mysql:5.7
--network-ailas
플래그도 지정 함, 잠시후에 설명 함
여기서는 todo-mysql-data
라는 볼륨 이름을 사용하고, MySQL에서 데이터를 저장하는 위치인 /var/lib/mysql
에 볼륨을 탑재합니다. 그러나 docker volume create
명령을 실행한 적은 없습니다. Docker에서 명명된 볼륨을 사용하려는 의도를 인식하고 자동으로 볼륨을 만듭니다.
데이터베이스가 시작되어 실행되고 있는지 확인하려면 데이터베이스에 연결하여 연결 상태를 확인함
$ docker exec -it <mysql-container-id> mysql -p
암호 프롬프트가 표시되면 secret을 입력합니다. MySQL 셀에서 데이터베이스 목록을 표시하고 todos
데이터베이스가 표시되는지 확인합니다.
nicolaka/netshoot
이미지를 사용하여 새 컨테이너를 시작, 같은 네트워크에 컨테이너를 연결해야 함
$ docker run -it --network todo-app nicolaka/netshoot
컨테이너 내에서 유용한 DNS 도구인 dig
명령을 사용함, Host이름 mysql
의 IP 주소를 조회
$ dig mysql
아래와 같은 출력이 표시 됨
; <<>> DiG 9.14.1 <<>> mysql
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32162
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;mysql. IN A
;; ANSWER SECTION:
mysql. 600 IN A 172.23.0.2
;; Query time: 0 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Tue Oct 01 23:47:24 UTC 2019
;; MSG SIZE rcvd: 44
“ANSWER SECTION”에서 mysql
에 대해 A
레코드가 표시되며, 172.23.0.2
로 확인됩니다(사용자 IP 주소는 다른 값일 가능성이 높음). mysql
는 일반적으로 유효한 호스트 이름이 아니지만, Docker에서 해당 네트워크 별칭을 가진 컨테이너의 IP 주소로 확인할 수 있었습니다(앞에서 사용한 --network-alias
플래그 참조).
따라서 앱이 mysql
이라는 호스트에 연결하기만 하면 데이터베이스와 통신할 수 있습니다. 매우 간단합니다.
todo 앱에서 몇 개의 환경 변수를 설정하여 MySQL 연결 설정을 지정할 수 있습니다. 관련 토폴로지는 아래와 같습니다.
MYSQL_HOST
- 실행 중인 MySQL 서버의 호스트 이름MYSQL_USER
- 연결에 사용할 사용자 이름MYSQL_PASSWORD
- 연결에 사용할 암호MYSQL_DB
- 연결된 후 사용할 데이터베이스이제 개발 환경용 컨테이너를 시작합니다.
위에서 언급한 각 환경 변수를 지정하고 컨테이너를 앱 네트워크에 연결
$ docker run -dp 3000:3000 \
-w /app -v ${PWD}:/app \
--network todo-app \
-e MYSQL_HOST=mysql \
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=secret \
-e MYSQL_DB=todos \
node:12-alpine \
sh -c "yarn install && yarn run dev"
컨테이너에 대한 로그(docker logs <container-id>
) 를 살펴보면 MySQL 데이터 베이스를 사용하고 있음을 나타내는 메시지를 볼 수 있습니다.
# Previous log messages omitted
$ nodemon src/index.js
[nodemon] 1.19.2
[nodemon] to restart at any time, enter `rs`
[nodemon] watching dir(s): *.*
[nodemon] starting `node src/index.js`
Connected to mysql db at host mysql
Listening on port 3000
브라우저에서 앱을 열고 todo 목록에 몇 개의 항목을 추가합니다.
MySQL 데이터베이스에 연결하여 데이터베이스에 항목이 기록되고 있음을 증명합니다. 암호는 secret 입니다.
$ docker exec -ti <mysql-container-id> mysql -p todos
MySQL 셸에서 다음을 실행합니다.
mysql> select * from todo_items;
+--------------------------------------+--------------------+-----------+
| id | name | completed |
+--------------------------------------+--------------------+-----------+
| c906ff08-60e6-44e6-8f49-ed56a0853e85 | Do amazing things! | 0 |
| 2912a79e-8486-4bc3-a4c5-460793a575ab | Be awesome! | 0 |
+--------------------------------------+--------------------+-----------+
사용자 테이블은 해당 항목을 포함하므로 다르게 표시될 것입니다. 그러나 항목이 테이블에 저장된 것은 확인할 수 있습니다.
IDE 에서 제공하는 Docker 확장을 살펴보면 앱 컨테이너 두개가 같이 실행되는 것을 확인할 수 있습니다.