본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

Heroku에서 마이그레이션하기 (Migrate from Heroku)

원문 보기 위키 갱신

이 가이드는 Heroku 앱을 Fly.io로 마이그레이션하는 과정을 순서대로 안내해 드려요. 웹 앱, Postgres, Redis, 백그라운드 워커, 환경 변수, 커스텀 도메인까지 대부분의 앱을 30분 안에 옮길 수 있어요. Heroku의 dyno 기반 요금제와 달리 Fly.io는 실제로 사용한 컴퓨팅, 스토리지, 대역폭만 지불하는 pay-as-you-go 가격 방식을 사용해요.

출처: 문서

본문

Illustration by Annie Ruygt of a bird carrying an app to a balloon who is welcoming the app to join his group

이 가이드에서는 Heroku 앱을 Fly.io로 마이그레이션하는 과정을 순서대로 안내해 드려요. 단계를 순서대로 따라 하세요.

이 가이드가 다루는 내용:

  • 모든 언어로 된 웹 앱(Node.js, Python, Ruby, Go 등)
  • Postgres 데이터베이스
  • Redis
  • 백그라운드 워커
  • 환경 변수
  • 커스텀 도메인

소요 시간: 대부분의 앱은 30분 안에 마이그레이션할 수 있어요.

Heroku의 dyno 기반 요금제와 달리 Fly.io는 pay-as-you-go 가격 방식을 사용해요—실제로 사용한 컴퓨팅, 스토리지, 대역폭만 지불하면 돼요. 선택할 수 있는 고정 요금제 티어는 없어요. 현재 요금은 fly.io/pricing에서 확인하세요.

TL;DR - 빠른 경로

경험 많은 개발자를 위한, 전체 마이그레이션을 7개 명령으로 요약한 버전이에요:

# 1. Export secrets (excluding Heroku-managed vars)
heroku config -s -a YOUR_HEROKU_APP | grep -v '^DATABASE_URL\|^REDIS_URL\|^HEROKU_' | sed "s/='\(.*\)'$/=\"\1\"/" > secrets.txt
# ⚠️ Don't commit secrets.txt to git!

# 2. Create Fly app (generates Dockerfile automatically)
cd your-app-directory
fly launch --no-deploy

# 3. Create Managed Postgres and import data
fly mpg create --name your-db --region iad
# ⚠️ Replace CLUSTER_ID below with the cluster ID from the output above.
# If you missed it, run: fly mpg list
fly mpg proxy CLUSTER_ID --local-port 15432 &
pg_dump --no-owner --no-acl "$(heroku config:get DATABASE_URL -a YOUR_HEROKU_APP)" | \
  PGPASSWORD=YOUR_FLY_DB_PASSWORD psql -h localhost -p 15432 -U fly-user -d fly-db
fly mpg attach CLUSTER_ID -a your-fly-app

# 4. Import secrets
cat secrets.txt | fly secrets import

# 5. Deploy
fly deploy

# 6. Verify
curl https://your-fly-app.fly.dev

더 자세한 설명은 계속 읽어 보세요.

사전 준비

두 CLI를 모두 설치하세요:

# Install Fly CLI
curl -fsSL https://fly.io/install.sh | sh

# Sign up / log in to Fly
fly auth signup   # or: fly auth login

# Make sure you're logged into Heroku
heroku login

1단계: Heroku 구성 내보내기

먼저 Heroku 앱에 대한 모든 것을 캡처해 보세요.

# Set your Heroku app name
export HEROKU_APP="your-app-name"

# Export environment variables (excluding Heroku-managed ones)
heroku config -s -a $HEROKU_APP | grep -v '^HEROKU_' | grep -v '^DATABASE_URL' | grep -v '^REDIS_URL' | sed "s/='\(.*\)'$/=\"\1\"/" > heroku-env.txt
# ⚠️ This file contains secrets - don't commit it to git!

# See what add-ons you have
heroku addons -a $HEROKU_APP

# Check your current process types
heroku ps -a $HEROKU_APP

다음을 기록해 두세요:

  • 애드온(Postgres, Redis 등)
  • dyno 유형(web, worker 등)

2단계: 앱 준비

앱의 소스 코드가 로컬에 있는지 확인하세요:

# If you don't have it locally, clone from Heroku
heroku git:clone -a $HEROKU_APP
cd $HEROKU_APP

Dockerfile 확인

Fly는 Dockerfile이 있을 때 가장 잘 작동해요. 없다면 괜찮아요—fly launch가 앱 유형에 따라 하나를 생성해 줄 거예요.

Procfile 확인

Heroku Procfile은 Fly 프로세스에 그대로 매핑돼요. 전형적인 Procfile:

web: npm start
worker: npm run worker
release: npm run db:migrate

3단계: Fly에서 Launch

앱 디렉터리에서:

fly launch

이 명령은:

  1. 앱 유형을 감지해요(Node, Python, Rails 등)
  2. 필요하면 Dockerfile을 생성해요
  3. fly.toml 설정 파일을 만들어요
  4. Postgres 데이터베이스를 프로비저닝할지 물어봐요

프롬프트가 나오면:

  • 앱 이름을 선택하세요(또는 생성된 이름을 수락)
  • 원하는 리전을 선택하세요
  • 데이터베이스가 필요하면 Postgres에 Yes라고 답하세요(완전 관리형 옵션에는 "Managed Postgres" 선택)
  • 지금 배포하지 않으려면 No라고 답하세요—시크릿을 설정한 후 배포할 거예요

4단계: 데이터베이스 설정

Heroku Postgres를 사용 중이라면 Fly에 Managed Postgres 클러스터를 만드세요:

fly mpg create --name your-app-db --region iad

출력되는 연결 정보를 저장하세요! 다음과 같은 내용이 보일 거예요:

Connection string: postgresql://fly-user:***@pgbouncer.CLUSTER_ID.flympg.net/fly-db

클러스터 ID(CLUSTER_ID 부분)를 기록해 두세요—다음 몇 개 명령에서 필요해요. 잊어버렸다면 fly mpg list로 언제든 찾을 수 있어요.

데이터를 가져오려면 fly mpg proxy로 로컬 터널을 만든 다음 pg_dump와 psql을 사용하세요:

# Terminal 1: Start a proxy to your Fly database (replace CLUSTER_ID with your cluster ID)
fly mpg proxy CLUSTER_ID --local-port 15432

# Terminal 2: Dump from Heroku and restore to Fly
export HEROKU_DB=$(heroku config:get DATABASE_URL -a $HEROKU_APP)

# Dump the database (plain SQL format)
pg_dump --no-owner --no-acl "$HEROKU_DB" > heroku-dump.sql

# Restore to Fly (via the proxy)
PGPASSWORD=YOUR_PASSWORD psql -h localhost -p 15432 -U fly-user -d fly-db -f heroku-dump.sql

Heroku 전용 확장(pg_stat_statements, event triggers)에 대한 오류가 일부 보일 텐데—이것들은 무시해도 안전해요. 실제 데이터는 성공적으로 가져와져요.

데이터베이스를 앱에 연결하세요:

# Replace CLUSTER_ID with the cluster ID from fly mpg create (or run fly mpg list)
fly mpg attach CLUSTER_ID -a your-app-name

이렇게 하면 앱에 DATABASE_URL이 자동으로 시크릿으로 설정돼요.

5단계: Redis 설정(필요한 경우)

Heroku Redis나 Redis Cloud를 사용한다면:

fly redis create

프롬프트에 따라 진행하세요. 완전 관리형인 Upstash Redis를 사용해요.

생성 후 앱에 연결하세요:

# The create command outputs a REDIS_URL - set it as a secret
fly secrets set REDIS_URL="redis://default:***@fly-your-redis.upstash.io:6379" -a your-app-name

참고: Fly Redis는 기존 데이터 가져오기를 지원하지 않아요. 대부분의 사용 사례(캐싱, 세션)에서는 괜찮아요—캐시가 자연스럽게 워밍업되거든요.

6단계: 환경 변수 가져오기

아까 만든 heroku-env.txt 파일을 기억하시나요? 가져와 보세요:

# Import all your Heroku environment variables
cat heroku-env.txt | fly secrets import -a your-app-name

시크릿이 제대로 가져와졌는지 다시 확인하세요:

fly secrets list -a your-app-name

7단계: 프로세스 구성(Web + Workers)

앱에 여러 프로세스 유형(web + worker)이 있다면 fly.toml을 편집하세요:

[processes]
  web = "npm start"
  worker = "npm run worker"

# The web process gets the HTTP service
[http_service]
  internal_port = 8080
  processes = ["web"]

릴리스 명령(데이터베이스 마이그레이션 같은)을 위해 추가하세요:

[deploy]
  release_command = "npm run db:migrate"

8단계: 배포

fly deploy

배포를 지켜보세요. 실패하면 로그를 확인하세요:

fly logs

9단계: 앱 검증

# Open your app in a browser
fly apps open

# Check the status
fly status

# View live logs
fly logs

10단계: 도메인 마이그레이션

Heroku에 커스텀 도메인이 있다면:

# Add your domain to Fly
fly certs add yourdomain.com -a your-app-name

# Get the IP addresses to point your DNS to
fly ips list -a your-app-name

DNS를 업데이트하세요:

  • 에이펙스 도메인(example.com)의 경우: IPv4 주소를 가리키는 A 레코드를 만드세요.
  • 서브도메인(www.example.com)의 경우: your-app-name.fly.dev를 가리키는 CNAME을 만드세요.

DNS가 전파되면 Fly가 SSL 인증서를 자동으로 프로비저닝해요.

빠른 참조: 명령 매핑

Heroku Fly
heroku apps fly apps list
heroku logs -t fly logs
heroku ps fly status
heroku config fly secrets list
heroku config:set KEY=value fly secrets set KEY=value
heroku run bash fly ssh console
heroku run rails console fly ssh console -C "rails console"
heroku pg:psql fly mpg connect CLUSTER_ID
heroku restart fly apps restart
heroku scale web=2 fly scale count web=2

흔한 애드온 대체

Heroku Add-on Fly Equivalent
Heroku Postgres fly mpg create (Managed Postgres)
Heroku Redis / Redis Cloud fly redis create (Upstash)
Heroku Scheduler Use cron in your app, or a separate "cron" process
Papertrail fly logs built-in, or add a log drain
SendGrid Keep using SendGrid (just use API key)
New Relic Keep using New Relic (just use license key)
S3 / Bucketeer fly storage create (Tigris) or keep using S3
Elasticsearch Deploy Elasticsearch as a Fly app, or use a hosted service
Memcached Use Redis instead (fly redis create)

여러 환경(스테이징/프로덕션)

Fly에는 Heroku 같은 "pipeline"이 없어요. 대신 별도의 앱을 만드세요:

# Production
fly launch --name myapp

# Staging
fly launch --name myapp-staging

CI/CD에는 Fly GitHub Action과 함께 GitHub Actions를 사용하세요.

Heroku 종료

Fly에서 모든 것이 작동하면:

  1. DNS를 Fly로 가리키도록 업데이트하세요.
  2. DNS 전파를 기다리세요(dig yourdomain.com으로 확인).
  3. 하루 동안 두 앱을 모니터링해 Heroku로 트래픽이 가지 않는지 확인하세요.
  4. Heroku dyno를 축소하세요: heroku ps:scale web=0 worker=0 -a $HEROKU_APP
  5. Heroku 애드온을 취소하세요.
  6. Heroku 앱을 삭제하세요: heroku apps:destroy -a $HEROKU_APP

도움 받기

더 알아보기 (Learn more)