diff --git a/app/Http/Controllers/AcademyController.php b/app/Http/Controllers/AcademyController.php index 2c35f0bd..7c12ba6c 100644 --- a/app/Http/Controllers/AcademyController.php +++ b/app/Http/Controllers/AcademyController.php @@ -43,4 +43,13 @@ public function frontendDev(Request $request): View|Response return view('academy.frontend-dev'); } + + public function dockerEnvironment(Request $request): View|Response + { + if ($request->header('HX-Request')) { + return response('', 200)->header('HX-Redirect', route('academy.docker-environment')); + } + + return view('academy.docker-environment'); + } } diff --git a/resources/views/academy/docker-environment.blade.php b/resources/views/academy/docker-environment.blade.php new file mode 100644 index 00000000..7b8f1c5a --- /dev/null +++ b/resources/views/academy/docker-environment.blade.php @@ -0,0 +1,1143 @@ +@extends('layouts.app') + +@section('title', 'Docker 환경이해') + +@push('styles') + +@endpush + +@section('content') +
SAM 프로젝트의 Docker 환경 — 비개발자도 이해할 수 있는 컨테이너 가이드
++ Docker는 애플리케이션을 컨테이너라는 격리된 환경에 넣어 실행하는 도구다. + 어떤 컴퓨터에서든 동일한 환경으로 프로그램을 돌릴 수 있게 해준다. +
+비유: 이삿짐 컨테이너
++ 이사할 때 가구를 컨테이너에 통째로 넣어서 옮기면, 어디로 가든 꺼내서 바로 사용할 수 있다. + Docker도 마찬가지다. 프로그램과 실행에 필요한 모든 것(PHP, MySQL, 설정 파일 등)을 컨테이너에 넣어두면, + 내 PC든 서버든 똑같이 동작한다. +
+Docker 없이 개발할 때의 문제점:
+"내 PC에선 되는데?"
+PHP 버전이 달라서
서버에서 오류 발생
의존성 충돌
+A 프로젝트는 PHP 7.3
B 프로젝트는 PHP 8.4 필요
설치 지옥
+PHP, MySQL, Nginx...
하나하나 설치하다 하루 종일
Docker를 쓰면:
+docker compose up 한 줄이면 모든 서비스가 동일한 환경으로 시작된다.
컨테이너 vs 가상머신 구조 비교
+| 비교 항목 | +가상머신 (VM) | +Docker 컨테이너 | +
|---|---|---|
| 비유 | +건물 통째로 빌리기 | +칸막이 사무실 임대 | +
| OS | +각각 별도 OS 설치 | +호스트 OS 커널 공유 | +
| 크기 | +수 GB | +수십~수백 MB | +
| 시작 시간 | +수 분 | +수 초 | +
| 자원 사용 | +무거움 (RAM 많이 차지) | +가벼움 (오버헤드 적음) | +
SAM Docker 전체 아키텍처 — samnet 브리지 네트워크
+ +
+ SAM은 9개 서비스가 하나의 samnet 브리지 네트워크에서 통신한다.
+ docker-compose.yml 파일로 전체 구성을 관리한다.
+
| 서비스 | +컨테이너명 | +기술 | +역할 | +
|---|---|---|---|
| nginx | +sam-nginx-1 |
+ Nginx | +리버스 프록시, SSL, 도메인 라우팅 | +
| api | +sam-api-1 |
+ PHP 8.4 + Laravel | +REST API, DB 마이그레이션 | +
| mng | +sam-mng-1 |
+ PHP 8.4 + Laravel | +관리자 웹 (HTMX + Blade) | +
| react | +sam-react-1 |
+ Node.js + Next.js 15 | +고객용 프론트엔드 (React) | +
| sales | +sam-sales-1 |
+ PHP + Laravel | +영업 관리 | +
| admin | +sam-admin-1 |
+ PHP + Laravel | +시스템 관리자 페이지 | +
| php73 | +sam-php73-1 |
+ PHP 7.3 | +레거시(5130) 호환 | +
| mysql | +sam-mysql-1 |
+ MySQL 8.0 | +데이터베이스 (samdb + chandj) | +
| phpmyadmin | +sam-phpmyadmin-1 |
+ phpMyAdmin | +DB 관리 웹 UI | +
요청 흐름 5단계 — 브라우저 → Nginx → PHP-FPM → Laravel → MySQL
+ +비유: 식당 주문 과정
++ 손님(브라우저)이 식당에 들어오면 → 안내 데스크(Nginx)가 좌석으로 안내 → + 서빙 직원(PHP-FPM)이 주문을 받아 → 주방(Laravel)에서 요리 → + 재료 창고(MySQL)에서 재료를 꺼내 요리를 완성한다. +
+mng.sam.kr 접속
+ 컨테이너 내부 프로세스 구조 — Supervisor가 관리
+ +MNG 컨테이너
+API 컨테이너
+비유: 식당 주방
++ 하나의 컨테이너 안에 주방장(Supervisor)이 있고, 그 아래 요리사(PHP-FPM), 서빙 직원(Nginx), 설거지 담당(Queue Worker)이 각자 일을 한다. + 주방장이 누가 쓰러지면 바로 새 직원을 투입한다(프로세스 자동 재시작). +
+React (Next.js) 컨테이너
+서버에서 빌드 금지! 로컬에서만 빌드
+MySQL 컨테이너
+samdb: SAM 메인 DBchandj: 레거시 DBdb_data 볼륨에 영구 저장Nginx 도메인 → 서비스 라우팅 맵
+ ++ 외부 Nginx가 도메인 이름을 보고 어떤 컨테이너로 보낼지 결정한다. + 모든 요청은 80/443 포트로 들어오고, Nginx가 내부 서비스로 분배한다. +
+| 도메인 | +서비스 | +내부 포트 | +
|---|---|---|
mng.sam.kr |
+ mng (Laravel) | +:8080 | +
api.sam.kr |
+ api (Laravel) | +:8080 | +
app.sam.kr |
+ react (Next.js) | +:3000 | +
admin.sam.kr |
+ admin (Laravel) | +:8080 | +
바인드 마운트 vs Docker 볼륨
+ +비유: 공유 폴더
++ 바인드 마운트는 내 PC 폴더를 컨테이너와 공유하는 것이다. + 내 PC에서 파일을 수정하면 컨테이너 안에서도 즉시 반영된다. + 마치 클라우드 공유 폴더처럼 양쪽이 항상 같은 파일을 본다. +
+# docker-compose.yml 예시 +volumes: + - ../mng:/var/www/mng # 바인드 마운트: 소스코드 + - mng_vendor:/var/www/mng/vendor # Docker 볼륨: 의존성+
바인드 마운트
+호스트 경로 ↔ 컨테이너 경로 연결
+코드 수정 → 즉시 반영
+Docker 볼륨
+Docker가 자체 관리하는 저장소
+vendor, node_modules 성능 향상
+
+ vendor와 node_modules는 Docker 볼륨으로 격리한다.
+ 이렇게 하면 호스트(WSL)의 파일 시스템 성능 문제를 피하고, 컨테이너 내부에서 빠르게 읽을 수 있다.
+
| 볼륨명 | +용도 | +특징 | +
|---|---|---|
db_data |
+ MySQL 데이터 | +컨테이너 삭제해도 데이터 유지 | +
api_vendor |
+ API Composer 패키지 | +컨테이너 내부 성능 최적화 | +
mng_vendor |
+ MNG Composer 패키지 | +컨테이너 내부 성능 최적화 | +
*_node_modules |
+ Node.js 패키지 | +호스트와 분리하여 속도 향상 | +
주의: Docker 볼륨은 호스트에서 직접 접근 불가
+
+ vendor 폴더는 Docker 볼륨 안에 있으므로,
+ 호스트(WSL)에서 직접 수정할 수 없다. 반드시 docker exec로 컨테이너에 들어가서 작업해야 한다.
+
+ .env 파일은 애플리케이션의 환경 설정을 저장하는 파일이다. + DB 접속 정보, API 키, 앱 이름 등 환경마다 달라지는 값을 코드 밖에서 관리한다. +
+비유: 매장별 설정 카드
++ 프랜차이즈 매장마다 전화번호, 주소, 영업시간이 다르다. + 매장 설정 카드(.env)에 적어두면, 같은 매뉴얼(코드)로도 매장마다 다르게 운영할 수 있다. + 코드를 바꾸지 않고도 DB 주소, 비밀번호 등을 변경 가능하다. +
+# .env 파일 예시 +APP_NAME=SAM +APP_ENV=local +APP_DEBUG=true + +# 데이터베이스 설정 +DB_HOST=sam-mysql-1 +DB_PORT=3306 +DB_DATABASE=samdb +DB_USERNAME=samuser +DB_PASSWORD=sampass + +# 메일 설정 +MAIL_MAILER=smtp +MAIL_HOST=smtp.gmail.com+
.env 파일에 넣는 것
+.env 파일 주의사항
+.env 로드 흐름과 우선순위
+ +
+ Docker Compose의 environment 설정은
+ 프로젝트 .env 파일보다 우선한다.
+ 즉, Docker에서 설정한 DB_HOST가 .env의 DB_HOST를 덮어쓴다.
+
environment 섹션
+ .env 파일
+ .env.example (참조용, 실제 로드 안 됨)
+ # docker-compose.yml에서 설정한 환경 변수 (최우선) +environment: + - DB_HOST=sam-mysql-1 # ← 이 값이 .env의 DB_HOST를 덮어씀 + - DB_PORT=3306 + - DB_DATABASE=samdb + +# 프로젝트 .env 파일의 DB_HOST=127.0.0.1 은 무시됨+
로컬(Docker) vs 서버(직접 설치) 환경 비교
+ +| 설정 항목 | +로컬 (Docker) | +서버 (운영) | +
|---|---|---|
| APP_ENV | +local |
+ production |
+
| APP_DEBUG | +true |
+ false |
+
| DB_HOST | +sam-mysql-1 (컨테이너명) |
+ 127.0.0.1 (로컬호스트) |
+
| DB_PASSWORD | +sampass (개발용) |
+ **** (운영용 복잡 비밀번호) |
+
| APP_URL | +https://mng.sam.kr |
+ https://mng.sam.kr |
+
| 실행 방법 | +docker exec |
+ 직접 명령 실행 |
+
핵심 차이: DB_HOST
+
+ 로컬에서는 Docker 네트워크 안에서 컨테이너 이름(sam-mysql-1)으로 DB에 접근하고,
+ 서버에서는 MySQL이 같은 서버에 직접 설치되어 있으므로 127.0.0.1로 접근한다.
+
Docker 명령어 치트시트
+ +안전한 명령어 (자유롭게 사용)
+# 컨테이너 상태 확인 +docker ps + +# 컨테이너 로그 확인 +docker logs sam-api-1 --tail 50 + +# 컨테이너 안에서 명령 실행 +docker exec sam-api-1 php artisan --version +docker exec sam-mng-1 php artisan route:list + +# 캐시 클리어 (설정 변경 후 필수) +docker exec sam-api-1 php artisan config:clear +docker exec sam-api-1 php artisan cache:clear +docker exec sam-mng-1 php artisan config:clear+
주의가 필요한 명령어
+# 모든 서비스 시작 +docker compose up -d + +# 특정 서비스 재시작 +docker compose restart api + +# 의존성 설치 (composer.json 변경 시) +docker exec sam-api-1 composer install + +# DB 마이그레이션 (반드시 API에서만!) +docker exec sam-api-1 php artisan migrate+
마이그레이션은 API에서만
+MNG에서 마이그레이션을 실행하면 안 된다. DB 스키마 관리는 API 프로젝트가 담당한다.
+docker exec sam-mng-1 php artisan migrate — 금지!
메뉴 시더 실행 금지
+메뉴 시더를 실행하면 부서별 권한 설정이 초기화된다. 메뉴 변경은 tinker로 개별 처리한다.
+php artisan db:seed --class=MngMenuSeeder — 금지!
서버에서 npm run build 금지
+서버 메모리 부족으로 빌드 실패. React 빌드는 반드시 로컬에서 수행한다.
+서버(2코어/3.8GB) → 빌드 시 OOM 위험
+올바른 작업 흐름
+로컬에서 코드 수정 → git commit → git push → 서버에서 git pull → composer install → config:clear
+코드 변경은 항상 로컬에서! 서버는 배포만!
+"컨테이너가 안 뜬다"
+# 1. 상태 확인 +docker ps -a # 종료된 컨테이너도 표시 + +# 2. 에러 로그 확인 +docker logs sam-api-1 --tail 100 + +# 3. 서비스 재시작 +cd /home/aweso/sam/docker && docker compose restart api+
"설정을 변경했는데 반영이 안 된다"
+# .env 변경 후 반드시 캐시 클리어 +docker exec sam-api-1 php artisan config:clear +docker exec sam-api-1 php artisan cache:clear +docker exec sam-api-1 php artisan view:clear+
Laravel은 설정을 캐시하므로, .env 변경 후 캐시를 비워야 새 값이 적용된다.
+"Class not found 에러"
+# Composer 오토로드 재생성 +docker exec sam-api-1 composer dump-autoload + +# 또는 패키지 전체 재설치 +docker exec sam-api-1 composer install+
"Permission denied 에러"
+# storage/logs 권한 확인 +docker exec sam-api-1 ls -la storage/logs/ + +# 권한 수정 (컨테이너 내부) +docker exec sam-api-1 chmod -R 775 storage/ +docker exec sam-api-1 chown -R www-data:www-data storage/+