All Posts54
- DOMMatrix is not defined: Next.js SSR 에러 하나 잡은 이야기
Next.js 프로젝트에 PDF 뷰어(react-pdf)를 붙였더니, 페이지를 열 때마다 콘솔에 이런 에러가 찍혔다. PDF 미리보기 화면을 아직 열지도 않았는데 왜 홈 화면만 들어가도 에러가 났을까. 원인을 따라가 보니 SSR(서버 사이드 렌더링)의…
- Next.js Server Function 에러 메시지가 프로덕션에서 사라지는 이유
개발 환경에서는 "이미 사용 중인 아이디입니다" 같은 에러 메시지가 잘 뜨는데,프로덕션에 배포하면 갑자기 이런 메시지로 바뀐 경험이 있을 것이다. An error occurred in the Server Components render.The spec…
- 서버가 호출하는 API와 브라우저가 호출하는 API는 다르다 : NEXTJS
Next.js로 개발하다 보면 이런 상황을 마주친다. 분명히 서버에서 API를 잘 호출하고 있는데, 같은 주소를 클라이언트 컴포넌트에서 쓰면 요청이 실패한다. 로컬에서는 둘 다 되던 코드가, 배포하고 나면 클라이언트 쪽만 망가진다. 이 글은 그 원인 …
- Next.js 캐싱의 기본값과 동적 렌더링 전환 조건
Next.js 공식 문서(Glossary)는 다음과 같이 명시한다. 즉, Request-time API를 사용하지 않는 컴포넌트는 기본적으로 빌드 시점에 HTML을 생성해 캐싱한다. dynamic 옵션의 기본값인 'auto'에 대한 설명도 같은 방향이…
- Next.js의 redirect() vs router.push() — nginx 리버스 프록시 + basePath 환경에서의 함정
Next.js App Router에서 로그인 후 대시보드로 이동시키는 코드를 작성할 때, 가장 먼저 떠오르는 방법은 Server Action에서 redirect()를 호출하는 것이다. 로컬에서는 잘 동작한다. 그런데 nginx 리버스 프록시 뒤에 배포…
- 방화벽 뚫지 않고 로컬 서버 공개하기 — Cloudflare Tunnel 실전 사용기
개발 서버에 22번 포트만 열려 있다면? 팀원들이 API를 테스트하려면 모두 SSH 터널링을 해야 할까요?Cloudflare Tunnel을 사용하면 인바운드 포트 개방 없이 외부에서 접근 가능한 공개 URL을 단 한 줄로 만들 수 있습니다. 개발 서버…
- Windows SSD 용량 부족 해결 — Docker vhdx, WSL 다른 드라이브로 이전하기
개발 환경에서 C: SSD 용량을 잡아먹는 주범은 대부분 Docker와 WSL의 가상 디스크 파일(.vhdx)이다. Docker vhdx 위치 확인 WSL vhdx 위치 확인 용량 확인: 심볼릭 링크를 활용해서 Docker가 원래 경로를 그대로 참조하…
- Ubuntu 서버에서 Docker / Laravel Sail 문제 해결 기록
Ubuntu 서버에서 Laravel Sail 실행이 안 되는 문제가 발생했습니다. 겉보기엔 다른 두 가지 문제였지만, 실제로는 Docker 환경이 꼬이면서 연쇄적으로 발생한 문제였습니다. 권한도 정상, 서비스도 정상인데 Docker 명령어가 모두 실패…
- Vue 개발자가 Next.js를 배우며 겪은 혼란: Server Component와 Client Component 이해하기
Vue와 Nuxt에 익숙한 개발자로서 Next.js를 처음 접했을 때, 가장 혼란스러웠던 부분은 "왜 데이터를 fetch 했는데 화면이 업데이트되지 않는가?"였습니다. Vue에서는 당연하게 작동하던 반응형 시스템이 Next.js에서는 전혀 다른 방식으…
- Dart 메서드 vs Getter: 언제 무엇을 사용해야 할까?
Flutter/Dart로 개발하다 보면 클래스의 속성에 접근하는 방법을 선택해야 할 때가 있습니다. 메서드로 구현할지, getter로 구현할지 고민되는 순간들이 있죠. 오늘은 이 둘의 차이와 올바른 선택 기준을 명확하게 정리해보겠습니다. 핵심 차이: …
- JavaScript 개발자가 Flutter의 copyWith를 이해하기까지
시작하며 Flutter를 배우면서 가장 궁금했던 것 중 하나가 바로 copyWith 패턴이었습니다. "JavaScript였으면 그냥 바꾸면 되는데..." 라는 생각이 들었습니다. 하지만 실제로 사용해보니 이 패턴이 왜 필요한지 이해하게 되었고, 오늘은…
- Git 경고 해결하기: CRLF와 LF, 그게 뭔데?
Windows 환경에서 Flutter 프로젝트를 만들고 Git에 커밋하려는 순간, 이런 경고 메시지를 본 적 있으신가요? 처음 보면 당황스럽지만, 사실 이 경고는 매우 흔한 상황입니다. 오늘은 CRLF와 LF가 무엇인지, 왜 이런 경고가 뜨는지, 그리…
- Laravel 운영 서버에서 env() 함수가 null을 반환하는 이유
Laravel 프로젝트를 운영 서버에 배포한 후, 이상한 현상을 경험했습니다. 분명 .env 파일에 FILESERVER_HOST 값이 설정되어 있는데, 화면에서는 빈 문자열이 출력되었습니다. 더 이상한 건 DB 연결은 정상적으로 작동한다는 점이었죠.t…
- MySQL 타임존 SYSTEM 설정과 UTC 저장 문제 해결하기
MySQL 쓰다 보면 SELECT @@global.time_zone, @@session.time_zone; 결과가 SYSTEM으로 나오는데, 막상 DB에 저장된 TIMESTAMP 값을 보면 UTC 기준으로 들어가 있는 당황스러운 상황, 겪어보셨나요? …
- JavaScript this 바인딩 이해하기
JavaScript에서 this는 함수가 어떻게 호출되느냐에 따라 결정됩니다. 함수를 작성할 때가 아니라, 실행될 때 결정된다는 게 핵심입니다. 함수를 그냥 호출하면 this는 undefined가 됩니다 (strict mode/모듈 환경). 객체의 메…
- JavaScript 이벤트 루프: Task Queue vs Microtask Queue
JavaScript는 싱글 스레드 언어입니다. 그런데 어떻게 비동기 작업을 처리할 수 있을까요? **이벤트 루프(Event Loop)**를 사용할 수 있습니다. 이벤트 루프는 JavaScript 엔진이 비동기 작업을 처리하는 메커니즘입니다. 코드 실행…
- TypeScript 인터페이스 확장: Declaration Merging과 Module Augmentation
Next.js에서 NextAuth를 사용하여 인증 시스템을 구축하던 중, 다음과 같은 TypeScript 에러를 만났습니다. session.user에 id 속성을 추가하려고 했지만, TypeScript는 이 속성이 존재하지 않는다고 불평합니다. Nex…
- Prisma로 Next.js 블로그 만들기: 데이터베이스 설정부터 마이그레이션까지
PostgreSQL과 Next.js로 블로그를 만들면서 Prisma ORM을 처음 도입하게 되었습니다. MySQL을 주로 사용하던 입장에서 새로운 도구를 배우는 과정에서 겪은 시행착오와 해결 방법을 공유합니다. Prisma는 Node.js와 TypeS…
- Sequelize vs Prisma: Node.js ORM 비교 분석
Node.js 생태계에서 가장 많이 사용되는 두 ORM인 Sequelize와 Prisma를 비교합니다. 두 도구는 근본적으로 다른 철학과 접근 방식을 가지고 있습니다. Sequelize는 Laravel의 Eloquent처럼 모델 클래스를 직접 작성하는…
- SSH 키 인증으로 비밀번호 없이 안전하게 서버 접속하기
서버 간 자동화 작업을 하다 보면 가장 먼저 마주치는 문제가 있습니다. "스크립트에 비밀번호를 넣어야 하나?" 답은 **"절대 아니요"**입니다. SSH 키 기반 인증을 사용하면 비밀번호 노출 없이 안전하게 자동화할 수 있습니다. 설정도 단 1분이면 …
- Let's Encrypt 인증서 자동 갱신 완벽 가이드
Let's Encrypt 인증서는 90일마다 만료되기 때문에 자동 갱신 설정이 필수입니다. 다행히 Ubuntu/Debian에서 certbot을 apt로 설치하면 자동 갱신이 패키지에 포함되어 있습니다. 이 명령어 하나로 다음이 자동으로 설치되고 활성화…
- nginx SSL 설정 중 만난 DNS 캐시 트러블슈팅
여러 도메인(example.com, example.kr, example.net)을 운영하는 nginx 서버에 SSL을 적용하던 중, 한 가지 이상한 현상을 발견했습니다. example.net만 유독 Apache 서버를 반환하고 있었습니다. 브라우저에서…
- apt autoremove란? 리눅스 패키지 관리의 숨은 조력자
리눅스에서 패키지를 제거할 때 이런 명령어를 본 적 있으신가요? 왜 remove 다음에 autoremove를 또 실행할까요? 이 두 명령어의 차이를 알아보겠습니다. 리눅스에서 프로그램을 설치할 때는 그 프로그램 하나만 설치되는 게 아닙니다. 프로그램이…
- MySQL vs PostgreSQL 차이점 비교 - 프로젝트에 맞는 DB 선택 기준
오늘은 두 데이터베이스의 차이점을 실제 사용 경험을 바탕으로 상세히 비교해보겠습니다! 특징 MySQL PostgreSQL MySQL은 일반적으로 필요한 데이터 타입들을 제공합니다. PostgreSQL은 훨씬 더 다양한 데이터 타입을 제공합니다. 실제 …
- 🔐 GitHub SSH 인증 설정하기 - 비밀번호 없이 Git 사용하는 방법
터미널에서 기존 SSH 키가 있는지 먼저 확인해보세요. id_rsa, id_ed25519 등의 파일이 있다면 이미 SSH 키가 존재합니다. 기존 키가 없거나 새로 만들고 싶다면 다음 명령어를 실행하세요. 💡 팁: your_email@example.c…
- Laravel Queue Worker 완벽 가이드: 비동기 작업 처리의 핵심
웹 애플리케이션을 개발하다 보면 시간이 오래 걸리는 작업들을 만나게 됩니다. 이메일 발송, 이미지 처리, 데이터 분석, 외부 API 호출 등이 대표적인 예시죠. 이런 작업들을 동기적으로 처리하면 사용자는 오랫동안 기다려야 하고, 최악의 경우 브라우저 …
- Vue3 Carousel에서 화면 줄어들 때 이전 슬라이드가 겹쳐 보이는 문제 해결하기
프로젝트에서 Vue3 Carousel을 사용하다 보면, 해상도가 작아지거나 브라우저 창 크기를 줄였을 때 이전/다음 슬라이드가 화면에 겹쳐서 보이는 문제가 발생할 수 있습니다. 처음에는 캐러셀 자체 버그인가 싶었는데, 원인은 뷰포트 영역이 슬라이드 밖…
- Vue + Tailwind에서 반응형 메뉴 구현 시 흔히 겪는 문제와 해결법
웹사이트에서 상단 메뉴를 구현할 때, PC에서는 hover로 메뉴가 열리고, 모바일에서는 클릭으로 메뉴가 열리는 방식을 자주 사용합니다. Vue 3 + <script setup> + TailwindCSS 환경에서 반응형 디자인이 아닌 PC와 동일한 디…
- Capacitor에서 앱 아이콘과 스플래시 이미지 자동 생성하기
앱을 배포하려면 각 플랫폼(Android/iOS)에서 요구하는 다양한 해상도의 아이콘과 스플래시 이미지를 준비해야 합니다. 수십 개의 리소스를 직접 만드는 건 너무 번거롭죠. Capacitor는 @capacitor/assets 패키지를 통해 아이콘과 …
- 📱 Framework7로 만든 앱을 Android APK로 패키징하는 방법
Framework7은 Vue, React, Svelte 등과 통합해서 사용할 수 있는 강력한 모바일 UI 프레임워크입니다. 이번 글에서는 Framework7 + Vue + Vite 조합으로 만든 프로젝트를 Android에서 실행 가능한 APK 파일로 …
- 모바일에서도 PC처럼 보이게 만드는 웹사이트 뷰포트 설정 방법
요즘 대부분의 웹사이트는 반응형 웹을 채택하고 있어, 화면 크기에 따라 레이아웃이 자동으로 조정됩니다. 하지만 경우에 따라서는 모바일에서도 PC와 동일한 고정 해상도로 보여주고 싶을 때가 있습니다. 예를 들어, 이 글에서는 HTML, CSS, 그리고 …
- Git Checkout 충돌 해결: 유실을 감수하는 방법 vs 안전한 방법
Git을 사용하시다 보면 브랜치를 전환하려 할 때, 아래와 같은 에러 메시지를 마주하실 수 있습니다: 이 메시지는 로컬에서 수정한 파일이 전환하려는 브랜치에서도 변경되어 있어서, Git이 해당 파일의 변경사항을 잃지 않도록 막고 있다는 의미입니다. 하…
- 😲 “((” 이게 다르다고? — 괄호의 숨겨진 정체
어느 날, ((와 같은 괄호가 텍스트 치환이 안 되는 이상한 상황을 마주했습니다. 분명 코드에서는 "("를 잘 인식하고 있었는데, 현실에서는 작동하지 않더군요. 왜 그럴까요? 우리가 흔히 쓰는 괄호 (와 )는 키보드에서 쉽게 입력할 수 있습니다. 그런…
- 🚫 Nginx 413 Request Entity Too Large 오류 해결 방법
웹 서버에서 파일 업로드 또는 대용량 데이터를 전송하려 할 때, 아래와 같은 오류를 마주한 적 있으신가요? 이는 클라이언트가 서버로 보낸 요청 본문(request body)의 크기가 Nginx가 허용하는 최대 크기를 초과했을 때 발생하는 오류입니다. …
- Laravel 외래 키 삭제 처리 – onDelete() 옵션 정리
Laravel에서 테이블 간 외래 키(foreign key)를 설정할 때, 부모 테이블의 데이터가 삭제되면 자식 테이블에 어떤 영향을 줄지 설정할 수 있습니다. 이때 사용하는 메서드가 바로 onDelete()입니다. 이 글에서는 Laravel 마이그레…
- Laravel Sail + Nginx 리버스 프록시 환경에서 Mixed Content 오류 해결기
Laravel을 Docker 기반의 Sail로 운영하고, Nginx를 호스트 서버(Ubuntu)에 리버스 프록시로 구성해 SSL을 적용했는데도, 브라우저에서 Mixed Content: HTTP 리소스를 요청했기 때문에 차단됨이라는 경고를 받았습니다. …
- [SSH] 접속 오류 해결: “REMOTE HOST IDENTIFICATION HAS CHANGED!” 메시지가 떴을 때
서버에 SSH 접속을 시도했는데 아래처럼 무시무시한 경고 메시지를 본 적 있으신가요? 처음 보는 분들은 해킹인가? 싶은 생각이 드실 수도 있습니다. 이 글에서는 이 경고 메시지가 왜 뜨는지, 실제로 위험한 상황인지, 그리고 어떻게 해결하면 되는지를 정…
- MySQL에서 특수문자(①~⑩) 검색 및 제거하는 방법 (버전별 정리)
데이터베이스를 사용하다 보면 데이터 정제가 필요한 경우가 자주 발생합니다. 특히 사용자 입력값이나 외부 데이터에 ①②③④⑤⑥⑦⑧⑨⑩ 같은 불필요한 특수문자가 포함되어 있을 수 있습니다. 이런 특수문자를 검색하고 제거하는 방법을 MySQL 8.0 이상 …
- Git에서 'Permission denied' 오류 해결 방법
우선, 문제가 발생한 파일의 소유권과 권한을 확인해야 합니다. 결과를 확인했을 때, 파일 소유자가 현재 로그인한 사용자와 다르다면 소유권을 변경해야 합니다. 또는 Git 폴더 전체에 쓰기 권한을 부여하는 방법도 있습니다. Linux 또는 macOS의 …
- Fail2Ban으로 리눅스 서버 보안 강화하기
Fail2Ban은 리눅스 서버 보안을 강화하는 침입 방지 도구입니다. 특정 패턴(예: 로그인 실패, 404 에러, 악성 봇 탐색 등)이 감지되면 자동으로 IP를 차단하는 기능을 제공합니다. 보통 SSH, Nginx, Apache, FTP, Postfi…
- Laravel에서 Custom Role Middleware 만들기
Laravel에서 사용자 권한(Role)에 따라 접근을 제한하려면 기본적인 인증 미들웨어 외에 추가적인 Role 미들웨어를 구현해야 합니다. 이번 글에서는 Custom Role Middleware를 생성하고 적용하는 방법을 단계별로 설명하겠습니다. 먼…
- 윈도우에서 하위 폴더 파일 일괄 이름 변경하는 방법
윈도우 탐색기에서 하위 폴더에 있는 파일의 이름을 일괄적으로 변경하는 것은 종종 필요한 작업입니다. 기본적으로 윈도우 탐색기에서는 이 기능을 지원하지 않지만, PowerShell을 이용하면 매우 쉽게 수행할 수 있습니다. 오늘은 PowerShell을 …
- Flask 포트 변경 방법 - VSCode launch.json 설정 완전 정리
Flask는 Python으로 웹 서버를 빠르게 구성할 수 있는 강력한 프레임워크입니다. VSCode(Visual Studio Code)와 함께 Flask 애플리케이션을 디버깅할 때, 서버가 실행되는 포트를 원하는 대로 설정하는 것이 중요합니다. 이 글…
- Laravel에서 increment() 메서드 사용 시 즉시 업데이트되지 않는 문제 해결하기
Laravel 개발자들이 자주 마주치는 문제 중 하나는 increment() 메서드를 사용했을 때 값이 즉시 업데이트되지 않는 현상입니다. 이번 포스트에서는 이 문제의 원인과 해결 방법에 대해 알아보겠습니다. increment() 메서드를 사용했는데 …
- Laravel에서 데이터 정렬하기: orderBy 메소드 활용하기
웹 애플리케이션을 개발할 때, 데이터베이스에서 원하는 정보를 효율적으로 정렬하는 것은 매우 중요합니다. Laravel은 직관적인 Eloquent ORM(Object-Relational Mapping)을 사용하여 데이터베이스 작업을 단순화해줍니다. 이번…
- Vue 3 컴포넌트 간 데이터 전달 방법 총정리 (props, emit, Pinia)
Vue 3는 컴포넌트 간 통신을 위한 다양한 방법을 제공합니다. 오늘은 부모 컴포넌트와 자식 컴포넌트 사이에서 데이터 변동을 감지하는 주요 방법들에 대해 알아보겠습니다. 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하고, 자식에서 부모로 이벤트를 전…
- 특정 버전의 Composer 설치
관리중인 시스템 중 php 기반의 laravel 5.x 를 사용하고 있는 시스템이 있습니다. 오래된 버전이다보니, php 버전도 낮은데요! php 버전이 낮으면 composer 2.x 버전에서는 install이 되지 않는 문제가 발생합니다. 그래서 c…
- 라라벨에서 커스텀 helper 등록하기
Laravel에서 커스텀 헬퍼를 등록하는 방법은 다음과 같습니다. 헬퍼는 자주 사용하는 기능을 간편하게 사용할 수 있도록 도와주는 유틸리티 함수입니다. 먼저, 헬퍼 파일을 생성합니다. Laravel의 app 디렉터리 안에 Helpers라는 디렉터리를 …
- Laravel의 whereJsonContains 메서드: JSON 데이터 필터링의 강력한 도구
Laravel은 PHP 프레임워크 중 하나로, 웹 애플리케이션 개발을 더 쉽게 만들어주는 다양한 기능을 제공합니다. 그중 하나가 whereJsonContains 메서드로, JSON 필드에서 특정 값을 필터링하는 데 유용하게 사용됩니다. 이 글에서는 w…
- Swift 기본 문법과 데이터 타입
스위프트(Swift)는 애플(Apple)에서 개발한 새로운 프로그래밍 언어로, iOS, macOS, watchOS, tvOS 등 다양한 애플 플랫폼에서 개발을 위해 사용됩니다. 이번 글에서는 스위프트의 기본 문법과 데이터 타입에 대해 예제를 통해 알아…
- 라라벨 Sail 설정 가이드
라라벨 Sail은 라라벨 프레임워크를 사용하여 웹 애플리케이션 개발을 위한 도구입니다. Sail은 Docker를 기반으로 동작하며, 컨테이너 기술을 사용하여 개발 환경을 구성합니다. 이를 통해 개발자는 별도의 환경 설정 없이 라라벨 프로젝트를 빠르게 …
- [apache2] SPA(Single Page Application) 새로고침 시 404 error
vue 와 같은 spa는 server side application과 달리 이름 그대로 "단일" 페이지를 로드한다. 즉, index.html에 대해서만 인식하고 있다는 의미. 서버는 클라이언트의 js를 브라우저에 전달하기 위해서만 존재하고 있다.. 그…
- [AWS-EC2] ufw 활성화 후 connection time out 문제
방화벽 특정포트 활성화 후 포트가 안열리기에 ufw를 활성화하는 삽질을 해서 멀쩡히 잘되던 ssh가 안되는 문제 발생 ec2 서버 중지 후 작업 > 인스턴스 설정 > 사용자 데이터 편집 으로 들어가서 아래와 같이 ufw를 비활성화 해준다. https:…
- [Laravel] log permission denied
laravel server 운용중 아래와 같은 에러 발생 로그 파일을 write 할 권한이 없다는 오류. 원인은 라라벨 스케쥴러를 crontab 으로 등록할 때 root user로 등록해서, root user가 생성한 log 파일을 서버 실행 유저 (…