Vercel이 이제 Dockerfile만 있으면 어떤 HTTP 서버든 바로 실행할 수 있게 됐다. Rails, Django, Spring Boot, Go 앱을 그대로 가져오면 Vercel이 빌드부터 배포, 자동 스케일링까지 처리하며, Fluid compute 환경에서 Active CPU 요금제로 운영된다.
컨테이너 안에 서버가 있다. Go 서비스일 수도, Rails 앱이나 Spring Boot API, 또는 nginx 뒤에서 동작하는 웹 서버일 수도 있다. HTTP로 통신하고, 특정 포트를 리슨한다. 실행할 공간만 있으면 된다.
프로젝트에 Dockerfile.vercel 파일 하나만 추가하면, Vercel이 이미지를 빌드하고 저장하며 Fluid compute 위에 배포와 자동 스케일링까지 처리한다. 실제로 코드가 사용한 CPU에 대해서만 비용을 낸다. 로컬에서 데몬을 띄우거나 레지스트리를 구성하거나 클러스터를 관리할 필요가 없다.
$PORT 포트를 리슨하는 간단한 Go HTTP 서버 예시다:
이 서버를 경량 이미지로 빌드하고 실행하는 Dockerfile.vercel 파일을 추가한다:
이제 배포한다:
파일 두 개, 이게 전부다. 이것만으로 바로 라이브 상태가 된다. git push 할 때마다 이미지가 새로 빌드되고 새로운 프리뷰 URL이 생성된다. 커밋 없이 배포하려면 vercel를 실행하면 된다.
예시에서는 Go를 사용했지만, 어떤 스택이든 동일하게 작동한다. Rails, Spring Boot, Express, Laravel, ASP.NET, FastAPI, nginx 기반 웹 서버 모두 같은 방식으로 배포된다. 유일한 조건은 서버가 $PORT 환경 변수로 지정된 포트(기본값: 80)를 리슨해야 한다는 것이다. HTTP로 통신한다면 배포할 수 있다. Java도, PHP도 예외가 없다.
Vercel에서 컨테이너는 일급 객체다. 프론트엔드나 다른 Vercel 서비스와 동일한 플랫폼, 동일한 컴퓨팅 환경에서 실행된다.
푸시마다 프리뷰 배포: 커밋마다 고유한 불변 URL이 생성되어 직접 열어보거나, 공유하거나, 해당 시점으로 롤백할 수 있다.
양방향 자동 스케일링: 트래픽이 몰리면 스케일 아웃, 트래픽이 줄면 인스턴스가 자동으로 축소된다. 서버 대수를 미리 정하거나 동시성 수치를 예측할 필요가 없다.
Active CPU 요금제: Fluid compute는 코드가 실제로 실행된 시간만 청구한다. 느린 쿼리나 외부 API 응답을 기다리며 대기 중인 서버는 CPU를 소모하지 않는다. 경과 시간이 아닌 실제 실행 시간에 대해서만 비용을 낸다.
옵저버빌리티 기본 제공: 컨테이너의 로그, 트레이스, 메트릭을 다른 서비스와 동일한 대시보드에서 한눈에 확인할 수 있다.
하나의 프로젝트, 하나의 도메인: 컨테이너가 프론트엔드 및 다른 서비스와 나란히 위치하며, Vercel 네트워크를 통해 내부적으로 통신한다. 전체 스택이 단일 배포로 완성된다.
컨테이너의 가치는 첫 번째 요청에 얼마나 빨리 응답하느냐에 달려 있다.
Vercel이 이미지를 빌드하면, 빠른 시작에 최적화된 컨테이너 디스크 압축 스냅샷인 최적화 부트 이미지 형태로 저장된다.
컨테이너가 부팅될 때, 전체 이미지를 다 내려받은 뒤 실행하는 방식이 아니라 스냅샷을 스트리밍하면서 필요한 부분부터 순차적으로 압축 해제한다. 덕분에 이미지가 완전히 다운로드되기 전에도 서버가 요청을 처리하기 시작할 수 있어, 이미지 크기가 크더라도 시작 시간에 큰 영향을 주지 않는다.
인스턴스가 실행 중일 때 Fluid compute는 이를 웜 상태로 유지하며 여러 요청을 처리한다. 요청마다 새 인스턴스를 시작하지 않는다. 웜 서버의 빠른 응답성을 누리면서도, 유휴 상태일 때는 비용이 발생하지 않는다.
각 컨테이너는 무상태(stateless) 프로세스다. 요청을 받아 응답을 반환할 뿐, 그 사이에 아무것도 보관하지 않는다. 영속적인 상태는 Vercel Marketplace의 데이터베이스나 캐시 같은 외부 서비스에 저장된다. 인스턴스가 보존해야 할 데이터를 갖지 않기 때문에, Vercel은 트래픽이 늘면 인스턴스를 추가하고 줄면 자연스럽게 종료할 수 있다. 컨테이너에 연결되는 영구 스토리지도 곧 출시할 예정이다.
우리의 첫 번째 플랫폼도 Dockerfile 하나로 단일 명령어 배포를 지원했다. 10년 전 일이다. 방향은 옳았지만, 이를 제대로 구현할 인프라가 아직 갖춰지지 않았었다.
그 이후로 우리는 이를 잘 처리하기 위한 기반 요소들을 차근차근 구축해왔다. 이 기반은 Vercel에서 실행되는 모든 것을 지탱한다. Builds, Functions, Sandboxes, 그리고 이제 컨테이너까지. 모두 트래픽에 따라 자동으로 확장되며, 사용한 CPU만큼만 비용을 낸다. 컨테이너는 이제 다른 모든 것과 동일한 시스템 위에서 동작하는 일급 객체가 됐다.
프레임워크 자동 감지는 우리의 첫 번째 관문이다. 프레임워크를 인식하면 코드를 분석해 앱에 필요한 인프라를 자동으로 도출한다. 코드 자체가 이미 무엇을 해야 하는지 설명하고 있기 때문이다. 대부분의 앱에는 이 방식이 가장 빠른 배포 방법이다. Dockerfile은 그 외의 모든 경우를 위한 것이다. FFmpeg이나 Chromium 같은 시스템 라이브러리가 필요한 서비스, 아직 자동 감지가 지원되지 않는 프레임워크, 또는 기존 실행 환경 그대로 가져오고 싶은 앱이 여기에 해당한다. Dockerfile은 프로그램을 어떻게 빌드해야 하는지를 나타내는 범용적인 방법이다. 읽어들일 프레임워크가 없을 때, 우리는 Dockerfile을 직접 받아들인다.
Dockerfile 주변의 모든 것은 별도 설정이 필요 없다. 이미지를 가리키기만 하면 빌드, 레지스트리, 롤아웃, 스케일링, URL이 모두 자동으로 처리된다.
이제 백엔드도 프론트엔드와 같은 방식으로 배포된다. 푸시 한 번, 프리뷰 하나, 플랫폼도 하나. 여러분이 무엇을 만들지 벌써부터 기대된다.
문서를 읽거나 예제를 직접 배포해보며 시작해보자.