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 ```