Understanding the nself project structure helps you customize and extend your backend effectively. Each file and directory has a specific purpose in the orchestration of your services.
your-project/
├── .env.local # Main configuration file
├── .env # Active environment (symlink or copy)
├── docker-compose.yml # Service orchestration
├── schema.dbml # Database schema definition
│
├── bin/ # nself runtime files
│ ├── dbsyncs/ # Database backup history
│ └── templates/ # Service templates
│
├── certs/ # SSL certificates
│ ├── local/ # Local development certs
│ └── production/ # Let's Encrypt certs
│
├── hasura/ # GraphQL Engine
│ ├── metadata/ # GraphQL schema & permissions
│ ├── migrations/ # Database migrations
│ └── config.yaml # Hasura configuration
│
├── nginx/ # Reverse proxy
│ ├── default.conf # Main proxy config
│ ├── ssl.conf # SSL configuration
│ └── services/ # Per-service configs
│
├── postgres/ # Database
│ ├── init.sql # Initial setup
│ └── extensions.sql # PostgreSQL extensions
│
├── seeds/ # Database seeding
│ ├── development.sql # Dev test data
│ ├── staging.sql # Staging data
│ └── production.sql # Production essentials
│
├── functions/ # Serverless functions
│ └── [function-name]/ # Individual functions
│
├── services/ # Microservices
│ ├── nestjs/ # NestJS services
│ ├── python/ # Python services
│ ├── golang/ # Go services
│ └── bullmq/ # Queue workers
│
└── storage/ # File storage
├── uploads/ # User uploads
└── public/ # Public files
The main configuration file containing all project settings:
# Project Settings
PROJECT_NAME=myapp
ENVIRONMENT=development
DOMAIN=myapp.com
# Database
POSTGRES_DB=myapp_db
POSTGRES_PASSWORD=secure_password
# Services
REDIS_ENABLED=true
NHOST_DASHBOARD_ENABLED=true
# Microservices
NESTJS_SERVICES=api,webhooks
PYTHON_SERVICES=ml-engine
Generated by nself build
, orchestrates all services:
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
- ./postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
hasura:
image: hasura/graphql-engine:latest
depends_on:
- postgres
environment:
HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
# Additional services...
Database schema using DBML (Database Markup Language):
Table users {
id uuid [pk]
email varchar [unique, not null]
created_at timestamp [default: `now()`]
}
Table posts {
id uuid [pk]
user_id uuid [ref: > users.id]
title varchar [not null]
content text
published boolean [default: false]
}
Contains GraphQL engine configuration:
# hasura/config.yaml
version: 3
endpoint: http://localhost:8080
metadata_directory: metadata
migrations_directory: migrations
actions:
kind: synchronous
handler_webhook_baseurl: http://nestjs-api:3000
Reverse proxy configuration for routing and SSL:
# nginx/default.conf
server {
listen 80;
server_name api.local.nself.org;
location / {
proxy_pass http://hasura:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Database initialization scripts:
-- postgres/init.sql
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
-- Create schemas
CREATE SCHEMA IF NOT EXISTS auth;
CREATE SCHEMA IF NOT EXISTS storage;
Each NestJS service has its own directory:
services/nestjs/api/
├── Dockerfile
├── package.json
├── tsconfig.json
├── src/
│ ├── main.ts
│ ├── app.module.ts
│ └── modules/
│ ├── auth/
│ ├── users/
│ └── webhooks/
Python services for ML/AI workloads:
services/python/ml-engine/
├── Dockerfile
├── requirements.txt
├── main.py
├── models/
│ └── prediction.py
└── utils/
└── preprocessing.py
Environment-specific seed data:
-- seeds/development.sql
INSERT INTO users (email, display_name) VALUES
('alice@example.com', 'Alice Developer'),
('bob@example.com', 'Bob Tester');
-- seeds/production.sql
INSERT INTO roles (name, permissions) VALUES
('admin', '{"*": true}'),
('user', '{"read": true}');
Automatic database backups with timestamps:
bin/dbsyncs/
├── 2024-01-15_10-30-00_backup.sql
├── 2024-01-15_14-45-00_backup.sql
└── latest.sql -> 2024-01-15_14-45-00_backup.sql
Files generated by nself build
:
docker-compose.yml
- Service definitionsnginx/*.conf
- Proxy configurationshasura/migrations/*
- SQL migrationsImportant file permissions for security:
# Environment files (sensitive)
chmod 600 .env*
# Certificates
chmod 600 certs/production/*.pem
# Executables
chmod +x bin/*.sh
# Directories
chmod 755 hasura/ nginx/ postgres/
Add your own services to docker-compose.yml
:
# Custom service in docker-compose.yml
services:
my-custom-service:
build: ./services/custom
environment:
- DATABASE_URL=${DATABASE_URL}
depends_on:
- postgres
Add custom routes in nginx/services/
:
# nginx/services/custom.conf
location /custom-api {
proxy_pass http://my-custom-service:3000;
proxy_set_header Host $host;
}
.env
, storage/
, and certs/production/
bin/dbsyncs/
for disaster recoverynself db run
for schema changes.env.test
for testing