turin's blog
만들고, 터지고,
기록합니다
풀스택, Flutter, 서버 운영, SEO, 배포 삽질을 실제 프로젝트 기준으로 정리합니다. 검색해서 들어온 사람이 바로 쓸 수 있는 체크리스트와 명령을 남기는 게 목표입니다.
자주 다루는 주제
주제별로 빠르게 훑어보기
전체 글
운영 중 부딪힌 문제를 검색 의도에 맞춰 정리
cron 작업 시간이 9시간 어긋나는 이유
cron은 서버 시스템 timezone을 그대로 따르기 때문에, UTC로 세팅된 서버에서 한국 시각 기준으로 스케줄링하면 반드시 어긋난다.
저장 버튼을 두 번 누르지 못하게 막는 가장 간단한 방법
폼 제출 중에 버튼을 비활성화하는 것만으로 중복 요청을 막을 수 있다. isSubmitting 상태 하나면 충분하다.
계속 읽기 →Next.js에서 한글 slug를 쓸 때 URL 복사가 깨지는 이유
한글 slug는 브라우저 주소창에서는 읽기 편하지만, 복사하면 퍼센트 인코딩된 긴 문자열이 된다. canonical URL도 같은 문제가 생긴다.
계속 읽기 →Docker Compose 서비스 이름을 명확하게 짓는 이유
Compose 서비스 이름은 컨테이너 간 호스트명이 된다. 이름이 모호하면 같은 compose 파일 안에서도 연결이 헷갈린다.
계속 읽기 →Prisma schema를 수정한 뒤 빠뜨리기 쉬운 단계들
schema.prisma를 고치고 나서 validate → migrate → generate 순서를 지키지 않으면 런타임에서 예상 못한 에러가 난다.
계속 읽기 →GitHub Actions 실패 로그를 읽는 순서
Actions 워크플로가 실패하면 웹 UI보다 gh CLI로 보는 게 빠르다. 어느 step에서 어떤 출력이 나왔는지 한 번에 확인할 수 있다.
계속 읽기 →블로그 글 목록에 날짜를 넣기로 한 이유
날짜 하나가 글 목록에 주는 정보량은 생각보다 크다. 언제 쓴 글인지 알면 읽을지 말지 판단이 빨라진다.
계속 읽기 →API 응답 필드명을 프론트 기준으로 맞추면 달라지는 것
백엔드 DB 컬럼명을 그대로 내려보내는 대신 프론트가 쓰기 편한 이름으로 설계하면 변환 코드가 사라진다.
계속 읽기 →TypeScript 타입 에러를 any로 덮지 않는 습관
타입 에러가 나면 any로 조용히 덮고 싶은 충동이 생기지만, 그 자리에 정확한 타입을 넣는 게 결국 더 빠르다.
계속 읽기 →git stash에 메시지를 붙여야 하는 이유
메시지 없는 stash는 나중에 꺼낼 때 뭔지 알 수 없다. 짧은 메모 하나가 복구 시간을 크게 줄여준다.
계속 읽기 →개인 서버를 업데이트하기 전에 확인하는 것들
apt upgrade 전에 디스크, 실행 중인 프로세스, 최근 로그를 먼저 훑으면 업데이트 후 문제가 생겼을 때 원인을 훨씬 빠르게 잡을 수 있다.
계속 읽기 →Nginx 설정을 고치기 전에 백업 파일을 남기는 이유
nginx.conf나 sites-available 파일을 수정하기 전에 백업을 남기면, 실수했을 때 복원까지 30초면 끝난다.
계속 읽기 →Docker 로그의 마지막 줄만 보면 놓치는 것들
컨테이너가 재시작 루프에 빠졌을 때 최신 로그만 보면 원인을 찾기 어렵다. 로그를 어떻게 읽어야 하는지 정리했다.
계속 읽기 →React 컴포넌트 이름을 대충 지으면 생기는 일
Button, Card, Modal처럼 범용적인 이름은 나중에 뭘 수정해야 하는지 찾기 어렵게 만든다. 이름 하나가 유지보수 속도를 바꾼다.
계속 읽기 →Next.js App Router에서 페이지별 title을 관리하는 방법
App Router의 Metadata API를 써서 전체 사이트 타이틀 템플릿과 페이지별 타이틀을 깔끔하게 분리한 방법을 정리했다.
계속 읽기 →작은 프로젝트에서 테스트를 어디까지 짜야 하는가
혼자 만드는 프로젝트에서 테스트 커버리지 100%는 현실적이지 않다. 어디에 먼저 써야 효과가 있는지 기준을 잡은 방법을 정리했다.
계속 읽기 →Markdown 코드 블럭이 깨졌을 때 배운 것
블로그 글의 코드 블럭이 배포 환경에서만 이상하게 렌더링됐다. 원인은 remark 플러그인 순서였다.
계속 읽기 →관리자 페이지와 공개 페이지를 처음부터 분리한 이유
같은 Next.js 앱 안에 관리자 라우트를 넣었다가 인증 미들웨어가 꼬이는 걸 겪고 나서, 아예 라우트 구조를 나눴다.
계속 읽기 →Docker Compose의 env_file과 environment, 뭐가 다른가
두 방식 모두 컨테이너에 환경 변수를 주입하지만 우선순위와 보안 동작이 다르다. 혼용할 때 어떤 값이 이기는지 정리했다.
계속 읽기 →배포 직후에 내가 꼭 확인하는 것들
빌드 성공이 곧 배포 성공은 아니다. 배포 후 5분 안에 체크하는 내 루틴을 정리했다.
계속 읽기 →TypeScript 타입을 과하게 만들었을 때 겪은 것들
조건부 타입과 mapped type을 남발했다가 빌드 시간이 늘고 팀원 코드 읽기도 힘들어진 경험을 정리했다.
계속 읽기 →개인 도메인을 바꿀 때 SEO에서 놓치기 쉬운 것들
도메인을 이전하면 기술적인 301 리다이렉트 외에도 검색 엔진 입장에서 꼼꼼히 챙겨야 할 것들이 생각보다 많다.
계속 읽기 →Nginx access 로그로 요청이 실제로 오는지 확인하는 방법
배포 후 응답이 이상하거나 트래픽이 예상대로 오는지 모를 때 Nginx access 로그를 실시간으로 보면 빠르게 파악할 수 있다.
계속 읽기 →loading 상태를 대충 구현하면 생기는 UX 문제들
스피너 하나 올려두는 게 전부라고 생각했다가, 버튼 중복 클릭과 레이아웃 시프트로 사용자 불만이 쌓였다.
계속 읽기 →