offline-first, p2p synced, atproto enabled, feed reader

add compose stuff

+43
.containerignore
··· 1 + # Containerignore for Podman (also works as .dockerignore for Docker compatibility) 2 + 3 + # Dependencies 4 + node_modules/ 5 + 6 + # Build outputs 7 + dist/ 8 + coverage/ 9 + doc/ 10 + 11 + # Development files 12 + *.log 13 + .eslintcache 14 + .tsbuildinfo 15 + 16 + # Git 17 + .git/ 18 + .gitignore 19 + 20 + # IDE 21 + .vscode/ 22 + .idea/ 23 + 24 + # Test files 25 + **/*.spec.ts 26 + **/*.spec.tsx 27 + __mocks__/ 28 + 29 + # Documentation 30 + *.md 31 + typedoc.json 32 + 33 + # Nix 34 + flake.nix 35 + flake.lock 36 + result 37 + 38 + # Local data 39 + data/ 40 + 41 + # Environment files (compose will mount these) 42 + .env 43 + .env.*
+1
.dockerignore
··· 1 + .containerignore
+57
Containerfile
··· 1 + # Build stage - install deps and build frontend 2 + FROM node:22-slim AS builder 3 + 4 + WORKDIR /app 5 + 6 + # Install pnpm 7 + RUN corepack enable && corepack prepare pnpm@latest --activate 8 + 9 + # Copy package files first for better layer caching 10 + COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ 11 + 12 + # Install all dependencies (including dev for build) 13 + RUN pnpm install --frozen-lockfile 14 + 15 + # Copy source code 16 + COPY tsconfig.json vite.config.js ./ 17 + COPY src ./src 18 + 19 + # Build the frontend 20 + RUN pnpm run build 21 + 22 + # Production stage - minimal runtime image 23 + FROM node:22-slim AS runtime 24 + 25 + WORKDIR /app 26 + 27 + # Install pnpm 28 + RUN corepack enable && corepack prepare pnpm@latest --activate 29 + 30 + # Copy package files 31 + COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ 32 + 33 + # Install production dependencies only 34 + RUN pnpm install --frozen-lockfile --prod 35 + 36 + # Copy built frontend from builder 37 + COPY --from=builder /app/dist ./dist 38 + 39 + # Copy server source (runs with tsx) 40 + COPY tsconfig.json ./ 41 + COPY src/feedline ./src/feedline 42 + COPY src/realm ./src/realm 43 + COPY src/lib ./src/lib 44 + 45 + # Create data directory for realm storage 46 + RUN mkdir -p /data/realms 47 + 48 + # Environment variables 49 + ENV NODE_ENV=production 50 + ENV PORT=4001 51 + ENV HOST=0.0.0.0 52 + ENV REALM_STORAGE_DIR=/data/realms 53 + 54 + EXPOSE 4001 55 + 56 + # Run the server 57 + CMD ["pnpm", "exec", "tsx", "src/feedline/main.ts"]
+35
compose.yaml
··· 1 + # Usage: podman-compose up -d 2 + # Or: podman compose up -d (with compose plugin) 3 + 4 + services: 5 + feedline: 6 + build: 7 + context: . 8 + dockerfile: Containerfile 9 + restart: unless-stopped 10 + ports: 11 + - '${PORT:-4001}:4001' 12 + environment: 13 + - NODE_ENV=production 14 + - REALM_STORAGE_DIR=/data/realms 15 + - PORT=4001 16 + # Public hostname for the service (used for WebSocket URLs, etc.) 17 + - FEEDLINE_HOST=${FEEDLINE_HOST:-localhost} 18 + volumes: 19 + # Persist realm data 20 + - feedline-data:/data/realms 21 + healthcheck: 22 + test: 23 + [ 24 + 'CMD', 25 + 'node', 26 + '-e', 27 + "fetch('http://localhost:4001/').then(r => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))", 28 + ] 29 + interval: 30s 30 + timeout: 10s 31 + retries: 3 32 + start_period: 10s 33 + 34 + volumes: 35 + feedline-data: