OSS 버전 업그레이드하기
Logto는 semver를 따릅니다. 모든 릴리스와 변경 사항은 GitHub Releases에서 확인할 수 있습니다. 이 가이드에서는 업그레이드가 어떻게 동작하는지, 각 일반적인 배포 유형별 업그레이드 방법, 그리고 발생할 수 있는 문제 해결 방법을 설명합니다.
업그레이드가 동작하는 방식
업그레이드는 두 부분으로 구성됩니다:
- Logto 코드: 실행 중인 Docker 이미지 또는 릴리스 tarball.
- 데이터베이스 스키마: 버전 간 스키마 변경 사항은 데이터베이스 변경(Alteration)으로 제공되며, Logto CLI로 배포합니다. 데이터베이스에는 어떤 변경이 배포되었는지 기록됩니다.
Logto가 시작될 때 데이터베이스를 확인합니다. 현재 Logto 버전에 포함된 변경 사항 중 아직 배포되지 않은 것이 있으면, Logto는 시작을 거부합니다:
배포되지 않은 데이터베이스 변경 사항이 발견되었습니다. 먼저 npm run alteration deploy 명령어로 배포해야 합니다.
...
Error: Undeployed database alterations found.
변경(Alteration)은 이전 버전의 Logto와 호환되도록 설계되어 있으므로, 이전 버전을 실행 중인 인스턴스도 변경이 배포된 후 계속 동작합니다. 이로 인해 다음과 같은 순서로 다운타임 없이 업그레이드할 수 있습니다:
- 새로운 Logto 버전으로 변경(Alteration)을 배포합니다.
- 실행 중인 인스턴스를 새 버전으로 교체합니다.
시작하기 전에 데이터베이스 백업을 권장합니다.
항상 업그레이드 대상 버전의 CLI(새 Docker 이미지 또는 새 릴리스 tarball에 포함된 CLI)로 변경(Alteration)을 배포하세요. 변경 스크립트는 CLI에 번들되어 있으므로, 이전 CLI로는 최신 Logto 버전의 변경을 배포할 수 없습니다.
여러 버전을 한 번에 업그레이드할 수 있습니다. 대상 버전까지의 모든 변경이 순서대로 배포됩니다.
업그레이드 전 준비 사항
- 현재 버전과 대상 버전 사이의 모든 릴리스 노트를 읽으세요.
- 데이터베이스 백업(권장): 예를 들어
pg_dump또는 데이터베이스 제공자의 스냅샷을 사용하세요. 변경은 롤백할 수 있지만, 백업이 가장 신뢰할 수 있는 복구 방법입니다. - 대상 버전을 고정하세요.
ghcr.io/logto-io/logto:1.45.0과 같이 정확한 버전을 사용하세요.latest를 사용하면, 재시작이나 새 pull 시 변경이 배포되기 전에 Logto가 업그레이드되어 시작하지 않을 수 있습니다. - Logto를 Node.js로 직접 실행한다면 Node.js 요구사항을 확인하세요. 각 릴리스는
package.json의engines필드에 명시되어 있습니다. 현재 릴리스는 Node.js^26.0.0을 요구합니다. - 커스텀 커넥터가 있다면 확인하세요. 업그레이드 후 커스텀 커넥터가 건너뛰어짐 항목을 참고하세요.
- 스테이징 환경을 먼저 업그레이드하세요. 별도의 데이터베이스를 사용하는 스테이징 환경이 있다면, 먼저 스테이징에서 업그레이드하세요. 스테이징 환경이 프로덕션과 데이터베이스를 공유한다면, 스테이징에서 변경을 배포하면 프로덕션 데이터베이스도 변경됩니다. 변경은 이전 버전과 호환되므로, 프로덕션 인스턴스도 계속 동작합니다.
업그레이드 단계
아래 예시에서 1.45.0은 대상 버전입니다. 실제 환경에 맞게 버전과 데이터베이스 URL을 변경하세요.
Docker
-
새 이미지를 pull 합니다:
docker pull ghcr.io/logto-io/logto:1.45.0 -
새 이미지로 변경(Alteration)을 배포합니다. 이 단계 동안 기존 Logto 컨테이너는 계속 실행됩니다:
docker run --rm \-e DB_URL=postgres://username:password@your_postgres_url:port/db_name \ghcr.io/logto-io/logto:1.45.0 \alteration deploy 1.45.0아래와 같은 출력이 나타납니다. 변경의 개수와 이름은 업그레이드하는 버전에 따라 다릅니다:
info Deploy target 1.45.0info Found 1 alteration to deployinfo Run alteration 1.45.0-1791531333-add-tenant-viewer-role.js `up()` function succeeded노트:이미지의 entrypoint는
npm run이므로, 이미지 이름 뒤의 인자는npm run에 전달됩니다.npm run alteration deploy 1.45.0이 아니라alteration deploy 1.45.0으로 작성하세요. -
실행 중인 컨테이너를 새 이미지로 교체합니다. 포트, 환경 변수 등은 이전과 동일하게 유지하세요:
docker stop logto && docker rm logtodocker run -d --name logto \-p 3001:3001 \-p 3002:3002 \-e DB_URL=postgres://username:password@your_postgres_url:port/db_name \ghcr.io/logto-io/logto:1.45.0
Docker Compose
-
Compose 파일에서 Logto 서비스의 이미지 태그를 업데이트한 후 pull 합니다:
services:logto:image: ghcr.io/logto-io/logto:1.45.0docker compose pull logto -
새 이미지의 일회성 컨테이너에서 변경(Alteration)을 배포합니다:
docker compose run --rm --entrypoint sh logto -c "npm run alteration deploy 1.45.0"Compose 파일에서 Logto 서비스의 이름이 다르다면
logto를 해당 이름으로 바꾸세요(데모docker-compose.yml에서는app입니다). entrypoint를 오버라이드하면 서비스가 자체entrypoint를 정의해도 명령이 동작합니다. -
새 이미지로 Logto 컨테이너를 재생성합니다:
docker compose up -d logto
Logto 인스턴스가 하나라면, 컨테이너가 시작할 때마다 새 데이터베이스를 시드하고 변경(Alteration)을 배포하도록 설정할 수 있습니다:
services:
logto:
image: ghcr.io/logto-io/logto:1.45.0
entrypoint:
['sh', '-c', 'npm run cli db seed -- --swe && npm run alteration deploy latest && npm start']
여기서 latest는 이미지에 포함된 최신 버전을 의미하므로, 항상 실행 중인 이미지와 변경이 일치합니다. 여러 인스턴스에서는 이 방법을 사용하지 마세요. 이유는 Kubernetes 항목을 참고하세요.
데모 docker-compose.yml을 기반으로 설정했다면, Postgres 컨테이너의 데이터가 익명 볼륨에 저장됩니다. 익명 볼륨은 docker compose down 이후 다시 마운트되지 않으므로, 다음 docker compose up 시 빈 데이터베이스로 시작합니다. docker compose down 실행 전 데이터를 명명된 볼륨이나 외부 데이터베이스로 옮기세요.
Kubernetes
Job으로 한 번 변경(Alteration)을 배포한 후, 새 이미지를 롤아웃하세요.
-
새 이미지로 변경(Alteration)을 실행하는 Job을 생성합니다:
apiVersion: batch/v1kind: Jobmetadata:name: logto-alteration-1-45-0spec:backoffLimit: 0template:spec:restartPolicy: Nevercontainers:- name: alterationimage: ghcr.io/logto-io/logto:1.45.0command: ['/bin/sh', '-c', 'npm run alteration deploy 1.45.0']env:- name: DB_URLvalueFrom:secretKeyRef:name: logtokey: db-url적용 후 완료될 때까지 기다립니다:
kubectl apply -f logto-alteration-job.yamlkubectl wait --for=condition=complete job/logto-alteration-1-45-0 --timeout=10mkubectl logs job/logto-alteration-1-45-0 -
Logto Deployment의 이미지를 업데이트하고 롤아웃이 완료될 때까지 기다립니다. Deployment에 Logto 이미지를 사용하는 init 컨테이너가 있다면(예: 공유 커넥터 폴더 예시), 그것도 함께 업데이트하세요:
kubectl set image deployment/logto logto=ghcr.io/logto-io/logto:1.45.0kubectl rollout status deployment/logto
Helm 또는 GitOps 도구로 배포한다면, Deployment가 업데이트되기 전에 Job을 실행하세요. 예를 들어 Helm의 pre-upgrade hook이나 Argo CD의 PreSync hook으로 사용할 수 있습니다.
한 곳에서만 변경(Alteration)을 배포하세요. CLI는 변경을 배포하는 동안 데이터베이스를 잠그지 않으므로, 모든 복제본의 시작 명령에서 변경을 배포하지 마세요.
Node.js
npm init @logto 또는 릴리스 tarball로 Logto를 설치했다면, 새 버전을 기존 버전 옆에 설치하세요. 업그레이드가 끝날 때까지 기존 디렉터리를 유지하면 빠르게 롤백할 수 있습니다.
-
Node.js 버전이 새 버전의 요구사항을 충족하는지 확인하세요.
-
새 릴리스를 다운로드하고 압축을 풉니다:
curl -fL -o logto-1.45.0.tar.gz https://github.com/logto-io/logto/releases/download/v1.45.0/logto.tar.gzmkdir logto-1.45.0tar -xzf logto-1.45.0.tar.gz -C logto-1.45.0 --strip-components=1최신 릴리스를 받으려면
npm init @logto@latest -- --path ./logto-new --skip-seed를 사용할 수도 있습니다. 데이터베이스가 이미 존재하므로--skip-seed옵션이 필요합니다. -
현재 설치(기본값:
~/logto)에서 설정 파일을 복사합니다:cp ~/logto/.env logto-1.45.0/.env -
공식 커넥터는 릴리스에 포함되어 있습니다. 추가한 커넥터가 있다면 새 디렉터리에 다시 추가하세요. 예시:
cd logto-1.45.0npm run cli connector add <connector-package-name> -
새 디렉터리에서 변경(Alteration)을 배포합니다. CLI는
.env파일에서DB_URL을 읽습니다:npm run alteration deploy 1.45.0 -
기존 Logto 프로세스를 중지하고, 새 디렉터리에서 새 버전을 시작합니다:
npm startsystemd, pm2 등 프로세스 관리자를 사용한다면, 작업 디렉터리를 새 디렉터리로 변경하세요.
호스팅 제공업체
호스팅 제공업체의 원클릭 템플릿으로 Logto를 배포했다면, Logto 이미지 태그를 대상 버전으로 변경하세요. 새 버전이 시작되기 전에, 제공업체의 일회성 명령 또는 셸 기능을 사용해 새 이미지로 npm run alteration deploy 1.45.0을 실행하여 변경을 배포하세요. 단일 인스턴스라면 Docker Compose tip의 시작 명령을 사용할 수도 있습니다. 템플릿은 제공업체에서 관리하므로, 자세한 내용은 해당 문서를 참고하세요.
롤백
새 버전이 예상대로 동작하지 않는 경우:
-
이전 버전으로 전환하세요. 변경(Alteration)은 이전 버전의 Logto와 호환되므로, 일반적으로 데이터베이스를 건드리지 않고 이전 버전을 다시 실행할 수 있습니다. 이는 바로 이전 버전에만 해당됩니다. 여러 버전을 건너뛰어 업그레이드했다면, 변경도 함께 롤백해야 합니다.
-
변경(Alteration) 롤백. 새 버전으로 롤백을 실행하세요. 이전 버전에는 최신 변경 스크립트가 없기 때문입니다. 그런 다음 이전 버전을 시작하세요. 예시(Docker):
docker run --rm \-e DB_URL=postgres://username:password@your_postgres_url:port/db_name \ghcr.io/logto-io/logto:1.45.0 \alteration rollback 1.44.0롤백 후에는 변경을 다시 배포하기 전까지 새 버전이 시작되지 않습니다. 자세한 내용은 변경 롤백을 참고하세요.
-
백업 복원. 백업을 해두었다면, 복원이 가장 신뢰할 수 있는 방법입니다. 단, 백업 이후 작성된 데이터는 모두 손실됩니다.
문제 해결
업그레이드 후 Logto가 시작되지 않음
로그에 Undeployed database alterations found가 표시된다면, 업그레이드 단계에서 설명한 대로 변경(Alteration)을 배포하세요.
이미 변경을 배포했는데도 이 오류가 계속된다면, 이전 CLI(예: 전역 설치된 logto 명령어나, 이전 버전으로 해석된 npx @logto/cli)로 배포했을 가능성이 높습니다. 이 경우, CLI는 Found 0 alteration to deploy라고 표시하며 최신 변경을 인식하지 못합니다. 새 버전의 CLI(새 Docker 이미지, 새 릴리스 디렉터리, 또는 npx @logto/[email protected] db alteration deploy 1.45.0)로 다시 배포하세요.
재시작 후 Logto가 시작되지 않음
latest 태그를 사용하면, 이미지 재시작 또는 새 pull 시 변경이 배포되지 않은 상태에서 Logto가 업그레이드될 수 있습니다. 실행 중인 이미지로 변경을 배포한 후, 예기치 않은 업그레이드를 방지하려면 정확한 버전으로 고정하세요.
Error: Missing target version
인터랙티브 터미널이 없으면, CLI가 배포할 버전을 물어볼 수 없습니다. alteration deploy 1.45.0처럼 대상 버전을 명시적으로 전달하거나, alteration deploy latest로 CLI에 포함된 최신 버전까지 배포하세요.
npm error Missing script: "npm"
docker run에서 이미지 이름 뒤에 npm run alteration ...을 전달한 경우입니다. 이미지의 entrypoint가 이미 npm run이므로, alteration deploy 1.45.0만 전달하세요.
변경(Alteration)이 실패함
각 변경은 트랜잭션 내에서 실행되므로, 실패해도 부분 변경이 남지 않습니다. 원인을 수정한 후 동일한 명령을 다시 실행하세요. 이미 배포된 변경은 건너뜁니다. 일반적인 원인:
- Statement timeout. 큰 테이블에서 변경을 실행하면 기본 60초 statement timeout보다 오래 걸릴 수 있습니다. 변경 명령에
DATABASE_STATEMENT_TIMEOUT(밀리초 단위) 또는DISABLE_TIMEOUT을 설정하세요. - 데이터베이스 권한. 데이터베이스 시드에 사용한 것과 동일한 권한의 사용자로 변경을 실행하세요.
일부 변경은 트랜잭션 외부에서 실행되는 단계가 포함되어 있습니다. 에러 메시지에 비트랜잭션 단계가 적용되었을 수 있다고 표시되면, 명령을 다시 실행하기 전에 데이터베이스 상태를 확인하세요.
업그레이드 후 커스텀 커넥터가 건너뛰어짐
Logto는 각 커넥터가 Logto에 번들된 @logto/connector-kit 버전을 지원하는지 확인합니다. 지원하지 않으면 Logto는 해당 커넥터를 건너뛰고 다음과 같이 로그를 남깁니다:
[load-connector] skip <connector-name> due to error: Connector requires @logto/connector-kit to be <range>, but the version here is <version>.
커넥터를 업데이트하여 새로운 @logto/connector-kit 버전을 지원하세요. IGNORE_CONNECTOR_VERSION_CHECK=1로 버전 체크를 건너뛸 수 있지만, 프로덕션 환경에서는 권장하지 않습니다.
이 현상은 공유 커넥터 폴더의 공식 커넥터에도 발생할 수 있습니다. npm run cli connector add -- --official은 npm에서 최신 커넥터를 다운로드하는데, 이 커넥터가 더 최신 Logto 버전을 요구할 수 있습니다. 이 경우 Logto를 업그레이드하거나, 공유 폴더 대신 Docker 이미지에 포함된 공식 커넥터를 사용하세요.
npm init @logto가 새 디렉터리를 삭제함
기존 데이터베이스에 대해 npm init @logto를 --skip-seed 없이 실행하면, 데이터베이스가 이미 존재하여 시드에 실패하고, CLI가 방금 생성한 디렉터리를 삭제합니다. 데이터베이스는 변경되지 않습니다. --skip-seed 옵션을 추가하여 다시 실행하세요.