diff --git a/app/Http/Controllers/AcademyController.php b/app/Http/Controllers/AcademyController.php index b2cf75bc..530e041c 100644 --- a/app/Http/Controllers/AcademyController.php +++ b/app/Http/Controllers/AcademyController.php @@ -53,6 +53,15 @@ public function dockerEnvironment(Request $request): View|Response return view('academy.docker-environment'); } + public function dockerCommands(Request $request): View|Response + { + if ($request->header('HX-Request')) { + return response('', 200)->header('HX-Redirect', route('academy.docker-commands')); + } + + return view('academy.docker-commands'); + } + public function webBasics(Request $request): View|Response { if ($request->header('HX-Request')) { diff --git a/resources/views/academy/docker-commands.blade.php b/resources/views/academy/docker-commands.blade.php new file mode 100644 index 00000000..07c6dd18 --- /dev/null +++ b/resources/views/academy/docker-commands.blade.php @@ -0,0 +1,1004 @@ +@extends('layouts.app') + +@section('title', 'Docker 명령어') + +@push('styles') + +@endpush + +@section('content') +
SAM 프로젝트 로컬 Docker 환경에서 반드시 알아야 할 명령어 — 실전 중심 가이드
+비유: 사무실 좌석 현황판
+
+ 사무실 출입구에 있는 좌석 현황판처럼, docker ps는
+ 지금 근무 중인(실행 중인) 컨테이너 목록을 보여준다.
+
비유: 가전제품 전원 관리
+
+ stop은 TV 끄기,
+ start는 TV 켜기,
+ restart는 TV를 껐다 다시 켜는 것이다.
+
비유: 회의실에 들어가서 지시하기
+
+ docker exec는
+ 컨테이너라는 방 안에 들어가서 명령을 전달하는 것이다.
+ 내 PC(WSL)에는 PHP가 없지만, 컨테이너 안에는 있으므로 exec로 실행한다.
+
-it 언제 쓰나?
+쓰지 않아도 되는 경우: 명령어 하나만 실행하고 끝날 때 docker exec sam-api-1 php artisan migrate
써야 하는 경우: 컨테이너 안에서 여러 명령을 연속으로 할 때, 또는 tinker처럼 대화형 프로그램을 실행할 때
핵심: 마이그레이션은 반드시 API 컨테이너에서!
+MNG에서 마이그레이션 실행 금지. 모든 DB 관련 작업은 sam-api-1에서만 실행한다.
| 목적 | +명령어 | +
|---|---|
| 마이그레이션 | +docker exec sam-api-1 php artisan migrate |
+
| 캐시 클리어 (MNG) | +docker exec sam-mng-1 php artisan cache:clear |
+
| 캐시 클리어 (API) | +docker exec sam-api-1 php artisan cache:clear |
+
| 설정 초기화 | +docker exec sam-api-1 php artisan config:clear |
+
| Composer 설치 | +docker exec sam-api-1 composer install |
+
| Tinker (대화형) | +docker exec -it sam-api-1 php artisan tinker |
+
| MySQL 접속 | +docker exec -it sam-mysql-1 mysql -u root -proot samdb |
+
| Pint 포맷팅 (MNG) | +docker exec sam-mng-1 ./vendor/bin/pint |
+
| 라우트 목록 | +docker exec sam-mng-1 php artisan route:list |
+
sam-api-1
+API 서버 (Laravel)
마이그레이션, 시더, API
sam-mng-1
+관리자 웹 (Laravel)
뷰, 라우트, 포맷팅
sam-mysql-1
+MySQL 데이터베이스
DB 접속, 쿼리 실행
비유: 오케스트라 지휘자
++ Docker Compose는 오케스트라 지휘자와 같다. 지휘자가 악보(docker-compose.yml) 하나로 + 모든 악기(컨테이너)를 동시에 시작·중지·조율하듯, Compose는 여러 컨테이너를 한 번에 관리한다. +
+SAM의 docker-compose.yml 위치
+/home/aweso/sam/docker-compose.yml
모든 docker compose 명령어는 이 파일이 있는 디렉토리(/home/aweso/sam)에서 실행해야 한다.
비유: USB 외장하드
++ 컨테이너가 컴퓨터라면, 볼륨은 USB 외장하드이다. + 컴퓨터(컨테이너)를 바꿔도 외장하드(볼륨)에 저장한 데이터는 그대로 남아 있다. +
+| 볼륨 이름 | +용도 | +삭제 시 영향 | +
|---|---|---|
| sam_mysql-data | +MySQL 데이터 저장 | +DB 데이터 전체 삭제! | +
| sam_phpmyadmin-data | +phpMyAdmin 세션 | +영향 미미 | +
SAM 네트워크 구조
+
+ 모든 SAM 컨테이너는 samnet 브리지 네트워크에 연결되어 있다.
+ 같은 네트워크 안에서는 컨테이너 이름으로 서로 접근할 수 있다.
+ 예: API 컨테이너가 MySQL에 접속할 때 sam-mysql-1:3306으로 연결한다.
+
문제 1: "사이트에 연결할 수 없음" (mng.sam.kr 접속 불가)
+원인: Docker 컨테이너가 실행되지 않았거나 중지된 상태
+해결:
+문제 2: "500 Server Error" (서버 내부 오류)
+원인: PHP 오류, .env 설정 문제, 캐시 문제 등
+해결:
+문제 3: "Class not found" (클래스를 찾을 수 없음)
+원인: Composer autoload가 갱신되지 않았거나, 새 패키지 설치가 필요
+해결:
+문제 4: "Connection refused" (MySQL 접속 실패)
+원인: MySQL 컨테이너가 아직 시작되지 않았거나, .env의 DB 설정이 잘못됨
+해결:
+문제 5: "Permission denied" (권한 오류)
+원인: storage, bootstrap/cache 디렉토리의 쓰기 권한이 없음
+해결:
+
+ 팁: .env 파일을 수정했다면 반드시 config:clear를 실행해야 변경이 적용된다.
+
경고: 아래 명령어는 데이터 손실을 유발할 수 있다
++ 의미를 정확히 이해하지 않은 채 실행하면 DB 데이터 전체 삭제, 이미지 삭제 등 돌이킬 수 없는 피해가 발생할 수 있다. + 반드시 팀장이나 담당 개발자에게 확인 후 실행하자. +
+
+ 안전한 대안: docker compose down (-v 없이) — 볼륨은 유지하면서 컨테이너만 종료
+
+ 디스크 공간이 부족하다면: docker image prune — 안 쓰는 이미지만 선별 삭제
+
+ 안전한 대안: docker stop sam-api-1 — 먼저 안전하게 중지
+
+ 볼륨 삭제 전 반드시: docker exec -it sam-mysql-1 mysqldump ...로 백업 먼저!
+
-v, -f, prune 플래그가 보이면 한 번 더 생각하기
+ docker compose down은 안전, docker compose down -v는 위험
+ docker ps로 현재 상태를 먼저 확인하는 습관 기르기
+