티스토리 뷰

하나의 App을 구성하기 위해 Container를 여러 개 실행해야 할 경우 Docker Compose가 유용하다.

하나의 file로 관련된 Container 설정을 해놓으면 해당 file을 통해 관련 Container를 모두 실행할 수 있기 때문.

간단한 node server(express)와 mysql Container를 Docker Compose로 구성해보겠다. 

 

Directory 구성

node 구성

설치 패키지

npm i expree
npm i mysql2

파일

server.js, db/index.js 두 개의 파일로 구성한다.

db/index.js

✔️ 여기서는 host에 network alias를 사용했다. 이후에 network alias를 mysql로 진행하는 것을 보겠다.

// db/index.js
const mysql = require("mysql2/promise")
    
const pool = mysql.createPool({
    host: "mysql",		// ip or network alias를 입력, 여기서는 network alias 사용
    port: "3306",
    user: "root",
    password: "root",
    database: "mysql",
    waitForConnections: true,
    connectionLimit: 10,
    queueLimit: 0,
})

exports.pool = pool
exports.select = () => pool.query("select '안녕' from dual");

server.js

const express = require('express')
const app = express()

const db = require("./db/index")
app.get("/", async (req, res) => {
    const [rows] = await db.select()
    res.send(rows)
})

const server = app.listen("3000", () => {
    console.log("Express server has started on port 3000")
})

 

Dcoker 구성

Dockerfile로 나만의 node image를 만든다. 

 

Dockerfile

FROM node:19-alpine
RUN mkdir /app 
WORKDIR /app
CMD ["node", "/app/server.js"]

확장자가 없는것이 맞다. 헷갈리지 말기를.

 

Dockerfile을 통한 image 생성

docker build -t mynode .

 

docker compose

docker-compose.yml

services:
  app:
    image: mynode
    volumes:
      - .:/app # 현재 경로에 bind mount
    ports: 
      - 3000:3000
  mysql:
    image: mysql:8.0
    volumes: 
      - v-mysql:/var/lib/mysql # v-mysql volume에 해당 경로 mount, db 내용을 저장하기 위함
    environment:
      - MYSQL_ROOT_PASSWORD=root # 환경변수 지정, root password 지정
volumes:
  v-mysql:

 

✔️ volume을 사용하기 위해서는 root level에 volumes 내에 선언해주어야 한다. 

✔️ services 하위에 선언된 service 이름은 network alias로 이용됨. (node에서 host를 mysql로 해서 접근 가능하다!)

 

실행

docker compose up -d

 

정상적으로 두 개의 Container가 실행된 것을 확인할 수 있다.

 

의문점

  • network를 명시하지 않아도 같은 network로 인식하는 것 같은데 맞는 건가? networks key가 별도로 있는데, 명시 안 하면 자동으로 하나의 network로 잡히는 것 같다. (docker 문서에서는 그런 내용을 언급하는 것을 확인하진 못했다...)
  • network-alias : network-alias 부분이 service 이름으로 자동으로 잡히는 것인가? 이것도 역시 aliases key가 별도로 있는 것을 확인했는데, 명시 안 하면 service 이름으로 network-alias가 지정되는 듯. 왜냐하면 node에서 mysql host 지정 시 'mysql'로 명시해도 연결이 되었으니 맞긴 한 것 같다.

 

관련 링크

https://docs.docker.com/get-started/08_using_compose/

https://docs.docker.com/compose/compose-file/#networks-top-level-element

댓글