처음부터 Node.js/Express 앱 Dockerizing [2부]



  • 이전에는 Docker에서 완전히 벗어난 Node-Express 애플리케이션을 만들었습니다. 머신에 Node.js를 설치할 필요가 전혀 없었습니다. 우리는 기본적으로 새로운 Node.js 프로젝트를 스캐폴딩하고 개발 워크플로를 설정하기 위해 Docker를 사용했습니다. 이 기사에서는 머신에 데이터베이스 서버를 설치하지 않고 현재 앱에 데이터베이스 솔루션을 추가하는 방법을 살펴보겠습니다.

    docker-compose 파일을 편집하여 시작하겠습니다.

    services:
      app:
        depends_on:
          - database
        image: node:lts-alpine
        working_dir: /usr/src/app
        volumes:
          - ./code:/usr/src/app:rw
        ports:
          - 8080:12345
        command:
          - npx
          - nodemon
          - -L
          - app.js
      database:
        image: postgres:alpine
        volumes:
          - postgres:/var/lib/postgresql/data:delegated
        environment:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: dockerized_node_express_app
        restart: always
      npm:
        image: node:lts-alpine
        working_dir: /tmp/app
        volumes:
          - ./code:/tmp/app:rw
        entrypoint:
          - npm
    volumes:
      postgres: ~
    


    방금 PostgreSQL 데이터베이스 서버를 추가하기 위해 official documentation을 따랐습니다. 우리의 앱이 곧 이에 의존하게 될 것이기 때문에 이것은 애플리케이션 컨테이너 역할을 할 것입니다. 그리고 애플리케이션 컨테이너를 시작할 때마다 데이터베이스 컨테이너가 항상 시작되도록 하기 위해 depends_on 서비스에 새 app 키를 추가하고 어떤 다른 서비스가 있는지 알려줍니다. 에 따라 달라집니다. 이렇게 하면 데이터베이스 서버가 앱보다 먼저 실행되고 있는지 확인할 수 있습니다. 또한 데이터베이스 서버의 데이터 경로에 약간 다르게 볼륨을 마운트한 것을 눈치채셨을 것입니다. 이를 "명명된 볼륨"이라고 합니다. 다른 부분에서 좀 더 논의할 것입니다. 여기서 배우는 것과는 관련이 없습니다.

    이제 docker compose up -d app 명령을 사용하여 응용 프로그램을 시작하려고 하면 응용 프로그램이 데이터베이스 자체와 함께 시작되는 것을 볼 수 있습니다. 애플리케이션에서 데이터베이스에 연결할 수 있도록 애플리케이션 코드를 변경해 보겠습니다.

    const express = require('express');
    const { Sequelize } = require('sequelize');
    
    const {
      DB_HOST,
      DB_PORT,
      DB_USER,
      DB_PASS,
      DB_NAME
    } = process.env;
    
    const app = express();
    const sequelize = new Sequelize({
      dialect: 'postgres',
      host: DB_HOST,
      port: DB_PORT,
      username: DB_USER,
      password: DB_PASS,
      database: DB_NAME,
      logging: false,
    });
    
    app.get('/', (req, res) => {
      res.json({ status: 200, message: 'Hello, world!' });
    });
    
    sequelize
      .authenticate()
      .then(() => console.log('Established connection with the database...'))
      .then(() => app.listen(12345))
      .then(() => console.log('Started the application server...'))
      .catch((error) => console.error(error.message));
    


    NEVER USE DATABASE CREDENTIALS DIRECTLY IN THE CODE.



    몇 가지 환경 변수가 있습니다. 우리는 Docker Compose를 사용하여 애플리케이션을 실행하고 있습니다. Docker에 이를 설정하고 정의하도록 지시하려면 어떻게 해야 합니까? environment 키를 사용합니다.

    services:
      app:
        depends_on:
          - database
        image: node:lts-alpine
        working_dir: /usr/src/app
        volumes:
          - ./code:/usr/src/app:rw
        environment:
          DB_HOST: database
          DB_PORT: 5432
          DB_USER: postgres
          DB_PASS: postgres
          DB_NAME: dockerized_node_express_app
        ports:
          - 8080:12345
        command:
          - npx
          - nodemon
          - -L
          - app.js
      database:
        image: postgres:alpine
        volumes:
          - postgres:/var/lib/postgresql/data:delegated
        environment:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: dockerized_node_express_app
        restart: always
      npm:
        image: node:lts-alpine
        working_dir: /tmp/app
        volumes:
          - ./code:/tmp/app:rw
        entrypoint:
          - npm
    volumes:
      postgres: ~
    

    DB_HOST 변수를 살펴보십시오. 일반적으로 localhost 를 사용하지만 왜 database 를 사용합니까? 애플리케이션과 데이터베이스 서버가 모두 단일 시스템에서 실행되는 경우 localhost를 사용합니다. 우리는 Docker를 사용하고 있으며 여기에 있는 모든 컨테이너는 각각 동일한 시스템에서 실행되지만 서로 완전히 격리되어 있습니다. 모든 것이 자체 "기계"내에서 작동하는 것과 같습니다. 그 때문에 애플리케이션 컨테이너는 데이터베이스 서버와 통신하는 방법을 모르기 때문에 해당 컨테이너의 IP 주소를 알아야 합니다. 운 좋게도 컨테이너의 서비스 이름을 사용하면 Docker가 내부적으로 이를 IP 주소로 확인합니다. 이것이 우리가 여러 컨테이너 간에 통신을 설정하는 방법입니다.

    거의 끝났습니다. 이제 앱에 몇 가지 종속 항목이 더 필요합니다. 종속 항목을 설치하고 마지막으로 앱을 불러오겠습니다. 우리는 예전npm 유틸리티 컨테이너를 다시 한 번 사용할 것입니다.

    docker compose run --rm npm i sequelize pg
    



    docker compose up app
    


    In case of you just started from this part and missed the previous one, run the following commands one after another: docker compose run --rm npm init -y, docker compose run --rm npm i express, docker compose run --rm npm i -D nodemon.



    잠시 후(연결 프로세스가 비동기식이며 완료하는 데 약간의 시간이 걸리므로) 터미널 콘솔에 성공 메시지가 표시됩니다. 예이! 그런 멋진 도구 Docker가 있습니다! 도커 만세!

    이제 앱에 데이터베이스를 추가하고 인기 있는 ORM "Sequelize"를 사용했으므로 집처럼 느껴질 것입니다. 자유롭게 해당 ORM(모델, 마이그레이션, 시더 등)을 활용하고 이 앱을 세상에 더 유용하게 만드십시오.

    다음 시간에는 파일 업로드에 대해 다루겠습니다. 개발 워크플로의 일부로 Docker를 사용할 때 사용자 생성 파일이 약간 다르게 처리되고 관리되는 것처럼 보이기 때문입니다. 거기서 보자!

    좋은 웹페이지 즐겨찾기