[MIRROR ONLY] A correct and efficient ATProto blob proxy for secure content delivery. codeberg.org/Blooym/porxie
36
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs: documentation first pass

ty to proof readers for helping out with this

Lyna e5b5669d f7d744eb

+216 -184
+1 -1
Cargo.toml
··· 1 1 [package] 2 2 name = "porxie" 3 - description = "A correct and efficient ATProto Blob proxy service with caching and policy enforcement." 3 + description = "A correct and efficient ATProto blob proxy for secure content delivery." 4 4 authors = ["Blooym"] 5 5 repository = "https://codeberg.org/Blooym/porxie" 6 6 homepage = "https://codeberg.org/Blooym/porxie/src/branch/main/README.md"
+212 -180
README.md
··· 1 1 # Porxie 2 2 3 - A correct and efficient ATProto Blob proxy service with caching and policy enforcement. 3 + A correct and efficient ATProto blob proxy for secure content delivery. 4 4 5 5 ## Features 6 6 7 - - **Secure by default** - verifies blob CIDs are legitimate and serves them with strict headers. 8 - - **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. 9 - - **Policy enforcement** - optional integration with an external policy service to control which blobs can be served. Bring your own rules. 10 - - **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. 7 + - Blob validation - verifies blob content matches its CID and rejects invalid/tampered content. 8 + - Secure serving - blobs are always served with secure headers to help improve end-user security. 9 + - MIME filtering - detects blob content MIME-types and enforces an optional allowlist of permitted types. 10 + - Policy enforcement - optionally integrate with an external policy service (like an AppView) to control which blobs can be served. 11 + - In-memory cache - configurable in-memory caching for fast repeat access with support for manual cache purging via authenticated HTTP DELETE. 11 12 12 13 ## Routes 13 14 14 - - **GET** `/{did}/{cid}` - Resolve and fetch a blob from its origin. 15 - - **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. 15 + - [GET] `/{did}/{cid}`: Resolve and fetch a blob from its origin. 16 + - [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. 16 17 17 18 ## Usage 18 19 19 - 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. 20 - 21 - 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. 20 + > [!NOTE] 21 + > 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. 22 + > 23 + > Putting a CDN in front of Porxie is also recommended for better long-term caching and worldwide latency. 22 24 23 25 ### Run: Binary 24 26 ··· 66 68 - no-new-privileges 67 69 ``` 68 70 69 - ### Run: Docker Compose & Imgproxy 71 + ### Run: Nix 70 72 71 - [Imgproxy](https://imgproxy.net) can be placed in front of Porxie to handle image transformations such as resizing, cropping, and format conversions. 73 + 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. 72 74 73 - Using Docker Compose, an example `compose.yml` would look like this: 75 + ## Policy Service 74 76 75 - ```yaml 76 - services: 77 - porxie: 78 - image: ghcr.io/blooym/porxie:latest 79 - restart: unless-stopped 80 - read_only: true 81 - cap_drop: 82 - - ALL 83 - security_opt: 84 - - no-new-privileges 85 - environment: 86 - PORXIE_BLOB_ALLOWED_MIMETYPES: "image/*" 87 - PORXIE_BLOB_MAX_SIZE: 25mb 77 + 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. 88 78 89 - imgproxy: 90 - image: darthsim/imgproxy:latest 91 - restart: unless-stopped 92 - read_only: true 93 - cap_drop: 94 - - ALL 95 - security_opt: 96 - - no-new-privileges 97 - depends_on: 98 - - porxie 99 - environment: 100 - # See https://docs.imgproxy.net/configuration/options for all options. 101 - IMGPROXY_BIND: ":8080" 102 - IMGPROXY_BASE_URL: "http://porxie:6314/" 103 - IMGPROXY_ALLOWED_SOURCES: "http://porxie:6314/" 104 - IMGPROXY_MAX_SRC_FILE_SIZE: 25000000 105 - IMGPROXY_CACHE_CONTROL_PASSTHROUGH: true 106 - IMGPROXY_RETURN_ATTACHMENT: true 107 - IMGPROXY_STRIP_METADATA: true 108 - ``` 79 + For every incoming request, Porxie sends `GET <policy-service-url>/<did>/<cid>` and expects one of the following responses: 109 80 110 - #### Replicating cdn.bsky.app 81 + - **200 OK** - the blob is allowed and will be served. 82 + - **410 Gone** - the blob is restricted and Porxie will refuse to serve it to the client. 111 83 112 - 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: 84 + Any other status code is treated as an error for now. 113 85 114 - ```yaml 115 - IMGPROXY_PRESETS: >- 116 - avatar=rs:fill:1000:1000:1:1/g:ce/ext:webp, 117 - avatar_thumbnail=rs:fill:128:128:1:1/g:ce/q:70/ext:webp, 118 - feed_thumbnail=rs:fit:1000:0/q:70/ext:webp, 119 - feed_fullsize=ext:webp, 120 - banner=rs:fill:3000:1000:1:1/g:ce/ext:webp 121 - IMGPROXY_ONLY_PRESETS: true 122 - ``` 86 + 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. 123 87 124 - 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.** 88 + 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. 125 89 126 - ## Policy Service 90 + See the [Configuration](#configuration) section for all available policy options. 127 91 128 - 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. 92 + ## Configuration 129 93 130 - ### How it works 94 + 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`. 131 95 132 - 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: 96 + ### Server 133 97 134 - - **200 OK**: the blob is allowed and will be served 135 - - **410 Gone**: the blob is restricted; Porxie returns 410 to the client 98 + ``` 99 + --server-address <SA_ADDRESS> 100 + Address to bind the server to. 136 101 137 - Any other status code is treated as an error. 102 + Use the 'ip:' prefix for an IP address (e.g. 'ip:127.0.0.1:6314'), or on UNIX systems, 103 + the 'unix:' prefix for a UNIX socket path (e.g. 'unix:/run/porxie.sock'). 138 104 139 - 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. 105 + [env: PORXIE_SERVER_ADDRESS=] 106 + [default: ip:127.0.0.1:6314] 140 107 141 - ### Headers 108 + --server-auth-token <SA_SERVER_AUTH_TOKEN> 109 + Bearer token for authenticating admin requests. 142 110 143 - 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. 111 + When unset, all authenticated endpoints will reject requests with HTTP 401. 144 112 145 - ### Fail-open vs fail-closed 113 + [env: PORXIE_SERVER_AUTH_TOKEN=] 114 + ``` 146 115 147 - 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. 116 + ### Blob 148 117 149 - ## Configuration 118 + ``` 119 + --blob-allowed-mimetypes <BA_BLOB_ALLOWED_MIMETYPES> 120 + Blob mimetypes that can be served. 150 121 151 - 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. 122 + Validation is done loosely via content inference. Further validation can be done by a 123 + layer above this proxy, such as an image transformation service. When inference fails, 124 + the blob's type falls back to `application/octet-stream`. When that type is allowed, 125 + blobs failing inference can still be served. 152 126 153 - ``` 154 - Usage: porxie [OPTIONS] 127 + When using the CLI, the flag can be used multiple times. When setting via environment 128 + variable, values are comma-separated 129 + (e.g. `PORXIE_BLOB_ALLOWED_MIMETYPES="video/*,image/*"`). 155 130 156 - Options: 157 - -h, --help 158 - Print help (see a summary with '-h') 131 + [env: PORXIE_BLOB_ALLOWED_MIMETYPES=] 132 + [default: image/*] 159 133 160 - -V, --version 161 - Print version 134 + --blob-max-size <BA_BLOB_MAX_SIZE> 135 + Maximum blob size that can be fetched and served. 162 136 163 - Server Options: 164 - --server-address <SA_ADDRESS> 165 - Address to bind the server to. 137 + Blobs that exceed this limit will return HTTP 413. Setting this too high can exhaust 138 + process or system memory. The minimum value is 512kb. 166 139 167 - 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'). 140 + [env: PORXIE_BLOB_MAX_SIZE=] 141 + [default: 50mb] 168 142 169 - [env: PORXIE_SERVER_ADDRESS=] 170 - [default: ip:127.0.0.1:6314] 143 + --blob-cache-header <BA_BLOB_CACHE_HEADER> 144 + The Cache-Control header value to send alongside blob responses. 171 145 172 - --server-auth-token <SA_SERVER_AUTH_TOKEN> 173 - Bearer token for authenticating admin requests. 146 + This does not affect internal cache lifetimes, only how downstream clients such as CDNs 147 + and browsers are instructed to cache responses. Intermediary caches may need to be 148 + cleared manually for changes to take effect quickly. 174 149 175 - When unset, all authenticated endpoints will reject requests with HTTP 401. 150 + [env: PORXIE_BLOB_CACHE_HEADER=] 151 + [default: "public, max-age=604800, must-revalidate, immutable"] 176 152 177 - [env: PORXIE_SERVER_AUTH_TOKEN=] 153 + --blob-processing-timeout <BA_BLOB_PROCESSING_TIMEOUT> 154 + Maximum duration a blob can be processed by this server before aborting 178 155 179 - Blob Options: 180 - --blob-allowed-mimetypes <BA_BLOB_ALLOWED_MIMETYPES> 181 - Blob mimetypes that can be served. 156 + [env: PORXIE_BLOB_PROCESSING_TIMEOUT=] 157 + [default: 1m] 182 158 183 - 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. 159 + --blob-http-timeout <BA_BLOB_FETCH_TIMEOUT> 160 + Maximum duration before blob fetch requests are timed out 184 161 185 - 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/*"`). 162 + [env: PORXIE_BLOB_HTTP_TIMEOUT=] 163 + [default: 30s] 186 164 187 - [env: PORXIE_BLOB_ALLOWED_MIMETYPES=] 188 - [default: image/*] 165 + --blob-http-connect-timeout <BA_BLOB_FETCH_CONNECT_TIMEOUT> 166 + Maximum duration before an attempted connection to a blob upstream is aborted. 189 167 190 - --blob-max-size <BA_BLOB_MAX_SIZE> 191 - Maximum blob size that can be fetched and served. 168 + This value should be lower than --blob-http-timeout. 192 169 193 - Blobs that exceed this limit will return HTTP 413. Setting this too high can exhaust process or system memory. The minimum value is 512kb. 170 + [env: PORXIE_BLOB_HTTP_CONNECT_TIMEOUT=] 171 + [default: 10s] 172 + ``` 194 173 195 - [env: PORXIE_BLOB_MAX_SIZE=] 196 - [default: 50mb] 174 + ### Identity 197 175 198 - --blob-cache-header <BA_BLOB_CACHE_HEADER> 199 - The Cache-Control header value to send alongside blob responses. 176 + ``` 177 + --identity-plc-url <IA_PLC_URL> 178 + URL of the PLC instance used for `did:plc` lookups. 200 179 201 - 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. 180 + Can typically be left as default unless using a custom or local development setup. 202 181 203 - [env: PORXIE_BLOB_CACHE_HEADER=] 204 - [default: "public, max-age=604800, must-revalidate, immutable"] 182 + [env: PORXIE_IDENTITY_PLC_URL=] 183 + [default: https://plc.directory] 205 184 206 - --blob-processing-timeout <BA_BLOB_PROCESSING_TIMEOUT> 207 - Maximum duration a blob can be processed by this server before aborting 185 + --identity-http-timeout <IA_IDENTITY_HTTP_TIMEOUT> 186 + Maximum duration before identity resolution requests are timed out 208 187 209 - [env: PORXIE_BLOB_PROCESSING_TIMEOUT=] 210 - [default: 1m] 188 + [env: PORXIE_IDENTITY_HTTP_TIMEOUT=] 189 + [default: 10s] 211 190 212 - --blob-http-timeout <BA_BLOB_FETCH_TIMEOUT> 213 - Maximum duration before blob fetch requests are timed out. 191 + --identity-http-connect-timeout <IA_IDENTITY_HTTP_CONNECT_TIMEOUT> 192 + Maximum duration before a connection attempt to an identity upstream is aborted. 214 193 215 - [env: PORXIE_BLOB_HTTP_TIMEOUT=] 216 - [default: 30s] 194 + This value should be lower than --identity-http-timeout. 217 195 218 - --blob-http-connect-timeout <BA_BLOB_FETCH_CONNECT_TIMEOUT> 219 - Maximum duration before an attempted connection to a blob upstream is aborted. 196 + [env: PORXIE_IDENTITY_HTTP_CONNECT_TIMEOUT=] 197 + [default: 8s] 198 + ``` 220 199 221 - This value should be lower than --blob-http-timeout. 200 + ### Cache 222 201 223 - [env: PORXIE_BLOB_HTTP_CONNECT_TIMEOUT=] 224 - [default: 10s] 202 + ``` 203 + --cache-allocation <CA_CACHE_ALLOCATION> 204 + Total memory allocation for the internal cache. 225 205 226 - Identity Options: 227 - --identity-plc-url <IA_PLC_URL> 228 - URL of the PLC instance used for `did:plc` lookups. 206 + Blobs are cached using an LFU policy. The most frequently requested blobs are kept 207 + longest when the cache approaches its limit. 229 208 230 - Can typically be left as default unless using a custom or local development setup. 209 + For production deployments, a CDN or caching layer in front of this server is 210 + recommended for lower latency and better global availability. 231 211 232 - [env: PORXIE_IDENTITY_PLC_URL=] 233 - [default: https://plc.directory] 212 + Setting this too high can exhaust process or system memory. The minimum value is 8mb. 234 213 235 - --identity-http-timeout <IA_IDENTITY_HTTP_TIMEOUT> 236 - Maximum duration before identity resolution requests are timed out 214 + [env: PORXIE_CACHE_ALLOCATION=] 215 + [default: 512mb] 237 216 238 - [env: PORXIE_IDENTITY_HTTP_TIMEOUT=] 239 - [default: 10s] 217 + --cache-blob-tti <CA_CACHE_BLOB_TTI> 218 + How long blobs can be idle in the cache before expiring 240 219 241 - --identity-http-connect-timeout <IA_IDENTITY_HTTP_CONNECT_TIMEOUT> 242 - Maximum duration before a connection attempt to an identity upstream is aborted. 220 + [env: PORXIE_CACHE_BLOB_TTI=] 221 + [default: 7days] 243 222 244 - This value should be lower than --identity-http-timeout. 223 + --cache-ownership-ttl <CA_CACHE_OWNERSHIP_TTL> 224 + How long blob ownership can be cached before expiring 245 225 246 - [env: PORXIE_IDENTITY_HTTP_CONNECT_TIMEOUT=] 247 - [default: 8s] 226 + [env: PORXIE_CACHE_OWNERSHIP_TTL=] 227 + [default: 1day] 248 228 249 - Cache Options: 250 - --cache-allocation <CA_CACHE_ALLOCATION> 251 - Total memory allocation for the internal cache. 229 + --cache-policy-ttl <CA_CACHE_POLICY_TTL> 230 + How long policy decisions can be cached before expiring 252 231 253 - Blobs are cached using an LFU policy. The most frequently requested blobs are kept longest when the cache approaches its limit. 232 + [env: PORXIE_CACHE_POLICY_TTL=] 233 + [default: 1h] 254 234 255 - For production deployments, a CDN or caching layer in front of this server is recommended for lower latency and better global availability. 235 + --cache-identity-ttl <CA_CACHE_IDENTITY_TTL> 236 + How long identity lookups (DID resolution, etc) can be cached before expiring 256 237 257 - Setting this too high can exhaust process or system memory. The minimum value is 8mb. 238 + [env: PORXIE_CACHE_IDENTITY_TTL=] 239 + [default: 1h] 240 + ``` 258 241 259 - [env: PORXIE_CACHE_ALLOCATION=] 260 - [default: 512mb] 242 + ### Policy Service 261 243 262 - --cache-blob-tti <CA_CACHE_BLOB_TTI> 263 - How long blobs can be idle in the cache before expiring 244 + ``` 245 + --policy-url <PA_POLICY_URL> 246 + Policy service URL that DID+CID pairs will be checked against. 264 247 265 - [env: PORXIE_CACHE_BLOB_TTI=] 266 - [default: 7days] 248 + Requests are sent as HTTP GET <url>/<did>/<cid>. 267 249 268 - --cache-ownership-ttl <CA_CACHE_OWNERSHIP_TTL> 269 - How long blob ownership can be cached before expiring 250 + The service is expected to return HTTP 200 (OK) if permitted or HTTP 410 (GONE) if 251 + restricted. 270 252 271 - [env: PORXIE_CACHE_OWNERSHIP_TTL=] 272 - [default: 1day] 253 + [env: PORXIE_POLICY_URL=] 273 254 274 - --cache-policy-ttl <CA_CACHE_POLICY_TTL> 275 - How long policy decisions can be cached before expiring 255 + --policy-request-headers <PA_POLICY_REQ_HEADERS> 256 + Headers sent alongside all requests to the policy service. 276 257 277 - [env: PORXIE_CACHE_POLICY_TTL=] 278 - [default: 1h] 258 + Each header must be in the format "Name: value". When using the CLI, the flag can be 259 + used multiple times. When setting via environment variable, headers are 260 + pipe-separated (|). 279 261 280 - Policy Service Options: 281 - --policy-url <PA_POLICY_URL> 282 - Policy service URL that DID+CID pairs will be checked against. 262 + As pipes are used as a delimiter, they cannot be contained in headers. 283 263 284 - Requests are sent as HTTP GET <url>/<did>/<cid>. 264 + Example (cli): '--policy-request-headers "Authorization: Bearer token" 265 + --policy-request-headers "X-Api-Key: your-key"' 285 266 286 - The service is expected to return HTTP 200 (OK) if permitted or HTTP 410 (GONE) if restricted. 267 + Example (env): 'PORXIE_POLICY_REQUEST_HEADERS="Authorization: Bearer 268 + token|X-Api-Key: your-key"' 287 269 288 - [env: PORXIE_POLICY_URL=] 270 + [env: PORXIE_POLICY_REQUEST_HEADERS=] 289 271 290 - --policy-request-headers <PA_POLICY_REQ_HEADERS> 291 - Headers sent alongside all requests to the policy service. 272 + --policy-fail-open 273 + Allow requests to proceed if the policy service is unavailable or returns an 274 + unexpected status code. 292 275 293 - 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 (|). 276 + Warning: enabling this means restricted blobs may be served when the policy service 277 + is unreachable. 294 278 295 - As pipes are used as a delimiter, they cannot be contained in headers. 279 + [env: PORXIE_POLICY_FAIL_OPEN=] 296 280 297 - Example (cli): '--policy-request-headers "Authorization: Bearer token" --policy-request-headers "X-Api-Key: your-key"' 281 + --policy-http-timeout <PA_POLICY_HTTP_TIMEOUT> 282 + Maximum duration before policy service requests are timed out 298 283 299 - Example (env): 'PORXIE_POLICY_REQUEST_HEADERS="Authorization: Bearer token|X-Api-Key: your-key"' 284 + [env: PORXIE_POLICY_HTTP_TIMEOUT=] 285 + [default: 30s] 300 286 301 - [env: PORXIE_POLICY_REQUEST_HEADERS=] 287 + --policy-http-connect-timeout <PA_POLICY_HTTP_CONNECT_TIMEOUT> 288 + Maximum duration before an attempted connection to the policy service is aborted. 302 289 303 - --policy-fail-open 304 - Allow requests to proceed if the policy service is unavailable or returns an unexpected status code. 290 + This value should be lower than --policy-http-timeout. 305 291 306 - Warning: enabling this means restricted blobs may be served when the policy service is unreachable. 292 + [env: PORXIE_POLICY_HTTP_CONNECT_TIMEOUT=] 293 + [default: 10s] 294 + ``` 307 295 308 - [env: PORXIE_POLICY_FAIL_OPEN=] 296 + ## Examples 309 297 310 - --policy-http-timeout <PA_POLICY_HTTP_TIMEOUT> 311 - Maximum duration before policy service requests are timed out 298 + > [!NOTE] 299 + > 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. 312 300 313 - [env: PORXIE_POLICY_HTTP_TIMEOUT=] 314 - [default: 30s] 301 + ### Porxie & Imgproxy 315 302 316 - --policy-http-connect-timeout <PA_POLICY_HTTP_CONNECT_TIMEOUT> 317 - Maximum duration before an attempted connection to the policy service is aborted. 303 + [Imgproxy](https://imgproxy.net) can be placed in front of Porxie to handle image transformations such as resizing, cropping, and format conversions. 318 304 319 - This value should be lower than --policy-http-timeout. 305 + Using Docker Compose, an example `compose.yml` would look like this: 320 306 321 - [env: PORXIE_POLICY_HTTP_CONNECT_TIMEOUT=] 322 - [default: 10s] 307 + ```yaml 308 + services: 309 + porxie: 310 + image: ghcr.io/blooym/porxie:latest 311 + restart: unless-stopped 312 + read_only: true 313 + cap_drop: 314 + - ALL 315 + security_opt: 316 + - no-new-privileges 317 + environment: 318 + PORXIE_BLOB_ALLOWED_MIMETYPES: "image/*" 319 + PORXIE_BLOB_MAX_SIZE: 25mb 320 + imgproxy: 321 + image: darthsim/imgproxy:latest 322 + restart: unless-stopped 323 + read_only: true 324 + cap_drop: 325 + - ALL 326 + security_opt: 327 + - no-new-privileges 328 + depends_on: 329 + - porxie 330 + environment: 331 + # See https://docs.imgproxy.net/configuration/options for all options. 332 + IMGPROXY_BIND: ":8080" 333 + IMGPROXY_BASE_URL: "http://porxie:6314/" 334 + IMGPROXY_ALLOWED_SOURCES: "http://porxie:6314/" 335 + IMGPROXY_MAX_SRC_FILE_SIZE: 25000000 336 + IMGPROXY_CACHE_CONTROL_PASSTHROUGH: true 337 + IMGPROXY_RETURN_ATTACHMENT: true 338 + IMGPROXY_STRIP_METADATA: true 323 339 ``` 340 + 341 + #### Replicating cdn.bsky.app 342 + 343 + 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. 344 + 345 + ```yaml 346 + IMGPROXY_PRESETS: >- 347 + avatar=rs:fill:1000:1000:1:1/g:ce/ext:webp, 348 + avatar_thumbnail=rs:fill:128:128:1:1/g:ce/q:70/ext:webp, 349 + feed_thumbnail=rs:fit:1000:0/q:70/ext:webp, 350 + feed_fullsize=ext:webp, 351 + banner=rs:fill:3000:1000:1:1/g:ce/ext:webp 352 + IMGPROXY_ONLY_PRESETS: true 353 + ``` 354 + 355 + Refer to the [imgproxy documentation](https://docs.imgproxy.net) for details on creating and modifying presets.
+2 -2
src/main.rs
··· 91 91 struct ServerArgs { 92 92 /// Address to bind the server to. 93 93 /// 94 - /// Use the 'ip:' prefix for an IP address (e.g. 'ip:127.0.0.1:6314'), or on Unix systems, 95 - /// the 'unix:' prefix for a Unix socket path (e.g. 'unix:/run/porxie.sock'). 94 + /// Use the 'ip:' prefix for an IP address (e.g. 'ip:127.0.0.1:6314'), or on UNIX systems, 95 + /// the 'unix:' prefix for a UNIX socket path (e.g. 'unix:/run/porxie.sock'). 96 96 #[arg( 97 97 id = "SA_ADDRESS", 98 98 long = "server-address",
+1 -1
src/routes/mod.rs
··· 28 28 |_| \___/|_| /_/\_\_|\___| 29 29 30 30 31 - A correct and efficient ATProto blob proxy service. 31 + A correct and efficient ATProto blob proxy for secure content delivery. 32 32 33 33 Links: 34 34 - Repo: https://codeberg.org/Blooym/porxie