DEV_WORKFLOW - nself-org/cli GitHub Wiki
Complete step-by-step guide from nself init to a fully working application with authentication.
Goal: Get from zero to working auth in under 5 minutes.
# 1. Initialize project (30 seconds)
nself init --demo
cd demo-app
# 2. Build configuration (30 seconds)
nself build
# 3. Start all services (2 minutes)
nself start
# 4. Setup authentication (1 minute)
nself auth setup --default-users
# 5. Verify it works (30 seconds)
curl -k -X POST https://auth.local.nself.org/signin/email-password \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"npass123"}'
# โ
You should get an access_token back!That's it! You now have:
- โ PostgreSQL database with auth schema
- โ Hasura GraphQL API tracking auth tables
- โ nHost authentication service
- โ 3 staff users ready to use
- โ Working login endpoint
# Create a new project
nself init
# Follow the interactive prompts:
# - Project name: my-app
# - Base domain: local.my-app.com
# - Enable demo mode: YesWhat happens:
- Creates
.envfile with your configuration - Sets up project structure directories
- Configures all services (PostgreSQL, Hasura, Auth, Nginx, etc.)
Verify:
ls -la
# You should see: .env, docker-compose.yml (placeholder), etc.nself buildWhat happens:
- Generates
docker-compose.ymlwith all services - Creates Nginx reverse proxy configuration
- Generates SSL certificates
- Sets up database initialization scripts
- Creates service-specific configurations
Verify:
ls -la
# You should see: docker-compose.yml, nginx/, ssl/, postgres/
docker compose config --services
# Should list all servicesnself startWhat happens:
- Starts all Docker containers
- Waits for health checks
- Shows service status
- Reports any issues
Expected output:
โ Starting services...
โ PostgreSQL (healthy)
โ Hasura (healthy)
โ Auth (healthy)
โ Nginx (healthy)
โ 20/20 services running
โ Health checks: 17/19 passing
๐ All services started successfully!
Verify:
nself status
# All services should show as running
nself urls
# Should list all service URLsThis is the critical step that the old workflow was missing!
nself auth setup --default-usersWhat happens:
- Checks PostgreSQL is running
- Applies Hasura metadata (tracks auth.users, auth.user_providers, etc.)
- Creates 3 staff users:
-
[email protected](role: owner) -
[email protected](role: admin) -
[email protected](role: support)
-
- All with password:
npass123(development only!) - Verifies auth service can query users
Expected output:
โน Auth Setup Wizard
โน Checking Hasura metadata...
โ Hasura metadata configured
โน Creating default users...
โ User created: [email protected]
โน User ID: 11111111-1111-1111-1111-111111111111
โ User created: [email protected]
โน User ID: 22222222-2222-2222-2222-222222222222
โ User created: [email protected]
โน User ID: 33333333-3333-3333-3333-333333333333
โ Created 3 default users (password: npass123)
โน Verifying auth service...
โ Auth service configured correctly!
โ Auth setup complete!
โน Next steps:
- Test login: curl -k https://auth.local.nself.org/signin/email-password
- Create more users: nself auth create-user [email protected]
- List users: nself auth list-users
Manual alternative:
# Interactive mode (prompts for confirmation)
nself auth setup# Test login via API
curl -k -X POST https://auth.local.nself.org/signin/email-password \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "npass123"
}'Expected response:
{
"session": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "...",
"expires_in": 900,
"user": {
"id": "11111111-1111-1111-1111-111111111111",
"email": "[email protected]",
"displayName": "Platform Owner",
"metadata": {
"role": "owner"
}
}
}
}Test GraphQL access:
# Query users via Hasura
curl -X POST http://localhost:8080/v1/graphql \
-H "x-hasura-admin-secret: $HASURA_GRAPHQL_ADMIN_SECRET" \
-H "Content-Type: application/json" \
-d '{"query":"{ users { id display_name metadata } }"}'Expected response:
{
"data": {
"users": [
{
"id": "11111111-1111-1111-1111-111111111111",
"display_name": "Platform Owner",
"metadata": {"role": "owner"}
},
{
"id": "22222222-2222-2222-2222-222222222222",
"display_name": "Administrator",
"metadata": {"role": "admin"}
},
{
"id": "33333333-3333-3333-3333-333333333333",
"display_name": "Support Staff",
"metadata": {"role": "support"}
}
]
}
}# Interactive mode
nself auth create-user
# Non-interactive with flags
nself auth create-user \
[email protected] \
--password=SecurePass123! \
--role=user \
--name="New User"nself auth list-usersOutput:
id | email | display_name | role | email_verified | disabled | created_at
--------------------------------------+--------------------+-------------------+---------+----------------+----------+----------------------------
11111111-1111-1111-1111-111111111111 | [email protected] | Platform Owner | owner | t | f | 2026-02-11 10:00:00.000000
22222222-2222-2222-2222-222222222222 | [email protected] | Administrator | admin | t | f | 2026-02-11 10:00:01.000000
33333333-3333-3333-3333-333333333333 | [email protected] | Support Staff | support | t | f | 2026-02-11 10:00:02.000000
# Create a seed file
nself db seed create my_data local
# Edit the file: nself/seeds/local/001_my_data.sql
# Add your INSERT statements
# Apply all seeds
nself db seed apply
# List seed status
nself db seed list# View logs for specific service
nself logs auth
# Follow logs in real-time
nself logs auth --follow
# View logs for all services
nself logs --all# Interactive PostgreSQL shell
nself exec postgres psql -U postgres -d myapp_db
# Run SQL query
nself db query "SELECT * FROM auth.users"
# Database backup
nself db backup
# Database migration
nself db migrate up# Track auth tables (done automatically by auth setup)
nself hasura track schema auth
# Export current metadata
nself hasura metadata export
# Reload metadata
nself hasura metadata reload
# Open Hasura console
nself hasura console# 1. Make changes to code, configuration, etc.
vim .env
# 2. Rebuild if configuration changed
nself build
# 3. Restart affected services
nself restart
# Or restart specific service
nself restart postgres# Check service health
nself status
# View logs for debugging
nself logs <service>
# Test endpoints
nself urls# Stop services
nself stop
# Complete reset (removes containers, volumes, networks)
nself destroy
# Start fresh
nself build && nself start# Add to .env
FRONTEND_APP_1_NAME=webapp
FRONTEND_APP_1_PORT=3000
FRONTEND_APP_1_ROUTE=app
# Rebuild nginx config
nself build
# Restart nginx
nself restart nginx
# Frontend will be available at: https://app.local.nself.org# Add to .env
CS_1=frontend:next-js:3000
# Rebuild
nself build && nself start// Example: Login from frontend
const response = await fetch('https://auth.local.nself.org/signin/email-password', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
email: '[email protected]',
password: 'npass123'
})
});
const {session} = await response.json();
const accessToken = session.access_token;
// Use token for GraphQL requests
const data = await fetch('https://api.local.nself.org/v1/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`
},
body: JSON.stringify({
query: '{ users { id display_name } }'
})
});Error:
{
"status": 500,
"message": "field 'users' not found in type: 'query_root'"
}Solution:
# Hasura hasn't tracked auth tables
nself auth setup
# or manually:
nself hasura track schema auth
nself hasura metadata reload# Check Docker status
docker ps
# Check for port conflicts
lsof -i :80
lsof -i :443
# View detailed logs
nself logs --all
# Try fresh start
nself stop && nself start# Verify services are running
nself status
# Check URLs
nself urls
# Test local DNS
ping api.local.nself.org
# On macOS, might need to add to /etc/hosts:
# 127.0.0.1 api.local.nself.org auth.local.nself.org# Check seed file location
ls -la nself/seeds/common/
ls -la nself/seeds/local/
# Check seed tracking
nself db seed list
# Force reapply (remove tracking first)
nself exec postgres psql -U postgres -d myapp_db -c "DELETE FROM nself_seeds WHERE filename = '001_auth_users.sql'"
nself db seed apply# Check PostgreSQL running
nself status | grep postgres
# Check database exists
nself exec postgres psql -U postgres -l
# Recreate database
nself db reset # โ ๏ธ Destructive!- Change all default passwords:
# Create production users with strong passwords
nself auth create-user \
[email protected] \
--password=$(openssl rand -base64 24) \
--role=owner- Update environment variables:
# Edit .env for production
ENV=production
BASE_DOMAIN=yourdomain.com
AUTH_DEFAULT_PASSWORD= # Remove default!- Use real SSL certificates:
# Replace self-signed certs
nself auth ssl install /path/to/production-cert.pem- Enable monitoring:
# Add to .env
MONITORING_ENABLED=true
nself build && nself start- Set up backups:
# Configure automated backups
nself db backup --schedule daily- โ Always change default passwords
- โ
Use environment-specific
.envfiles - โ
Never commit
.envto git - โ Use strong passwords in production
- โ Enable rate limiting
- โ Use real SSL certificates
- โ
Use
nself db seed applyfor test data - โ Version control your seed files
- โ Use migrations for schema changes
- โ Test with realistic data volumes
- โ Monitor logs during development
- โ Test in staging first
- โ Use environment-aware seeding
- โ Enable monitoring and alerting
- โ Configure automated backups
- โ Document custom configurations
- Read AUTH_SETUP.md for detailed auth information
- Read SEEDING.md for advanced seeding patterns
- Explore Command Reference for all available commands
- Check Troubleshooting Guide for common issues
Questions? Issues?
- GitHub Issues: https://github.com/nself-org/cli/issues
- Documentation: https://docs.nself.org
- Discord: [Coming soon]