Updated for nself v0.4.8 v0.4.8
Let's build your first nself project step by step. We'll create a complete backend for a todo application with user authentication, real-time data, and file storage.
In this tutorial, we'll create a backend that includes:
First, create a new directory for your project and navigate to it:
mkdir todo-backend
cd todo-backendInitialize a new nself project:
nself initYou'll be asked a few questions (or accept defaults):
local.nself.org)What gets created:
todo-backend/
├── .env # Your configuration
├── .env.secrets # Sensitive credentials (auto-generated)
└── nself/ # Project directoryGenerate the Docker configuration and start services:
nself build # Generate docker-compose.yml, nginx configs, etc.
nself start # Launch all servicesFirst start takes 2-5 minutes (downloading Docker images).
Check status:
nself status # Service health
nself urls # Access URLsnself uses a database-first approach. Create schema.dbml to define your todo application schema:
// Todo Application Schema
Table users {
id uuid [pk, default: `gen_random_uuid()`]
email varchar(255) [unique, not null]
display_name varchar(255)
created_at timestamp [default: `now()`]
updated_at timestamp [default: `now()`]
}
Table todos {
id uuid [pk, default: `gen_random_uuid()`]
user_id uuid [not null, ref: > users.id]
title varchar(255) [not null]
description text
completed boolean [default: false]
due_date timestamp
created_at timestamp [default: `now()`]
updated_at timestamp [default: `now()`]
indexes {
user_id
completed
(user_id, completed) [name: "idx_user_completed"]
}
}
Table todo_attachments {
id uuid [pk, default: `gen_random_uuid()`]
todo_id uuid [not null, ref: > todos.id]
file_url varchar(500) [not null]
file_name varchar(255) [not null]
file_size integer
mime_type varchar(100)
uploaded_at timestamp [default: `now()`]
indexes {
todo_id
}
}Apply your schema with a single command:
nself db schema apply schema.dbmlThis command:
Sample users created (local/staging):
admin@example.com (admin role)user@example.com (user role)demo@example.com (viewer role)Trust SSL certificates for HTTPS access:
nself trustYour backend is now running! Access the services:
| Service | URL | Description |
|---|---|---|
| GraphQL API | https://api.local.nself.org | Hasura console + API |
| Auth | https://auth.local.nself.org | Authentication service |
| Admin | https://admin.local.nself.org | Admin dashboard (if enabled) |
https://mail.local.nself.org | Email testing UI (if enabled) |
Open the Hasura Console at https://api.local.nself.org/console and try this GraphQL query:
mutation CreateTodo {
insert_todos_one(object: {
title: "Learn nself"
description: "Complete the tutorial"
user_id: "00000000-0000-0000-0000-000000000000"
}) {
id
title
created_at
}
}Configure authentication rules in Hasura Console:
{ "user_id": { "_eq": "X-Hasura-User-Id" } }Extend your backend with third-party integrations:
# List available plugins
nself plugin list
# Install Stripe for payments
nself plugin install stripe
# Install GitHub for CI/CD integration
nself plugin install github
# Sync data from Stripe
nself plugin stripe sync
# View synced customers
nself plugin stripe customers listWhen ready for production:
# Create production environment
nself env create prod production
# Edit server configuration
# .environments/prod/server.json
# Deploy
nself deploy prodYour project structure should now look like:
todo-backend/
├── .env # Main configuration
├── .env.secrets # Sensitive credentials
├── schema.dbml # Your database schema
├── docker-compose.yml # Generated orchestration
├── nginx/ # Reverse proxy configs
├── postgres/ # Database initialization
│ └── migrations/ # SQL migrations
├── ssl/ # SSL certificates
├── services/ # Custom services (if any)
└── nself/
├── migrations/ # Migration files
├── seeds/ # Seed data files
├── types/ # Generated types
└── backups/ # Database backupsCongratulations! You've built a complete backend with:
Extend your backend with Stripe, GitHub, or Shopify integrations. Run nself plugin list to see available plugins and nself plugin install stripe to get started.
Next, explore: