A modern Node.js/Express photo gallery and client delivery system with an admin panel for photographers. Features private client galleries, a customizable About page, flexible site settings, and RESTful API support.
- Clone the repository:
git clone https://github.com/colehammond65/Focal-Point
cd focalpoint
- Edit
docker-compose.yml.example
with your environment variables - Start the application:
docker-compose up -d
git clone https://github.com/colehammond65/Focal-Point
cd focalpoint
docker build -t focalpoint .
docker run -p 3000:3000 \
-v $(pwd)/data:/home/node/app/data \
-e SESSION_SECRET=your-secret-here \
-e TRUST_PROXY=1 \
focalpoint
git clone https://github.com/colehammond65/Focal-Point
cd focalpoint
npm install
Create a .env
file in the root directory:
SESSION_SECRET=your-super-secret-random-string-here
TRUST_PROXY=false
# Production
npm start
# Development (with auto-reload)
npm run dev
Visit http://localhost:3000
to see your gallery!
- Admin Panel:
/admin
for managing images, categories, About page, site settings, and client galleries - Client Galleries: Create private galleries for clients, with login, download tracking, and zip download
- About Page: Markdown-powered About page with optional image, editable in admin
- Site Settings: Change site title, accent color, favicon, and header image from the admin panel
- Image Storage: Images organized in
public/images/<category>/
(public) anddata/client-uploads/
(private) - Categories: Each folder in
public/images/
is a category; supports drag-and-drop ordering - Database: SQLite database stored in
data/gallery.db
- EJS Templates: All views are rendered with EJS and customizable
- Security: Session-based admin login, rate limiting, and secure static file serving
- RESTful API: Provides endpoints for managing galleries, images, and settings programmatically
- Migrations: Database migration scripts for easy updates
focalpoint/
├── public/ # Static files and images
│ ├── images/ # Public image storage (categories as folders)
│ ├── uploads/ # Favicon and branding uploads
│ └── js/ # Client-side JS
├── data/ # Database and client uploads
│ ├── gallery.db # SQLite database
│ ├── client-uploads/ # Private client gallery images
│ └── backups/ # Database backups
├── views/ # EJS templates
├── migrations/ # Database migration scripts
├── utils/ # Helper modules (admin, categories, images, settings, backup, etc.)
├── temp/ # Temporary files (zip archives, etc.)
├── routes/ # Express route handlers
├── server.js # Main application server
├── docker-compose.yml.example # Docker compose exmaple
├── Dockerfile # Docker build instructions
└── .env # Environment configuration
Edit docker-compose.yml
or pass as environment variables:
SESSION_SECRET
– Required random string for session securityTRUST_PROXY
– Set to1
if running behind a reverse proxy (Nginx, Cloudflare Tunnel, etc.)
./data
→/home/node/app/data
(database, images)
Both directories are automatically created and persist across container restarts.
# Start the application
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the application
docker-compose down
# Rebuild after changes
docker-compose up --build -d
- ✅ Set a strong, random
SESSION_SECRET
- ✅ Use
TRUST_PROXY=1
when behind a reverse proxy ⚠️ Never serve thedata/
folder as static content⚠️ Only thepublic/
folder should be web-accessible⚠️ Client galleries are private and require login
The following directories are excluded from Git and Docker builds:
data/
- Database and client uploadstemp/
- Temporary files
- Node.js: Backend runtime
- Express: Web framework
- SQLite: Lightweight database
- EJS: Templating engine
- Docker: Containerization
- RESTful API: Programmatic access to features
MIT License - Feel free to use this project for personal or commercial purposes.
Built with ❤️ using Node.js, Express, EJS, and SQLite