A Node.js/Express application with Neon Database integration, featuring separate Docker configurations for development (using Neon Local) and production (using Neon Cloud).
This application uses different database connection strategies based on the environment:
- Development: Uses Neon Local via Docker for ephemeral database branches
- Production: Connects directly to Neon Cloud database
- Docker and Docker Compose installed
- Neon Database account and project
- Node.js 20+ (for local development without Docker)
- Log in to Neon Console
- Go to your project settings
- Copy your:
- API Key (from Account Settings β Developer Settings)
- Project ID (from Project Settings β General)
- Parent Branch ID (usually your main branch ID)
Update the environment files with your actual credentials:
# Update these with your actual Neon credentials
NEON_API_KEY=your_actual_neon_api_key_here
NEON_PROJECT_ID=your_actual_neon_project_id_here
PARENT_BRANCH_ID=your_parent_branch_id_here
ARCJET_KEY=your_actual_arcjet_key_here# Update with your production Neon database URL
DATABASE_URL=postgresql://your_user:your_password@your-endpoint.neon.tech/your_db?sslmode=require
ARCJET_KEY=your_production_arcjet_key_here-
Start the development environment:
# Load development environment variables and start services docker-compose --env-file .env.development -f docker-compose.dev.yml up -d -
View logs:
# View all logs docker-compose -f docker-compose.dev.yml logs -f # View app logs only docker-compose -f docker-compose.dev.yml logs -f app # View Neon Local logs only docker-compose -f docker-compose.dev.yml logs -f neon-local
-
Access the application:
- Application: http://localhost:3000
- Database: postgres://neon:npg@localhost:5432/neondb
-
Stop the development environment:
docker-compose -f docker-compose.dev.yml down
-
Install dependencies:
npm install
-
Set up environment:
cp .env.development .env # Edit .env with your actual credentials -
Run the application:
npm run dev
- Hot Reload: Source code changes are automatically reflected
- Ephemeral Branches: Each container start creates a fresh database branch
- Automatic Cleanup: Database branches are deleted when containers stop
- Git Integration: Optional persistent branches per Git branch
-
Build and start production services:
# Load production environment variables and start services docker-compose --env-file .env.production -f docker-compose.prod.yml up -d -
View production logs:
docker-compose -f docker-compose.prod.yml logs -f
-
Scale the application (optional):
docker-compose -f docker-compose.prod.yml up -d --scale app=3
-
Build production image:
docker build --target production -t acquisitions:latest . -
Run production container:
docker run -d \ --name acquisitions-prod \ -p 3000:3000 \ -e NODE_ENV=production \ -e DATABASE_URL="your_production_neon_url" \ -e ARCJET_KEY="your_production_arcjet_key" \ acquisitions:latest
# Run database migrations in development
docker-compose -f docker-compose.dev.yml exec app npm run db:migrate
# Generate new migrations
docker-compose -f docker-compose.dev.yml exec app npm run db:generate
# Open Drizzle Studio
docker-compose -f docker-compose.dev.yml exec app npm run db:studio# Run database migrations in production
docker-compose -f docker-compose.prod.yml exec app npm run db:migrate- Application Health:
GET http://localhost:3000/health(if implemented) - Docker Health: Built-in health checks for all services
# Development
docker-compose -f docker-compose.dev.yml ps
# Production
docker-compose -f docker-compose.prod.yml ps-
Neon Local Connection Issues
# Check if Neon Local is ready docker-compose -f docker-compose.dev.yml logs neon-local # Verify health check docker-compose -f docker-compose.dev.yml exec neon-local pg_isready -h localhost -p 5432 -U neon
-
App Connection Issues
# Check app logs docker-compose -f docker-compose.dev.yml logs app # Restart app service docker-compose -f docker-compose.dev.yml restart app
-
Environment Variable Issues
# Verify environment variables are loaded docker-compose -f docker-compose.dev.yml exec app env | grep -E '(NODE_ENV|DATABASE_URL|NEON_)'
The application automatically detects the environment and uses the appropriate database driver:
- Development + Neon Local: Uses
pg(PostgreSQL driver) - Production + Neon Cloud: Uses
@neondatabase/serverless
Check the application logs for connection messages:
- π§ Connecting to Neon Local (postgres driver)...
- βοΈ Connecting to Neon Cloud (serverless driver)...
- β Database connection established successfully
- Self-signed certificates are accepted for Neon Local
- Debug logging is enabled
- Hot reload exposes source code
- SSL/TLS encryption enforced
- Non-root user execution
- Resource limits applied
- Security headers via Helmet middleware
- Rate limiting via Arcjet
acquisitions/
βββ src/
β βββ config/
β β βββ database.js # Multi-environment database config
β βββ controllers/
β βββ middlewares/
β βββ models/
β βββ routes/
β βββ services/
β βββ utils/
βββ Dockerfile # Multi-stage Docker build
βββ docker-compose.dev.yml # Development with Neon Local
βββ docker-compose.prod.yml # Production with Neon Cloud
βββ .env.development # Development environment vars
βββ .env.production # Production environment vars
βββ README.md # This file
| Variable | Description | Required |
|---|---|---|
NEON_API_KEY |
Your Neon API key | β |
NEON_PROJECT_ID |
Your Neon project ID | β |
PARENT_BRANCH_ID |
Parent branch for ephemeral branches | β |
ARCJET_KEY |
Arcjet security key | β |
NODE_ENV |
Set to development |
β |
PORT |
Application port (default: 3000) | β |
LOG_LEVEL |
Logging level | β |
| Variable | Description | Required |
|---|---|---|
DATABASE_URL |
Full Neon Cloud database URL | β |
ARCJET_KEY |
Production Arcjet security key | β |
NODE_ENV |
Set to production |
β |
PORT |
Application port (default: 3000) | β |
LOG_LEVEL |
Logging level | β |
- Fork the repository
- Create a feature branch
- Make your changes
- Test with both development and production setups
- Submit a pull request
This project is licensed under the ISC License - see the package.json file for details.