···11[package]
22name = "porxie"
33-description = "A correct and efficient ATProto Blob proxy service with caching and policy enforcement."
33+description = "A correct and efficient ATProto blob proxy for secure content delivery."
44authors = ["Blooym"]
55repository = "https://codeberg.org/Blooym/porxie"
66homepage = "https://codeberg.org/Blooym/porxie/src/branch/main/README.md"
+212-180
README.md
···11# Porxie
2233-A correct and efficient ATProto Blob proxy service with caching and policy enforcement.
33+A correct and efficient ATProto blob proxy for secure content delivery.
4455## Features
6677-- **Secure by default** - verifies blob CIDs are legitimate and serves them with strict headers.
88-- **MIME type filtering** - auto-detects blob MIME type from content and optionally restricts which types can be served. Detection falls back to `application/octet-stream` when the type cannot be inferred.
99-- **Policy enforcement** - optional integration with an external policy service to control which blobs can be served. Bring your own rules.
1010-- **In-memory cache** - TinyLFU-based caching for fast repeat access to frequently requested content and policy decisions. Manual cache purging is supported via a simple authenticated HTTP DELETE request.
77+- Blob validation - verifies blob content matches its CID and rejects invalid/tampered content.
88+- Secure serving - blobs are always served with secure headers to help improve end-user security.
99+- MIME filtering - detects blob content MIME-types and enforces an optional allowlist of permitted types.
1010+- Policy enforcement - optionally integrate with an external policy service (like an AppView) to control which blobs can be served.
1111+- In-memory cache - configurable in-memory caching for fast repeat access with support for manual cache purging via authenticated HTTP DELETE.
11121213## Routes
13141414-- **GET** `/{did}/{cid}` - Resolve and fetch a blob from its origin.
1515-- **DELETE** `/cache/{cid or did}` - Invalidate cache for either a CID (blob, policy, ownership) or for a DID (ownerships and policies). Requires configured bearer auth token.
1515+- [GET] `/{did}/{cid}`: Resolve and fetch a blob from its origin.
1616+- [DELETE] `/cache/{cid or did}`: Invalidate all valid cache items for a specific blob CID or for an entire user DID. Requires configured bearer auth token.
16171718## Usage
18191919-Porxie does not handle TLS, so it should be placed behind a reverse proxy such as [Caddy](https://caddyserver.com), [Traefik](https://traefik.io/traefik), or [nginx](https://nginx.org). Make sure your reverse proxy (and any other intermediaries) pass through, at minimum, the `Cache-Control`, `Content-Security-Policy` and `Content-Disposition` headers from upstream responses.
2020-2121-It is also recommended to put a CDN in front of Porxie for long-term caching and faster responses. Additionally, as Porxie is stateless, you can deploy in several regions for better availability.
2020+> [!NOTE]
2121+> Porxie does not handle TLS, so it should be placed behind a reverse proxy like [Caddy](https://caddyserver.com), [Traefik](https://traefik.io/traefik), or [NGINX](https://nginx.org). Ensure that any intermediaries between Porxie and the client pass through the `Cache-Control`, `Content-Security-Policy` and `Content-Disposition` headers, or otherwise set them securely.
2222+>
2323+> Putting a CDN in front of Porxie is also recommended for better long-term caching and worldwide latency.
22242325### Run: Binary
2426···6668 - no-new-privileges
6769```
68706969-### Run: Docker Compose & Imgproxy
7171+### Run: Nix
70727171-[Imgproxy](https://imgproxy.net) can be placed in front of Porxie to handle image transformations such as resizing, cropping, and format conversions.
7373+For Nix users, a [`flake.nix`](./flake.nix) is included in this repository that provides a package and a NixOS module. Please note that this is maintained on a best-effort basis for now and may be upstreamed by another contributor later.
72747373-Using Docker Compose, an example `compose.yml` would look like this:
7575+## Policy Service
74767575-```yaml
7676-services:
7777- porxie:
7878- image: ghcr.io/blooym/porxie:latest
7979- restart: unless-stopped
8080- read_only: true
8181- cap_drop:
8282- - ALL
8383- security_opt:
8484- - no-new-privileges
8585- environment:
8686- PORXIE_BLOB_ALLOWED_MIMETYPES: "image/*"
8787- PORXIE_BLOB_MAX_SIZE: 25mb
7777+Porxie can optionally check with an external HTTP service before serving any blob. You build and run this service yourself - Porxie just calls it and acts on the response. This is useful for things like content takedowns or blob allow lists.
88788989- imgproxy:
9090- image: darthsim/imgproxy:latest
9191- restart: unless-stopped
9292- read_only: true
9393- cap_drop:
9494- - ALL
9595- security_opt:
9696- - no-new-privileges
9797- depends_on:
9898- - porxie
9999- environment:
100100- # See https://docs.imgproxy.net/configuration/options for all options.
101101- IMGPROXY_BIND: ":8080"
102102- IMGPROXY_BASE_URL: "http://porxie:6314/"
103103- IMGPROXY_ALLOWED_SOURCES: "http://porxie:6314/"
104104- IMGPROXY_MAX_SRC_FILE_SIZE: 25000000
105105- IMGPROXY_CACHE_CONTROL_PASSTHROUGH: true
106106- IMGPROXY_RETURN_ATTACHMENT: true
107107- IMGPROXY_STRIP_METADATA: true
108108-```
7979+For every incoming request, Porxie sends `GET <policy-service-url>/<did>/<cid>` and expects one of the following responses:
10980110110-#### Replicating cdn.bsky.app
8181+- **200 OK** - the blob is allowed and will be served.
8282+- **410 Gone** - the blob is restricted and Porxie will refuse to serve it to the client.
11183112112-Bluesky's CDN serves images at URLs in the form of `https://cdn.bsky.app/img/{preset}/plain/{did}/{cid}@{format}`. By configuring imgproxy with matching presets and enabling preset-only mode, you can use the same URL scheme as a near drop-in replacement. Set the following presets:
8484+Any other status code is treated as an error for now.
11385114114-```yaml
115115-IMGPROXY_PRESETS: >-
116116- avatar=rs:fill:1000:1000:1:1/g:ce/ext:webp,
117117- avatar_thumbnail=rs:fill:128:128:1:1/g:ce/q:70/ext:webp,
118118- feed_thumbnail=rs:fit:1000:0/q:70/ext:webp,
119119- feed_fullsize=ext:webp,
120120- banner=rs:fill:3000:1000:1:1/g:ce/ext:webp
121121-IMGPROXY_ONLY_PRESETS: true
122122-```
8686+Policy decisions are cached per DID+CID pair, so your service won't be hit on every request. To clear a cached decision early, use the `DELETE /cache/{cid}` endpoint.
12387124124-Please refer to the imgproxy documentation for up-to-date details if you wish to add more or modify these. **Bluesky may change the format of their CDN at any time.**
8888+By default, Porxie will fail-closed: if the policy service errors, the blob request fails too. This can be changed to fail-open if preferred.
12589126126-## Policy Service
9090+See the [Configuration](#configuration) section for all available policy options.
12791128128-The policy service is an optional external HTTP service that Porxie consults before serving any blob. You build and run the service yourself - Porxie just calls it and acts on the response. This lets you implement domain-specific policy for your service such as takedowns, allow lists, account-level bans, or anything else.
9292+## Configuration
12993130130-### How it works
9494+All options can be set via flags, environment variables, or a `.env` file. For the most detailed and up-to-date descriptions, use `porxie --help`.
13195132132-For every incoming request, Porxie sends `GET <policy-service-url>/<did>/<cid>` to your policy service. The response code received will determine what Porxie does:
9696+### Server
13397134134-- **200 OK**: the blob is allowed and will be served
135135-- **410 Gone**: the blob is restricted; Porxie returns 410 to the client
9898+```
9999+--server-address <SA_ADDRESS>
100100+ Address to bind the server to.
136101137137-Any other status code is treated as an error.
102102+ Use the 'ip:' prefix for an IP address (e.g. 'ip:127.0.0.1:6314'), or on UNIX systems,
103103+ the 'unix:' prefix for a UNIX socket path (e.g. 'unix:/run/porxie.sock').
138104139139-Policy decisions are cached per DID+CID pair for the duration set by `--cache-policy-ttl`, so your service will not be hit on every request. To clear a cached decision immediately, use the `DELETE /cache/{cid}` endpoint.
105105+ [env: PORXIE_SERVER_ADDRESS=]
106106+ [default: ip:127.0.0.1:6314]
140107141141-### Headers
108108+--server-auth-token <SA_SERVER_AUTH_TOKEN>
109109+ Bearer token for authenticating admin requests.
142110143143-Custom headers can be attached to every request Porxie sends to the policy service, for example to pass authentication credentials. See the [Configuration](#configuration) section for details.
111111+ When unset, all authenticated endpoints will reject requests with HTTP 401.
144112145145-### Fail-open vs fail-closed
113113+ [env: PORXIE_SERVER_AUTH_TOKEN=]
114114+```
146115147147-By default, if the policy service is unreachable or returns an unexpected status, Porxie blocks the request and returns a 500. This is fail-closed behaviour. When `--policy-fail-open` is set, requests will go through as normal. Use this if uptime matters more to you than strict enforcement.
116116+### Blob
148117149149-## Configuration
118118+```
119119+--blob-allowed-mimetypes <BA_BLOB_ALLOWED_MIMETYPES>
120120+ Blob mimetypes that can be served.
150121151151-All options can be set via flags, environment variables, or a `.env` file. For up-to-date and complete help, please use the `--help` flag.
122122+ Validation is done loosely via content inference. Further validation can be done by a
123123+ layer above this proxy, such as an image transformation service. When inference fails,
124124+ the blob's type falls back to `application/octet-stream`. When that type is allowed,
125125+ blobs failing inference can still be served.
152126153153-```
154154-Usage: porxie [OPTIONS]
127127+ When using the CLI, the flag can be used multiple times. When setting via environment
128128+ variable, values are comma-separated
129129+ (e.g. `PORXIE_BLOB_ALLOWED_MIMETYPES="video/*,image/*"`).
155130156156-Options:
157157- -h, --help
158158- Print help (see a summary with '-h')
131131+ [env: PORXIE_BLOB_ALLOWED_MIMETYPES=]
132132+ [default: image/*]
159133160160- -V, --version
161161- Print version
134134+--blob-max-size <BA_BLOB_MAX_SIZE>
135135+ Maximum blob size that can be fetched and served.
162136163163-Server Options:
164164- --server-address <SA_ADDRESS>
165165- Address to bind the server to.
137137+ Blobs that exceed this limit will return HTTP 413. Setting this too high can exhaust
138138+ process or system memory. The minimum value is 512kb.
166139167167- Use the 'ip:' prefix for an IP address (e.g. 'ip:127.0.0.1:6314'), or on Unix systems, the 'unix:' prefix for a Unix socket path (e.g. 'unix:/run/porxie.sock').
140140+ [env: PORXIE_BLOB_MAX_SIZE=]
141141+ [default: 50mb]
168142169169- [env: PORXIE_SERVER_ADDRESS=]
170170- [default: ip:127.0.0.1:6314]
143143+--blob-cache-header <BA_BLOB_CACHE_HEADER>
144144+ The Cache-Control header value to send alongside blob responses.
171145172172- --server-auth-token <SA_SERVER_AUTH_TOKEN>
173173- Bearer token for authenticating admin requests.
146146+ This does not affect internal cache lifetimes, only how downstream clients such as CDNs
147147+ and browsers are instructed to cache responses. Intermediary caches may need to be
148148+ cleared manually for changes to take effect quickly.
174149175175- When unset, all authenticated endpoints will reject requests with HTTP 401.
150150+ [env: PORXIE_BLOB_CACHE_HEADER=]
151151+ [default: "public, max-age=604800, must-revalidate, immutable"]
176152177177- [env: PORXIE_SERVER_AUTH_TOKEN=]
153153+--blob-processing-timeout <BA_BLOB_PROCESSING_TIMEOUT>
154154+ Maximum duration a blob can be processed by this server before aborting
178155179179-Blob Options:
180180- --blob-allowed-mimetypes <BA_BLOB_ALLOWED_MIMETYPES>
181181- Blob mimetypes that can be served.
156156+ [env: PORXIE_BLOB_PROCESSING_TIMEOUT=]
157157+ [default: 1m]
182158183183- Validation is done loosely via content inference. Further validation can be done by a layer above this proxy, such as an image transformation service. When inference fails, the blob's type falls back to `application/octet-stream`. When that type is allowed, blobs failing inference can still be served.
159159+--blob-http-timeout <BA_BLOB_FETCH_TIMEOUT>
160160+ Maximum duration before blob fetch requests are timed out
184161185185- When using the CLI, the flag can be used multiple times. When setting via environment variable, values are comma-separated (e.g. `PORXIE_BLOB_ALLOWED_MIMETYPES="video/*,image/*"`).
162162+ [env: PORXIE_BLOB_HTTP_TIMEOUT=]
163163+ [default: 30s]
186164187187- [env: PORXIE_BLOB_ALLOWED_MIMETYPES=]
188188- [default: image/*]
165165+--blob-http-connect-timeout <BA_BLOB_FETCH_CONNECT_TIMEOUT>
166166+ Maximum duration before an attempted connection to a blob upstream is aborted.
189167190190- --blob-max-size <BA_BLOB_MAX_SIZE>
191191- Maximum blob size that can be fetched and served.
168168+ This value should be lower than --blob-http-timeout.
192169193193- Blobs that exceed this limit will return HTTP 413. Setting this too high can exhaust process or system memory. The minimum value is 512kb.
170170+ [env: PORXIE_BLOB_HTTP_CONNECT_TIMEOUT=]
171171+ [default: 10s]
172172+```
194173195195- [env: PORXIE_BLOB_MAX_SIZE=]
196196- [default: 50mb]
174174+### Identity
197175198198- --blob-cache-header <BA_BLOB_CACHE_HEADER>
199199- The Cache-Control header value to send alongside blob responses.
176176+```
177177+--identity-plc-url <IA_PLC_URL>
178178+ URL of the PLC instance used for `did:plc` lookups.
200179201201- This does not affect internal cache lifetimes, only how downstream clients such as CDNs and browsers are instructed to cache responses. Intermediary caches may need to be cleared manually for changes to take effect quickly.
180180+ Can typically be left as default unless using a custom or local development setup.
202181203203- [env: PORXIE_BLOB_CACHE_HEADER=]
204204- [default: "public, max-age=604800, must-revalidate, immutable"]
182182+ [env: PORXIE_IDENTITY_PLC_URL=]
183183+ [default: https://plc.directory]
205184206206- --blob-processing-timeout <BA_BLOB_PROCESSING_TIMEOUT>
207207- Maximum duration a blob can be processed by this server before aborting
185185+--identity-http-timeout <IA_IDENTITY_HTTP_TIMEOUT>
186186+ Maximum duration before identity resolution requests are timed out
208187209209- [env: PORXIE_BLOB_PROCESSING_TIMEOUT=]
210210- [default: 1m]
188188+ [env: PORXIE_IDENTITY_HTTP_TIMEOUT=]
189189+ [default: 10s]
211190212212- --blob-http-timeout <BA_BLOB_FETCH_TIMEOUT>
213213- Maximum duration before blob fetch requests are timed out.
191191+--identity-http-connect-timeout <IA_IDENTITY_HTTP_CONNECT_TIMEOUT>
192192+ Maximum duration before a connection attempt to an identity upstream is aborted.
214193215215- [env: PORXIE_BLOB_HTTP_TIMEOUT=]
216216- [default: 30s]
194194+ This value should be lower than --identity-http-timeout.
217195218218- --blob-http-connect-timeout <BA_BLOB_FETCH_CONNECT_TIMEOUT>
219219- Maximum duration before an attempted connection to a blob upstream is aborted.
196196+ [env: PORXIE_IDENTITY_HTTP_CONNECT_TIMEOUT=]
197197+ [default: 8s]
198198+```
220199221221- This value should be lower than --blob-http-timeout.
200200+### Cache
222201223223- [env: PORXIE_BLOB_HTTP_CONNECT_TIMEOUT=]
224224- [default: 10s]
202202+```
203203+--cache-allocation <CA_CACHE_ALLOCATION>
204204+ Total memory allocation for the internal cache.
225205226226-Identity Options:
227227- --identity-plc-url <IA_PLC_URL>
228228- URL of the PLC instance used for `did:plc` lookups.
206206+ Blobs are cached using an LFU policy. The most frequently requested blobs are kept
207207+ longest when the cache approaches its limit.
229208230230- Can typically be left as default unless using a custom or local development setup.
209209+ For production deployments, a CDN or caching layer in front of this server is
210210+ recommended for lower latency and better global availability.
231211232232- [env: PORXIE_IDENTITY_PLC_URL=]
233233- [default: https://plc.directory]
212212+ Setting this too high can exhaust process or system memory. The minimum value is 8mb.
234213235235- --identity-http-timeout <IA_IDENTITY_HTTP_TIMEOUT>
236236- Maximum duration before identity resolution requests are timed out
214214+ [env: PORXIE_CACHE_ALLOCATION=]
215215+ [default: 512mb]
237216238238- [env: PORXIE_IDENTITY_HTTP_TIMEOUT=]
239239- [default: 10s]
217217+--cache-blob-tti <CA_CACHE_BLOB_TTI>
218218+ How long blobs can be idle in the cache before expiring
240219241241- --identity-http-connect-timeout <IA_IDENTITY_HTTP_CONNECT_TIMEOUT>
242242- Maximum duration before a connection attempt to an identity upstream is aborted.
220220+ [env: PORXIE_CACHE_BLOB_TTI=]
221221+ [default: 7days]
243222244244- This value should be lower than --identity-http-timeout.
223223+--cache-ownership-ttl <CA_CACHE_OWNERSHIP_TTL>
224224+ How long blob ownership can be cached before expiring
245225246246- [env: PORXIE_IDENTITY_HTTP_CONNECT_TIMEOUT=]
247247- [default: 8s]
226226+ [env: PORXIE_CACHE_OWNERSHIP_TTL=]
227227+ [default: 1day]
248228249249-Cache Options:
250250- --cache-allocation <CA_CACHE_ALLOCATION>
251251- Total memory allocation for the internal cache.
229229+--cache-policy-ttl <CA_CACHE_POLICY_TTL>
230230+ How long policy decisions can be cached before expiring
252231253253- Blobs are cached using an LFU policy. The most frequently requested blobs are kept longest when the cache approaches its limit.
232232+ [env: PORXIE_CACHE_POLICY_TTL=]
233233+ [default: 1h]
254234255255- For production deployments, a CDN or caching layer in front of this server is recommended for lower latency and better global availability.
235235+--cache-identity-ttl <CA_CACHE_IDENTITY_TTL>
236236+ How long identity lookups (DID resolution, etc) can be cached before expiring
256237257257- Setting this too high can exhaust process or system memory. The minimum value is 8mb.
238238+ [env: PORXIE_CACHE_IDENTITY_TTL=]
239239+ [default: 1h]
240240+```
258241259259- [env: PORXIE_CACHE_ALLOCATION=]
260260- [default: 512mb]
242242+### Policy Service
261243262262- --cache-blob-tti <CA_CACHE_BLOB_TTI>
263263- How long blobs can be idle in the cache before expiring
244244+```
245245+--policy-url <PA_POLICY_URL>
246246+ Policy service URL that DID+CID pairs will be checked against.
264247265265- [env: PORXIE_CACHE_BLOB_TTI=]
266266- [default: 7days]
248248+ Requests are sent as HTTP GET <url>/<did>/<cid>.
267249268268- --cache-ownership-ttl <CA_CACHE_OWNERSHIP_TTL>
269269- How long blob ownership can be cached before expiring
250250+ The service is expected to return HTTP 200 (OK) if permitted or HTTP 410 (GONE) if
251251+ restricted.
270252271271- [env: PORXIE_CACHE_OWNERSHIP_TTL=]
272272- [default: 1day]
253253+ [env: PORXIE_POLICY_URL=]
273254274274- --cache-policy-ttl <CA_CACHE_POLICY_TTL>
275275- How long policy decisions can be cached before expiring
255255+--policy-request-headers <PA_POLICY_REQ_HEADERS>
256256+ Headers sent alongside all requests to the policy service.
276257277277- [env: PORXIE_CACHE_POLICY_TTL=]
278278- [default: 1h]
258258+ Each header must be in the format "Name: value". When using the CLI, the flag can be
259259+ used multiple times. When setting via environment variable, headers are
260260+ pipe-separated (|).
279261280280-Policy Service Options:
281281- --policy-url <PA_POLICY_URL>
282282- Policy service URL that DID+CID pairs will be checked against.
262262+ As pipes are used as a delimiter, they cannot be contained in headers.
283263284284- Requests are sent as HTTP GET <url>/<did>/<cid>.
264264+ Example (cli): '--policy-request-headers "Authorization: Bearer token"
265265+ --policy-request-headers "X-Api-Key: your-key"'
285266286286- The service is expected to return HTTP 200 (OK) if permitted or HTTP 410 (GONE) if restricted.
267267+ Example (env): 'PORXIE_POLICY_REQUEST_HEADERS="Authorization: Bearer
268268+ token|X-Api-Key: your-key"'
287269288288- [env: PORXIE_POLICY_URL=]
270270+ [env: PORXIE_POLICY_REQUEST_HEADERS=]
289271290290- --policy-request-headers <PA_POLICY_REQ_HEADERS>
291291- Headers sent alongside all requests to the policy service.
272272+--policy-fail-open
273273+ Allow requests to proceed if the policy service is unavailable or returns an
274274+ unexpected status code.
292275293293- Each header must be in the format "Name: value". When using the CLI, the flag can be used multiple times. When setting via environment variable, headers are pipe-separated (|).
276276+ Warning: enabling this means restricted blobs may be served when the policy service
277277+ is unreachable.
294278295295- As pipes are used as a delimiter, they cannot be contained in headers.
279279+ [env: PORXIE_POLICY_FAIL_OPEN=]
296280297297- Example (cli): '--policy-request-headers "Authorization: Bearer token" --policy-request-headers "X-Api-Key: your-key"'
281281+--policy-http-timeout <PA_POLICY_HTTP_TIMEOUT>
282282+ Maximum duration before policy service requests are timed out
298283299299- Example (env): 'PORXIE_POLICY_REQUEST_HEADERS="Authorization: Bearer token|X-Api-Key: your-key"'
284284+ [env: PORXIE_POLICY_HTTP_TIMEOUT=]
285285+ [default: 30s]
300286301301- [env: PORXIE_POLICY_REQUEST_HEADERS=]
287287+--policy-http-connect-timeout <PA_POLICY_HTTP_CONNECT_TIMEOUT>
288288+ Maximum duration before an attempted connection to the policy service is aborted.
302289303303- --policy-fail-open
304304- Allow requests to proceed if the policy service is unavailable or returns an unexpected status code.
290290+ This value should be lower than --policy-http-timeout.
305291306306- Warning: enabling this means restricted blobs may be served when the policy service is unreachable.
292292+ [env: PORXIE_POLICY_HTTP_CONNECT_TIMEOUT=]
293293+ [default: 10s]
294294+```
307295308308- [env: PORXIE_POLICY_FAIL_OPEN=]
296296+## Examples
309297310310- --policy-http-timeout <PA_POLICY_HTTP_TIMEOUT>
311311- Maximum duration before policy service requests are timed out
298298+> [!NOTE]
299299+> The examples below are starting points to demonstrate what is possible with Porxie. They will likely need further modification to suit your needs and are not intended to be used as-is.
312300313313- [env: PORXIE_POLICY_HTTP_TIMEOUT=]
314314- [default: 30s]
301301+### Porxie & Imgproxy
315302316316- --policy-http-connect-timeout <PA_POLICY_HTTP_CONNECT_TIMEOUT>
317317- Maximum duration before an attempted connection to the policy service is aborted.
303303+[Imgproxy](https://imgproxy.net) can be placed in front of Porxie to handle image transformations such as resizing, cropping, and format conversions.
318304319319- This value should be lower than --policy-http-timeout.
305305+Using Docker Compose, an example `compose.yml` would look like this:
320306321321- [env: PORXIE_POLICY_HTTP_CONNECT_TIMEOUT=]
322322- [default: 10s]
307307+```yaml
308308+services:
309309+ porxie:
310310+ image: ghcr.io/blooym/porxie:latest
311311+ restart: unless-stopped
312312+ read_only: true
313313+ cap_drop:
314314+ - ALL
315315+ security_opt:
316316+ - no-new-privileges
317317+ environment:
318318+ PORXIE_BLOB_ALLOWED_MIMETYPES: "image/*"
319319+ PORXIE_BLOB_MAX_SIZE: 25mb
320320+ imgproxy:
321321+ image: darthsim/imgproxy:latest
322322+ restart: unless-stopped
323323+ read_only: true
324324+ cap_drop:
325325+ - ALL
326326+ security_opt:
327327+ - no-new-privileges
328328+ depends_on:
329329+ - porxie
330330+ environment:
331331+ # See https://docs.imgproxy.net/configuration/options for all options.
332332+ IMGPROXY_BIND: ":8080"
333333+ IMGPROXY_BASE_URL: "http://porxie:6314/"
334334+ IMGPROXY_ALLOWED_SOURCES: "http://porxie:6314/"
335335+ IMGPROXY_MAX_SRC_FILE_SIZE: 25000000
336336+ IMGPROXY_CACHE_CONTROL_PASSTHROUGH: true
337337+ IMGPROXY_RETURN_ATTACHMENT: true
338338+ IMGPROXY_STRIP_METADATA: true
323339```
340340+341341+#### Replicating cdn.bsky.app
342342+343343+Bluesky's CDN typically serves images using URLs like `https://cdn.bsky.app/img/{preset}/plain/{did}/{cid}`. By configuring imgproxy with presets and enabling preset-only mode, you can create a compatiable service. The presets below are based on what Bluesky used at the time of writing and may not be up-to-date.
344344+345345+```yaml
346346+IMGPROXY_PRESETS: >-
347347+ avatar=rs:fill:1000:1000:1:1/g:ce/ext:webp,
348348+ avatar_thumbnail=rs:fill:128:128:1:1/g:ce/q:70/ext:webp,
349349+ feed_thumbnail=rs:fit:1000:0/q:70/ext:webp,
350350+ feed_fullsize=ext:webp,
351351+ banner=rs:fill:3000:1000:1:1/g:ce/ext:webp
352352+IMGPROXY_ONLY_PRESETS: true
353353+```
354354+355355+Refer to the [imgproxy documentation](https://docs.imgproxy.net) for details on creating and modifying presets.
+2-2
src/main.rs
···9191struct ServerArgs {
9292 /// Address to bind the server to.
9393 ///
9494- /// Use the 'ip:' prefix for an IP address (e.g. 'ip:127.0.0.1:6314'), or on Unix systems,
9595- /// the 'unix:' prefix for a Unix socket path (e.g. 'unix:/run/porxie.sock').
9494+ /// Use the 'ip:' prefix for an IP address (e.g. 'ip:127.0.0.1:6314'), or on UNIX systems,
9595+ /// the 'unix:' prefix for a UNIX socket path (e.g. 'unix:/run/porxie.sock').
9696 #[arg(
9797 id = "SA_ADDRESS",
9898 long = "server-address",
+1-1
src/routes/mod.rs
···2828|_| \___/|_| /_/\_\_|\___|
292930303131-A correct and efficient ATProto blob proxy service.
3131+A correct and efficient ATProto blob proxy for secure content delivery.
32323333Links:
3434 - Repo: https://codeberg.org/Blooym/porxie