Deployment Guide#
This guide covers how to deploy the Annotations API service both locally for development and to production using fly.io.
Prerequisites#
- Docker and Docker Compose
- Node.js (v18 or later)
- npm or yarn
- Git
- flyctl (for fly.io deployment only)
Local Deployment#
Environment Setup#
-
Clone the repository:
git clone <repository-url> cd <repository-directory> -
Create environment files:
cp .env.example .env.local -
Edit
.env.localwith your configuration:NODE_ENV=local # Database DB_HOST=localhost DB_PORT=5432 DB_USERNAME=postgres DB_PASSWORD=postgres DB_NAME=annotations # Auth JWT_SECRET=your-local-secret-key ACCESS_TOKEN_EXPIRES_IN=3600 REFRESH_TOKEN_EXPIRES_IN=2592000 # ATProto ATPROTO_SERVICE_ENDPOINT=https://bsky.social ATPROTO_REDIRECT_URI=http://127.0.0.1:3000/api/users/oauth/callback # Server PORT=3000 HOST=127.0.0.1
Using Docker Compose#
-
Create a
docker-compose.ymlfile:version: '3.8' services: app: build: context: . dockerfile: Dockerfile ports: - '3000:3000' environment: - NODE_ENV=local - DB_HOST=db - DB_PORT=5432 - DB_USERNAME=postgres - DB_PASSWORD=postgres - DB_NAME=annotations depends_on: - db volumes: - ./:/app - /app/node_modules db: image: postgres:14 ports: - '5432:5432' environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - POSTGRES_DB=annotations volumes: - postgres_data:/var/lib/postgresql/data volumes: postgres_data: -
Create a
Dockerfile:FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build EXPOSE 3000 CMD ["npm", "run", "start"] -
Start the services:
docker-compose up -d -
Run migrations (if needed):
docker-compose exec app npm run migrate -
Access the API at http://localhost:3000
Without Docker#
-
Install dependencies:
npm install -
Start a PostgreSQL database:
docker run -d --name annotations-db \ -e POSTGRES_USER=postgres \ -e POSTGRES_PASSWORD=postgres \ -e POSTGRES_DB=annotations \ -p 5432:5432 \ postgres:14 -
Run migrations:
npm run migrate -
Start the development server:
npm run dev
Production Deployment with fly.io#
Setup#
-
Install the flyctl CLI if you haven't already:
curl -L https://fly.io/install.sh | sh -
Login to fly.io:
fly auth login -
Create a fly.io app:
fly apps create annotations-api -
Create a PostgreSQL database:
fly postgres create --name annotations-db -
Attach the database to your app:
fly postgres attach --app annotations-api annotations-db
Configuration#
-
Create a
fly.tomlfile:app = "annotations-api" primary_region = "iad" # Choose your preferred region [build] dockerfile = "Dockerfile" [env] NODE_ENV = "prod" PORT = "8080" HOST = "0.0.0.0" ATPROTO_SERVICE_ENDPOINT = "https://bsky.social" ATPROTO_REDIRECT_URI = "https://your-app-url.fly.dev/api/users/oauth/callback" [http_service] internal_port = 8080 force_https = true auto_stop_machines = true auto_start_machines = true min_machines_running = 1 processes = ["app"] -
Set secrets:
fly secrets set JWT_SECRET=your-production-secret-key \ ACCESS_TOKEN_EXPIRES_IN=3600 \ REFRESH_TOKEN_EXPIRES_IN=2592000 -
Update the
Dockerfilefor production:FROM node:18-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # Production image FROM node:18-alpine WORKDIR /app COPY --from=builder /app/package*.json ./ COPY --from=builder /app/dist ./dist RUN npm ci --only=production EXPOSE 8080 CMD ["node", "dist/index.js"]
Deployment#
-
Deploy the application:
fly deploy -
Open your application:
fly open
Scaling#
To scale your application:
fly scale count 2 # Adjust the number as needed
Monitoring#
Monitor your application:
fly status
fly logs
Environment Variables#
| Variable | Description | Default |
|---|---|---|
| NODE_ENV | Environment (local, dev, prod) | local |
| DB_HOST | Database host | localhost |
| DB_PORT | Database port | 5432 |
| DB_USERNAME | Database username | postgres |
| DB_PASSWORD | Database password | postgres |
| DB_NAME | Database name | annotations |
| DATABASE_URL | Full database connection string | - |
| JWT_SECRET | Secret for JWT tokens | default-secret-change-in-production |
| ACCESS_TOKEN_EXPIRES_IN | Access token expiry in seconds | 3600 |
| REFRESH_TOKEN_EXPIRES_IN | Refresh token expiry in seconds | 2592000 |
| ATPROTO_SERVICE_ENDPOINT | AT Protocol service endpoint | https://bsky.social |
| ATPROTO_REDIRECT_URI | OAuth callback URL | http://127.0.0.1:3000/api/users/oauth/callback |
| PORT | Server port | 3000 |
| HOST | Server host | 127.0.0.1 |
Troubleshooting#
Database Connection Issues#
If you encounter database connection issues:
-
Verify the database is running:
docker ps # For local Docker deployment fly postgres list # For fly.io deployment -
Check connection parameters in environment variables.
-
For fly.io, ensure the database is properly attached:
fly postgres attach --app annotations-api annotations-db
Application Errors#
-
Check application logs:
docker-compose logs app # For local Docker deployment fly logs # For fly.io deployment -
Verify all required environment variables are set.
-
For production issues, try redeploying:
fly deploy