One Server

문서

대기열 · Vault · GraphQL · 접속 제한

pgmq와 같은 대기열, 데이터베이스 안의 암호화된 비밀(Vault), /graphql/v1, 직접 연결의 주소 제한과 TLS.

대기열, Vault, GraphQL, 접속 제한

모두 전용 데이터베이스(p_<ref>)에 있는 프로젝트에서 써요. 새 프로젝트는 처음부터 전용 데이터베이스예요.

대기열 (pgmq)

pgmq와 같은 SQL 함수예요. create_queue가 처음이면 pgmq 스키마를 설치해요.

select pgmq.create('jobs');
select * from pgmq.send('jobs', '{"to": "[email protected]"}');
select * from pgmq.read('jobs', 30, 10);
select pgmq.archive('jobs', 1);
select pgmq.delete('jobs', 2);
select * from pgmq.pop('jobs');
select * from pgmq.metrics('jobs');

도구: list_queues, create_queue, send_queue_message, peek_queue(가져가지 않고 보기), purge_queue, delete_queue, set_queues_api. 대기열 표 pgmq.q_<이름>은 서비스 역할의 것이고 접근 규칙이 켜져 있어요. set_queues_api { exposed: true }면 데이터 API에서 부를 수 있어요.

await supabase.schema('pgmq_public').rpc('send', { queue_name: 'jobs', message: { hello: 'world' } })
await supabase.schema('pgmq_public').rpc('read', { queue_name: 'jobs', sleep_seconds: 30, n: 5 })

공개 키·로그인 사용자가 쓰려면 SQL로 권한과 규칙을 줘요.

grant insert, select, update on pgmq.q_jobs to authenticated;
create policy "own jobs" on pgmq.q_jobs for all to authenticated using (true) with check (true);

Vault

비밀을 암호화해 프로젝트 데이터베이스의 vault.secrets에 저장해요. 키는 플랫폼이 갖고 있고 데이터베이스에 저장되지 않아서 덤프·백업·브랜치에는 암호문만 남아요. 비밀 키(서비스 역할)로 읽을 때만 풀려요.

select vault.create_secret('sk_live_...', 'stripe_key', 'Stripe');
select decrypted_secret from vault.decrypted_secrets where name = 'stripe_key';
select vault.update_secret('<id>', 'sk_live_new');

도구: list_vault_secrets(이름만), create_vault_secret, update_vault_secret, delete_vault_secret. 공개 키와 로그인 사용자는 vault 스키마를 볼 수 없고, 직접 연결(<ref>_db)에서는 decrypted_secret이 null이에요.

전용 데이터베이스로 옮기기

Vault와 큰 데이터베이스는 전용 데이터베이스에서만 쓸 수 있어요(Pro 요금제부터). get_database_move가 지금 어디에 있는지와 옮기기 상태를 보여 주고, move_to_dedicated_database가 콘솔의 "지금 옮기기"처럼 옮기기를 요청해요(소유자·관리자). 차례가 오면 옮기고, 옮기는 동안 쓰기는 멈추고 읽기는 돼요. REST: GET·POST /projects/<ref>/database/move, CLI: oneend db move, oneend db move now.

전용 디스크

데이터베이스가 커진 유료 프로젝트는 함께 쓰는 디스크에서 이 프로젝트 전용 디스크와 Postgres로 옮겨요(Supabase의 프로젝트별 서버와 볼륨처럼). 데이터베이스가 20GB를 넘으면 자동으로 옮기고(지출 상한이 꺼진 조직 또는 Enterprise), Enterprise는 크기와 관계없이 요청할 수 있어요. 디스크는 max(1.2 × 데이터베이스, 20GB)로 시작해 75% 넘게 차면 1.5배로 늘어나고(4시간에 한 번까지), 만든 크기만큼 GB당 월 ₩1,200(75¢)로 청구돼요. 옮기는 동안 쓰기가 실패하고 읽기는 돼요(expected_downtime_seconds). 연결 주소와 비밀번호는 그대로예요. 옮긴 뒤에는 특정 시각으로 복원할 수 없고, 매일 받는 백업으로 복원해요.

get_dedicated_disk가 디스크 크기, 쓴 공간, 한 달 비용, 30일 기록, 줄이기 제안을 보여 주고, request_dedicated_disk가 옮기기를, shrink_dedicated_disk가 줄이기를 요청해요(소유자·관리자). 디스크는 저절로 줄지 않아요: 7일 동안 25% 아래로 쓰면 줄이기를 제안하고, 확인하면 더 작은 디스크를 만들어 옮긴 뒤 원래 디스크를 지워요. 프로젝트를 지우면 30일 뒤 디스크도 지워져 비용이 0이 돼요. REST: GET·POST /projects/<ref>/database/dedicated-disk, POST /projects/<ref>/database/dedicated-disk/shrink, CLI: oneend db disk, oneend db disk request, oneend db disk shrink.

전용 서버

Pro부터 프로젝트 하나만 쓰는 서버를 빌릴 수 있어요(앱과 데이터베이스가 함께 쓰고, 데이터베이스가 메모리의 25%). 크기와 위치별 월 금액은 list_server_sizes가 보여 주고, 여기에는 적지 않아요. get_server가 지금 서버·대기 서버·작업을, request_server(tier, region)가 빌리기를, resize_server(tier, when=now|tonight)가 크기 바꾸기를(대기 서버가 없으면 3~5분 응답 없음), set_standby(standby, auto_failover)가 대기 서버와 자동 전환(60초 응답 없음)을, move_server(region)가 위치 옮기기를(무료, 한 달에 한 번, 옛 서버 7일 보관), release_server(confirm=ref)가 반납을, set_restore_days(7|28)가 되돌리기 기간을 정해요. 결제가 실패하면 7일 동안 읽기 전용이 되고, 그 뒤 마지막 백업을 받고 서버를 지워요. REST: GET·POST·PATCH·DELETE /projects/<ref>/server, PUT /projects/<ref>/server/standby, POST /projects/<ref>/server/move, PUT /projects/<ref>/server/restore-days. CLI: oneend server, oneend server request|resize|standby|move|release|restore-days.

GraphQL

enable_extension { ref, name: "pg_graphql" }로 켜면 /graphql/v1이 열려요. 키와 접근 규칙은 /rest/v1과 같아요.

POST https://<ref>.<zone>/graphql/v1
apikey: <publishable key>
{"query": "{ todosCollection { edges { node { id title } } } }"}

직접 연결의 접속 제한과 TLS

get_network_restrictions, update_network_restrictions { ref, allowed_cidrs: ["203.0.113.0/24"], enforce_ssl: true }. 기본값은 모든 주소 허용, TLS 필수예요. 요청을 보낸 주소가 목록에 없으면 confirm: true 없이는 저장되지 않아요. 콘솔·API·run_sql은 연결 풀러를 거치지 않아서 제한을 잘못 걸어도 여기서 되돌릴 수 있어요.

읽기 전용 복제본

아직 없어요. 운영 대기 서버는 장애 대비용이라 고객 연결을 받지 않아요.

HTTP로는 GET /queues, POST /queues, POST /queues/<이름>/messages, GET /queues/<이름>/messages, POST /queues/<이름>/purge, DELETE /queues/<이름>, PUT /queues/api, GET /vault, POST /vault, PATCH /vault/<이름>, DELETE /vault/<이름>, GET /network-restrictions, PUT /network-restrictions이에요.