← 블로그 목록 2026-05-19

Fly.io에 Node + Socket.io 배포 (도쿄 리전)

Dogkov Arena의 핵심 사용 케이스는 회사 LAN 멀티지만, 인터넷에서도 동작하도록 fly.io에 배포해뒀습니다. 동료가 출장 가있어도 같이 칠 수 있게. Fly.io는 Node 앱 배포가 간단하고, WebSocket을 잘 지원해서 Socket.io랑 궁합이 좋습니다.

Dockerfile

멀티 스테이지 빌드로 이미지 크기를 줄였습니다. 빌드 시 esbuild를 돌려 클라이언트 번들을 만들고, 최종 이미지에는 dev 의존성을 제거:

ARG NODE_VERSION=24.13.0
FROM node:${NODE_VERSION}-slim AS base
WORKDIR /app
ENV NODE_ENV="production"

# Build stage
FROM base AS build
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3
COPY package-lock.json package.json ./
RUN npm ci --include=dev
COPY . .
RUN npm run build          # esbuild → public/js/game.min.js
RUN npm prune --omit=dev   # esbuild 같은 dev 의존성 제거

# Final
FROM base
COPY --from=build /app /app
EXPOSE 3000
CMD [ "npm", "run", "start" ]

최종 이미지 크기 68MB. Node 24 slim + 빌드 결과물만.

fly.toml — internal_port 함정

app = 'dogkov'
primary_region = 'nrt'   # Tokyo (한국과 가장 가까움)

[http_service]
  internal_port = 3000   # ★ 서버가 listen하는 포트와 정확히 일치해야 함
  force_https = true
  auto_stop_machines = 'off'
  auto_start_machines = true
  min_machines_running = 1

[[vm]]
  memory = '1gb'
  cpus = 1

내가 한 번 망친 점: 처음엔 internal_port = 5000이었는데 Dockerfile은 3000을 expose하고 서버도 3000에서 listen. fly proxy가 5000으로 보냈는데 안 듣고 있어서 502. 둘을 일치시켜야 합니다.

WebSocket 통과 확인

Socket.io는 기본으로 WebSocket을 시도하고 실패하면 long-polling으로 fallback. fly.io는 WebSocket을 그대로 통과시키니까 별도 설정 불필요. 단, HTTPS 강제하면 클라도 wss:// 자동 선택됩니다.

클라 측 connection:

const socket = io({ transports: ['websocket', 'polling'] });

특정 호스트 지정 없이 빈 옵션이면 현재 페이지 origin으로 연결. 같은 origin이라 CORS 신경 안 써도 됨.

배포 명령

flyctl deploy --remote-only

--remote-only는 fly의 builder를 써서 Docker daemon 없이 빌드. 로컬에 Docker 없어도 됨.

로그 확인

flyctl logs -a dogkov          # 실시간 stream
flyctl logs -a dogkov --no-tail  # 최근 로그만

처음 deploy 후엔 banner도 잘 뜨는지, "WARNING The app is not listening" 경고가 없는지 확인.

macOS 방화벽 (로컬 호스트 시)

로컬에서 npm start 처음 띄우면 macOS가 "Do you want the application 'node' to accept incoming connections?" 묻습니다. Allow 누르면 LAN에서 접속 가능. 한 번만 누르면 됨.

비용

fly의 1 GB · 1 vCPU 인스턴스 (auto_start_machines + min_machines_running=1)는 거의 무료에 가깝게 운영됩니다. 트래픽도 미미해서 한 달 $0~$3 수준.

대안: 자체 호스팅

회사 LAN에서만 쓰면 fly.io 안 거치고 그냥 npm start로 누군가 노트북에 띄우면 됩니다. fly는 "출장 중 동료" 같은 외부 접근용 백업 정도.

← Bot AI