https://github.com/ShimHyesu/KakaoTech_Bootcamp/tree/main/0728_Docker_DB
목표
Docker로 MariaDB 연결하여 테이블 생성하고 내용 삽입한다.
테이블 데이터를 Docker로 띄운 웹에서 확인한다.
파일 구조
- app
- app.js → 앱 진입
- connection.js → 데이터베이스와의 연결을 설정
- userRouter.js → 사용자 정의 라우터 모듈
- Dockerfile
- db
- Dockerfile
- initdb.sql → 데이터베이스 초기화
- docker-compose.yaml
- .env
Docker Compose
version: '3.9'
services:
app:
build:
context: ./app
dockerfile: Dockerfile
restart: on-failure
ports:
- "4000:4000"
depends_on:
- db
volumes:
- ./app:/app
env_file: # 환경변수 파일 설정
- .env
networks:
- app-network
db:
build:
context: ./db
dockerfile: Dockerfile
restart: on-failure
environment: # 환경변수 설정 - .env 파일에 정의
MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MARIADB_DATABASE: ${DB_DATABASE}
ports:
- "3307:3306"
volumes: # db-data 볼륨에 저장되어 컨테이너가 재시작되거나 삭제되더라도 데이터가 유지
- db-data:/var/lib/mysql
networks:
- app-network
volumes:
db-data:
networks:
app-network:
- 환경변수
- docker compose 파일과 동일한 위치면 env_file로 지정하지 않아도 바로 반영 docker compose convert → 이 명령어로 환경변수 주입된 값 확인 가능
- docker compose --env-file <파일 위치> → 이렇게 여러개의 파일로 구성 가능 개발 환경(production, develop)에 따라 다르게 환경 변수 값을 조정 가능
- env_file 항목을 함께 포함하면 서비스마다 다른 환경변수 파일을 적용
- https://seongjin.me/environment-variables-in-docker-compose/
DB
# Dockerfile
FROM mariadb:latest
# /docker-entrypoint-initdb.d/ : 컨테이너가 처음 시작될 때 실행되는 SQL 파일을 저장하는 디렉토리
# 데이터베이스 초기화 작업 진행
COPY initdb.sql /docker-entrypoint-initdb.d
-- initdb.sql
-- 데이터베이스 생성 및 테이블 생성
CREATE DATABASE IF NOT EXISTS mydatabase;
use mydatabase;
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email varchar(100) NOT NULL
);
insert into users (name, email) values ('hyesu', 'hesushim@gmail.com');
-- 사용자 생성 및 권한 부여
CREATE USER '<user>'@'%' IDENTIFIED BY '<user-password>';
GRANT ALL PRIVILEGES ON mydatabase.* TO '<user>'@'%';
FLUSH PRIVILEGES;
- sql 권한
- ALTER USER ‘<user>’@'~' IDENTIFIED BY ‘<user-password>’;
- ‘<user>’@’localhost’ : 내부 접근
- ‘<user>’@’%’ : 외부 접근
- ‘<user>’@’<특정 ip>’
- ‘<user>’@’192.168.%’ : 특정 대역 허용
- https://jay-so.tistory.com/67
App
//
// app.js
// 서버를 설정하고, 기본 라우트와 사용자 라우트를 설정하고, 서버를 시작
//
const express = require('express');
const userRouter = require('./userRouter');
const app = express();
const PORT = 4000;
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.use('/users', userRouter); // 사용자 라우트를 설정
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
//
// 데이터베이스와의 연결을 설정하는 파일
//
const mariadb = require('mariadb');
require('dotenv').config({path: '../.env'});
const db = process.env.DB_DATABASE
const dbUser = process.env.DB_USER
const dbPassword = process.env.DB_PASSWORD
// 연결 풀을 생성
// 여러 개의 연결을 미리 열어 두고 요청이 있을 때마다 재사용
const pool = mariadb.createPool({
host: 'db', // Docker Compose 설정에서 'db' 서비스
user: dbUser,
password: dbPassword,
database: db,
connectionLimit: 10, // 최대 연결 수
})
async function fetchConn(){
let conn = await pool.getConnection();
return conn;
}
module.exports = fetchConn;
- .env 파일 상위에 있을때
- Docker-compose.yaml에 env_file 지정
- config에 path 지정
- pool
- https://mariadb.com/docs/server/connect/programming-languages/nodejs/promise/connection-pools/
- mariadb.createConnection 으로는 지속적으로 열린 상태 유지하지 않음 → 열린 상태 재사용하는 mysql.createPool 사용
- mariadb 라이브러리의 createPool 메서드
- 연결 풀은 미리 여러 개의 연결을 생성하여 풀(pool)에 보관하고, 필요할 때마다 이를 가져와 사용하고, 사용이 끝나면 다시 풀에 반환
//
// userRouter.js
// 데이터베이스와 상호작용하여 사용자 데이터를 조회하는 기능을 제공
//
const express = require('express');
const fetchConn = require('./connection');
const userRouter = express.Router();
userRouter.get('/', (req, res) => {
res.send('User Router');
})
userRouter.get('/getUsers', async (req, res) => {
let conn;
try {
conn = await fetchConn();
const [results] = await conn.query('SELECT * FROM users');
res.json(results);
} catch (err) {
console.error('Error fetching users:', err);
res.status(500).send('Error fetching users');
}finally {
if(conn) conn.end();
}
});
module.exports = userRouter;
- localhost:4000/users/ → ‘User Router’ 확인 가능
- localhost:4000/users/getUsers → users 테이블의 데이터 확인 가능
- promise 기반의 반환된 pull → async/await
- 연결한 풀에 쿼리 날려서 데이터 가져옴 → json으로 바꿔 웹에 출력
'DevOps' 카테고리의 다른 글
[Kafka] Docker로 Kafka 구축 (0) | 2024.08.19 |
---|---|
[Kafka] Kafka란? (0) | 2024.08.19 |