뉴질랜드 다이어리(NZ Diary) 라빠
[삽질포함] Docker 따라하기 #4 본문
지금까지는 Docker 로 하나의 Container 를 돌리는 실습을 해 보았습니다.
이번에는 Docker Compese 라는 툴을 이용하여, 두개 이상의 Container 를 구동하여 서비스를 만드는 연습을 해 보겠습니다.
최종 목표
Mysql Container 와 Node.js Container 를 각각 구동하고, Node.js 에서 Mysql Database 를 접근하는 서비스를 만들어봅니다.
간단하게 구조화하면 아래와 같습니다.
Browser (Host) -> Node.js (Container #1) -> Mysql(Container #2)
Node.js Image 만들기
Docker 따라하기 #3 에서는 단순하게 String 을 결과값으로 반환했으나, 이제는 MySql Database 에서 값을 로드하도록 변경해야 합니다.
'use strict';
const express = require('express');
const mysql = require('mysql');
const app = express();
const connection = mysql.createConnection({
host: '0.0.0.0',
user: 'root',
post: 3306,
password: 'password',
database: 'engineer'
});
app.get('/', (req, res) => {
connection.connect();
let sql = 'show tables';
connection.query(sql, (err, rows) => {
if (err) {
res.send('Opps. Error happened\n');
} else {
res.send('Hello Engineers\n');
}
})
});
app.listen(8080, '0.0.0.0');
console.log(`Node Web App is Running on http://0.0.0.0:8080`);
Node.js 에서 MySql 을 사용할 수 있도록 package 에 mysql 을 dependency 를 추가하고, 이미지를 새로 만들어줍니다.
$ npm install mysql --save
결과적으로 package.json 은 아래와 같이 변경됩니다.
{
"name": "node_web_app",
"version": "1.0.0",
"description": "Node.js on Docker",
"author": "",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.16.3",
"mysql": "^2.16.0"
}
}
Docker Compose 설정하기
Docker Composer 는 하나 이상의 Docker Container 를 구동할 수 있게 도와주는 툴입니다. 이 어플리케이션처럼 두개 이상의 Container 를 구동할때, 각각을 구동하지 않고, Docker Composer 를 통해 한번에 구동할 수 있게 도와줍니다.
docker-compse.yml 은 node 와 mysql 이라는 두개의 container 를 어떻게 빌드하고 구동할지를 정의한 파일이라고 생각하시면 되겠네요.
version: '3'
services:
node:
build: .
ports:
- "8080:8080"
expose:
- "8080"
links:
- mysql
depends_on:
- mysql
mysql:
image: "mysql/mysql-server"
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: engineer
MYSQL_USER: root
MYSQL_PASSWORD: password
expose:
- "3306"
위와 같이 설정파일을 생성하고, 아래의 커맨드를 실행하면, 두개의 컨테이너가 동시에 구동됩니다.
$ docker-compose up
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dfdeaeeac0e1 compose_node "npm start" 6 minutes ago Up 4 seconds 0.0.0.0:8080->8080/tcp compose_node_1
45248769f312 mysql/mysql-server:5.7 "/entrypoint.sh mysq…" 6 minutes ago Up 5 seconds (health: starting) 0.0.0.0:3306->3306/tcp, 33060/tcp compose_mysql_1
문제점 #1
두개의 container 가 정상적으로 구동되긴 한데, node 에서 mysql 에 접속을 하지 못하는 현상이 발견됨.
Error: connect ECONNREFUSED 0.0.0.0:3306
접근방법 #1
node 에서 mysql 을 접근할때, localhost 로 접근을 하는데, node 의 3306 포트가 mysql 의 3306 포트로 연결이 되지 않았으므로, localhost 로 접근을 하지 말고, mysql 의 ip 로 접근을 해야 한다.
alice_k106 님의 블로그 를 참고하여 Host 와 Container 의 포트 연결에 대해 좀더 알아보자.
container 의 ip 를 알려면, docker inspect 명령을 사용하면 된다.
$ docker inspect <container_id>
Mysql 의 ip 로 접속하도록 Server.js 를 수정
'use strict';
const connection = mysql.createConnection({
host: '172.19.0.2', // 획득한 IP 로 수정
user: 'root',
post: 3306,
password: 'password',
database: 'engineer'
});
문제점 #2
서버에서 에러를 리턴함.
Error: ER_HOST_NOT_PRIVILEGED: Host '172.19.0.3' is not allowed to connect to this MySQL server
접근방법 #1
Mysql 의 root 사용자가 로컬에서 접근을 허용하도록 설정되어있는 문제이므로, 신규 사용자를 추가하고, node 에서의 접근을 허용하도록 함.
$ docker exec -it <mysql_container_id> bash
$ mysql -u root -p
$ CREATE USER 'engineer'@'172.19.0.3' IDENTIFIED BY 'password';
$ GRANT ALL ON *.* TO 'engineer'@'172.19.0.3';
위와 같이 `engineer' 라는 사용자를 추가하고, 접근을 허용해준다. node 의 mysql 접근코드도 함께 변경한다.
'use strict';
const connection = mysql.createConnection({
host: '172.19.0.2',
user: 'engineer', // 사용자 변경
post: 3306,
password: 'password',
database: 'engineer'
});
문제점 #3
서버에 로그인을 할 수 없는 문제가 발생.
Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
접근방법 #1
Mysql 8 에서부터 사용자 인증방식이 변경되었다고 한다. docker-compose.yml 에서 버전을 지정해 주지 않아서, 최신버전인 8 을 사용하고 있었음. node 의 mysql 모듈이 아직 이를 지원하지 않으므로, mysql 버전을 5.7 로 변경하여 다시 시도함.
mysql:
image: "mysql/mysql-server:5.7"
정상적으로 동작확인
$ curl -i localhost:8080
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 16
ETag: W/"10-JhXyAELZ+v4AaWuE4SR9QoGav+4"
Date: Sat, 02 Mar 2019 08:42:49 GMT
Connection: keep-alive
Hello Engineers
일단 여기까지가 Docker 를 이용한 기본적인 사용방법을 익히는 따라하기
가 될것 같습니다.
다음부터는 Docker 의 꽃
. Orchestration
을 한번 익혀볼까 합니다. (언제가 될지는 모르지만...쿨럭..)