Skip to main content
This guide covers building each component of Anchor for production use. Whether you’re deploying the server, web app, or mobile app, you’ll find the necessary build commands and configurations here.

Building the Server

The server is a NestJS application that compiles TypeScript to JavaScript.

Development Build

1

Navigate to server directory

cd server
2

Install dependencies

pnpm install
3

Generate Prisma client

pnpm exec prisma generate
4

Build the application

pnpm build
This runs nest build which compiles TypeScript to the dist/ directory.

Production Build

pnpm build
pnpm run start:prod
The production start command (start:prod) runs node dist/src/main, which starts the compiled server on the configured PORT (default: 3001).

Environment Variables

Ensure these are set for production:
DATABASE_URL=postgresql://user:password@host:5432/anchor
JWT_SECRET=your-secure-random-secret
APP_URL=https://your-domain.com
NODE_ENV=production
PORT=3001

Build Scripts

From server/package.json:
CommandDescription
pnpm buildCompile TypeScript to JavaScript
pnpm startStart server (requires build)
pnpm start:devStart in development mode with watch
pnpm start:prodStart production server
pnpm lintRun ESLint
pnpm testRun unit tests
pnpm test:e2eRun end-to-end tests

Building the Web App

The web app is a Next.js 16 application that can be built for static export or as a Node.js server.

Development Build

1

Navigate to web directory

cd web
2

Install dependencies

pnpm install
3

Build for production

pnpm build
This runs next build which creates an optimized production build in .next/.

Production Deployment

pnpm build
pnpm start
The web app requires the server to be running and accessible. Configure the SERVER_URL environment variable if the server is not on the default http://127.0.0.1:3001.

Build Optimization

Next.js automatically:
  • Minifies JavaScript and CSS
  • Optimizes images with next/image
  • Splits code for optimal loading
  • Generates static pages where possible
  • Creates a service worker for offline support (if configured)

Build Scripts

From web/package.json:
CommandDescription
pnpm devStart development server on :3000
pnpm buildCreate production build
pnpm startStart production server
pnpm lintRun ESLint

Environment Variables

SERVER_URL=http://127.0.0.1:3001  # Backend API URL
NODE_ENV=production

Building the Mobile App

The mobile app is built with Flutter and supports Android and iOS.

Prerequisites

  • Flutter SDK installed and configured
  • For Android: Android SDK and NDK
  • For iOS: Xcode and CocoaPods (macOS only)

Android Build

1

Navigate to mobile directory

cd mobile
2

Install dependencies

flutter pub get
3

Run code generation

dart run build_runner build --delete-conflicting-outputs
This generates code for:
  • Riverpod providers
  • Drift database tables
  • JSON serialization
  • Freezed data classes
4

Build APK

flutter build apk --release
Split APKs create smaller files for specific CPU architectures (arm64-v8a, armeabi-v7a, x86_64). The universal APK works on all devices but is larger.
5

Build App Bundle (for Play Store)

flutter build appbundle --release
The .aab file will be in build/app/outputs/bundle/release/.

iOS Build

1

Install dependencies

cd mobile
flutter pub get
cd ios
pod install
cd ..
2

Run code generation

dart run build_runner build --delete-conflicting-outputs
3

Build IPA

flutter build ios --release
For App Store submission, use Xcode to archive and upload.

Build Configuration

From mobile/pubspec.yaml:
name: anchor
version: 0.9.1+11

environment:
  sdk: ^3.10.1
The version format is major.minor.patch+buildNumber.

Flutter Build Commands

CommandDescription
flutter pub getInstall dependencies
flutter runRun in development mode
flutter build apkBuild Android APK
flutter build appbundleBuild Android App Bundle
flutter build iosBuild iOS app
dart run build_runner buildGenerate code
flutter cleanClean build cache

Docker Builds

Anchor provides Docker configurations for easy deployment.

Development Build

Use the development Docker Compose file:
docker compose -f docker-compose.dev.yml up -d
This builds and runs:
  • PostgreSQL database
  • Server with hot reload
  • Web app with hot reload

Production Build

1

Build the production image

docker build -t anchor:latest .
The Dockerfile:
  1. Builds the server (NestJS)
  2. Builds the web app (Next.js)
  3. Combines them in a single container
  4. Includes embedded PostgreSQL (PGlite)
2

Run the container

docker run -d \
  -p 3000:3000 \
  -v anchor_data:/data \
  --name anchor \
  anchor:latest

Using Pre-built Image

services:
  anchor:
    image: ghcr.io/zhfahim/anchor:latest
    container_name: anchor
    restart: unless-stopped
    ports:
      - "3000:3000"
    volumes:
      - anchor_data:/data
    environment:
      - APP_URL=https://your-domain.com
      - JWT_SECRET=your-secret-here

volumes:
  anchor_data:

Build Verification

After building, verify each component:

Server

curl http://localhost:3001/api/health
# Expected: {"status":"ok"}

Web

Visit http://localhost:3000 and verify:
  • Pages load correctly
  • Assets are minified
  • API requests work
  • Authentication flow works

Mobile

Test the built APK/IPA:
  • Install on a physical device or emulator
  • Verify offline functionality
  • Test sync with server
  • Check performance and stability

Build Troubleshooting

Server Build Errors

pnpm exec prisma generate
pnpm build

Web Build Errors

# Clear Next.js cache
rm -rf .next
pnpm build

Mobile Build Errors

flutter clean
flutter pub get
dart run build_runner build --delete-conflicting-outputs

Performance Considerations

Server

  • Enable production mode (NODE_ENV=production)
  • Use connection pooling for PostgreSQL
  • Configure appropriate memory limits
  • Enable gzip compression

Web

  • Ensure next build runs successfully
  • Enable compression middleware
  • Use CDN for static assets
  • Configure caching headers

Mobile

  • Use --release flag for production builds
  • Enable ProGuard for Android (code shrinking)
  • Optimize images and assets
  • Test on real devices for performance

Continuous Integration

Example GitHub Actions workflow:
name: Build
on: [push]

jobs:
  build-server:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: pnpm/action-setup@v2
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: cd server && pnpm install
      - run: cd server && pnpm build
      - run: cd server && pnpm test

  build-web:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: pnpm/action-setup@v2
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: cd web && pnpm install
      - run: cd web && pnpm build

  build-mobile:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: subosito/flutter-action@v2
        with:
          flutter-version: '3.x'
      - run: cd mobile && flutter pub get
      - run: cd mobile && dart run build_runner build
      - run: cd mobile && flutter build apk

Next Steps

Build docs developers (and LLMs) love