Next.js 블로그 자동 배포에서 환경변수 실패를 막는 운영 기준
Futory의 Next.js Markdown 블로그 자동 게시 흐름을 기준으로 빌드 시점 환경변수, 선택 기능, PM2 재시작 환경을 안전하게 관리하는 방법을 정리했습니다.
요약
AI와 함께 Next.js 블로그를 운영하면 새 글 작성부터 검증, 빌드, 배포까지 빠르게 자동화할 수 있습니다. 하지만 자동화가 안정적으로 돌아가려면 콘텐츠 품질만큼 환경변수 관리도 중요합니다. Futory는 Markdown 글을 content/posts/*.md에 추가하고, npm run test:theme, npm run test:content, npm run build를 통과한 뒤 호스트의 /opt/wordblog로 동기화하고 PM2/Nginx를 통해 공개합니다. 이 흐름에서 환경변수 하나가 잘못되면 글은 멀쩡한데 빌드나 런타임이 실패할 수 있습니다.
특히 Next.js는 빌드 시점과 서버 실행 시점이 분리됩니다. 어떤 값은 npm run build 중에 필요하고, 어떤 값은 PM2로 실행된 서버가 요청을 처리할 때만 필요합니다. AI가 기능을 빠르게 추가하다 보면 선택 기능에 필요한 API 키를 최상단에서 바로 읽거나, 없는 환경변수를 import 시점에 throw 하도록 만들 수 있습니다. 그러면 실제로는 사용하지 않는 기능 때문에 전체 블로그 빌드가 막히는 일이 생깁니다.
이 글은 Futory 운영 맥락에서 환경변수 실패를 어떻게 예방하고, 어떤 검증 문장을 자동 배포 루틴에 넣어야 하는지 정리합니다. 목표는 “비밀값을 잘 넣자”가 아니라, 선택 기능의 실패가 블로그 전체 게시 실패로 번지지 않게 만드는 것입니다.
빌드 시점과 실행 시점을 분리해야 한다
Next.js 블로그 운영에서 먼저 구분할 것은 빌드 시점 환경과 실행 시점 환경입니다. 빌드 시점은 npm run build가 페이지, 라우트, 정적 자산을 만들 때입니다. 실행 시점은 PM2가 next start를 통해 내부 포트 127.0.0.1:8042에서 요청을 처리할 때입니다. 두 시점 모두 같은 .env를 참조할 수 있지만, 실패가 발생하는 위치와 복구 방법은 다릅니다.
예를 들어 Markdown 글 목록을 읽는 기능은 빌드 중에 필요합니다. frontmatter 형식이 잘못되면 npm run test:content나 빌드가 실패하는 것이 맞습니다. 반대로 외부 AI API를 호출하는 선택 기능이 있다면, 블로그의 모든 페이지를 빌드하는 순간에 반드시 클라이언트를 생성할 필요는 없습니다. 해당 기능을 호출하는 라우트에서만 환경변수를 검사하고, 값이 없으면 명확한 503 응답이나 안내 메시지를 주는 편이 운영에 안전합니다.
Futory의 자동 게시 루틴은 매일 글 하나를 추가하는 흐름입니다. 이 작업의 핵심 성공 조건은 새 글이 검증을 통과하고 공개 도메인에서 보이는 것입니다. 선택 기능의 API 키 누락이 이 핵심 흐름을 막는 구조라면, 기능 설계를 다시 봐야 합니다. 자동화에서는 작은 의존성이 전체 파이프라인의 병목이 되기 쉽기 때문입니다.
환경변수 실패가 자동 게시를 막는 대표 상황
import 시점에 바로 실패하는 코드
가장 흔한 문제는 모듈 최상단에서 환경변수를 읽고, 없으면 즉시 예외를 던지는 코드입니다. 이 방식은 개발 중에는 빠르게 문제를 발견하게 해주지만, 자동 배포에서는 위험할 수 있습니다. Next.js 빌드는 여러 페이지와 라우트를 분석하면서 모듈을 불러오기 때문에, 실제 요청이 없어도 import만으로 실패할 수 있습니다.
운영 기준은 간단합니다. 블로그 전체에 필수인 값만 빌드 시점에 강하게 검사하고, 선택 기능의 값은 해당 기능이 실행될 때 검사합니다. 예를 들어 관리자용 요약 생성, 외부 검색 제출, 실험용 AI 기능 같은 것은 글 목록과 상세 페이지 렌더링을 막지 않아야 합니다.
PM2가 이전 환경을 들고 있는 경우
두 번째 문제는 PM2가 오래된 환경을 유지하는 경우입니다. .env를 수정했거나 호스트 환경변수를 바꿨는데 단순 재시작만으로 반영되지 않는 상황이 생길 수 있습니다. 그래서 Futory 배포에서는 호스트 빌드가 성공한 뒤 pm2 restart futory-wordblog --update-env를 사용합니다. 환경이 크게 바뀐 경우에는 프로세스를 삭제하고 다시 시작하는 방식까지 고려해야 합니다.
여기서 중요한 점은 빌드 성공과 런타임 성공을 따로 확인하는 것입니다. npm run build가 통과해도 PM2 프로세스가 새 환경으로 떠 있지 않으면 공개 페이지 요청에서 문제가 생길 수 있습니다. 반대로 PM2가 정상이어도 빌드 산출물이 오래되었다면 새 글이 보이지 않을 수 있습니다.
스테이징과 호스트 환경이 다른 경우
Futory는 스테이징 경로 /opt/data/wordblog_next_staging에서 먼저 검증하고, 호스트 라이브 경로 /opt/wordblog로 동기화합니다. 이때 .env, node_modules, .next는 보존하거나 제외해야 합니다. 스테이징에서 빌드가 성공했다고 해서 호스트 빌드도 자동으로 성공한다고 가정하면 안 됩니다. 호스트에는 실제 서비스 환경이 있고, PM2와 Nginx가 연결되어 있기 때문입니다.
그래서 배포 절차는 스테이징 검증 한 번으로 끝나지 않습니다. 호스트에서도 npm run test:theme, npm run test:content, npm run build를 다시 실행해야 합니다. 같은 명령을 반복하는 것이 비효율적으로 보일 수 있지만, 환경 차이를 발견하는 가장 직접적인 방법입니다.
AI에게 맡길 때 필요한 환경변수 운영 문장
AI 자동화에 환경변수 기준을 넣을 때는 추상적인 지시보다 실행 가능한 문장이 좋습니다. Futory에서는 다음 기준을 사용할 수 있습니다.
1. 새 글 배포 작업에서 기존 .env를 덮어쓰지 않는다.
2. 선택 기능의 API 키가 없다는 이유로 블로그 전체 빌드가 실패하지 않게 한다.
3. 필수 환경변수와 선택 환경변수를 코드 구조에서 분리한다.
4. 호스트 동기화 후에도 테스트와 빌드를 다시 실행한다.
5. .env 변경이 있었다면 PM2 재시작에 --update-env를 붙이고, 공개 URL로 실제 응답을 확인한다.
이 문장은 자동화의 안전장치입니다. AI는 새 기능을 만들 때 “빠르게 동작하는 코드”에 집중할 수 있지만, 운영자는 “없어도 되는 값 때문에 전체 서비스가 멈추지 않는 구조”를 요구해야 합니다. 특히 매일 자동 게시되는 블로그에서는 실패 원인이 콘텐츠인지, 빌드인지, 환경인지 빨리 분리할 수 있어야 합니다.
Futory 배포 루틴에 넣을 확인 순서
환경변수 관리는 별도 문서로만 남기면 잊히기 쉽습니다. 자동 게시 루틴 안에 확인 순서로 들어가야 합니다. 먼저 스테이징에서 새 글만 추가되었는지 확인합니다. 기존 다크/라이트 모드 기능인 components/ThemeToggle.tsx, app/theme-init.tsx, CSS의 data-theme 변수는 유지되어야 하며, npm run test:theme가 그 기준을 잡아줍니다.
그다음 npm run test:content로 frontmatter, 카테고리, 태그, FAQ, 분량 같은 콘텐츠 조건을 확인합니다. 여기까지 통과하면 npm run build를 실행합니다. 만약 빌드가 환경변수 때문에 실패한다면 곧바로 값을 새로 만들기보다 먼저 그 값이 정말 블로그 전체 빌드에 필수인지 판단해야 합니다. 선택 기능이라면 코드가 lazy runtime 검사로 바뀌어야 합니다.
호스트 동기화 후에는 같은 검증을 반복하고 PM2를 재시작합니다. 마지막으로 https://futory.oig.kr의 새 글 URL과 /posts 목록을 확인합니다. 공개 HTML에 오늘 날짜와 새 제목이 보이면 환경, 빌드, 런타임, 프록시가 함께 통과한 것으로 볼 수 있습니다.
자주 묻는 질문
모든 환경변수를 빌드 전에 강제로 검사하면 더 안전하지 않나요?
필수 값이라면 도움이 됩니다. 하지만 선택 기능의 값까지 빌드 전에 강제하면 사용하지 않는 기능 때문에 전체 블로그 게시가 실패할 수 있습니다. 블로그 렌더링에 필수인 값과 특정 API 요청에만 필요한 값을 분리하는 것이 더 안전합니다.
.env를 스테이징에서 라이브로 같이 복사하면 간단하지 않나요?
간단해 보이지만 위험합니다. 라이브 .env에는 실제 운영 값이 있고, 스테이징 값으로 덮어쓰면 서비스가 다른 데이터나 잘못된 설정을 사용할 수 있습니다. Futory 배포에서는 .env를 보존하고, 필요한 변경은 별도 의사결정과 검증을 거쳐 반영하는 편이 안전합니다.
PM2 재시작만 하면 환경변수가 항상 반영되나요?
항상 그렇지는 않습니다. 그래서 pm2 restart futory-wordblog --update-env를 사용하고, 변경 폭이 크면 프로세스를 재생성하는 방법도 고려합니다. 중요한 것은 명령 실행 자체보다 공개 URL과 실제 기능 요청으로 새 환경이 반영되었는지 확인하는 것입니다.
AI가 환경변수 문제를 자동으로 고칠 수 있나요?
일부는 가능합니다. 빌드 로그를 보고 import 시점 실패인지, .env 누락인지, PM2 환경 반영 문제인지 분리할 수 있습니다. 다만 비밀값을 새로 생성하거나 외부 서비스 키를 발급하는 일은 운영자의 결정이 필요합니다. AI는 안전한 구조로 코드를 바꾸고, 필요한 값이 무엇인지 명확히 보고하는 역할을 맡는 것이 좋습니다.
결론
자동 게시의 성공은 글을 쓰는 능력만으로 결정되지 않습니다. Next.js Markdown 블로그에서는 콘텐츠 검증, 테마 보존, 빌드, 호스트 동기화, PM2 재시작, 공개 URL 확인이 모두 이어져야 합니다. 이 중 환경변수는 눈에 잘 보이지 않지만, 실패하면 전체 흐름을 멈추게 만드는 중요한 운영 요소입니다.
Futory처럼 AI와 함께 만들고, 자동화하고, 운영하는 블로그라면 환경변수를 필수 값과 선택 값으로 나누고, 선택 기능의 누락이 전체 빌드를 막지 않게 설계해야 합니다. 또한 스테이징과 호스트에서 같은 검증을 반복하고, PM2 환경 반영과 공개 응답까지 확인해야 합니다. 이런 기준이 쌓이면 매일의 자동 게시가 단순한 글 발행을 넘어 안정적인 운영 실험으로 발전합니다.