단순히 방법론에 대한 이야기이므로, 틀린 내용이 있다면 댓글로 지적해주시면 너무 감사하겠습니다.
웹 서버 서비스를 물리적 장치에 할당하는 과정에서(호스팅) 많은 주니어 개발자들이 하나의 컴퓨터(인스턴스)을 호스팅하여, 모든 도구들을 몰아서 사용합니다.
주니어 백엔드 개발자를 예시로 들자면, PostgreSQL DB 서버와, Web Server를 하나의 인스턴스에 다 넣어두고 개발을 하는 경우가 있겠네요.
하지만 실제로는 DB서버와 WebServer는 물리적으로 같은 컴퓨터(인스턴스)에 존재하지 않는 경우가 대부분입니다. 특히, 구조에서 DB와 WebServer가 어떠한 종속성을 띄어야 하는지 설명을 하고자 합니다.
Docker, node.js(express 서버) PostgreSQL, prisma를 통해 그 예시로 하여서 설명하겠습니다.
특히, Prisma에 초점을 두고 설명을 하겠습니다.
같은 환경을 쓰지 않더라도, 다중 서버 환경에서 ORM, DB server, Web server를 구현하고자 하는 분들에게 도움이 되길 바랍니다.
처음 데이터베이스 설계를 수행하는 과정에서, RDB를 직접 설계하고 쿼리문을 작성하는 방법이 가장 원시적입니다.
몇 개발자들은 Prisma와 같은 ORM 도구(사실, Prisma는 ORM이 아닙니다 ㅎ 근데 작성 편의상 ORM이라 하겠습니다)를 활용하여 스키마를 작성하고, 이를 Migration(혹은 Push)하여 초기 데이터베이스를 생성 및 동기화하는 경우가 있습니다.
단일 서버에서, 백엔드 개발자가 DB와 웹 서버를 모두 관리한다면 문제 없어보일 수 있습니다.
하지만, DB 서버와 웹서버를 나누고, 그 수가 많아진다면 문제가 생깁니다.
다음은 서버를 나눈 모습입니다. 웹 서버의 Prisma가 DB의 변환을 수행할 수 있으므로, DB 주도권을 WebServer가 가지고 있는 것으로 보입니다.
그럼 문제가 무엇일까요?
더 나아가기에 앞서, Docker환경에서 서버를 배포하기 위해서는, DB 서버를 WebServer보다 먼저 올려야 한다는 사실을 아시길 바랍니다. 자세한 내용은 구글링
대부분의 경우에, DB서버를 동적으로 확장하는 경우보다는 웹 서버를 동적으로 확장하는 경우가 많습니다. (더 많은 트래픽을 감당하기 위해서라던지) 그러한 경우에는 다음과 같은 양상을 띄게 됩니다.
DB의 구조에 대한 제어권을 모든 각각의 서버가 가지게 되는 것이지요. 이러면 여러가지로 문제가 될 수 있습니다.
ex1 : 바뀐 prisma 스키마(구조)를 가진 웹 서버가 생성되면서 DB에 강제로 동기화 시켜버리는 경우
ex2: 새 서버에서 마이그레이션 생성을 시도하는 과정에서 기존의 DB 데이터 정보를 강제로 밀어버리는 경우 (diff 명령어를 사용하려 해도, 이미 db가 존재해서 빈 sql이 생성됨)
무결성이 위기가 되겠네요.
이러한 경우, 제어권을 DB만 가지고 있는 것이 무결성을 유지하는데 더 도움이 됩니다.
DB 서버를 Docker로 감아서 올린 경우, 다음의 Dockerfile 예시를 보여드리겠습니다.
FROM postgis/postgis:latest # 그냥 postgreSQL입니다.
ENV POSTGRES_USER=postgres
ENV POSTGRES_PASSWORD=postgres
ENV POSTGRES_DB=ecosave
ENV POSTGRES_PORT=5433
EXPOSE 5433
VOLUME ["/var/lib/postgresql/data"]
COPY migration.sql /docker-entrypoint-initdb.d/migration.sql
# 실행 명령
CMD ["postgres", "-p", "5433"]
COPY migration.sql /docker-entrypoint-initdb.d/migration.sql
DB 서버 단에서 데이터베이스의 생성 SQL(migration.sql)를 가져와서 초기 DB를 생성하는 모습을 볼 수 있습니다.
즉, DB 구조에 대한 결정권은 DB 서버만 가지게 됩니다.
이후, 동적으로 생성하는 웹 서버에서는 push나 migration을 수행하지 않고, prisma client 생성 후, db로부터 prisma.schema를 pull만을 해서 사용을 하면 됩니다.
앞으로 DB의 구조를 변경할 수 있는 작업(명령어 포함)은, WebServer에서 하지 않고, DB 서버에서 수행하는 것을 지향합시다.(서버가 나뉘는 경우)
서버가 나뉘었을 때, 특히 주도권 문제가 중요할 때, 잘 생각해서 개발하도록 합시다.
잘보고감미다 ^^