OSS 버전 업그레이드하기
Logto는 semver를 따릅니다. 모든 릴리스와 변경 사항은 GitHub Releases에서 확인할 수 있습니다. 이 가이드에서는 업그레이드가 어떻게 동작하는지, 각 일반적인 배포 유형별 업그레이드 방법, 그리고 발생할 수 있는 문제 해결 방법을 설명합니다.
업그레이드가 동작하는 방식
업그레이드는 두 부분으로 구성됩니다:
- Logto 코드: 실행 중인 Docker 이미지 또는 릴리스 tarball.
- 데이터베이스 스키마: 버전 간 스키마 변경은 데이터베이스 변경 사항으로 제공되며, Logto CLI로 배포합니다. 데이터베이스에는 어떤 변경 사항이 배포되었는지 기록됩니다.
Logto가 시작될 때, 데이터베이스를 확인합니다. 이 Logto 버전에 포함된 변경 사항 중 아직 배포되지 않은 것이 있으면, Logto는 시작을 거부합니다:
배포되지 않은 데이터베이스 변경 사항이 발견되었습니다. 먼저 npm run alteration deploy 명령어로 배포해야 합니다.
...
Error: Undeployed database alterations found.
변경 사항은 이전 버전의 Logto와 호환되도록 설계되어 있으므로, 이전 버전을 실행 중인 인스턴스도 변경 사항이 배포된 후 계속 동작합니다. 이로 인해 다음과 같은 순서로 다운타임 없이 업그레이드할 수 있습니다:
- 새로운 Logto 버전으로 변경 사항을 배포합니다.
- 실행 중인 인스턴스를 새 버전으로 교체합니다.
시작하기 전에 데이터베이스 백업을 권장합니다.
항상 업그레이드 대상 버전의 CLI(새 Docker 이미지 또는 새 릴리스 tarball에 포함된 CLI)로 변경 사항을 배포하세요. 변경 스크립트는 CLI에 번들되어 있으므로, 이전 CLI로는 최신 Logto 버전의 변경 사항을 배포할 수 없습니다.
여러 버전을 한 번에 업그레이드할 수 있습니다. 대상 버전까지 변경 사항을 배포하면, 중간의 모든 변경 사항이 순서대로 적용됩니다.
업그레이드 전 준비 사항
- 현재 버전과 대상 버전 사이의 모든 릴리스 노트를 읽으세요.
- 데이터베이스 백업(권장): 예를 들어
pg_dump나 데이터베이스 제공업체의 스냅샷 기능을 사용하세요. 변경 사항은 롤백할 수 있지만, 백업이 가장 확실한 복구 방법입니다. - 대상 버전을 고정하세요.
latest대신ghcr.io/logto-io/logto:1.45.0과 같이 정확한 버전을 사용하세요.latest를 사용하면, 재시작이나 새 pull 시 변경 사항 배포 전 Logto가 업그레이드되어 시작하지 않을 수 있습니다. - Logto를 Node.js로 직접 실행한다면, Node.js 요구 사항을 확인하세요. 각 릴리스는
package.json의engines필드에 명시되어 있습니다. 예: Logto 1.45.0은 Node.js^22.14.0이 필요합니다. - 커스텀 커넥터가 있다면 확인하세요. 업그레이드 후 커스텀 커넥터가 건너뛰어짐 항목을 참고하세요.
- 스테이징 환경을 먼저 업그레이드하세요. 스테이징 환경이 별도의 데이터베이스를 사용한다면, 먼저 스테이징에서 테스트하세요. 스테이징이 프로덕션과 데이터베이스를 공유한다면, 스테이징에서 변경 사항을 배포하면 프로덕션 데이터베이스도 변경됩니다. 변경 사항은 이전 버전과 호환되므로, 프로덕션 인스턴스도 계속 동작합니다.
업그레이드 단계
아래 예시에서 1.45.0은 대상 버전입니다. 실제 환경에 맞게 버전과 데이터베이스 URL을 변경하세요.
Docker
-
새 이미지를 pull 합니다:
docker pull ghcr.io/logto-io/logto:1.45.0 -
새 이미지로 변경 사항을 배포합니다. 이 단계에서 기존 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 -
새 이미지의 일회성 컨테이너에서 변경 사항을 배포합니다:
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 인스턴스가 하나라면, 컨테이너가 시작할 때마다 새 데이터베이스를 시드하고 변경 사항을 배포하도록 설정할 수 있습니다:
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으로 한 번 변경 사항을 배포한 후, 새 이미지를 롤아웃하세요.
-
새 이미지로 변경 사항을 배포하는 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의 이미지를 업데이트하고 롤아웃이 완료될 때까지 기다립니다. 공유 커넥터 폴더 예시처럼 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을 사용할 수 있습니다.
한 곳에서만 변경 사항을 배포하세요. 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> -
새 디렉터리에서 변경 사항을 배포합니다. 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의 시작 명령을 사용할 수도 있습니다. 템플릿은 제공업체에서 관리하므로, 자세한 내용은 해당 문서를 참고하세요.
롤백
새 버전이 예상대로 동작하지 않는 경우:
-
이전 버전으로 되돌리세요. 변경 사항은 이전 버전의 Logto와 호환되므로, 일반적으로 데이터베이스를 건드리지 않고도 이전 버전을 다시 실행할 수 있습니다. 이 방법은 바로 이전 버전에만 해당됩니다. 여러 버전을 건너뛰어 업그레이드했다면, 변경 사항도 함께 롤백해야 합니다.
-
변경 사항 롤백. 새 버전에서 롤백을 실행하세요. 이전 버전에는 최신 변경 스크립트가 없기 때문입니다. 그런 다음 이전 버전을 시작하세요. 예: 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가 표시되면, 업그레이드 단계에서 설명한 대로 변경 사항을 배포하세요.
이미 변경 사항을 배포했는데도 이 오류가 계속된다면, 이전 CLI(글로벌로 설치된 logto 명령어나, 구버전으로 해석된 npx @logto/cli 등)로 배포했을 가능성이 높습니다. 이 경우, CLI는 Found 0 alteration to deploy라고 표시하지만, 최신 변경 사항을 인식하지 못합니다. 새 버전의 CLI(새 Docker 이미지, 새 릴리스 디렉터리, 또는 npx @logto/cli@1.45.0 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만 전달하세요.
변경 사항 배포 실패
각 변경 사항은 트랜잭션 내에서 실행되므로, 실패해도 부분적으로만 적용되는 일은 없습니다. 원인을 해결한 후 동일한 명령을 다시 실행하세요. 이미 배포된 변경 사항은 건너뜁니다. 일반적인 원인:
- 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 옵션을 추가해 다시 실행하세요.