네트워킹
Docker 네트워크 구성을 설명합니다.
2계층 네트워크 구조
Multi-SaaS Kit은 2계층 네트워크 구조를 사용합니다.
┌─────────────────── ──────────────────────────────────────────┐
│ 프로젝트 A │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ {PLATFORM_NAME}-projectA-network │ │
│ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │
│ │ │ nginx │ │ web │ │postgres│ │ redis │ │ │
│ │ └────────┘ └────────┘ └───┬────┘ └────────┘ │ │
│ └───────────────────────────────┼─────────────────────────┘ │
│ │ │
├─────────────────────────────────┼───────────────────────────┤
│ 공유 네트워크 ↓ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ {PLATFORM_NAME}-shared-network │ │
│ │ ┌────────────────┐ │ │
│ │ │ pgAdmin │ ← 모든 프로젝트 DB 접근 가능 │ │
│ │ └────────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
네트워크 유형
프로젝트 네트워크 (default)
각 프로젝트의 내부 통신을 위한 격리된 네트워크입니다.
# docker-compose.yml
networks:
default:
name: ${PLATFORM_NAME}-${PROJECT_NAME}-network
driver: bridge
특징:
- 프로젝트 간 완전 격리
- 컨테이너 이름으로 서로 접근
- 외부에서 직접 접근 불가 (포트 매핑 필요)
공유 네트워크 (shared)
플랫폼 서비스(pgAdmin 등)가 모든 프로젝트에 접근하기 위한 네트워크입니다.
# docker-compose.yml
networks:
shared:
name: ${PLATFORM_NAME}-shared-network
external: true
특징:
- 미리 생성되어 있어야 함 (
external: true) - postgres만 연결 (보안상 최소 연결)
- pgAdmin에서 모든 프로젝트 DB 관리
서비스 간 통신
내부 통신 (컨테이너 이름)
Docker 내부에서는 컨테이너 이 름(서비스 이름)으로 통신합니다.
// Laravel .env (Docker 내부)
DB_HOST=postgres // postgres 컨테이너
REDIS_HOST=redis // redis 컨테이너
# nginx 설정
upstream php {
server web:9000; // web 컨테이너의 9000 포트
}
외부 접근 (포트 매핑)
외부에서 접근할 때는 매핑된 포트를 사용합니다.
# docker-compose.yml
services:
nginx:
ports:
- "${APP_PORT}:80" # 외부:내부
postgres:
ports:
- "${DB_PORT}:5432"
redis:
ports:
- "${REDIS_PORT}:6379"
접근 예시:
- 브라우저:
http://localhost:8080→ nginx:80 - DBeaver:
localhost:5432→ postgres:5432 - Redis CLI:
localhost:6379→ redis:6379
네트워크 격리
프로젝트 간 격리
프로젝트 A와 B는 서로 통신할 수 없습니다.
프로젝트 A (MSK-projectA-network)
├── projectA-nginx
├── projectA-web
├── projectA-postgres
└── projectA-redis
프로젝트 B (MSK-projectB-network) ← 완전히 분리
├── projectB-nginx
├── projectB-web
├── projectB-postgres
└── projectB-redis
보안 이점
- 데이터 격리: 각 프로젝트의 DB는 자체 네트워크에서만 접근
- 침해 방지: 한 프로젝트가 해킹되어도 다른 프로젝트에 영향 없음
- 테넌트 분리: RLS와 함께 다층 보안 제공
DNS 해석
Docker는 내장 DNS 서버를 통해 컨테이너 이름을 IP로 변환합니다.
web 컨테이너에서:
ping postgres
→ Docker DNS (127.0.0.11)
→ postgres 컨테이너 IP 반환
→ 172.18.0.3 (예 시)
서비스 디스커버리
# web 컨테이너에서 다른 서비스 확인
make shell NAME=myproject
> ping postgres
PING postgres (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.071 ms
> ping redis
PING redis (172.18.0.4): 56 data bytes
64 bytes from 172.18.0.4: seq=0 ttl=64 time=0.089 ms
공유 네트워크 설정
네트워크 생성
# Makefile이 자동으로 생성
make setup
# 또는 수동 생성
docker network create MSK-shared-network
postgres를 공유 네트워크에 연결
# docker-compose.yml
services:
postgres:
networks:
- default # 프로젝트 내부
- shared # 공유 (pgAdmin용)
networks:
shared:
name: ${PLATFORM_NAME}-shared-network
external: true
문제 해결
네트워크 확인
# 네트워크 목록
docker network ls
# 특정 네트워크 상세
docker network inspect MSK-myproject-network
# 컨테이너 연결 확인
docker network inspect MSK-shared-network | grep -A5 "Containers"
연결 테스트
# 컨테이너 간 통신 테스트
make shell NAME=myproject
> ping postgres
> ping redis
> nc -zv postgres 5432
일반적인 문제
| 문제 | 원인 | 해결 |
|---|---|---|
| 서비스 이름으로 접근 안 됨 | 다른 네트워크 | 같은 네트워크 확인 |
| 공유 네트워크 연결 실패 | 네트워크 미 생성 | make setup 실행 |
| 포트 충돌 | 동일 포트 사용 | .env에서 포트 변경 |