A social knowledge tool for researchers built on ATProto
1# Deployment Guide 2 3This guide covers how to deploy the Annotations API service both locally for development and to production using fly.io. 4 5## Prerequisites 6 7- [Docker](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/install/) 8- [Node.js](https://nodejs.org/) (v18 or later) 9- [npm](https://www.npmjs.com/) or [yarn](https://yarnpkg.com/) 10- [Git](https://git-scm.com/) 11- [flyctl](https://fly.io/docs/hands-on/install-flyctl/) (for fly.io deployment only) 12 13## Local Deployment 14 15### Environment Setup 16 171. Clone the repository: 18 19 ```bash 20 git clone <repository-url> 21 cd <repository-directory> 22 ``` 23 242. Create environment files: 25 26 ```bash 27 cp .env.example .env.local 28 ``` 29 303. Edit `.env.local` with your configuration: 31 32 ``` 33 NODE_ENV=local 34 35 # Database 36 DB_HOST=localhost 37 DB_PORT=5432 38 DB_USERNAME=postgres 39 DB_PASSWORD=postgres 40 DB_NAME=annotations 41 42 # Auth 43 JWT_SECRET=your-local-secret-key 44 ACCESS_TOKEN_EXPIRES_IN=3600 45 REFRESH_TOKEN_EXPIRES_IN=2592000 46 47 # ATProto 48 ATPROTO_SERVICE_ENDPOINT=https://bsky.social 49 ATPROTO_REDIRECT_URI=http://127.0.0.1:3000/api/users/oauth/callback 50 51 # Server 52 PORT=3000 53 HOST=127.0.0.1 54 ``` 55 56### Using Docker Compose 57 581. Create a `docker-compose.yml` file: 59 60 ```yaml 61 version: '3.8' 62 63 services: 64 app: 65 build: 66 context: . 67 dockerfile: Dockerfile 68 ports: 69 - '3000:3000' 70 environment: 71 - NODE_ENV=local 72 - DB_HOST=db 73 - DB_PORT=5432 74 - DB_USERNAME=postgres 75 - DB_PASSWORD=postgres 76 - DB_NAME=annotations 77 depends_on: 78 - db 79 volumes: 80 - ./:/app 81 - /app/node_modules 82 83 db: 84 image: postgres:14 85 ports: 86 - '5432:5432' 87 environment: 88 - POSTGRES_USER=postgres 89 - POSTGRES_PASSWORD=postgres 90 - POSTGRES_DB=annotations 91 volumes: 92 - postgres_data:/var/lib/postgresql/data 93 94 volumes: 95 postgres_data: 96 ``` 97 982. Create a `Dockerfile`: 99 100 ```dockerfile 101 FROM node:18-alpine 102 103 WORKDIR /app 104 105 COPY package*.json ./ 106 107 RUN npm install 108 109 COPY . . 110 111 RUN npm run build 112 113 EXPOSE 3000 114 115 CMD ["npm", "run", "start"] 116 ``` 117 1183. Start the services: 119 120 ```bash 121 docker-compose up -d 122 ``` 123 1244. Run migrations (if needed): 125 126 ```bash 127 docker-compose exec app npm run migrate 128 ``` 129 1305. Access the API at http://localhost:3000 131 132### Without Docker 133 1341. Install dependencies: 135 136 ```bash 137 npm install 138 ``` 139 1402. Start a PostgreSQL database: 141 142 ```bash 143 docker run -d --name annotations-db \ 144 -e POSTGRES_USER=postgres \ 145 -e POSTGRES_PASSWORD=postgres \ 146 -e POSTGRES_DB=annotations \ 147 -p 5432:5432 \ 148 postgres:14 149 ``` 150 1513. Run migrations: 152 153 ```bash 154 npm run migrate 155 ``` 156 1574. Start the development server: 158 ```bash 159 npm run dev 160 ``` 161 162## Production Deployment with fly.io 163 164### Setup 165 1661. Install the flyctl CLI if you haven't already: 167 168 ```bash 169 curl -L https://fly.io/install.sh | sh 170 ``` 171 1722. Login to fly.io: 173 174 ```bash 175 fly auth login 176 ``` 177 1783. Create a fly.io app: 179 180 ```bash 181 fly apps create annotations-api 182 ``` 183 1844. Create a PostgreSQL database: 185 186 ```bash 187 fly postgres create --name annotations-db 188 ``` 189 1905. Attach the database to your app: 191 ```bash 192 fly postgres attach --app annotations-api annotations-db 193 ``` 194 195### Configuration 196 1971. Create a `fly.toml` file: 198 199 ```toml 200 app = "annotations-api" 201 primary_region = "iad" # Choose your preferred region 202 203 [build] 204 dockerfile = "Dockerfile" 205 206 [env] 207 NODE_ENV = "prod" 208 PORT = "8080" 209 HOST = "0.0.0.0" 210 ATPROTO_SERVICE_ENDPOINT = "https://bsky.social" 211 ATPROTO_REDIRECT_URI = "https://your-app-url.fly.dev/api/users/oauth/callback" 212 213 [http_service] 214 internal_port = 8080 215 force_https = true 216 auto_stop_machines = true 217 auto_start_machines = true 218 min_machines_running = 1 219 processes = ["app"] 220 ``` 221 2222. Set secrets: 223 224 ```bash 225 fly secrets set JWT_SECRET=your-production-secret-key \ 226 ACCESS_TOKEN_EXPIRES_IN=3600 \ 227 REFRESH_TOKEN_EXPIRES_IN=2592000 228 ``` 229 2303. Update the `Dockerfile` for production: 231 232 ```dockerfile 233 FROM node:18-alpine AS builder 234 235 WORKDIR /app 236 237 COPY package*.json ./ 238 239 RUN npm ci 240 241 COPY . . 242 243 RUN npm run build 244 245 # Production image 246 FROM node:18-alpine 247 248 WORKDIR /app 249 250 COPY --from=builder /app/package*.json ./ 251 COPY --from=builder /app/dist ./dist 252 253 RUN npm ci --only=production 254 255 EXPOSE 8080 256 257 CMD ["node", "dist/index.js"] 258 ``` 259 260### Deployment 261 2621. Deploy the application: 263 264 ```bash 265 fly deploy 266 ``` 267 2682. Open your application: 269 ```bash 270 fly open 271 ``` 272 273### Scaling 274 275To scale your application: 276 277```bash 278fly scale count 2 # Adjust the number as needed 279``` 280 281### Monitoring 282 283Monitor your application: 284 285```bash 286fly status 287fly logs 288``` 289 290## Environment Variables 291 292| Variable | Description | Default | 293| ------------------------ | ------------------------------- | ---------------------------------------------- | 294| NODE_ENV | Environment (local, dev, prod) | local | 295| DB_HOST | Database host | localhost | 296| DB_PORT | Database port | 5432 | 297| DB_USERNAME | Database username | postgres | 298| DB_PASSWORD | Database password | postgres | 299| DB_NAME | Database name | annotations | 300| DATABASE_URL | Full database connection string | - | 301| JWT_SECRET | Secret for JWT tokens | default-secret-change-in-production | 302| ACCESS_TOKEN_EXPIRES_IN | Access token expiry in seconds | 3600 | 303| REFRESH_TOKEN_EXPIRES_IN | Refresh token expiry in seconds | 2592000 | 304| ATPROTO_SERVICE_ENDPOINT | AT Protocol service endpoint | https://bsky.social | 305| ATPROTO_REDIRECT_URI | OAuth callback URL | http://127.0.0.1:3000/api/users/oauth/callback | 306| PORT | Server port | 3000 | 307| HOST | Server host | 127.0.0.1 | 308 309## Troubleshooting 310 311### Database Connection Issues 312 313If you encounter database connection issues: 314 3151. Verify the database is running: 316 317 ```bash 318 docker ps # For local Docker deployment 319 fly postgres list # For fly.io deployment 320 ``` 321 3222. Check connection parameters in environment variables. 323 3243. For fly.io, ensure the database is properly attached: 325 ```bash 326 fly postgres attach --app annotations-api annotations-db 327 ``` 328 329### Application Errors 330 3311. Check application logs: 332 333 ```bash 334 docker-compose logs app # For local Docker deployment 335 fly logs # For fly.io deployment 336 ``` 337 3382. Verify all required environment variables are set. 339 3403. For production issues, try redeploying: 341 ```bash 342 fly deploy 343 ```