// 이 파일이 하는 일: "리눅스 심화" 코스 — 환경변수와 PATH에서 출발해
// 셸 스크립트, 크론, 파이프, systemctl, 로그 관습, 그리고 우리 서버의
// 실제 운영 명령까지 7개 섹션으로 안내하는 정적 학습 페이지.
// (환경변수·PATH → 셸 스크립트 → 크론 → 파이프·리다이렉션 → 프로세스 관리 → /var/log → 운영 명령 모음)
// 학습 포인트: API 호출이 없는 '내용 고정' 페이지다. 스타일은 global.css의
// 가이드 전용 클래스(step-card, code-block, tip 등)를 재사용한다 — 색을 여기서 하드코딩하지 않는다.
// 셸 예제·텍스트 다이어그램은 JSX 중괄호/백틱 충돌을 피하려고 파일 상단의 백틱 문자열 상수로 정의한다.

import { Link } from 'react-router-dom';

// ── 셸 예제 · 텍스트 다이어그램 상수들 ──

const CODE_ENV_BASIC = `# 환경변수 = 셸이라는 '작업실'에 붙여 둔 포스트잇

# 지금 붙어 있는 포스트잇 전부 보기
printenv            # (또는 env)

# 하나만 골라 보기 — $를 붙이면 "이 이름의 값으로 바꿔 줘"
echo $HOME          # 내 홈 디렉터리   예) /home/ubuntu
echo $USER          # 지금 로그인한 사용자
echo $SHELL         # 지금 쓰는 셸     예) /bin/bash

# 새 포스트잇 붙이기 (export가 있어야 자식 프로세스에도 전달돼요)
export DB_PASSWORD=secret123
echo $DB_PASSWORD

# 단, 터미널을 닫으면 사라짐! 계속 쓰려면 ~/.bashrc에 적어 둡니다.`;

const CODE_PATH = `# PATH = "명령어를 찾을 때 뒤져 볼 폴더 목록" (콜론 : 으로 구분)

echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:...

# docker 라고 치면 셸이 하는 일:
# 1) /usr/local/bin/docker 있나? → 없네
# 2) /usr/bin/docker 있나?       → 있다! 실행!
# 왼쪽 폴더부터 순서대로 찾고, 처음 발견한 것을 실행해요.

# 어떤 명령이 실제로 어디 있는지 확인
which docker        # /usr/bin/docker
which java          # /usr/bin/java

# "command not found"의 정체:
# 프로그램이 없거나, 있어도 PATH에 등록된 폴더 밖에 있다는 뜻!
# 그래서 설치 안내문 끝에 "PATH에 추가하세요"가 자주 나오는 거예요.`;

const CODE_SH_FIRST = `#!/bin/bash
# ↑ 셔뱅(shebang): "이 파일은 bash로 실행해 주세요"라는 첫 줄 선언

# hello.sh — 나의 첫 셸 스크립트
NAME="어썸데브"                 # 변수 선언 (= 양옆에 공백 금지!)
echo "안녕하세요, $NAME 수습 여러분!"
echo "오늘 날짜: $(date +%Y-%m-%d)"   # $( ) = 명령 실행 결과를 값으로 사용

# 실행하는 법:
#   chmod +x hello.sh   ← 실행 권한 주기 (딱 한 번)
#   ./hello.sh          ← 실행!`;

const CODE_SH_IF_FOR = `#!/bin/bash
# if — "조건이 맞으면 이 길, 아니면 저 길"

if [ -f .env ]; then                # -f = 파일이 존재하면
  echo ".env 있음 — 배포 진행!"
else
  echo ".env 없음 — 먼저 만들어 주세요"
  exit 1                            # 0이 아닌 종료 코드 = 실패 신호
fi

# for — "목록의 항목마다 반복"
for svc in frontend backend db; do
  echo "[$svc] 상태 점검 중..."
done

# 실제 배포 스크립트(deploy.sh)의 뼈대가 딱 이 모양이에요:
# "필요한 파일 있는지 확인(if) → 서비스마다 순서대로 처리(for)"
# 스크립트 = 손으로 치던 명령들을 파일에 적어 둔 자동 조리법입니다.`;

const CODE_CRON = `# 크론(cron) = 리눅스에 내장된 알람시계 + 자동 실행 비서
# "매일 새벽 4시에 이 명령 실행해 줘"를 등록해 두는 곳

crontab -l          # 내 예약 목록 보기
crontab -e          # 예약 편집하기

# 예약 한 줄의 문법 — 별 5개 + 명령
# ┌─ 분 (0-59)
# │ ┌─ 시 (0-23)
# │ │ ┌─ 일 (1-31)
# │ │ │ ┌─ 월 (1-12)
# │ │ │ │ ┌─ 요일 (0-7, 0과 7 = 일요일)
# │ │ │ │ │
# 0 4 * * *  /home/ubuntu/backup.sh >> /var/log/backup.log 2>&1
# → "매일(일·월·요일은 * = 아무 때나) 새벽 4시 0분에 백업 스크립트 실행,
#    출력은 로그 파일에 이어 붙이기"

# 자주 쓰는 패턴
# */10 * * * *   → 10분마다
# 0 * * * *      → 매시 정각
# 30 2 * * 1     → 매주 월요일 새벽 2시 30분

# 우리 서버의 DB 백업도 이렇게 돌아가요 — 사람이 새벽에 안 일어나도
# pg_dump가 알아서 실행되고, 결과는 로그로 남습니다.`;

const CODE_PIPE = `# 파이프( | ) = 왼쪽 명령의 출력을 오른쪽 명령의 입력으로 흘려보내는 배관

# "프로세스 목록에서 java가 들어간 줄만 보여 줘"
ps aux | grep java

# "로그에서 ERROR 줄만 골라 → 최근 20줄만"
cat app.log | grep ERROR | tail -20

# 리다이렉션 — 출력의 방향을 파일로 꺾기
echo "안녕" >  memo.txt    # >  : 파일에 저장 (기존 내용 덮어씀! 주의)
echo "추가" >> memo.txt    # >> : 파일 끝에 이어 붙임 (안전)

# 조합 연습 — 작은 부품을 이어 큰 도구 만들기
history | grep docker              # 내가 쳤던 docker 명령 다시 찾기
ls -l | wc -l                      # 현재 폴더의 항목 수 세기
grep ERROR app.log | wc -l         # 에러가 총 몇 번 났는지 세기
ps aux | grep java > java_ps.txt   # 조사 결과를 파일로 보관

# 리눅스 철학: 한 가지만 잘하는 작은 도구들을
# 파이프로 이어 붙여 무엇이든 만든다 — 레고 블록과 같아요.`;

const CODE_SYSTEMCTL = `# systemd = 리눅스 서버의 '매니저'. 부팅하면 제일 먼저 일어나서
# 등록된 서비스들을 깨우고, 죽으면 다시 살리고, 상태를 관리해요.
# systemctl = 그 매니저에게 말을 거는 리모컨.

sudo systemctl status caddy     # 상태 보기 (active (running)이면 정상)
sudo systemctl restart caddy    # 재시작 — "껐다 켜 보세요"의 서버 버전
sudo systemctl stop caddy       # 정지
sudo systemctl start caddy      # 시작
sudo systemctl enable caddy     # 부팅 시 자동 시작 등록 ★중요★

# enable을 빼먹으면? 서버 재부팅(정전, EC2 재시작...) 후
# 서비스가 안 살아나서 "사이트가 안 열려요" 사태가 납니다.

# 직접 실행(./run.sh)과 서비스 등록의 차이:
# 직접 실행 = 알바생이 손으로 켬 → 터미널 끊기면 같이 죽을 수 있음
# systemd 등록 = 매니저가 관리 → 죽으면 재기동, 부팅하면 자동 시작
# 참고: 우리 백엔드처럼 Docker로 띄우는 것들은 Docker가
# restart 정책으로 같은 역할을 해 줘요. 매니저가 둘인 셈!`;

const CODE_VARLOG = `# /var/log = 서버의 블랙박스. 무슨 일이 있었는지 전부 여기 남아요.

/var/log/
├── syslog (또는 messages)   # 시스템 전반의 일기장
├── auth.log                 # 로그인 시도 기록 — 침입 흔적도 여기!
├── kern.log                 # 커널(OS 심장부) 메시지
└── ...                      # 프로그램마다 자기 폴더/파일을 만들기도

# 로그 읽기 3종 세트
tail -n 50 /var/log/syslog     # 마지막 50줄
tail -f /var/log/syslog        # 실시간 감시 (f=follow, Ctrl+C로 종료)
grep "Failed" /var/log/auth.log # 실패한 로그인 시도 찾기

# systemd가 관리하는 서비스의 로그는 journalctl로
journalctl -u caddy --since "1 hour ago"

# Docker 컨테이너의 로그는 docker가 따로 모아 줘요
docker logs -f backend

# 로그가 무한히 쌓이면 디스크가 꽉 차므로, logrotate라는 도구가
# 오래된 로그를 압축·삭제해 줍니다. (일기장을 연도별로 묶어 창고에 넣는 셈)`;

const CODE_OPS = `# AWESOMEDEV 서울 EC2 — 실전 운영 명령 모음
# (멘토 옆에서 실제로 보게 될 명령들이에요. 순서대로 읽어 보세요.)

# 1) 서버 접속 — 열쇠(키 파일)로 문 열기
ssh -i awesomedev-key.pem ubuntu@<서버IP>

# 2) 서버 건강검진
df -h                        # 디스크 남은 용량 (Use% 90↑면 위험!)
free -h                      # 메모리 사용량
docker ps                    # 컨테이너 목록 — STATUS가 Up이면 정상

# 3) 서비스 로그 확인 (문제 신고가 들어왔을 때 1순위)
docker logs --tail 100 backend          # 백엔드 최근 100줄
docker logs -f backend | grep ERROR     # 에러만 실시간 감시

# 4) 배포 — Gitea에서 최신 코드 받아 다시 띄우기
cd ~/mirim-app
git pull                     # edu.awesomedevapp.com 의 Gitea에서 받기
docker compose up -d --build # 바뀐 것만 다시 빌드해서 교체

# 5) HTTPS 현관(Caddy) 상태
sudo systemctl status caddy
journalctl -u caddy --since "10 min ago"

# 6) DB 백업이 잘 돌았는지 확인 (섹션 3의 크론!)
crontab -l                   # 예약 목록에 backup.sh가 있는지
tail /var/log/backup.log     # 오늘 새벽 백업 로그 확인

# 이 여섯 묶음이 "서버 좀 봐 주세요"를 받았을 때의 기본 동선입니다.`;

// ── 이 페이지 안에서만 쓰는 작은 부품들 ──
// 학습 포인트: 같은 모양이 반복되면 컴포넌트로 뽑는다. props만 바꿔 재사용.
function Section({ n, title, sub, children }) {
  return (
    <section className="step-card" id={`sec-${n}`}>
      <div className="step-head">
        <span className="step-num">{n}</span>
        <div>
          <h3>{title}</h3>
          {sub && <span className="step-sub">{sub}</span>}
        </div>
      </div>
      <div className="step-body">{children}</div>
    </section>
  );
}

function Code({ children }) {
  return <pre className="code-block"><code>{children}</code></pre>;
}

const SECTIONS = [
  { n: 1, label: '환경변수와 PATH' },
  { n: 2, label: '셸 스크립트 첫걸음' },
  { n: 3, label: '크론 예약 작업' },
  { n: 4, label: '파이프와 리다이렉션' },
  { n: 5, label: '프로세스 관리 심화' },
  { n: 6, label: '로그는 /var/log에' },
  { n: 7, label: '실전 운영 명령 모음' },
];

export default function LinuxAdvancedPage() {
  return (
    <div>
      {/* 히어로: 이 코스가 어디서 출발해 어디까지 가는지 */}
      <div className="hero">
        <div className="eyebrow">Course · 서버와 데이터</div>
        <h1>리눅스 심화<br />— 명령어를 넘어, 서버를 운영하는 감각으로</h1>
        <p>
          리눅스 기초에서 폴더를 오가고 파일을 다뤘다면, 이제는 서버가 <strong>스스로
          일하게</strong> 만들 차례예요. 환경변수와 스크립트, 예약 작업, 로그 읽는 법을 거쳐
          우리 EC2 서버에서 실제로 쓰는 운영 명령까지 — <strong>"직접 확인해 보기"</strong>는
          꼭 손으로 해보세요.
        </p>
        <div className="chip-row">
          <span className="chip">예상 소요 90분</span>
          <span className="chip">실습 3개</span>
          <span className="chip">선수 코스: 리눅스 기초</span>
        </div>
      </div>

      {/* 섹션 바로가기 */}
      <nav className="pill-nav">
        {SECTIONS.map((s) => (
          <a key={s.n} href={`#sec-${s.n}`}>
            <b>{s.n}</b>
            {s.label}
          </a>
        ))}
      </nav>

      <Section n={1} title="환경변수와 PATH" sub="셸의 포스트잇, 그리고 명령어를 찾는 지도">
        <p>
          <strong>환경변수</strong>는 셸이라는 작업실 벽에 붙여 둔 <strong>포스트잇</strong>이에요.
          "내 홈은 여기", "DB 비밀번호는 이것" 같은 정보를 이름표를 붙여 적어 두면,
          그 작업실에서 실행되는 프로그램들이 전부 읽어 갈 수 있죠. 우리 백엔드(Spring Boot)가
          DB 비밀번호를 코드에 박아 두지 않고 환경변수로 받는 이유가 바로 이것 —
          <strong>코드는 공개돼도 포스트잇은 서버에만</strong> 붙어 있으니까요.
        </p>
        <Code>{CODE_ENV_BASIC}</Code>
        <p>
          그중 가장 유명한 환경변수가 <span className="icode">PATH</span>입니다.
          터미널에 <span className="icode">docker</span>라고 치면 셸은 "docker라는 프로그램이
          어디 있지?" 하고 <strong>PATH에 적힌 폴더들을 왼쪽부터 순서대로</strong> 뒤져요.
          지도에 표시된 서랍만 열어 보는 셈이죠.
        </p>
        <Code>{CODE_PATH}</Code>
        <div className="warn">
          <b>흔한 함정</b> — 분명 설치했는데 <span className="icode">command not found</span>가
          뜬다면, 프로그램이 PATH에 없는 폴더에 설치된 거예요. 프로그램이 없는 게 아니라
          <strong> 지도에 그 서랍이 안 그려져 있는 것</strong>. 침착하게{' '}
          <span className="icode">which</span>와 <span className="icode">echo $PATH</span>부터 확인!
        </div>
      </Section>

      <Section n={2} title="셸 스크립트 첫걸음" sub="손으로 치던 명령을 자동 조리법으로">
        <p>
          매번 같은 명령 5개를 순서대로 치고 있다면, 그건 <strong>스크립트로 만들라는
          신호</strong>예요. 셸 스크립트(<span className="icode">.sh</span>)는 터미널에 칠 명령들을
          파일에 순서대로 적어 둔 <strong>조리법(레시피)</strong>입니다. 요리사(셸)에게 건네면
          위에서부터 한 줄씩 그대로 실행하죠.
        </p>
        <Code>{CODE_SH_FIRST}</Code>
        <p>
          조리법에도 "간을 보고 싱거우면 소금 추가" 같은 판단이 필요하죠.
          그게 <span className="icode">if</span>(조건)와 <span className="icode">for</span>(반복)예요.
          이 두 개만 알면 실무 배포 스크립트의 8할을 읽을 수 있습니다.
        </p>
        <Code>{CODE_SH_IF_FOR}</Code>
        <div className="tip">
          <b>직접 확인해 보기 ①</b> 위의 <span className="icode">hello.sh</span>를 그대로 만들어
          실행해 보세요. Windows라면 <strong>Git Bash</strong>에서, 서버 실습 계정이 있다면 EC2에서요.
          성공했다면 <span className="icode">NAME</span>을 내 이름으로 바꾸고,{' '}
          <span className="icode">for</span>문으로 "1일차 화이팅~5일차 화이팅"을 출력하도록
          고쳐 보세요. 그다음 멘토에게 우리 프로젝트의 <span className="icode">deploy.sh</span>를
          보여 달라고 해서 — <strong>어디가 if고 어디가 for인지</strong> 손가락으로 짚어 보기!
        </div>
      </Section>

      <Section n={3} title="크론으로 예약 작업" sub="새벽 4시의 백업, 사람 대신 알람시계가">
        <p>
          "매일 새벽에 DB를 백업해야 해요"라는 일을 사람이 하면 어떻게 될까요? 하루 이틀은
          하겠지만 언젠가 반드시 까먹어요. 그래서 리눅스에는 <strong>크론(cron)</strong>이라는
          알람시계 겸 비서가 있습니다. "이 시각이 되면 이 명령을 실행해"라고 등록해 두면,
          서버가 켜져 있는 한 <strong>영원히, 정확하게</strong> 반복하죠.
        </p>
        <Code>{CODE_CRON}</Code>
        <p>
          별 5개 문법이 처음엔 암호 같지만, <strong>왼쪽부터 "분·시·일·월·요일"</strong> 하나만
          기억하면 돼요. <span className="icode">*</span>는 "아무 때나(매번)"라는 뜻이고요.
          섹션 2에서 만든 스크립트를 크론에 등록하는 순간 — 여러분은 <strong>자동화</strong>를
          한 거예요. 이게 운영의 핵심 기술입니다.
        </p>
        <div className="warn">
          <b>크론의 함정</b> — 크론은 여러분의 터미널과 <strong>다른 환경</strong>(다른 PATH,
          다른 작업 폴더)에서 실행돼요. "내가 치면 되는데 크론에선 안 돌아요"의 원인 대부분이
          이것! 그래서 크론에 등록하는 명령은 <strong>절대 경로</strong>로 쓰고, 출력을{' '}
          <span className="icode">&gt;&gt; 로그파일</span>로 남겨 두는 게 관례입니다.
        </div>
      </Section>

      <Section n={4} title="파이프와 리다이렉션" sub="작은 도구들을 배관으로 이어 붙이기">
        <p>
          리눅스 명령어들은 하나하나는 단순해요. <span className="icode">grep</span>은 골라내기만,{' '}
          <span className="icode">wc</span>는 세기만, <span className="icode">tail</span>은 끝부분만.
          진짜 힘은 <strong>파이프(<span className="icode">|</span>)로 이어 붙일 때</strong> 나옵니다 —
          왼쪽 명령의 출력이 배관을 타고 오른쪽 명령의 입력으로 흘러 들어가요. 레고 블록처럼요.
        </p>
        <svg className="diagram" viewBox="0 0 640 240" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="파이프 연결 도해: tail -f의 출력이 파이프를 타고 grep의 입력으로 들어가고, 걸러진 결과만 화면에 표시된다">
          <text x="320" y="28" textAnchor="middle" fontSize="15" fontWeight="700" fill="var(--ink)">tail -f app.log | grep ERROR</text>
          <text x="95" y="58" textAnchor="middle" fontSize="12" fill="var(--muted)">① 만들기(출력)</text>
          <text x="320" y="58" textAnchor="middle" fontSize="12" fill="var(--muted)">② 골라내기(필터)</text>
          <text x="545" y="58" textAnchor="middle" fontSize="12" fill="var(--muted)">③ 보기(화면)</text>
          <rect x="20" y="70" width="150" height="85" rx="8" fill="var(--card)" stroke="var(--line)" />
          <text x="95" y="100" textAnchor="middle" fontSize="14" fontWeight="700" fill="var(--primary)">tail -f app.log</text>
          <text x="95" y="122" textAnchor="middle" fontSize="12" fill="var(--muted)">로그 끝을 실시간으로</text>
          <text x="95" y="140" textAnchor="middle" fontSize="12" fill="var(--muted)">계속 흘려보냄</text>
          <rect x="245" y="70" width="150" height="85" rx="8" fill="var(--card)" stroke="var(--line)" />
          <text x="320" y="100" textAnchor="middle" fontSize="14" fontWeight="700" fill="var(--teal)">grep ERROR</text>
          <text x="320" y="122" textAnchor="middle" fontSize="12" fill="var(--muted)">ERROR 포함 줄만 통과</text>
          <text x="320" y="140" textAnchor="middle" fontSize="12" fill="var(--muted)">(나머지는 버림)</text>
          <rect x="470" y="70" width="150" height="85" rx="8" fill="var(--card)" stroke="var(--line)" />
          <text x="545" y="100" textAnchor="middle" fontSize="14" fontWeight="700" fill="var(--ink)">화면(터미널)</text>
          <text x="545" y="122" textAnchor="middle" fontSize="12" fill="var(--rose)">ERROR: 연결 실패</text>
          <text x="545" y="140" textAnchor="middle" fontSize="12" fill="var(--muted)">에러만 실시간 표시</text>
          <line x1="170" y1="112" x2="236" y2="112" stroke="var(--muted)" strokeWidth="2" />
          <path d="M236 107 L245 112 L236 117 Z" fill="var(--muted)" />
          <circle cx="207" cy="112" r="13" fill="var(--card)" stroke="var(--teal)" strokeWidth="2" />
          <text x="207" y="117" textAnchor="middle" fontSize="15" fontWeight="700" fill="var(--teal)">|</text>
          <line x1="395" y1="112" x2="461" y2="112" stroke="var(--muted)" strokeWidth="2" />
          <path d="M461 107 L470 112 L461 117 Z" fill="var(--muted)" />
          <circle cx="432" cy="112" r="13" fill="var(--card)" stroke="var(--teal)" strokeWidth="2" />
          <text x="432" y="117" textAnchor="middle" fontSize="15" fontWeight="700" fill="var(--teal)">|</text>
          <line x1="207" y1="128" x2="207" y2="168" stroke="var(--line)" strokeDasharray="4 3" />
          <text x="207" y="186" textAnchor="middle" fontSize="12" fill="var(--muted)">모든 로그 줄</text>
          <line x1="432" y1="128" x2="432" y2="168" stroke="var(--line)" strokeDasharray="4 3" />
          <text x="432" y="186" textAnchor="middle" fontSize="12" fill="var(--muted)">ERROR 줄만</text>
          <text x="320" y="218" textAnchor="middle" fontSize="13" fill="var(--muted)">파이프( | ) = 왼쪽 명령의 출력을 오른쪽 명령의 입력으로 잇는 배관</text>
        </svg>
        <p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: 파이프는 tail -f의 출력을 grep의 입력으로 이어 붙이는 배관이다</p>
        <Code>{CODE_PIPE}</Code>
        <p>
          <span className="icode">&gt;</span>와 <span className="icode">&gt;&gt;</span>의 차이는 꼭
          기억하세요. <span className="icode">&gt;</span>는 <strong>덮어쓰기</strong>(기존 내용 삭제!),{' '}
          <span className="icode">&gt;&gt;</span>는 <strong>이어 붙이기</strong>예요. 로그를 모을 때{' '}
          <span className="icode">&gt;</span>를 잘못 쓰면 어제까지의 기록이 통째로 사라집니다.
        </p>
        <div className="tip">
          <b>직접 확인해 보기 ②</b> Git Bash를 열고 우리 프로젝트 폴더에서 파이프 3단 조합에
          도전해 보세요. <span className="icode">git log --oneline | grep fix | wc -l</span> —
          "커밋 기록에서 fix가 들어간 줄만 골라, 몇 개인지 세라"는 뜻이에요. 결과가 나오면{' '}
          <span className="icode">grep feat</span>으로 바꿔 기능 추가 커밋 수와 비교해 보고,
          마지막에 <span className="icode">&gt; commit_report.txt</span>를 붙여 파일로 저장까지!
        </div>
      </Section>

      <Section n={5} title="프로세스 관리 심화" sub="서비스를 매니저(systemd)에게 맡기기">
        <p>
          리눅스 기초에서 <span className="icode">ps</span>로 프로세스를 구경했다면, 이제는
          프로세스를 <strong>서비스로 관리</strong>하는 법이에요. 서버 프로그램은 알바생이 손으로
          켜는 게 아니라, <strong>매니저에게 등록</strong>해 두고 "죽으면 살리고, 가게 문 열면
          (부팅하면) 자동으로 출근시켜"라고 맡겨야 합니다. 그 매니저가{' '}
          <strong>systemd</strong>이고, 매니저와 대화하는 리모컨이{' '}
          <span className="icode">systemctl</span>이에요.
        </p>
        <Code>{CODE_SYSTEMCTL}</Code>
        <p>
          우리 서버에서는 HTTPS 현관 역할의 <strong>Caddy</strong>가 systemd 서비스로 돌고,
          React 프론트와 Spring Boot 백엔드, PostgreSQL은 <strong>Docker</strong>가 컨테이너로
          관리해요. 관리 주체는 달라도 철학은 같습니다 — <strong>"사람 손이 아니라 시스템이
          살아 있게 한다."</strong>
        </p>
        <div className="tip">
          <b>기억할 것</b> — 문제가 생겼을 때의 순서는{' '}
          <span className="icode">status</span>(상태 확인) → 로그 확인(다음 섹션!) →{' '}
          <span className="icode">restart</span>(재시작)예요. 원인도 안 보고 restart부터 누르는 건
          아픈 이유를 안 물어보고 진통제부터 주는 것 — 당장은 낫지만 병은 그대로입니다.
        </div>
      </Section>

      <Section n={6} title="로그는 /var/log에" sub="서버의 블랙박스를 여는 법">
        <p>
          서버에서 벌어지는 모든 일 — 누가 로그인했고, 어떤 서비스가 언제 죽었고, 디스크에
          무슨 문제가 있었는지 — 는 전부 <strong>로그</strong>로 남아요. 그리고 리눅스 세계의
          오랜 관습으로, 그 로그들은 <span className="icode">/var/log</span> 폴더에 모입니다.
          비행기의 블랙박스처럼, <strong>사고 원인은 언제나 여기서 찾아요</strong>.
        </p>
        <Code>{CODE_VARLOG}</Code>
        <p>
          특히 <span className="icode">tail -f</span>는 운영자의 단짝이에요. 로그 파일의 끝을
          <strong> 실시간으로 계속 보여 주는</strong> 명령이라, 배포 직후 화면에 띄워 두고
          "에러 안 나나?" 지켜보는 용도로 매일 씁니다. 섹션 4의 파이프와 합치면{' '}
          <span className="icode">tail -f 로그 | grep ERROR</span> — 에러만 골라 실시간 감시!
        </p>
        <div className="warn">
          <b>디스크 꽉 참 주의보</b> — 로그를 방치하면 몇 달 뒤 디스크가 가득 차서
          <strong> 멀쩡한 서비스가 갑자기 죽는</strong> 사고가 납니다. "잘 되던 서버가 이유 없이
          죽었다"의 단골 범인이에요. <span className="icode">df -h</span>로 디스크를 주기적으로
          확인하는 습관이 여러분을 구합니다.
        </div>
      </Section>

      <Section n={7} title="우리 서버의 실전 운영 명령 모음" sub="1~6섹션 총출동 — 멘토의 어깨너머 미리 보기">
        <p>
          이제 배운 걸 전부 이어 붙일 시간이에요. 아래는 AWESOMEDEV의 서울 EC2 서버에서
          실제로 쓰는 운영 동선입니다. <strong>접속 → 건강검진 → 로그 → 배포 → 현관 확인 →
          백업 확인</strong> — 어느 회사를 가도 이 뼈대는 같아요.
        </p>
        <Code>{CODE_OPS}</Code>
        <ol className="olist">
          <li><strong>ssh</strong> — 열쇠 파일(.pem)로 서버에 들어가요. 비밀번호보다 안전한 방식이에요.</li>
          <li><strong>df·free·docker ps</strong> — 디스크·메모리·컨테이너, 건강검진 3종 세트.</li>
          <li><strong>docker logs</strong> — "느려요/안 돼요" 신고가 오면 무조건 로그부터. (섹션 6)</li>
          <li><strong>git pull + compose up</strong> — Gitea의 최신 코드로 교체하는 우리 팀의 배포. (섹션 2의 스크립트가 이걸 묶은 것!)</li>
          <li><strong>systemctl·journalctl</strong> — Caddy 현관 점검. (섹션 5)</li>
          <li><strong>crontab -l + 백업 로그</strong> — 새벽의 자동 백업이 잘 돌았는지. (섹션 3)</li>
        </ol>
        <div className="tip">
          <b>직접 확인해 보기 ③</b> 실습 서버 계정을 받았다면 위 <strong>2번 건강검진 3종
          세트</strong>만 직접 쳐 보세요(읽기만 하는 안전한 명령들이에요). 디스크 사용률(Use%)이
          몇 %인지, 컨테이너가 몇 개 떠 있는지 수첩에 적어 멘토의 기록과 비교해 보기.
          아직 계정이 없다면 내 PC의 Git Bash에서 <span className="icode">docker ps</span>와{' '}
          <span className="icode">df -h</span>가 어떻게 나오는지 먼저 관찰!
        </div>
      </Section>

      <div className="step-card">
        <div className="step-body">
          <h3 style={{ marginBottom: 6 }}>🐧 여기까지 왔다면</h3>
          <p className="muted">
            이제 여러분은 환경변수로 설정을 주입하고, 스크립트와 크론으로 <strong>서버가 스스로
            일하게</strong> 만들고, 문제가 생기면 <strong>로그부터 여는</strong> 사람이 됐어요.
            명령어를 아는 것과 운영 감각이 있는 것의 차이가 바로 이것입니다. 다음은 이 서버 위에서
            돌아가는 데이터의 집 — <Link to="/learn/sql"><strong>데이터베이스 기초</strong></Link>
            코스로 이어 가거나, 멘토에게 <strong>"배포 스크립트 함께 읽기"</strong> 과제를 요청해
            오늘 배운 if·for·파이프를 실전 코드에서 찾아보세요.
          </p>
        </div>
      </div>
    </div>
  );
}
