alpha
Login
or
Join now
pds.dad
/
pds-gatekeeper
Star
0
Fork
3
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Microservice to bring 2FA to self hosted PDSes
Star
0
Fork
3
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Overview
Issues
Pulls
Pipelines
docs: add coolify compose example
author
dane.is.extraordinarily.cool
committer
Tangled
date
7 months ago
(Nov 18, 2025, 5:27 AM UTC)
commit
0202c7fa
0202c7fa0f60f9eb3ae76c9a3363cc76f3700694
parent
3d3b821b
3d3b821be3a57544b67024353c43ba7f391a6ec1
+117
2 changed files
Expand all
Collapse all
Unified
Split
README.md
examples
coolify-compose.yml
+44
README.md
Reviewed
···
49
49
- pds
50
50
```
51
51
52
52
+
For Coolify, if you're using Traefik as your proxy you'll need to make sure the labels for the container are set up correctly. A full example can be found at [./examples/coolify-compose.yml](./examples/coolify-compose.yml).
53
53
+
54
54
+
```yml
55
55
+
gatekeeper:
56
56
+
container_name: gatekeeper
57
57
+
image: 'fatfingers23/pds_gatekeeper:latest'
58
58
+
restart: unless-stopped
59
59
+
volumes:
60
60
+
- '/pds:/pds'
61
61
+
environment:
62
62
+
- 'PDS_DATA_DIRECTORY=${PDS_DATA_DIRECTORY:-/pds}'
63
63
+
- 'PDS_BASE_URL=http://pds:3000'
64
64
+
- GATEKEEPER_HOST=0.0.0.0
65
65
+
depends_on:
66
66
+
- pds
67
67
+
healthcheck:
68
68
+
test:
69
69
+
- CMD
70
70
+
- timeout
71
71
+
- '1'
72
72
+
- bash
73
73
+
- '-c'
74
74
+
- 'cat < /dev/null > /dev/tcp/0.0.0.0/8080'
75
75
+
interval: 10s
76
76
+
timeout: 5s
77
77
+
retries: 3
78
78
+
start_period: 10s
79
79
+
labels:
80
80
+
- traefik.enable=true
81
81
+
- 'traefik.http.routers.pds-gatekeeper.rule=Host(`yourpds.com`) && (Path(`/xrpc/com.atproto.server.getSession`) || Path(`/xrpc/com.atproto.server.updateEmail`) || Path(`/xrpc/com.atproto.server.createSession`) || Path(`/xrpc/com.atproto.server.createAccount`) || Path(`/@atproto/oauth-provider/~api/sign-in`))'
82
82
+
- traefik.http.routers.pds-gatekeeper.entrypoints=https
83
83
+
- traefik.http.routers.pds-gatekeeper.tls=true
84
84
+
- traefik.http.routers.pds-gatekeeper.priority=100
85
85
+
- traefik.http.routers.pds-gatekeeper.middlewares=gatekeeper-cors
86
86
+
- traefik.http.services.pds-gatekeeper.loadbalancer.server.port=8080
87
87
+
- traefik.http.services.pds-gatekeeper.loadbalancer.server.scheme=http
88
88
+
- 'traefik.http.middlewares.gatekeeper-cors.headers.accesscontrolallowmethods=GET,POST,PUT,DELETE,OPTIONS,PATCH'
89
89
+
- 'traefik.http.middlewares.gatekeeper-cors.headers.accesscontrolallowheaders=*'
90
90
+
- 'traefik.http.middlewares.gatekeeper-cors.headers.accesscontrolalloworiginlist=*'
91
91
+
- traefik.http.middlewares.gatekeeper-cors.headers.accesscontrolmaxage=100
92
92
+
- traefik.http.middlewares.gatekeeper-cors.headers.addvaryheader=true
93
93
+
- traefik.http.middlewares.gatekeeper-cors.headers.accesscontrolallowcredentials=true
94
94
+
```
95
95
+
52
96
## Caddy setup
53
97
54
98
For the reverse proxy I use caddy. This part is what overwrites the endpoints and proxies them to PDS gatekeeper to add
+73
examples/coolify-compose.yml
Reviewed
···
1
1
+
services:
2
2
+
pds:
3
3
+
image: 'ghcr.io/bluesky-social/pds:0.4.182'
4
4
+
volumes:
5
5
+
- '/pds:/pds'
6
6
+
environment:
7
7
+
- SERVICE_URL_PDS_3000
8
8
+
- 'PDS_HOSTNAME=${SERVICE_FQDN_PDS_3000}'
9
9
+
- 'PDS_JWT_SECRET=${SERVICE_HEX_32_JWTSECRET}'
10
10
+
- 'PDS_ADMIN_PASSWORD=${SERVICE_PASSWORD_ADMIN}'
11
11
+
- 'PDS_ADMIN_EMAIL=${PDS_ADMIN_EMAIL}'
12
12
+
- 'PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX=${SERVICE_HEX_32_ROTATIONKEY}'
13
13
+
- 'PDS_DATA_DIRECTORY=${PDS_DATA_DIRECTORY:-/pds}'
14
14
+
- 'PDS_BLOBSTORE_DISK_LOCATION=${PDS_DATA_DIRECTORY:-/pds}/blocks'
15
15
+
- 'PDS_BLOB_UPLOAD_LIMIT=${PDS_BLOB_UPLOAD_LIMIT:-104857600}'
16
16
+
- 'PDS_DID_PLC_URL=${PDS_DID_PLC_URL:-https://plc.directory}'
17
17
+
- 'PDS_EMAIL_FROM_ADDRESS=${PDS_EMAIL_FROM_ADDRESS}'
18
18
+
- 'PDS_EMAIL_SMTP_URL=${PDS_EMAIL_SMTP_URL}'
19
19
+
- 'PDS_BSKY_APP_VIEW_URL=${PDS_BSKY_APP_VIEW_URL:-https://api.bsky.app}'
20
20
+
- 'PDS_BSKY_APP_VIEW_DID=${PDS_BSKY_APP_VIEW_DID:-did:web:api.bsky.app}'
21
21
+
- 'PDS_REPORT_SERVICE_URL=${PDS_REPORT_SERVICE_URL:-https://mod.bsky.app/xrpc/com.atproto.moderation.createReport}'
22
22
+
- 'PDS_REPORT_SERVICE_DID=${PDS_REPORT_SERVICE_DID:-did:plc:ar7c4by46qjdydhdevvrndac}'
23
23
+
- 'PDS_CRAWLERS=${PDS_CRAWLERS:-https://bsky.network}'
24
24
+
- 'LOG_ENABLED=${LOG_ENABLED:-true}'
25
25
+
command: "sh -c '\n set -euo pipefail\n echo \"Installing required packages and pdsadmin...\"\n apk add --no-cache openssl curl bash jq coreutils gnupg util-linux-misc >/dev/null\n curl -o /usr/local/bin/pdsadmin.sh https://raw.githubusercontent.com/bluesky-social/pds/main/pdsadmin.sh\n chmod 700 /usr/local/bin/pdsadmin.sh\n ln -sf /usr/local/bin/pdsadmin.sh /usr/local/bin/pdsadmin\n echo \"Creating an empty pds.env file so pdsadmin works...\"\n touch ${PDS_DATA_DIRECTORY}/pds.env\n echo \"Launching PDS, enjoy!...\"\n exec node --enable-source-maps index.js\n'\n"
26
26
+
healthcheck:
27
27
+
test:
28
28
+
- CMD
29
29
+
- wget
30
30
+
- '--spider'
31
31
+
- 'http://127.0.0.1:3000/xrpc/_health'
32
32
+
interval: 5s
33
33
+
timeout: 10s
34
34
+
retries: 10
35
35
+
gatekeeper:
36
36
+
container_name: gatekeeper
37
37
+
image: 'fatfingers23/pds_gatekeeper:latest'
38
38
+
restart: unless-stopped
39
39
+
volumes:
40
40
+
- '/pds:/pds'
41
41
+
environment:
42
42
+
- 'PDS_DATA_DIRECTORY=${PDS_DATA_DIRECTORY:-/pds}'
43
43
+
- 'PDS_BASE_URL=http://pds:3000'
44
44
+
- GATEKEEPER_HOST=0.0.0.0
45
45
+
depends_on:
46
46
+
- pds
47
47
+
healthcheck:
48
48
+
test:
49
49
+
- CMD
50
50
+
- timeout
51
51
+
- '1'
52
52
+
- bash
53
53
+
- '-c'
54
54
+
- 'cat < /dev/null > /dev/tcp/0.0.0.0/8080'
55
55
+
interval: 10s
56
56
+
timeout: 5s
57
57
+
retries: 3
58
58
+
start_period: 10s
59
59
+
labels:
60
60
+
- traefik.enable=true
61
61
+
- 'traefik.http.routers.pds-gatekeeper.rule=Host(`yourpds.com`) && (Path(`/xrpc/com.atproto.server.getSession`) || Path(`/xrpc/com.atproto.server.updateEmail`) || Path(`/xrpc/com.atproto.server.createSession`) || Path(`/xrpc/com.atproto.server.createAccount`) || Path(`/@atproto/oauth-provider/~api/sign-in`))'
62
62
+
- traefik.http.routers.pds-gatekeeper.entrypoints=https
63
63
+
- traefik.http.routers.pds-gatekeeper.tls=true
64
64
+
- traefik.http.routers.pds-gatekeeper.priority=100
65
65
+
- traefik.http.routers.pds-gatekeeper.middlewares=gatekeeper-cors
66
66
+
- traefik.http.services.pds-gatekeeper.loadbalancer.server.port=8080
67
67
+
- traefik.http.services.pds-gatekeeper.loadbalancer.server.scheme=http
68
68
+
- 'traefik.http.middlewares.gatekeeper-cors.headers.accesscontrolallowmethods=GET,POST,PUT,DELETE,OPTIONS,PATCH'
69
69
+
- 'traefik.http.middlewares.gatekeeper-cors.headers.accesscontrolallowheaders=*'
70
70
+
- 'traefik.http.middlewares.gatekeeper-cors.headers.accesscontrolalloworiginlist=*'
71
71
+
- traefik.http.middlewares.gatekeeper-cors.headers.accesscontrolmaxage=100
72
72
+
- traefik.http.middlewares.gatekeeper-cors.headers.addvaryheader=true
73
73
+
- traefik.http.middlewares.gatekeeper-cors.headers.accesscontrolallowcredentials=true