cd..blog

AdonisJS & DigitalOcean: Scalable TypeScript Deployments

const published = "Mar 17, 2026, 10:36 PM";const readTime = 4 min;
adonisjsdigitaloceantypescriptdeploymentcloud
Deploy robust AdonisJS applications with TypeScript on DigitalOcean, leveraging Managed Databases, Spaces, and App Platform for a scalable, production-ready stack.

AdonisJS & DigitalOcean: Scalable TypeScript Deployments

Modern web development demands robust backends and flexible, scalable infrastructure. This post explores integrating AdonisJS, a full-stack Node.js framework, with DigitalOcean's suite of services. We'll build a TypeScript-first application, demonstrating how to leverage managed databases, object storage, and a streamlined deployment pipeline for a production-ready setup.

AdonisJS: A Backend Powerhouse with TypeScript

AdonisJS provides a comprehensive ecosystem for building web applications, emphasizing developer experience and performance. Its first-class TypeScript support ensures type safety and better maintainability for complex projects.

First, set up a new AdonisJS project:

npm init adonis-ts-app@latest my-adonis-app
cd my-adonis-app

Let's create a simple user controller and route. Run node ace make:controller Users and add a basic index method.

// app/Controllers/Http/UsersController.ts
import type { HttpContext } from '@adonisjs/core/http'

export default class UsersController {
  public async index({ response }: HttpContext) {
    return response.json([
      { id: 1, name: 'Alice' },
      { id: 2, name: 'Bob' }
    ])
  }
}

Define the route in start/routes.ts:

// start/routes.ts
import router from '@adonisjs/core/services/router'

router.get('/users', '#controllers/users_controller.index')

Managed PostgreSQL: Robust Data Storage on DigitalOcean

DigitalOcean Managed Databases offer a scalable, highly available, and secure database solution without the operational overhead. Integrating it with AdonisJS is straightforward.

Provision a PostgreSQL database instance on DigitalOcean. Once created, you'll receive connection details (host, port, user, password, database name). Update your AdonisJS .env file with these credentials:

DB_CONNECTION=pg
PG_HOST=your-do-db-host.ondigitalocean.com
PG_PORT=25060
PG_USER=doadmin
PG_PASSWORD=your_secure_password
PG_DB_NAME=your_database_name

Ensure your config/database.ts is configured to use these environment variables:

// config/database.ts
import { defineConfig } from '@adonisjs/lucid'

const dbConfig = defineConfig({
  connection: 'pg',
  connections: {
    pg: {
      client: 'pg',
      connection: {
        host: Env('PG_HOST'),
        port: Env('PG_PORT'),
        user: Env('PG_USER'),
        password: Env('PG_PASSWORD'),
        database: Env('PG_DB_NAME'),
        ssl: { rejectUnauthorized: false } // Required for DO connections
      },
      migrations: { tableName: 'adonis_schema' }
    }
  }
})

export default dbConfig

DigitalOcean Spaces: Scalable Object Storage

DigitalOcean Spaces provides S3-compatible object storage, perfect for static assets, user uploads, and backups. AdonisJS's Drive module can easily integrate with Spaces using an S3 driver.

Install the S3 driver for AdonisJS:

npm i @adonisjs/s3-driver
node ace configure @adonisjs/s3-driver

Configure your .env with Spaces credentials (key, secret, region, endpoint, bucket name):

DRIVE_DISK=s3
S3_KEY=YOUR_SPACES_KEY
S3_SECRET=YOUR_SPACES_SECRET
S3_REGION=nyc3
S3_ENDPOINT=https://nyc3.digitaloceanspaces.com
S3_BUCKET=your-space-name

Now, you can use the Drive facade to upload files:

// app/Controllers/Http/UploadsController.ts
import type { HttpContext } from '@adonisjs/core/http'
import app from '@adonisjs/core/services/app'
import Drive from '@adonisjs/core/services/drive'

export default class UploadsController {
  public async store({ request, response }: HttpContext) {
    const file = request.file('avatar', { size: '2mb', extnames: ['jpg', 'png'] })

    if (!file) {
      return response.badRequest('No file uploaded.')
    }

    const fileName = `${Date.now()}.${file.extname}`
    await file.move(app.tmpPath('uploads'), { name: fileName })

    // Upload to DigitalOcean Spaces
    const filePathInSpace = `avatars/${fileName}`
    await Drive.put(filePathInSpace, file.tmpPath!)

    return response.json({ message: 'File uploaded successfully', path: filePathInSpace })
  }
}

Seamless Deployment with DigitalOcean App Platform

DigitalOcean App Platform simplifies deploying and scaling web applications, handling infrastructure, CI/CD, and scaling automatically. It integrates directly with your GitHub repository.

Create an app.yaml file in your project root to define your application's components and settings:

// app.yaml
name: my-adonis-app
region: nyc
services:
  - name: web
    github:
      repo: your-github-username/my-adonis-app
      branch: main
      deploy_on_push: true
    build_command: npm install && npm run build
    run_command: node ace migration:run --force && node server.js
    environment_slug: node-js
    instance_size_slug: basic-s
    routes:
      - path: /
    envs:
      - key: APP_KEY
        scope: RUN_TIME
        value: <YOUR_ADONIS_APP_KEY>
      - key: DB_CONNECTION
        scope: RUN_TIME
        value: pg
      - key: PG_HOST
        scope: RUN_TIME
        value: ${DB_HOST}
      - key: PG_PORT
        scope: RUN_TIME
        value: ${DB_PORT}
      - key: PG_USER
        scope: RUN_TIME
        value: ${DB_USERNAME}
      - key: PG_PASSWORD
        scope: RUN_TIME
        value: ${DB_PASSWORD}
      - key: PG_DB_NAME
        scope: RUN_TIME
        value: ${DB_NAME}
      - key: S3_KEY
        scope: RUN_TIME
        value: <YOUR_SPACES_KEY>
      - key: S3_SECRET
        scope: RUN_TIME
        value: <YOUR_SPACES_SECRET>
      - key: S3_REGION
        scope: RUN_TIME
        value: nyc3
      - key: S3_ENDPOINT
        scope: RUN_TIME
        value: https://nyc3.digitaloceanspaces.com
      - key: S3_BUCKET
        scope: RUN_TIME
        value: your-space-name

Link your GitHub repository to DigitalOcean App Platform, select your app.yaml, and let App Platform handle the rest. It will automatically build, deploy, and connect to your managed database and Spaces.

Conclusion: A Unified, Productive Ecosystem

Integrating AdonisJS with DigitalOcean's robust services creates a powerful, scalable, and developer-friendly stack. By leveraging Managed Databases, Spaces, and App Platform, you can focus on building features rather than managing infrastructure, ensuring your TypeScript applications are performant and resilient from development to production.