PostgREST turns a Postgres schema into a REST API with no glue code - you point
it at a database and it serves the tables. I wanted the smallest local setup that
gets it running, so I followed the docs on
Containerized PostgREST with Docker Compose,
added a Swagger UI service to browse the generated API, and lined up the
environment variables with
Tutorial 0 - Get it Running.
The one extra piece is a seed.sql mounted into the db, so the roles PostgREST
needs exist the moment the container starts.
Docker Compose
Three services. server is PostgREST itself, talking to Postgres as the
authenticator role and exposing the api schema; anonymous requests fall back
to the web_anon role. db is plain Postgres with the data volume and seed
script mounted in. swagger gives you an interactive UI on 8080 pointed at the
API.
services: server: image: postgrest/postgrest ports: - "3000:3000" environment: PGRST_DB_URI: postgres://authenticator:mysecretpassword@db:5432/app_db PGRST_DB_SCHEMAS: api PGRST_DB_ANON_ROLE: web_anon PGRST_OPENAPI_SERVER_PROXY_URI: http://127.0.0.1:3000 depends_on: - db db: image: postgres ports: - "5432:5432" environment: POSTGRES_DB: app_db POSTGRES_USER: app_user POSTGRES_PASSWORD: password volumes: - ./pgdata:/var/lib/postgresql/data - ./seed.sql:/docker-entrypoint-initdb.d/seed.sql swagger: image: swaggerapi/swagger-ui ports: - "8080:8080" expose: - "8080" environment: API_URL: http://localhost:3000/The seed script
Postgres runs any .sql file in /docker-entrypoint-initdb.d/ once, on first
startup. That is where the schema and roles go. The api schema is what
PostgREST exposes; web_anon is the read-only role anonymous callers get; and
authenticator is the login role PostgREST connects as, which can switch into
web_anon because it is granted to it. Match mysecretpassword to the
PGRST_DB_URI above or the API will not connect.
create schema api;
create table api.todos ( id int primary key generated by default as identity, done boolean not null default false, task text not null, due timestamptz);
insert into api.todos (task) values ('finish tutorial 0'), ('pat self on back');
create role web_anon nologin;
grant usage on schema api to web_anon;grant select on api.todos to web_anon;
create role authenticator noinherit login password 'mysecretpassword';grant web_anon to authenticator;Run it
Bring it up with docker compose up -d, then hit http://localhost:3000/todos
for the live API and http://localhost:8080 for the Swagger UI. No controllers,
no serializers, no route definitions - the schema is the API.