A service to aggregate local music events from multiple sources, making it easy to discover live shows in Western Massachusetts.
- Frontend: Nuxt 4 (Vue 3 + SSR)
- Backend: Nuxt server routes
- Database: PostgreSQL + PostGIS
- ORM: Prisma
- Scrapers: Playwright + Cheerio
- Deployment: Docker + DigitalOcean VPS
- Node.js 20+
- Docker and Docker Compose
- npm
-
Clone the repository and install dependencies:
git clone <repo-url> cd local-music npm install
-
Start the database services:
docker compose up -d
-
Set up the database:
npm run db:push npm run db:generate npm run db:seed
-
Start the development server:
npm run dev
Visit http://localhost:3000 to see the app.
If you prefer running PostgreSQL locally:
-
Create a PostgreSQL database with PostGIS:
CREATE DATABASE local_music; \c local_music CREATE EXTENSION IF NOT EXISTS postgis;
-
Update
.envwith your connection string:DATABASE_URL="postgresql://user:password@localhost:5432/local_music?schema=public" -
Follow steps 3-4 from Quick Start above.
npm run dev- Start development servernpm run build- Build for productionnpm run preview- Preview production build
npm run db:generate- Generate Prisma clientnpm run db:migrate- Run database migrationsnpm run db:push- Push schema changes to databasenpm run db:seed- Seed database with sample datanpm run db:studio- Open Prisma Studio
npm run lint- Run ESLintnpm run lint:fix- Fix ESLint errorsnpm run format- Format code with Prettiernpm run typecheck- Run TypeScript type checking
-
Create a DigitalOcean Droplet (Ubuntu 24.04, 2GB RAM minimum)
-
SSH into the server and run the setup script:
curl -sSL https://raw.githubusercontent.com/<your-repo>/main/scripts/setup-server.sh | bash
-
Configure environment variables:
nano /opt/local-music/.env
Required variables:
POSTGRES_PASSWORD=your-secure-password DOMAIN=your-domain.com GITHUB_REPOSITORY=your-username/local-music -
Copy production files to the server:
scp docker-compose.prod.yml Caddyfile root@your-server:/opt/local-music/
-
Update Caddyfile with your domain:
nano /opt/local-music/Caddyfile # Replace {$DOMAIN:localhost} with your domain -
Start the services:
cd /opt/local-music docker compose -f docker-compose.prod.yml up -d
Add these secrets to your GitHub repository:
| Secret | Description |
|---|---|
SERVER_HOST |
Your server's IP address |
SERVER_USER |
SSH user (e.g., root) |
SERVER_SSH_KEY |
Private SSH key for deployment |
Once configured, pushing to main will automatically deploy.
Backups run automatically at 2am daily. Manual commands:
# Create backup
./scripts/backup.sh
# Restore from backup
./scripts/restore.sh backups/local_music_20240101_020000.sql.gz/local-music
├── app/
│ ├── components/ # Vue components
│ ├── composables/ # Vue composables
│ └── pages/ # Nuxt pages
├── server/
│ ├── api/ # API routes
│ ├── scrapers/ # Scraper implementations
│ └── utils/ # Server utilities
├── prisma/
│ ├── schema.prisma # Database schema
│ └── seed.ts # Seed script
├── scripts/ # Deployment and maintenance scripts
├── .github/workflows/ # CI/CD pipelines
├── docker-compose.yml # Local development services
├── docker-compose.prod.yml # Production services
├── Dockerfile # App container
├── Caddyfile # Reverse proxy config
└── PLANNING.md # Architecture docs
See PLANNING.md for architecture decisions, MVP phases, and roadmap.
MIT