@extends('layouts.app') @section('title', 'Docker 명령어') @push('styles') @endpush @section('content')
{{-- ============================================================ --}} {{-- 히어로 배너 --}} {{-- ============================================================ --}}
아카데미 Docker 명령어

Docker 명령어

SAM 프로젝트 로컬 Docker 환경에서 반드시 알아야 할 명령어 — 실전 중심 가이드

🐳
{{-- ============================================================ --}} {{-- 좌측 고정 목차 (TOC) --}} {{-- ============================================================ --}} {{-- ============================================================ --}} {{-- 우측 콘텐츠 --}} {{-- ============================================================ --}}
{{-- 모바일 목차 --}} {{-- ============================================================ --}} {{-- 1. Docker 기본 확인 --}} {{-- ============================================================ --}}

1 Docker 기본 확인

docker ps — 실행 중인 컨테이너 확인 ?가장 자주 쓰는 명령어. "지금 어떤 컨테이너가 돌아가고 있지?" 궁금할 때 사용한다.

비유: 사무실 좌석 현황판

사무실 출입구에 있는 좌석 현황판처럼, docker ps지금 근무 중인(실행 중인) 컨테이너 목록을 보여준다.

기본 실행 중인 컨테이너만
$ docker ps CONTAINER ID IMAGE STATUS NAMES a1b2c3d4 sam-mng Up 2 hours sam-mng-1 e5f6g7h8 sam-api Up 2 hours sam-api-1 i9j0k1l2 mysql:8.0 Up 2 hours sam-mysql-1 m3n4o5p6 nginx:alpine Up 2 hours sam-nginx-1
응용 모든 컨테이너 (중지된 것 포함)
$ docker ps -a # -a = all. 중지된 컨테이너까지 전부 보여준다 CONTAINER ID IMAGE STATUS NAMES a1b2c3d4 sam-mng Up 2 hours sam-mng-1 q7r8s9t0 sam-react Exited (0) 3 hours ago sam-react-1

docker images — 설치된 이미지 목록 ?이미지는 컨테이너를 만들기 위한 "설계도"이다. 어떤 설계도가 설치되어 있는지 확인할 때 사용한다.

$ docker images REPOSITORY TAG IMAGE ID SIZE sam-mng latest abc123def 650MB sam-api latest 456ghi789 620MB mysql 8.0 jkl012mno 580MB nginx alpine pqr345stu 40MB
{{-- ============================================================ --}} {{-- 2. 컨테이너 제어 --}} {{-- ============================================================ --}}

2 컨테이너 제어

start / stop / restart ?컨테이너를 시작, 중지, 재시작하는 명령어. 전원 버튼을 누르는 것과 같다.

비유: 가전제품 전원 관리

stop은 TV 끄기, start는 TV 켜기, restart는 TV를 껐다 다시 켜는 것이다.

시작 컨테이너 시작
$ docker start sam-api-1 # 중지된 컨테이너를 다시 시작
중지 컨테이너 중지
$ docker stop sam-mng-1 # 실행 중인 컨테이너를 안전하게 중지
재시작 컨테이너 재시작
$ docker restart sam-api-1 # stop + start를 한 번에. 설정 변경 후 자주 사용
응용 여러 컨테이너 한번에
# 여러 컨테이너를 한 번에 중지/시작/재시작 $ docker stop sam-api-1 sam-mng-1 $ docker start sam-api-1 sam-mng-1 $ docker restart sam-api-1 sam-mng-1 sam-nginx-1
{{-- ============================================================ --}} {{-- 3. 컨테이너 진입 & 실행 --}} {{-- ============================================================ --}}

3 컨테이너 진입 & 실행

docker exec — 컨테이너 안에서 명령 실행 ?실행 중인 컨테이너 "안으로 들어가서" 명령어를 실행한다. SAM에서 가장 많이 쓰는 핵심 명령어이다.

비유: 회의실에 들어가서 지시하기

docker exec컨테이너라는 방 안에 들어가서 명령을 전달하는 것이다. 내 PC(WSL)에는 PHP가 없지만, 컨테이너 안에는 있으므로 exec로 실행한다.

기본 명령어 한 줄 실행
$ docker exec sam-api-1 php artisan migrate # sam-api-1 컨테이너 안에서 php artisan migrate 실행
대화형 컨테이너 안에 직접 들어가기 (-it)
$ docker exec -it sam-api-1 bash # -i = interactive (키보드 입력 가능) # -t = tty (터미널 화면 할당) # bash = 쉘 프로그램 실행 root@a1b2c3d4:/var/www/html# ← 컨테이너 안에 들어온 상태 root@a1b2c3d4:/var/www/html# exit ← exit로 빠져나오기

-it 언제 쓰나?

쓰지 않아도 되는 경우: 명령어 하나만 실행하고 끝날 때 docker exec sam-api-1 php artisan migrate

써야 하는 경우: 컨테이너 안에서 여러 명령을 연속으로 할 때, 또는 tinker처럼 대화형 프로그램을 실행할 때

SAM 프로젝트 전용 명령어 패턴

!

핵심: 마이그레이션은 반드시 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 접속, 쿼리 실행

{{-- ============================================================ --}} {{-- 4. 로그 확인 --}} {{-- ============================================================ --}}

4 로그 확인

docker logs — 컨테이너 로그 보기 ?컨테이너가 출력하는 모든 메시지(에러, 접속 기록 등)를 확인할 수 있다. 오류 원인을 찾을 때 필수.

기본 전체 로그 보기
$ docker logs sam-api-1 # 컨테이너 시작부터 지금까지의 모든 로그 출력
응용 최근 N줄만 보기 (--tail)
$ docker logs --tail 50 sam-nginx-1 # 최근 50줄만 출력. 로그가 많을 때 유용
실시간 실시간 로그 추적 (-f)
$ docker logs -f sam-api-1 # -f = follow. 새 로그가 생기면 실시간으로 표시 # Ctrl + C 로 종료
시간 필터 특정 시간 이후 로그 (--since)
$ docker logs --since 30m sam-api-1 # 최근 30분 이내의 로그만 출력 $ docker logs --since 2h sam-mng-1 # 최근 2시간 이내의 로그만 출력
조합 실무에서 가장 많이 쓰는 조합
$ docker logs --tail 100 -f sam-api-1 # 최근 100줄 출력 후 실시간 추적. 실무 디버깅의 기본!
{{-- ============================================================ --}} {{-- 5. Docker Compose --}} {{-- ============================================================ --}}

5 Docker Compose

주요 명령어 ?Docker Compose는 여러 컨테이너를 한 번에 관리하는 도구이다. docker-compose.yml 파일에 모든 설정이 정의되어 있다.

비유: 오케스트라 지휘자

Docker Compose는 오케스트라 지휘자와 같다. 지휘자가 악보(docker-compose.yml) 하나로 모든 악기(컨테이너)를 동시에 시작·중지·조율하듯, Compose는 여러 컨테이너를 한 번에 관리한다.

SAM의 docker-compose.yml 위치

/home/aweso/sam/docker-compose.yml

모든 docker compose 명령어는 이 파일이 있는 디렉토리(/home/aweso/sam)에서 실행해야 한다.

시작 모든 컨테이너 시작
$ cd /home/aweso/sam $ docker compose up -d # -d = detached (백그라운드 실행) # docker-compose.yml에 정의된 모든 서비스를 한 번에 시작
종료 모든 컨테이너 종료
$ docker compose down # 모든 컨테이너를 중지하고 제거 # 볼륨(DB 데이터)은 유지됨!
상태 서비스 상태 확인
$ docker compose ps NAME SERVICE STATUS PORTS sam-api-1 api running 9000/tcp sam-mng-1 mng running 9000/tcp sam-mysql-1 mysql running 3306/tcp sam-nginx-1 nginx running 0.0.0.0:80->80/tcp
로그 전체 서비스 로그 보기
$ docker compose logs -f # 모든 서비스의 로그를 한 화면에서 실시간 추적 $ docker compose logs -f api mng # 특정 서비스만 골라서 로그 확인
재시작 특정 서비스만 재시작
$ docker compose restart api # api 서비스만 재시작 (다른 서비스는 그대로) $ docker compose restart # 모든 서비스 재시작
{{-- ============================================================ --}} {{-- 6. 볼륨 & 네트워크 --}} {{-- ============================================================ --}}

6 볼륨 & 네트워크

볼륨 관리 ?볼륨은 컨테이너 데이터를 영구 저장하는 공간이다. 컨테이너를 삭제해도 볼륨에 저장된 데이터(DB 등)는 남아 있다.

비유: USB 외장하드

컨테이너가 컴퓨터라면, 볼륨은 USB 외장하드이다. 컴퓨터(컨테이너)를 바꿔도 외장하드(볼륨)에 저장한 데이터는 그대로 남아 있다.

$ docker volume ls # 생성된 볼륨 목록 조회 DRIVER VOLUME NAME local sam_mysql-data local sam_phpmyadmin-data
$ docker volume inspect sam_mysql-data # 볼륨의 상세 정보(저장 위치 등) 확인
볼륨 이름 용도 삭제 시 영향
sam_mysql-data MySQL 데이터 저장 DB 데이터 전체 삭제!
sam_phpmyadmin-data phpMyAdmin 세션 영향 미미

네트워크 관리 ?Docker 네트워크는 컨테이너들이 서로 통신하는 가상 네트워크이다. SAM의 모든 컨테이너는 samnet이라는 하나의 네트워크에 연결되어 있다.

$ docker network ls # Docker 네트워크 목록 조회 NETWORK ID NAME DRIVER SCOPE abc123def samnet bridge local
$ docker network inspect samnet # samnet에 연결된 컨테이너 목록과 IP 주소 확인

SAM 네트워크 구조

모든 SAM 컨테이너는 samnet 브리지 네트워크에 연결되어 있다. 같은 네트워크 안에서는 컨테이너 이름으로 서로 접근할 수 있다. 예: API 컨테이너가 MySQL에 접속할 때 sam-mysql-1:3306으로 연결한다.

{{-- ============================================================ --}} {{-- 7. 트러블슈팅 --}} {{-- ============================================================ --}}

7 트러블슈팅

자주 발생하는 문제 & 해결 방법

{{-- 문제 1 --}}

문제 1: "사이트에 연결할 수 없음" (mng.sam.kr 접속 불가)

원인: Docker 컨테이너가 실행되지 않았거나 중지된 상태

해결:

$ docker ps # 실행 중인 컨테이너 확인 $ cd /home/aweso/sam $ docker compose up -d # 모든 서비스 시작
{{-- 문제 2 --}}

문제 2: "500 Server Error" (서버 내부 오류)

원인: PHP 오류, .env 설정 문제, 캐시 문제 등

해결:

# 1. 로그 확인 (원인 파악) $ docker logs --tail 50 sam-mng-1 # 2. 캐시 전부 클리어 $ docker exec sam-mng-1 php artisan config:clear $ docker exec sam-mng-1 php artisan cache:clear $ docker exec sam-mng-1 php artisan view:clear
{{-- 문제 3 --}}

문제 3: "Class not found" (클래스를 찾을 수 없음)

원인: Composer autoload가 갱신되지 않았거나, 새 패키지 설치가 필요

해결:

$ docker exec sam-mng-1 composer dump-autoload # 또는 composer install로 전체 의존성 재설치 $ docker exec sam-mng-1 composer install
{{-- 문제 4 --}}

문제 4: "Connection refused" (MySQL 접속 실패)

원인: MySQL 컨테이너가 아직 시작되지 않았거나, .env의 DB 설정이 잘못됨

해결:

# 1. MySQL 컨테이너 상태 확인 $ docker ps -a | grep mysql # STATUS가 "Up"인지 확인 # 2. MySQL이 중지되어 있다면 시작 $ docker start sam-mysql-1 # 3. MySQL 접속 테스트 $ docker exec -it sam-mysql-1 mysql -u root -proot samdb
{{-- 문제 5 --}}

문제 5: "Permission denied" (권한 오류)

원인: storage, bootstrap/cache 디렉토리의 쓰기 권한이 없음

해결:

$ docker exec sam-mng-1 chmod -R 777 storage bootstrap/cache # storage와 bootstrap/cache에 모든 권한 부여
{{-- SAM 캐시 클리어 총정리 --}}

🧹 SAM 캐시 클리어 총정리 (외우면 좋은 명령어)

# === MNG 캐시 클리어 === $ docker exec sam-mng-1 php artisan config:clear # 설정 캐시 $ docker exec sam-mng-1 php artisan cache:clear # 앱 캐시 $ docker exec sam-mng-1 php artisan view:clear # 뷰 캐시 $ docker exec sam-mng-1 php artisan route:clear # 라우트 캐시 # === API 캐시 클리어 === $ 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 $ docker exec sam-api-1 php artisan route:clear

팁: .env 파일을 수정했다면 반드시 config:clear를 실행해야 변경이 적용된다.

{{-- ============================================================ --}} {{-- 8. 위험한 명령어 --}} {{-- ============================================================ --}}

8 위험한 명령어

!

경고: 아래 명령어는 데이터 손실을 유발할 수 있다

의미를 정확히 이해하지 않은 채 실행하면 DB 데이터 전체 삭제, 이미지 삭제 등 돌이킬 수 없는 피해가 발생할 수 있다. 반드시 팀장이나 담당 개발자에게 확인 후 실행하자.

위험도 ★★★ docker compose down -v
$ docker compose down -v # -v = volumes. 컨테이너뿐만 아니라 볼륨(DB 데이터)까지 전부 삭제! # MySQL 데이터가 완전히 사라진다. 절대 함부로 실행하지 말 것!

안전한 대안: docker compose down (-v 없이) — 볼륨은 유지하면서 컨테이너만 종료

위험도 ★★★ docker system prune -a
$ docker system prune -a # 사용하지 않는 모든 이미지, 네트워크, 컨테이너를 일괄 삭제 # SAM 이미지까지 삭제되어 docker compose up 시 처음부터 빌드해야 함

디스크 공간이 부족하다면: docker image prune — 안 쓰는 이미지만 선별 삭제

위험도 ★★ docker rm -f
$ docker rm -f sam-api-1 # -f = force. 실행 중인 컨테이너를 강제로 삭제 # 정상적인 종료 절차 없이 즉시 제거됨

안전한 대안: docker stop sam-api-1 — 먼저 안전하게 중지

위험도 ★★ docker volume rm
$ docker volume rm sam_mysql-data # MySQL 데이터 볼륨 삭제 = DB 데이터 완전 손실! # 관련 컨테이너가 중지된 상태에서만 삭제 가능

볼륨 삭제 전 반드시: docker exec -it sam-mysql-1 mysqldump ...로 백업 먼저!

위험도 ★★ docker rmi
$ docker rmi sam-mng # SAM MNG 이미지 삭제. 다시 빌드하는 데 시간이 소요됨
{{-- 안전 체크리스트 --}}

Docker 사용 시 안전 수칙

  • 1. -v, -f, prune 플래그가 보이면 한 번 더 생각하기
  • 2. 볼륨 삭제 전 반드시 DB 백업
  • 3. docker compose down은 안전, docker compose down -v는 위험
  • 4. 모르는 명령어는 팀장에게 확인 후 실행
  • 5. docker ps로 현재 상태를 먼저 확인하는 습관 기르기
{{-- Lightbox --}} @include('components.academy-glossary', ['domain' => 'docker-commands']) @endsection @push('scripts') @endpush