노드 마이크로서비스를 도커 컨테이너화하여 실행 성공하는것이 이번 게시글의 목표입니다.
# 준비물 :
- Node.js 설치 [ https://nodejs.org/en/download/package-manager ]
- Docker 설치 [ https://www.docker.com/products/docker-desktop/ ]
- VScode 등의 텍스트 에디터 [ https://code.visualstudio.com/download ]
- Windows PowerShell 등 터미널 환경
0. Node 프로젝트를 초기화하고 express와 axios 설치합니다.
# Node 프로젝트 초기화 (package.json 파일 생성)
npm init -y
# express와 axios 설치
npm install express axios
1. index.js 작성합니다
const express = require('express');
const axios = require('axios');
const app = express();
const PORT = 3000;
const SPRINGBOOT_API = 'http://userservice:8080/users'; // Spring Boot 서비스 이름을 올바르게 수정
app.use(express.static('public')); // public 폴더에 HTML, CSS, JS 파일 배치
app.use(express.json());
// Spring Boot에서 데이터 가져오기
app.get('/api/get-data', async (req, res) => {
try {
const response = await axios.get(SPRINGBOOT_API); // 수정된 API 주소
res.json(response.data);
} catch (error) {
console.error(error); // 오류 로깅 추가
res.status(500).json({ error: 'Failed to fetch data' });
}
});
// Spring Boot에 데이터 추가하기
app.post('/api/add-data', async (req, res) => {
try {
const { name, email } = req.body;
const response = await axios.post(SPRINGBOOT_API, { name, email }); // 수정된 API 주소
res.json(response.data);
} catch (error) {
console.error(error); // 오류 로깅 추가
res.status(500).json({ error: 'Failed to add data' });
}
});
app.listen(PORT, () => {
console.log(`Node.js server running on port ${PORT}`);
});
2. 루트 경로에서 public 폴더를 만들고 안에 index.html을 작성합니다
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Data Management</title>
<script>
async function fetchData() {
const response = await fetch("/api/get-data");
const data = await response.json();
document.getElementById("data").innerText = JSON.stringify(
data,
null,
2
);
}
async function addData() {
const name = document.getElementById("name").value;
const email = document.getElementById("email").value; // email 입력 받기
await fetch("/api/add-data", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name, email }), // name과 email을 함께 보냄
});
fetchData();
}
</script>
</head>
<body>
<h1>Manage Data</h1>
<input type="text" id="name" placeholder="Enter name" />
<input type="email" id="email" placeholder="Enter email" />
<!-- 이메일 입력 -->
<button onclick="addData()">Add Data</button>
<button onclick="fetchData()">Refresh</button>
<pre id="data"></pre>
</body>
</html>
3. Dockerfile 작성합니다.
# node/Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install
EXPOSE 3000
CMD ["node", "index.js"]
4. 도커 이미지를 빌드합니다.
// 자신의 노드 프로젝트명으로 대체하세요
docker build -t 프로젝트명 .
5. 컨테이너를 실행합니다.
docker run -d -p 3000:3000 --name 프로젝트명-container 프로젝트명
/*
-d: 백그라운드에서 컨테이너를 실행합니다.
-p 3000:3000: 호스트의 포트 3000을 컨테이너의 포트 3000에 매핑합니다.
--name 프로젝트명-container: 프로젝트명-container라는 이름으로 컨테이너를 지정합니다.
프로젝트명: 이전에 docker build -t 명령어에서 사용한 이미지 이름입니다.
*/
* myapp 예시 *
// 이미지 빌드
docker build -t my-app .
// 컨테이너 실행
docker run -d -p 3000:3000 --name my-app-container my-app
// 실행중인 컨테이너 확인
docker ps
// 애플리케이션 접속
http://localhost:3000
// 컨테이너 중지
docker stop my-node-container
// 컨테이너 삭제
docker rm my-node-container
:: 실행결과 ::
JSON 문자열에서 "error"가 난 이유는
이 노드 마이크로서비스는 스프링부트 8080포트에 통신하지만,
현재 스프링부트 컨테이너가 실행되지 않았기 때문입니다.
스프링부트 컨테이너와 노드 컨테이너를 docker-compose로 묶으면 같은 환경에서 동시에 실행할 수 있습니다.
도커 컴포즈로 실행하면, 스프링부트의 H2DB에 노드 컨테이너가 데이터를 조작할 수 있게 됩니다.
RestController로 가는 URI가 제대로 매핑되있다면, 두 컨테이너를 동시에 실행하여 노드의 3000번 포트에서 스프링부트 8080번 포트로 통신할 수 있습니다.
[ # 참고 : Docker로 스프링부트 jar를 컨테이너화 해보자 ]
이 스프링부트 컨테이너와 노드 컨테이너를 docker-compose로 묶어 같은 환경에서 실행할 수 있습니다.
https://rexondex.tistory.com/36
:: 정리 ::
위의 코드는 Node.js 미들웨어 마이크로서비스로서, 다음 목적을 갖습니다.
Spring Boot API 활용: axios를 사용해 Spring Boot 컨테이너의 REST API (http://userservice:8080/users)와 상호작용합니다. 이 Node.js 서비스는 Spring Boot 서비스의 API를 호출하여 데이터를 가져오거나 추가할 수 있습니다.
Static 파일 제공: public 폴더를 정적 파일 경로로 설정하여, HTML, CSS, JavaScript 파일 등을 제공합니다. 이렇게 하면 Node.js 서버가 사용자 인터페이스를 제공할 수 있습니다.
API 엔드포인트 제공: /api/get-data 및 /api/add-data 엔드포인트를 통해 프런트엔드 요청을 처리하고, 필요한 경우 Spring Boot 서비스와의 데이터 전송을 중개합니다.
즉, 이 Node.js 서버는 Spring Boot API와 프론트엔드 간의 미들웨어 역할을 하는 마이크로서비스로 작동하며, 사용자가 Spring Boot API와 간접적으로 상호작용할 수 있도록 돕습니다.
'Docker' 카테고리의 다른 글
Docker로 스프링부트 JAR을 컨테이너화 해보자 [Gradle] (4) | 2024.12.27 |
---|---|
Docker Compose로 여러 컨테이너를 동시에 실행해보자 [Docker] (0) | 2024.12.27 |