···11+ARG GLEAM_VERSION=v1.13.0
22+33+# Build stage - compile the application
44+FROM ghcr.io/gleam-lang/gleam:${GLEAM_VERSION}-erlang-alpine AS builder
55+66+# Install build dependencies including Rust for NIFs
77+RUN apk add --no-cache \
88+ git \
99+ build-base \
1010+ sqlite-dev \
1111+ rust \
1212+ cargo
1313+1414+# Configure git for non-interactive use
1515+ENV GIT_TERMINAL_PROMPT=0
1616+1717+# Add local dependencies first (these change less frequently)
1818+COPY ./jetstream /build/jetstream
1919+COPY ./lexicon /build/lexicon
2020+COPY ./graphql /build/graphql
2121+COPY ./lexicon_graphql /build/lexicon_graphql
2222+2323+# Add server code
2424+COPY ./server /build/server
2525+2626+# Build Rust NIFs for lexicon package (Linux build produces .so)
2727+RUN cd /build/lexicon/native/lexicon_nif && cargo build --release && \
2828+ mkdir -p /build/lexicon/priv && \
2929+ cp /build/lexicon/native/lexicon_nif/target/release/liblexicon_nif.so /build/lexicon/priv/liblexicon_nif.so
3030+3131+# Install dependencies for all projects
3232+RUN cd /build/jetstream && gleam deps download
3333+RUN cd /build/lexicon && gleam deps download
3434+RUN cd /build/graphql && gleam deps download
3535+RUN cd /build/lexicon_graphql && gleam deps download
3636+RUN cd /build/server && gleam deps download
3737+3838+# Compile the server code
3939+RUN cd /build/server \
4040+ && gleam export erlang-shipment
4141+4242+# Runtime stage - slim image with only what's needed to run
4343+FROM ghcr.io/gleam-lang/gleam:${GLEAM_VERSION}-erlang-alpine
4444+4545+# Install runtime dependencies
4646+RUN apk add --no-cache sqlite-libs
4747+4848+# Copy the compiled server code from the builder stage
4949+COPY --from=builder /build/server/build/erlang-shipment /app
5050+5151+# Copy lexicons directory to the runtime image
5252+COPY --from=builder /build/server/priv/lexicons /app/priv/lexicons
5353+5454+# Set up the entrypoint
5555+WORKDIR /app
5656+RUN echo -e '#!/bin/sh\nexec ./entrypoint.sh "$@"' > ./start.sh \
5757+ && chmod +x ./start.sh
5858+5959+# Set environment variables
6060+ENV HOST=0.0.0.0
6161+ENV PORT=8000
6262+6363+# Expose the port the server will run on
6464+EXPOSE $PORT
6565+6666+# Run the server
6767+CMD ["./start.sh", "run"]
+18
server/.env.example
···11+# AIP (AT Protocol Identity Provider) Configuration
22+AIP_BASE_URL=https://auth.example.com
33+44+# Server Configuration
55+# HOST: The interface to bind to (use 0.0.0.0 for Docker, 127.0.0.1 for local dev)
66+HOST=127.0.0.1
77+# PORT: The port to listen on
88+PORT=8000
99+1010+# Database Configuration
1111+DATABASE_URL=quickslice.db
1212+1313+# Jetstream Configuration
1414+JETSTREAM_URL=wss://jetstream2.us-east.bsky.network/subscribe
1515+1616+# Relay Configuration
1717+RELAY_URL=https://relay1.us-west.bsky.network
1818+PLC_DIRECTORY_URL=https://plc.directory
+16-2
server/src/backfill.gleam
···11import database
22+import envoy
23import gleam/dynamic.{type Dynamic}
34import gleam/dynamic/decode
45import gleam/erlang/process.{type Subject}
···58595960/// Creates a default backfill configuration
6061pub fn default_config() -> BackfillConfig {
6262+ // Get PLC directory URL from environment variable or use default
6363+ let plc_url = case envoy.get("PLC_DIRECTORY_URL") {
6464+ Ok(url) -> url
6565+ Error(_) -> "https://plc.directory"
6666+ }
6767+6168 BackfillConfig(
6262- plc_directory_url: "https://plc.directory",
6969+ plc_directory_url: plc_url,
6370 index_actors: True,
6471 max_workers: 10,
6572 )
···483490 cursor: Option(String),
484491 acc: List(String),
485492) -> Result(List(String), String) {
493493+ // Get relay URL from environment variable or use default
494494+ let relay_url = case envoy.get("RELAY_URL") {
495495+ Ok(url) -> url
496496+ Error(_) -> "https://relay1.us-west.bsky.network"
497497+ }
498498+486499 // Build URL with large limit and cursor
487500 let base_url =
488488- "https://relay1.us-west.bsky.network/xrpc/com.atproto.sync.listReposByCollection?collection="
501501+ relay_url
502502+ <> "/xrpc/com.atproto.sync.listReposByCollection?collection="
489503 <> collection
490504 <> "&limit=1000"
491505