docker-compose를 통해 redis 연동 node express 앱을 만들어보는 블로그를 봤다.
node와 redis 컨테이너로 별도로 실행시켜주면, 다른 컨테이너 환경이기 때문에 통신을 할 수 없다.
그래서 Docker-Compose를 통해 같은 컨테이너 환경에서 실행할 수 있다.
그러나 아래와 같은 오류가 계속 발생했다
- return Promise.reject(new errors_1.ClientClosedError());
- The client is closed
redis 패키지가 버전 3에서 4 (연결 비동기 처리 방식)로 넘어가면서, 문제가 발생했다고 한다.
나는 redis npm 모듈을 그냥 설치했더니, 최신 버전 (v4.6.8)로 설치됐다..
$ npm i redis@3.0.0
특정 버전 선언을 통해 설치하면 될 것 같다. (해결하고 나서 생각났다...)
프로젝트 생성
$ npm init -y
$ npm i express
$ npm i redis
$ npm i body-parser
package.json
{
"name": "docker-k8s",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.20.2",
"express": "^4.18.2",
"redis": "^4.6.8"
},
"type": "module"
}
type=module
옵션을 통해, 모듈을 require가 아닌 import 키워드를 통해 가져오도록 설정
index.js
import express from "express";
import { set, get } from "./redis.js";
import bodyParser from "body-parser";
const app = express();
const PORT = 8080;
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
app.get("/", async (req, res) => {
res.send("running app !");
});
app.get("/:key", async (req, res) => {
const key = req.params.key;
const value = await get(key);
res.status(200).send(`redis get ${key} : ${value}`);
});
app.post("/", async (req, res) => {
const key = req.body.key;
const value = req.body.value;
await set(key, value);
res.status(201).send(`redis set ${key} ${value}`);
});
app.listen(PORT, () => {
console.log(`Running Server: ${PORT}`);
});
redis.js
import redis from "redis";
const client = redis.createClient({
url: `redis://redis-hostname`,
});
const run = async () => await client.connect();
run();
const set = async (key, value) => await client.set(key, value);
const get = async (key) => await client.get(key);
export { set, get };
Docker-compose.yml 에서 설정한 redis의 hostname을 url에 넣어줍니다
Dockerfile
FROM node
# 프로젝트 경로
WORKDIR /Users/sejin/Documents/docker-k8s
COPY package.json ./
RUN npm install
COPY ./ ./
CMD [ "node", "index.js" ]
Docker-compose.yml
version: '1' # 버전 관리를 위함. 큰 의미는 없다
services:
node-app: # 원하는 서비스 이름 선언
build: . # Dockerfile이 동일한 경로에 존재하여 현재 경로의 Dockerfile을 빌드
ports:
- 8080:8080 # 왼쪽 포트는 외부, 오른쪽 포트는 내부 포트를 지정한다. 포트포워딩 용도
depends_on: # 종속성을 정의. 다른 서비스의 시작을 기다림
- redis-service # redis 서비스명을 입력하였고. redis 시작 후 node 앱이 실행된다
redis-service:
image: redis
command: redis-server --port 6379
container_name: redis-container
hostname: redis-hostname
labels:
- "name=redis"
- "mode=standalone"
ports:
- 6379:6379
Docker compose 실행하기
# 작업 공간 (workspace)에서 실행. 이미지가 있다면 바로 실행. 없다면 빌드 후 실행
$ docker-compose up
# 만약 소스에 변경사항이 있다면 빌드 후 실행
$ docker-compose up --build
# detached 모드. 백그라운드에서 실행
$ docker-compose up -d
# 특정 경로에 있는 docker-compose 파일 실행
$ docker-compose -f /workspace/docker-k8s/Docker-compose.yml up
Docker Container 접속
$ docker exec -it <container-name> bash
Node Express 서버 (with Redis) API 확인
참고 링크
'Docker & k8s' 카테고리의 다른 글
Docker 시작하기 (0) | 2022.04.02 |
---|