docker-compose를 통해  redis 연동 node express 앱을 만들어보는 블로그를 봤다.

 

node와 redis 컨테이너로 별도로 실행시켜주면, 다른 컨테이너 환경이기 때문에 통신을 할 수 없다.

 

그래서 Docker-Compose를 통해 같은 컨테이너 환경에서 실행할 수 있다.

 

그러나 아래와 같은 오류가 계속 발생했다

  1. return Promise.reject(new errors_1.ClientClosedError());
  2. 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 / docker-compose를 실행하면 Docker Desktop에서 실행된 것을 확인할 수 있습니다
docker ps , docker-compose ls 명령어를 통해 컨테이너가 실행되고 있는 것을 확인할 수 있습니다
redis 명령어를 통한 키 값 조회, 설정

Docker Container 접속

$ docker exec -it <container-name> bash

Node Express 서버 (with Redis) API 확인

key: user 의 value 값 아직 없음
key, value 등록
등록한 key: user의 value 값을 들고 오는 것을 확인

 


참고 링크

 

redis + node 연동

node 에서 redis 를 이용하기 위해 구글링으로 example code를 찾아보았다. 그러나 돌아온 결과는 보기 좋게 Error를 띄웠다. 하지만 stackoverflow는 모르는게 없는법. 바로 관련된 자료를 찾으러 달려갔다.

velog.io

 

 

Redis NodeJs server error,client is closed

I am developing an application where chats has to cached and monitored, currently it is an local application where i have installed redis and redis-cli. The problem i'm facing is (node:5368)

stackoverflow.com

 

'Docker & k8s' 카테고리의 다른 글

Docker 시작하기  (0) 2022.04.02

+ Recent posts