An entry for the streamplace vod showcase
0
fork

Configure Feed

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

docs: add Docker deployment files and runner hosting guide

- Add Dockerfile for runner (Bun + Deno + ffmpeg)
- Add docker-compose.yml with volume mounts for keys
- Add HOSTING.md with deployment guides for Dokploy, Fly.io, etc.
- Add .dockerignore files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+295
+9
.dockerignore
··· 1 + node_modules 2 + **/node_modules 3 + **/dist 4 + **/*.log 5 + .env.local 6 + .git 7 + .gitignore 8 + *.md 9 + apps/web
+19
docker-compose.yml
··· 1 + services: 2 + runner: 3 + build: 4 + context: . 5 + dockerfile: packages/at-run/runner/Dockerfile 6 + ports: 7 + - "3000:3000" 8 + environment: 9 + - PORT=3000 10 + - DEV=false 11 + volumes: 12 + # Mount keys from host 13 + - ~/.at-run:/root/.at-run:ro 14 + # Optional: persistent cache for bundles 15 + - runner-cache:/tmp 16 + restart: unless-stopped 17 + 18 + volumes: 19 + runner-cache:
+4
packages/at-run/runner/.dockerignore
··· 1 + node_modules 2 + dist 3 + *.log 4 + .env.local
+33
packages/at-run/runner/Dockerfile
··· 1 + # at-run runner Dockerfile 2 + FROM oven/bun:1 AS base 3 + 4 + # Install Deno for sandboxed execution 5 + RUN curl -fsSL https://deno.land/install.sh | sh 6 + ENV DENO_INSTALL="/root/.deno" 7 + ENV PATH="${DENO_INSTALL}/bin:${PATH}" 8 + 9 + # Install ffmpeg for video processing 10 + RUN apt-get update && apt-get install -y ffmpeg && rm -rf /var/lib/apt/lists/* 11 + 12 + WORKDIR /app 13 + 14 + # Copy package files 15 + COPY package.json bun.lock ./ 16 + COPY packages/at-run/runtime/package.json ./packages/at-run/runtime/ 17 + COPY packages/at-run/runner/package.json ./packages/at-run/runner/ 18 + 19 + # Install dependencies 20 + RUN bun install --frozen-lockfile 21 + 22 + # Copy source code 23 + COPY packages/at-run/runtime ./packages/at-run/runtime 24 + COPY packages/at-run/runner ./packages/at-run/runner 25 + 26 + WORKDIR /app/packages/at-run/runner 27 + 28 + # Expose port 29 + ENV PORT=3000 30 + EXPOSE 3000 31 + 32 + # Run the server 33 + CMD ["bun", "run", "src/index.ts"]
+230
packages/at-run/runner/HOSTING.md
··· 1 + # Hosting an at-run Runner 2 + 3 + This guide covers deploying an at-run runner to production using Docker. 4 + 5 + ## Prerequisites 6 + 7 + - Docker and Docker Compose 8 + - A server with at least 1GB RAM 9 + - (Optional) FFmpeg if your bundles need video processing 10 + 11 + ## Quick Start 12 + 13 + ### 1. Generate Runner Keys 14 + 15 + On your server, create the keys directory and generate a keypair: 16 + 17 + ```bash 18 + mkdir -p ~/.at-run 19 + 20 + # Generate a keypair (you can use the CLI or create manually) 21 + # The runner will auto-generate keys on first start if none exist 22 + ``` 23 + 24 + Or create `~/.at-run/runner-key.json` manually: 25 + 26 + ```json 27 + { 28 + "publicKey": "<base64-encoded-x25519-public-key>", 29 + "secretKey": "<base64-encoded-x25519-secret-key>", 30 + "createdAt": "2026-01-01T00:00:00.000Z" 31 + } 32 + ``` 33 + 34 + ### 2. Configure the Runner (Optional) 35 + 36 + Create `~/.at-run/runner.json` for additional configuration: 37 + 38 + ```json 39 + { 40 + "did": "did:plc:your-did-here", 41 + "maxLimits": { 42 + "maxMemoryMB": 512, 43 + "timeoutMs": 300000 44 + }, 45 + "maxPermissions": { 46 + "net": true, 47 + "read": ["/tmp"], 48 + "write": ["/tmp"], 49 + "run": ["ffmpeg", "ffprobe"] 50 + }, 51 + "access": { 52 + "allowedDids": ["did:plc:trusted-author"] 53 + } 54 + } 55 + ``` 56 + 57 + Configuration options: 58 + 59 + | Field | Description | 60 + |-------|-------------| 61 + | `did` | Your AT Protocol DID (for secrets decryption) | 62 + | `maxLimits.maxMemoryMB` | Max memory per execution (default: 128) | 63 + | `maxLimits.timeoutMs` | Max execution time in ms (default: 30000, max: 600000) | 64 + | `maxPermissions` | Cap permissions bundles can request | 65 + | `access.allowedDids` | Restrict to specific bundle authors | 66 + | `access.blockedDids` | Block specific authors | 67 + 68 + ### 3. Deploy with Docker Compose 69 + 70 + Create a `docker-compose.yml`: 71 + 72 + ```yaml 73 + services: 74 + runner: 75 + build: 76 + context: . 77 + dockerfile: packages/at-run/runner/Dockerfile 78 + ports: 79 + - "3000:3000" 80 + environment: 81 + - PORT=3000 82 + - DEV=false 83 + volumes: 84 + # Use absolute path to your keys directory 85 + - /home/youruser/.at-run:/root/.at-run:ro 86 + - runner-cache:/tmp 87 + restart: unless-stopped 88 + 89 + volumes: 90 + runner-cache: 91 + ``` 92 + 93 + Deploy: 94 + 95 + ```bash 96 + docker compose up -d --build 97 + ``` 98 + 99 + ### 4. Verify Deployment 100 + 101 + ```bash 102 + curl http://localhost:3000/health 103 + # Should return: ok 104 + ``` 105 + 106 + Test executing a bundle: 107 + 108 + ```bash 109 + curl http://localhost:3000/bundle/did:plc:xxx/bundle-name/latest/endpoint 110 + ``` 111 + 112 + ## Deployment Platforms 113 + 114 + ### Dokploy 115 + 116 + 1. Create new project → "Docker Compose" or "Dockerfile" 117 + 2. Connect your Git repository 118 + 3. Configure: 119 + - **Build context:** `.` 120 + - **Dockerfile:** `packages/at-run/runner/Dockerfile` 121 + 4. Add volume mount: `/home/youruser/.at-run:/root/.at-run:ro` 122 + 5. Set environment variables: `PORT=3000`, `DEV=false` 123 + 6. Deploy 124 + 125 + ### Coolify / CapRover 126 + 127 + Similar to Dokploy - use the Dockerfile with volume mounts for keys. 128 + 129 + ### Fly.io 130 + 131 + ```bash 132 + # Create fly.toml 133 + fly launch --dockerfile packages/at-run/runner/Dockerfile 134 + 135 + # Set secrets 136 + fly secrets set AT_RUN_KEYS="$(cat ~/.at-run/runner-key.json | base64)" 137 + 138 + # Deploy 139 + fly deploy 140 + ``` 141 + 142 + Note: For Fly.io, you'll need to modify the runner to read keys from environment variables or use Fly Volumes. 143 + 144 + ### Railway / Render 145 + 146 + These platforms don't support persistent volumes well. Consider: 147 + - Storing keys in environment variables (base64 encoded) 148 + - Using external secrets management 149 + 150 + ## Security Considerations 151 + 152 + ### Keys 153 + 154 + - Keep `runner-key.json` secure - it's used to decrypt bundle secrets 155 + - Use read-only mounts (`:ro`) when possible 156 + - Never commit keys to version control 157 + 158 + ### Permissions 159 + 160 + Restrict what bundles can do via `maxPermissions`: 161 + 162 + ```json 163 + { 164 + "maxPermissions": { 165 + "net": ["*.example.com"], 166 + "read": false, 167 + "write": ["/tmp"], 168 + "run": false, 169 + "ffi": false 170 + } 171 + } 172 + ``` 173 + 174 + ### Access Control 175 + 176 + Limit which DIDs can execute bundles: 177 + 178 + ```json 179 + { 180 + "access": { 181 + "allowedDids": [ 182 + "did:plc:trusted-author-1", 183 + "did:plc:trusted-author-2" 184 + ] 185 + } 186 + } 187 + ``` 188 + 189 + ## Monitoring 190 + 191 + ### Health Check 192 + 193 + ```bash 194 + curl http://your-runner:3000/health 195 + ``` 196 + 197 + ### Logs 198 + 199 + ```bash 200 + docker compose logs -f runner 201 + ``` 202 + 203 + ### Resource Usage 204 + 205 + Monitor memory and CPU - bundles are sandboxed but can still consume resources up to configured limits. 206 + 207 + ## Troubleshooting 208 + 209 + ### "Deno is required for sandboxed execution" 210 + 211 + Deno isn't installed or not in PATH. The Dockerfile should handle this, but verify: 212 + 213 + ```bash 214 + docker compose exec runner deno --version 215 + ``` 216 + 217 + ### "Module not found" errors 218 + 219 + The bundle couldn't be fetched from the PDS. Check: 220 + - Network connectivity to the PDS 221 + - The AT URI is correct 222 + - The bundle exists and is public 223 + 224 + ### Timeout errors 225 + 226 + Increase `maxLimits.timeoutMs` in runner config or the endpoint's declared limits. 227 + 228 + ### Memory errors 229 + 230 + Increase `maxLimits.maxMemoryMB` or optimize the bundle.