Repository navigation
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
134 lines (128 loc) · 5.39 KB
/
Copy pathdocker-compose.yml
File metadata and controls
134 lines (128 loc) · 5.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# A set of services for trying arkhe in OIDC mode.
#
# Matching the issuer string is the point
#
# The authorisation server's issuer has to be the same string seen from the browser and
# seen from arkhe inside its container. If they differ, verifying iss fails.
#
# Here both are keycloak.localhost:8080:
# browser keycloak.localhost, 127.0.0.1, published port 8080, Keycloak
# arkhe keycloak.localhost, a compose network alias, Keycloak:8080
#
# *.localhost resolves to 127.0.0.1 in most environments (systemd-resolved and the major
# browsers). Where it does not, add 127.0.0.1 keycloak.localhost to the hosts file.
#
# One process per role
#
# It has the same shape as production: the minter has no resolution route and the
# resolver has no minting route. A resolver needs no authentication at all, so stopping
# Keycloak leaves resolution running, and being able to try that is why they are
# separate here.
#
# docker compose up -d --build
# http://localhost:8057/admin/ the admin interface and the minting API
# http://localhost:8058/ark:/... resolution, which needs no credentials
#
# The users are ops, naan-admin and org-admin, all with the password arkhe-demo-2026.
name: arkhe-oidc
services:
keycloak:
image: quay.io/keycloak/keycloak:26.0
command: ["start-dev", "--import-realm"]
environment:
KC_BOOTSTRAP_ADMIN_USERNAME: admin
KC_BOOTSTRAP_ADMIN_PASSWORD: admin
# The issuer is pinned to this string. By default it is built from the request
# Host, which differs between the browser and the container.
KC_HOSTNAME: http://keycloak.localhost:8080
KC_HOSTNAME_BACKCHANNEL_DYNAMIC: "false"
KC_HEALTH_ENABLED: "true"
volumes:
- ./realm-arkhe.json:/opt/keycloak/data/import/realm-arkhe.json:ro
ports:
- "127.0.0.1:8080:8080"
networks:
default:
aliases: [keycloak.localhost]
healthcheck:
# This image has no curl, so bash's /dev/tcp is used. CMD-SHELL runs /bin/sh, so
# bash is named explicitly.
test: ["CMD", "bash", "-c",
"exec 3<>/dev/tcp/127.0.0.1/9000; printf 'GET /health/ready HTTP/1.1\\r\\nHost: x\\r\\nConnection: close\\r\\n\\r\\n' >&3; grep -q UP <&3"]
interval: 5s
timeout: 5s
retries: 40
db:
image: postgres:17-alpine
environment:
POSTGRES_USER: arkhe
POSTGRES_PASSWORD: arkhe
POSTGRES_DB: arkhe
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U arkhe"]
interval: 5s
timeout: 5s
retries: 20
arkhe:
build:
context: ../..
dockerfile: Dockerfile
image: arkhe:local
depends_on:
db: {condition: service_healthy}
keycloak: {condition: service_healthy}
environment:
ARKHE_DATABASE_URL: postgresql+psycopg://arkhe:arkhe@db/arkhe
# The way in to the admin interface. arkhe acts as an OIDC relying party and runs
# the authorization code flow; it is not an authorisation server, issues no tokens
# and holds no consent.
ARKHE_ADMIN_LOGIN: oidc
ARKHE_OIDC_ISSUER: http://keycloak.localhost:8080/realms/arkhe
ARKHE_ADMIN_CLIENT_ID: arkhe-admin
ARKHE_ADMIN_CLIENT_SECRET: arkhe-admin-secret-for-demo-only
# Values for trying it out. Always replace them in production.
ARKHE_SESSION_SECRET: demo-only-session-secret-change-me-0123456789
ARKHE_SESSION_SECURE: "false" # this runs over http; drop it under HTTPS
# The mechanisms are not exclusive. All three are enabled so that the difference
# can be compared here; during a migration, accepting both an API key and OIDC is
# ordinary.
# apikey a credential arkhe issued, sent as a bearer token
# oauth2 a client secret exchanged for a token at arkhe's own /oauth/token
# oidc a token from an external authorisation server, Keycloak here
ARKHE_AUTH: apikey,oauth2,oidc
# The signing key for oauth2. A value for trying it out; replace it in
# production.
ARKHE_TOKEN_SECRET: demo-only-token-secret-change-me-0123456789abcd
# The audience required of an access token for the API. The realm's arkhe-api
# client scope sets it through an audience mapper. The aud of the ID token used to
# sign in to the admin interface is arkhe-admin: a different thing, not mixed.
ARKHE_OIDC_AUDIENCE: arkhe-api
ports:
- "127.0.0.1:8057:8000"
command: >
sh -c "alembic upgrade head && python -m arkhe.seed_demo &&
uvicorn arkhe.app:create_app --factory --host 0.0.0.0 --port 8000"
# Resolution only. It carries no authentication settings, because there is no reason
# for them here. Stop Keycloak with docker compose stop keycloak and then resolve
# something: minting answers 401 while resolution keeps working.
resolver:
image: arkhe:local
depends_on:
arkhe: {condition: service_started} # wait for the schema to be applied
db: {condition: service_healthy}
environment:
ARKHE_RESOLVER: "1"
ARKHE_DATABASE_URL: postgresql+psycopg://arkhe:arkhe@db/arkhe
# In production this points at a read-only role, ideally on a replica.
# ARKHE_READ_DATABASE_URL: postgresql+psycopg://arkhe_ro:…@replica/arkhe
ARKHE_GLOBAL_RESOLVER: https://n2t.net
ports:
- "127.0.0.1:8058:8000"
command: >
uvicorn arkhe.app:create_app --factory --host 0.0.0.0 --port 8000
volumes:
pgdata:
networks:
default: