DEV Community

Cover image for Full-Stack Deployment on NEXUS AI: Frontend, Backend, and Database in One Command
Saif Ali
Saif Ali

Posted on • Originally published at nexusai.run on

Full-Stack Deployment on NEXUS AI: Frontend, Backend, and Database in One Command

Shipping a full-stack application used to mean writing a Compose file by hand, generating passwords, wiring service names into environment variables, and hoping the health checks fired in the right order. NEXUS AI handles all of that. One command deploys your code alongside a database, connects them on a private network, and injects the credentials your app needs to connect.

How it works

When you deploy from source using nexusai_deploy_source (or nexus deploy source in the CLI) with a services array, NEXUS AI calls composeService.ts internally to generate a docker-compose.yml for your stack. Every service runs in the same private Docker network (deploy-network-{deploymentId}), so your app container reaches the database by service name rather than IP address.

Database volumes are named {serviceType}-data-{deploymentId} and persist across container restarts and redeploys. Your data survives unless you explicitly destroy the deployment.

Health checks gate startup. Your application container does not start until the database passes its readiness check:

  • PostgreSQL: pg_isready
  • MySQL: mysqladmin ping
  • MongoDB: mongosh --eval db.adminCommand("ping")
  • Redis: redis-cli ping

This means your app never boots into a state where the database is still initializing.

Database credentials are generated at deploy time with random passwords. You do not set them. NEXUS AI injects them directly into your containers as environment variables.

Supported database services

Service Image Default version
PostgreSQL postgres 15-alpine
MySQL mysql 8.0
MongoDB mongo 7
Redis redis 7-alpine

Deploying from source with a database

Via the CLI

nexus deploy source --repo https://github.com/your/repo \
  --name my-app \
  --services postgresql \
  --environment production \
  --provider docker
  --json
Enter fullscreen mode Exit fullscreen mode

Multiple services:

nexus deploy source https://github.com/your/repo \
  --name my-app \
  --services postgresql,redis \
  --environment production
Enter fullscreen mode Exit fullscreen mode

Via the MCP tool

{
  "tool": "nexusai_deploy_source",
  "input": {
    "repoUrl": "https://github.com/your/repo",
    "name": "my-app",
    "environment": "PRODUCTION",
    "services": [
      { "type": "postgresql" },
      { "type": "redis" }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

NEXUS AI clones the repo, builds the image, generates the Compose file, and brings everything up in one job.

Connecting to the database from your app

Auto-injected environment variables

When NEXUS AI provisions a database service, it injects connection variables into every container in the stack automatically. You do not configure these. Read them from process.env (Node.js), os.environ (Python), or however your framework reads environment variables.

PostgreSQL

POSTGRES_HOST      postgresql
POSTGRES_PORT      5432
POSTGRES_DB        appdb
POSTGRES_USER      appuser
POSTGRES_PASSWORD  <generated>
Enter fullscreen mode Exit fullscreen mode

Node.js example:

const { Pool } = require('pg');

const pool = new Pool({
  host: process.env.POSTGRES_HOST,
  port: parseInt(process.env.POSTGRES_PORT),
  database: process.env.POSTGRES_DB,
  user: process.env.POSTGRES_USER,
  password: process.env.POSTGRES_PASSWORD,
});
Enter fullscreen mode Exit fullscreen mode

Prisma .env:

DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
Enter fullscreen mode Exit fullscreen mode

Or inline in schema.prisma:

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}
Enter fullscreen mode Exit fullscreen mode

MySQL

MYSQL_HOST      mysql
MYSQL_PORT      3306
MYSQL_DATABASE  appdb
MYSQL_USER      appuser
MYSQL_PASSWORD  <generated>
Enter fullscreen mode Exit fullscreen mode

Node.js example:

const mysql = require('mysql2/promise');

const pool = mysql.createPool({
  host: process.env.MYSQL_HOST,
  port: parseInt(process.env.MYSQL_PORT),
  database: process.env.MYSQL_DATABASE,
  user: process.env.MYSQL_USER,
  password: process.env.MYSQL_PASSWORD,
});
Enter fullscreen mode Exit fullscreen mode

MongoDB

MONGO_HOST      mongodb
MONGO_PORT      27017
MONGO_DATABASE  appdb
MONGO_USERNAME  root
MONGO_PASSWORD  <generated>
Enter fullscreen mode Exit fullscreen mode

Mongoose example:

const mongoose = require('mongoose');

mongoose.connect(
  `mongodb://${process.env.MONGO_USERNAME}:${process.env.MONGO_PASSWORD}` +
  `@${process.env.MONGO_HOST}:${process.env.MONGO_PORT}/${process.env.MONGO_DATABASE}`
);
Enter fullscreen mode Exit fullscreen mode

Redis

REDIS_HOST  redis
REDIS_PORT  6379
Enter fullscreen mode Exit fullscreen mode

ioredis example:

const Redis = require('ioredis');

const redis = new Redis({
  host: process.env.REDIS_HOST,
  port: parseInt(process.env.REDIS_PORT),
});
Enter fullscreen mode Exit fullscreen mode

The host in every case is the service name on the internal Docker network. From inside your container, postgresql resolves to the Postgres container, mysql to MySQL, and so on. These hostnames are not reachable from outside the deployment.

Using the secrets vault for external databases

If you connect to a database that runs outside NEXUS AI (a managed RDS instance, a MongoDB Atlas cluster, a Redis Cloud endpoint), use the secrets vault instead of hardcoding credentials.

Step 1: Create a secret

nexus secret create \
  --name DATABASE_URL \
  --value "postgresql://user:password@rds.amazonaws.com:5432/mydb" \
  --environment production
Enter fullscreen mode Exit fullscreen mode

Step 2: Link it to your deployment

Pass the secret name when deploying:

nexus deploy source https://github.com/your/repo \
  --name my-app \
  --secret-ids <secret-id>
Enter fullscreen mode Exit fullscreen mode

At deploy time, NEXUS AI decrypts the secret (AES-256-GCM) and injects it as an environment variable into the container. Secrets do not override variables you pass explicitly in --env. The lookup order is: explicit env vars first, then secrets.

Your application reads process.env.DATABASE_URL exactly as it would for any other environment variable. There is nothing special to configure in your code.

Rotating a secret

nexus secret update --id <secret-id> --value "new-connection-string"
nexus deploy redeploy <deployment-name>
Enter fullscreen mode Exit fullscreen mode

The new value takes effect on the next deploy.

Frontend deployment

NEXUS AI Docker deployments run a single application container (plus database sidecar services). There is no built-in multi-container split for frontend and backend today.

Two patterns work:

Pattern 1: Serve the frontend from the backend

Build your frontend and serve the static files from your backend server. This is the simplest approach and fits most full-stack frameworks:

  • Next.js — runs as a single Node.js server (next start) that handles both SSR and API routes
  • Express + React — build the React app into dist/, then serve it with express.static
  • Django + Vue — run npm run build in your Dockerfile, copy dist/ into Django's static files directory

Your Dockerfile handles the build:

FROM node:20-alpine AS frontend-build
WORKDIR /app/frontend
COPY frontend/package*.json ./
RUN npm ci
COPY frontend/ ./
RUN npm run build

FROM node:20-alpine
WORKDIR /app
COPY backend/package*.json ./
RUN npm ci --production
COPY backend/ ./
COPY --from=frontend-build /app/frontend/dist ./public
EXPOSE 3000
CMD ["node", "src/index.js"]
Enter fullscreen mode Exit fullscreen mode

Pattern 2: Deploy frontend separately

Deploy the frontend as a separate NEXUS AI deployment (static site or Node.js server), and point it at the backend's public URL. Use nexus deploy status <backend-name> to get the backend URL, then pass it as an environment variable to the frontend deployment.

# Get backend URL
BACKEND_URL=$(nexus deploy status my-api --json | jq -r '.url')

# Deploy frontend pointing at backend
nexus deploy source https://github.com/your/repo \
  --name my-frontend \
  --env VITE_API_URL=$BACKEND_URL
Enter fullscreen mode Exit fullscreen mode

What gets deployed

After nexus deploy source completes with a database service, you get:

  • Your application container running on a public NEXUS AI subdomain
  • One or more database containers on a private internal network
  • Named volumes for each database (data persists across redeploys)
  • Auto-generated credentials injected as environment variables
  • Health checks configured and active
  • A lastBackup field ready for daily automated backups (see the backup guide)

Run nexus deploy status <name> to see the full picture: URL, status, attached services, and their connection metadata.

Top comments (0)