Official website for esjaythegreat - singer-songwriter based in seoul.
- Frontend: Next.js 15 with React 19, TypeScript, Tailwind CSS
- Backend: Strapi 5 (Headless CMS)
- Database: PostgreSQL 15
- Deployment: Docker & Docker Compose
- 🎵 Music albums showcase with streaming links
- 📝 Blog with rich content support
- 📅 Events calendar for upcoming shows
- 💌 Newsletter subscription system
- 📧 Contact form
- 🔍 Full SEO optimization with structured data
- 📱 Fully responsive design
- 🌐 Bilingual support (Korean/English)
- Docker & Docker Compose
- Node.js 18+ (for local development)
- Make (optional, for using Makefile commands)
# Copy environment example
cp .env.example .env
# Edit .env with your values
# Generate secrets:
openssl rand -base64 32 # For JWT_SECRET, API_TOKEN_SALT, ADMIN_JWT_SECRET# Using Makefile
make build
make up
# Or using Docker Compose
docker-compose up -d- Frontend: http://localhost:3000
- Strapi Admin: http://localhost:1337/admin
The project supports three environments via APP_ENV:
- local: Development with hot-reload
- development: Mini-PC production mode
- production: Full production
Key variables in .env:
# Environment (local | development | production)
APP_ENV=local
# Database credentials
POSTGRES_USER=strapi
POSTGRES_PASSWORD=your_password
POSTGRES_DB=strapi
# Strapi secrets (generate with: openssl rand -base64 32)
JWT_SECRET=your_jwt_secret
API_TOKEN_SALT=your_api_token_salt
ADMIN_JWT_SECRET=your_admin_jwt_secret
APP_KEYS=key1,key2,key3,key4
# Frontend URLs
NEXT_PUBLIC_STRAPI_API_URL=http://strapi:1337/api
NEXT_PUBLIC_STRAPI_BROWSER_URL=http://localhost:1337
NEXT_PUBLIC_SITE_URL=http://localhost:3000make help # Show all commands
make build # Build Docker containers
make up # Start all services
make down # Stop all services
make restart # Restart services
make logs # View all logs
make logs-strapi # View Strapi logs
make logs-frontend # View Frontend logs
make clean # Stop containers (keeps data)
make clean-cache # Remove node_modules and build artifacts
make clean-all # Remove everything including database
make status # Show service status.
├── frontend/ # Next.js application
│ ├── app/ # Pages and components
│ ├── lib/ # Utilities (API, SEO, utils)
│ └── public/ # Static assets
├── backend/ # Strapi CMS
│ ├── src/
│ ├── config/
│ └── public/
├── docker-compose.yml # Unified Docker configuration
├── Makefile # Easy commands
└── .env # Environment variables
Create these in Strapi admin panel:
- title (Text, Required)
- slug (UID, Required)
- description (Text, Long)
- releaseDate (Date, Required)
- lyrics (Rich Text)
- coverImage (Media, Single)
- melonUrl, genieUrl, bugsUrl, spotifyUrl, youtubeUrl (Text)
- title (Text, Required)
- slug (UID, Required)
- excerpt (Text)
- content (Rich Text, Required)
- publishedDate (DateTime, Required)
- featuredImage (Media, Single)
- youtubeEmbedUrl (Text)
- title (Text, Required)
- date (DateTime, Required)
- venue (Text)
- city (Text)
- ticketUrl (Text)
- description (Rich Text)
See SETUP_GUIDE.md for detailed instructions.
- Dynamic meta tags for all pages
- Open Graph tags for social sharing
- Twitter Card support
- JSON-LD structured data (MusicAlbum, BlogPosting, MusicEvent)
- Automatic sitemap generation
- robots.txt (blocks non-production from indexing)
- Semantic HTML markup
# Frontend only
cd frontend
npm install
npm run dev
# Backend only
cd backend
npm install
npm run developSet APP_ENV=production in .env, then:
make build
make upFrontend will build and run in production mode automatically.
# .env settings
APP_ENV=development
NODE_ENV=production
NEXT_PUBLIC_STRAPI_BROWSER_URL=http://esjay.iptime.org:1337
NEXT_PUBLIC_SITE_URL=http://esjay.iptime.org# .env settings
APP_ENV=production
NODE_ENV=production
NEXT_PUBLIC_STRAPI_BROWSER_URL=https://esjaythegreat.com
NEXT_PUBLIC_SITE_URL=https://esjaythegreat.comdocker exec esjaythegreat-db pg_dump -U strapi strapi > backup.sqldocker exec -i esjaythegreat-db psql -U strapi strapi < backup.sqlmake logs # All services
make logs-strapi # Strapi only
make logs-frontend # Frontend onlymake clean-cache # Remove node_modules, .next, etc.
make build # Rebuild from scratch
make up # Start servicesmake clean
make build
make upmake clean-cache # Remove all node_modules and build files
make build
make upmake logs-postgres # Check database logs
make db-console # Test connectionlsof -i :3000 # Find process
kill -9 <PID> # Kill processThroughout the codebase, you'll see comments like // lowercase intentional. This indicates that lowercase text (like "esjaythegreat", "seoul", "all rights reserved") is intentional styling and should not be changed to uppercase or title case.
- Local: Use
localhostfor browser URLs - Development: Use
esjay.iptime.org(blocked from search engines) - Production: Use
esjaythegreat.com(indexed by search engines)
The SEO implementation uses standard Schema.org structured data types:
MusicGroup- For artist/band informationMusicAlbum- For album pagesBlogPosting- For blog postsMusicEvent- For concert/event listings
These are recognized by Google, Bing, and other search engines for rich results.
- README.md - This file (overview)
- SETUP_GUIDE.md - Step-by-step setup instructions
- DEPLOYMENT.md - Production deployment guide
- QUICK_REFERENCE.md - Command cheat sheet
All rights reserved © 2025 esjaythegreat
For issues or questions:
- Check documentation files
- Review logs:
make logs - Check service status:
make status - Visit https://esjaythegreat.com/contact
Official website for esjaythegreat - Seoul-based singer-songwriter.
- Frontend: Next.js 15 with React 19, TypeScript, Tailwind CSS
- Backend: Strapi 5 (Headless CMS)
- Database: PostgreSQL 15
- Deployment: Docker & Docker Compose
- 🎵 Music albums showcase with streaming links
- 📝 Blog with rich content support
- 📅 Events calendar for upcoming shows
- 💌 Newsletter subscription system
- 📧 Contact form
- 🔍 Full SEO optimization with structured data
- 📱 Fully responsive design
- 🌐 Bilingual support (Korean/English)
- Docker & Docker Compose
- Node.js 18+ (for local development)
- Make (optional, for using Makefile commands)
# Start all services
make up
# View logs
make logs
# Stop services
make down
# Rebuild containers
make build
# Restart all services
make restart
# View help
make help# Start services
docker-compose up -d
# Stop services
docker-compose down
# View logs
docker-compose logs -f
# Rebuild
docker-compose buildCreate a .env file in the root directory:
# Database
POSTGRES_USER=strapi
POSTGRES_PASSWORD=your_secure_password
POSTGRES_DB=strapi
DATABASE_CLIENT=postgres
DATABASE_HOST=postgres
DATABASE_PORT=5432
DATABASE_NAME=strapi
DATABASE_USERNAME=strapi
DATABASE_PASSWORD=your_secure_password
# Strapi Secrets (generate with: openssl rand -base64 32)
JWT_SECRET=your_jwt_secret
API_TOKEN_SALT=your_api_token_salt
ADMIN_JWT_SECRET=your_admin_jwt_secret
APP_KEYS=key1,key2,key3,key4
# Email (optional)
EMAIL_PROVIDER=sendgrid
EMAIL_API_KEY=your_sendgrid_api_key
EMAIL_DEFAULT_FROM=noreply@esjaythegreat.com
EMAIL_DEFAULT_REPLY_TO=hello@esjaythegreat.com
# Frontend
NEXT_PUBLIC_STRAPI_API_URL=http://localhost:1337
NEXT_PUBLIC_SITE_URL=https://esjaythegreat.com
NEXT_PUBLIC_SITE_NAME=esjaythegreat
NEXT_PUBLIC_DOMAIN=esjaythegreat.com
NEXT_PUBLIC_INSTAGRAM=https://instagram.com/esjaythegreat
NEXT_PUBLIC_YOUTUBE=https://youtube.com/@esjaythegreat
# Node Environment
NODE_ENV=development.
├── frontend/ # Next.js application
│ ├── app/
│ │ ├── blog/ # Blog pages
│ │ ├── events/ # Events page
│ │ ├── music/ # Music album pages
│ │ ├── contact/ # Contact page
│ │ ├── components/ # React components
│ │ └── lib/ # Utilities and API helpers
│ ├── public/ # Static assets
│ └── Dockerfile
├── backend/ # Strapi CMS
│ ├── src/
│ ├── config/
│ └── Dockerfile
├── docker-compose.yml # Docker orchestration
├── Makefile # Make commands
└── .env # Environment variables
- Port: 3000
- URL: http://localhost:3000
- Port: 1337
- Admin Panel: http://localhost:1337/admin
- API: http://localhost:1337/api
- Port: 5432
- Internal only (not exposed to host)
cd frontend
npm install
npm run devcd backend
npm install
npm run developYou need to create these content types in Strapi admin panel:
- title (Text)
- slug (UID)
- description (Text, Long)
- releaseDate (Date)
- lyrics (Rich text)
- coverImage (Media, Single)
- melonUrl (Text)
- genieUrl (Text)
- bugsUrl (Text)
- spotifyUrl (Text)
- youtubeUrl (Text)
- title (Text)
- slug (UID)
- excerpt (Text)
- content (Rich text)
- publishedDate (DateTime)
- featuredImage (Media, Single)
- youtubeEmbedUrl (Text)
- title (Text)
- date (DateTime)
- venue (Text)
- city (Text)
- ticketUrl (Text)
- description (Rich text)
- email (Email, Unique)
- subscribedAt (DateTime)
- isActive (Boolean)
- unsubscribeToken (UID)
- name (Text)
- email (Email)
- subject (Text)
- message (Rich text)
- receivedAt (DateTime)
- isRead (Boolean)
- ✅ Dynamic meta tags per page
- ✅ Open Graph tags for social sharing
- ✅ Twitter Card support
- ✅ Structured data (JSON-LD) for:
- Organization/Person
- Music Albums
- Blog Posts
- Events
- ✅ XML Sitemap
- ✅ robots.txt
- ✅ Semantic HTML
- ✅ Optimized images with Next.js Image
- ✅ Proper heading hierarchy
make help # Show all available commands
make build # Build Docker containers
make up # Start services
make down # Stop services
make restart # Restart services
make logs # View all logs
make logs-strapi # View Strapi logs only
make logs-frontend # View Frontend logs only
make logs-postgres # View PostgreSQL logs only
make clean # Stop and remove containers (keeps data)
make clean-all # Remove everything including volumes (⚠️ deletes database)
make status # Show service status
make shell-strapi # Open shell in Strapi container
make shell-frontend # Open shell in Frontend container
make db-console # Access PostgreSQL console# Frontend
cd frontend
npm run build
npm start
# Update docker-compose.yml environment
NODE_ENV=production- Change all default passwords
- Generate new secure secrets
- Enable HTTPS/SSL
- Configure CORS properly
- Set up firewall rules
- Enable Strapi production mode
- Configure proper backup strategy
- Set up monitoring and logging
- Enable rate limiting
docker-compose exec postgres pg_dump -U strapi strapi > backup.sqldocker-compose exec -T postgres psql -U strapi strapi < backup.sqlmake clean
make build
make up- Check if PostgreSQL container is healthy:
make status - Verify environment variables in
.env - Check logs:
make logs-postgres
- Ensure Strapi is running:
make logs-strapi - Verify
NEXT_PUBLIC_STRAPI_API_URLin.env - Check Docker network:
docker network ls
All rights reserved © 2025 esjaythegreat
For questions or support, visit esjaythegreat.com/contact