← 목록 Creatiview Suite · 개발 환경 분리 구축
01 / 13
ISOLATION BOUNDARY
◀ 운영 · PROD 개발 · DEV ▶
계획 · 미실행 · 승인 전 검토용

Creatiview Suite
개발 환경
분리 구축

동일 서버 안에 별도 경로 · 별도 DB 스키마로 격리된 개발 환경을 만든다.
운영 데이터 · 트래픽 · 메일 · 스케줄러에 무영향(회귀 0)을 최우선으로.

● Creatiview Suite Laravel 12 · PHP 8 MySQL 8.0.45 2026-09-28
SCROLL↓
02한눈에 보기 · OVERVIEW

무엇을, 왜 만드나

현재 Creatiview Suite는 운영본 하나만 존재한다. 안전하게 실험·검증할 별도 공간이 없다.

GOAL

격리된 dev 환경

운영과 같은 서버 안에 코드·데이터·부작용이 완전히 분리된 개발 공간을 확보한다.

CONSTRAINT

회귀 0

이 머신이 곧 라이브 운영 웹서버다. 운영 데이터·트래픽에 어떤 영향도 주지 않는다.

METHOD

같은 서버 · 다른 계층

형제 경로에 코드를 복제하고, 로컬 MySQL에 별도 스키마를 둔다. 신규 서버 비용 0.

이 계획의 핵심 원칙

격리는 경로 분리가 아니라 데이터 계층 분리 + 부작용 차단(메일·스케줄러)이 핵심이다. 경로 분리는 기본 전제다.

CREATIVIEW SUITE · DEV ENV PLAN
03현재 상태 · 실측 근거

실측으로 확인한 현황

셋업 방향은 추정이 아니라 서버 실측값을 근거로 정했다. 운영은 앱서버·DB서버가 물리 분리돼 있다.

운영 앱서버 · APP  1.201.174.47 운영 DB서버 · DB  1.201.175.67  내부 192.168.10.20:3306
8.0.45
운영 DB — MySQL
(MariaDB 아님)
62.3MB
DB 전체 · 40 테이블
전량 rpt_* 집계
31GB
앱서버 RAM (여유 20GB)
8코어 · 240GB 디스크
3306
로컬 MariaDB 방치본
제거하면 비는 포트
제약 조건

기본 콜레이션 utf8mb4_0900_ai_ci

MySQL 8 전용 콜레이션이라 MariaDB로는 덤프 import가 실패한다. → dev 엔진도 MySQL 8이어야 함.

위험 신호

session · cache · queue = database

메일은 실제 Gmail SMTP로 발송된다. DB나 설정을 공유하면 그대로 운영 사고로 이어진다.

측정: hostname · free · df · information_schema · .env
04핵심 위험 · WHY IT MATTERS

"경로만 분리"가 위험한 이유

경로만 복사하고 .env를 그대로 두면 dev가 운영 DB에 직접 쓴다. 격리가 깨진다.

운영 · 그대로 두면
  • DB_DATABASE 공유
  • jobs 테이블 공유
  • sessions 공유
  • MAIL_MAILER=smtp
BREACH
개발이 일으키는 사고
  • 운영 스키마·데이터 오염
  • 운영 job을 가로채 실행
  • 운영 사용자 로그아웃
  • 실사용자에게 실제 메일 발송
공용 스키마dev migrate/seed가 운영 데이터를 오염치명
QUEUE = databasedev 워커가 운영 job을 가로채 실행치명
SESSION · MAIL운영 세션 오염 · 실사용자에게 메일 발송높음

판단 기준은 dev 장애가 dev에만 머무는지가 아니라 dev가 운영을 해칠 수 있는지이다. 따라서 격리는 경로가 아니라 데이터 계층에서 이뤄진다.

공유 자원 = 사고 경로
05결정 1 · 데이터베이스

별도 스키마에 운영 전체 덤프

두 후보의 격리 안전성은 동일하다(둘 다 별도 스키마). 차이는 초기 데이터 유무뿐.

옵션 1 · 빈 스키마옵션 2 · 전체 덤프 ✅
운영 격리동일동일
데이터없음운영과 동일 형태
로직 검증불가가능
부담최소62MB — 사실상 0
왜 전체 덤프인가

검증하려면 실제 데이터가 필요하다

이 솔루션의 가치는 ReportStore 정합 불변식 · 비용보정 money-math · AI 그라운딩처럼 실제 형태의 집계 데이터가 있어야만 검증되는 로직이다. 빈 스키마면 앱은 뜨지만 검증 대상이 없다.

전량 rpt_* 집계 팩트라 PII 리스크도 낮다.

단, 적재 직후 필수 스크럽

운영성 테이블(sessions·cache·jobs·tokens) truncate + 계정 메일 마스킹. dev 워커가 운영 잔재 job을 실행하는 사고를 원천 차단한다.

결정 1 · 데이터 — 옵션 2 채택
06결정 1-c · DB 배치와 엔진

운영 DB서버가 아닌 별도 로컬 MySQL 8.0

① 배치 — 운영 DB서버 1.201.175.67에 두지 않는다

"별도 스키마"는 이름공간만 나눈다. 같은 인스턴스(운영 DB서버 1.201.175.67)면 장애·자원 도메인은 공유된다.

InnoDB 버퍼풀운영 hot page 축출
max_connections운영이 굶음
CPU · IO · 디스크폭주 시 운영 DB 중단
② 엔진 — MariaDB 아닌 MySQL 8.0

앱서버 로컬 MariaDB(11.4.4)는 2025-02 테스트 방치본(빈 test·커넥션 0). 제거하고 그 자리에 MySQL 8.0을 설치.

결정적 근거: 운영 콜레이션 utf8mb4_0900_ai_ci는 MySQL 8 전용 → MariaDB는 import 실패. 정렬·money-math 경계 동작도 어긋난다.

남는 트레이드오프

로컬에 두면 운영 앱서버(1.201.174.47)와 같은 머신을 공유하므로 웹 티어 경합이 남는다. 완화: dev innodb_buffer_pool_size 512MB 캐핑 + systemd MemoryMax·CPUQuota 상한. 신규 서버 비용은 0.

결정 1-c · dev DB = 로컬 네이티브 MySQL 8.0.45
07결정 1-b · 리프레시 전략

수동 · 전체 교체 (증분 아님)

증분을 배제한 이유: 룩백 수집으로 지난 날짜의 rpt_fact_* 행이 나중에 값이 바뀐다(restatement). 날짜 이후만 추가하는 방식은 이 정정을 놓쳐 dev를 운영과 어긋나게 만든다. 62MB 전량 집계라 전체 교체가 증분보다 싸고 정확하다.

① 현재

전체 교체

매번 운영 전체 dump → dev 교체. 가장 단순·정확.
② 운영 부하 시

백업/리플리카

live 아닌 백업본에서 추출. 운영 무부하.
③ 디스크 부담 시

범위 슬라이스

최근 N개월 통째 재적재. 창 내 정정 정확.
④ 수십 GB+

스토리지 스냅샷

LVM/ZFS CoW · clone plugin. 용량 무관.
⑤ 상시

큐레이션 픽스처

익명화 대표 시드셋. 운영 의존 제거.
설계 반영

refresh-dev-db.sh는 처음부터 범위 파라미터 구조(FULL / --since=YYYY-MM)로 만든다. ①→③ 전환 시 스크립트 재작성 없이 인자만 바꾼다.

결정 1-b · 수동 전체 교체 + 확장 로드맵
08결정 2 · 3 · 접속과 스케줄러

부작용을 원천 차단한다

결정 2 · 사용자 확정

별도 URL(vhost)로 노출

포트 방식(artisan serve)은 SSO·쿠키 도메인 테스트에 제약이 있다. 따라서 운영과 동일한 HTTPS·쿠키 흐름을 재현하는 별도 서브도메인 vhost로 노출한다.

결정 3

스케줄러 · collectors 미등록

dev는 crontab을 등록하지 않는다. 룩백 수집이 운영 데이터·외부 API·메일을 건드리지 않게 하기 위함. 필요하면 개별 커맨드만 수동 실행.

MAIL

= log

실제 발송 없이 로그로만.

REDIS

DB 1 또는 prefix

키 충돌 방지.

APP

local · debug

dev 전용 새 APP_KEY.

결정 2 · 3 — 접속 vhost / 스케줄러 미등록
09목표 아키텍처 · TOPOLOGY

최종 서버 구성

운영은 앱서버와 DB서버가 물리 분리돼 있다. dev는 앱서버(.47) 로컬에 두고, 그 서버의 기존 MariaDB(방치본)를 제거한 뒤 MySQL 8.0을 새로 설치해 dev DB로 쓴다. 운영 DB서버(.67)는 건드리지 않는다.

운영 앱서버 · APP1.201.174.47
운영 앱 /…/creatiview-suite https://creatiview.innored.co.kr
개발 — 앱 + DB co-location /…/creatiview-suite-dev · https://<dev-url> ① 기존 MariaDB(11.4.4 방치본) 제거 → ② MySQL 8.0.45 신규 설치 creatiview_suite_dev @127.0.0.1:3306 · 로컬 MySQL 8.0.45 APP_ENV=local · MAIL=log · 무스케줄 · 버퍼풀 512MB
운영 DB서버 · DB1.201.175.67
운영 DB (전용) creatiview_suite @192.168.10.20:3306 · MySQL 8.0.45
dev DB는 이 서버에 두지 않음 — 운영 DB 성능·자원 보호
덤프 흐름  DB서버 1.201.175.67 에서 읽기 1회 ──▶ 앱서버 1.201.174.47 로컬 dev로 적재
코드

별도 경로

DB 엔진

MariaDB 제거 → MySQL 8.0

세션·캐시·큐

별도 스키마 자동 격리

부작용

메일 log · 무스케줄

10실행 계획 · TASKS

6단계 · 단계마다 검증

스크립트로 구성해 단계별로 확인하며 진행한다. 스크럽(Task 3) 완료 전에는 dev에서 워커·메일을 실행하지 않는다.

1

코드 트리 복제

형제 경로로 clone, composer install, 권한 정리.

✓ php -l 통과
2

MySQL + 적재

MariaDB 제거 → MySQL 8.0.45 설치, 스키마 생성, 운영 덤프 import.

✓ 40 테이블 대조
3

스크럽

운영성 테이블 truncate, 메일 마스킹.

✓ count = 0
4

dev .env

local·dev DB·log 메일. 새 APP_KEY.

✓ tinker 확인
5

vhost 노출

docroot·TLS 발급, SSO 쿠키 정책.

✓ curl 200
6

차단 확인

스케줄러 미등록 확인, refresh 스크립트.

✓ dry-run
검증 도구

자동 테스트 프레임워크가 없으므로 php -l · php artisan about · tinker 덤프 · curl 200으로 각 단계를 확인한다.

실행은 승인 후 · 스크립트 단위 진행
11안전장치 · 롤백

되돌릴 수 있게 설계한다

운영 영향 0

읽기(mysqldump)뿐

운영 스키마·파일 무변경. dev DB는 운영 DB서버(.20)가 아닌 로컬이라, dev 폭주가 운영 DB에 도달하지 않는다.

가역적 제거

MariaDB 삭제 전 백업

--all-databases 1회 백업 후 제거. 필요 시 벤더 repo 재설치로 원복. PHP는 mysqlnd라 운영 .20 접속 무영향.

실행 순서 규칙

스크럽 전 워커 금지

Task 3 완료 전에는 dev에서 queue:work·스케줄러·메일 커맨드를 절대 실행하지 않는다.

설정 격리

운영 .env 복사 금지

반드시 .env.example 기반 신규 작성. 실 크리덴셜·SMTP·prod URL 이월을 막는다.

롤백

dev 구축 실패 시 롤백은 dev 트리 삭제 + 로컬 MySQL/스키마 제거로 완결된다. 운영 영향 0.

안전장치 · 롤백
12실행 전 확정 필요 · OPEN QUESTIONS

승인 전 확정할 항목

✓MySQL 설치 방식 — [해결] MariaDB 제거 → 네이티브 MySQL 8.0.45(3306) 확정.
2dev URL — 서브도메인 값 미정 (예: dev.creatiview.innored.co.kr).
3소유 계정 — dev 트리/인스턴스를 어느 계정으로 운영? (운영은 justin/dante)
4코멘트 PII — rpt_*_comment 원문을 유지할지 마스킹할지.
5운영 DB 읽기 권한 — 덤프용 creatiview_suite 읽기 계정 확보 여부.
6Redis 격리 — DB 인덱스(REDIS_DB=1) vs prefix 중 택.

이 문서는 승인 전 검토용이다. 위 항목을 확정하면 Task 1부터 스크립트 단위로 실행한다.

13용어 각주 · GLOSSARY

쉽게 풀어 쓴 용어

본문에 나온 기술 용어를 한 줄로 설명한다. 비개발자도 흐름을 따라갈 수 있게.

회귀 0기존 기능이 망가지는 일(회귀)을 전혀 만들지 않음
스키마DB 안에서 테이블을 담는 독립 공간(데이터베이스 하나)
콜레이션문자를 정렬·비교하는 규칙. MySQL 8 전용이라 MariaDB엔 없음
덤프 · mysqldumpDB 내용을 파일로 통째 복사(백업)
파리티 · 파리티 유지dev를 운영과 똑같이 맞춤(엔진·버전·규칙 동일)
co-location두 프로그램을 같은 서버에 함께 두는 것
InnoDB 버퍼풀MySQL이 자주 쓰는 데이터를 얹어두는 메모리 캐시
truncate테이블의 모든 행을 비움(구조는 유지, 데이터만 삭제)
마스킹실제 값(이메일 등)을 가짜 값으로 가림
vhost한 서버에서 여러 도메인을 구분해 서비스하는 웹 설정
스케줄러 · crontab정해진 시각에 작업을 자동 실행하는 예약 기능
큐 · 워커 · job대기열(큐)에 쌓인 작업(job)을 프로세스(워커)가 꺼내 실행
룩백 · restatement지난 날짜를 다시 수집해 과거 수치가 나중에 정정되는 것
증분전체가 아니라 바뀐 부분만 추가로 반영하는 방식
money-math · 그라운딩비용·마크업 금액 계산 / AI 답을 실제 데이터에 근거시키기
PII · SSO개인식별정보(이름·이메일 등) / 한 번 로그인으로 여러 서비스 이용
부록 · 용어 각주