A volunteer scheduling system for festivals and community events, originally built for Apogaea and now maintained by DenverBurners.
This platform helps event organizers coordinate volunteer shifts across departments, manage role-based access, and track training certifications. It's designed for events that need to staff everything from greeters and gate ticket checkers to certified positions like emergency medical response, fire safety, and conflict de-escalation.
Events and Departments — Organizers create events and break them into departments (e.g. Gate, Medical, Fire, Rangers). Each department can have its own set of shifts across the event's schedule.
Shifts and Slots — Shifts define the work that needs doing: what time, how long, and how many volunteers are needed. Each shift is broken into individual slots that volunteers can sign up for.
Roles and Permissions — Every shift can be gated by permission level to ensure volunteers have the right training or certification. The built-in roles include admin, volunteer, medical, fire, ranger, ranger-khaki, event-admin, department-lead, photography, and board-member.
Training Verification — Volunteers can upload certification documents (CPR cards, fire training certificates, etc.) through their profile. Administrators review and approve uploads before granting the corresponding role, ensuring nobody signs up for a shift they aren't qualified for.
Password-Protected Shifts — Shifts can also be gated by password, giving department leads another way to control access to sensitive positions.
This project has been in production use for over 10 years. We're actively modernizing the codebase and expanding it into a broader open source event management platform. Most volunteer coordination and event management tools are proprietary and expensive. We believe event organizers deserve software they can own, modify, and self-host.
Bringing the project up to current standards while keeping it stable for existing users.
- Dockerized development and deployment environment
- Upgraded to MariaDB 10.11 (from MySQL 5.7)
- Upgraded to Node 16 and Composer 2
- Dynamic UID/GID configuration for portable deployments
- Nginx security hardening (restricted PHP execution)
- Upgrade from Laravel 5.6 to the latest Laravel release
- Upgrade frontend build tooling (webpack to Vite)
- Update PHP from 7.4 to current supported version
Building out support for multiple organizations and events on a single installation.
- Multi-event database consolidation and import tooling
- Dedicated Playasoft website (replacing the current GitHub redirect)
- Improved onboarding for new organizations
- Modernized UI and mobile experience
Expanding beyond volunteer scheduling into a full suite of open source event management tools.
- Broader event coordination features
- Hosted option for organizations that don't want to self-host
- Plugin architecture for community extensions
Contributions are welcome at every phase. See the issues page for current tasks.
Requirements: Docker and Docker Compose.
git clone https://github.com/playasoft/volunteers.git
cd volunteers
# Create your environment config
cp .env.example .env
# Set UID/GID to match your host user (required for file permissions)
sed -i "s/^UID=.*/UID=$(id -u)/" .env && sed -i "s/^GID=.*/GID=$(id -g)/" .env
# Set a real database password in .env
# Edit DB_PASSWORD, SITE_NAME, SITE_URL, and any other values for your environment
# Build and start containers
docker compose build
docker compose up -d
# Install dependencies
docker compose exec app composer install
# Set up the application
docker compose exec app php artisan key:generate
docker compose exec app php artisan migrate
docker compose exec app php artisan db:seed
# Build frontend assets
docker compose exec app cp resources/js/config.example.js resources/js/config.js
docker compose exec app npm install
docker compose exec app npm run buildThe site will be available at http://localhost (or whatever NGINX_PORT you configured in .env).
All configuration is done through the .env file. Key settings:
| Variable | Purpose |
|---|---|
SITE_NAME |
Displayed on the home page and in emails |
SITE_DESCRIPTION |
HTML description shown on the home page |
SITE_URL |
Used in email links sent to volunteers |
NGINX_PORT |
Host port for the web server (default: 80) |
DB_PORT |
Host port for MariaDB (default: 3306) |
DB_PASSWORD |
Database password — change this from the default |
UID / GID |
Must match your host user for file permissions |
The project runs three containers:
| Container | Image | Purpose |
|---|---|---|
| voldb-app | PHP 7.4-FPM + Node 16 | Runs the Laravel application |
| voldb-nginx | nginx:alpine | Serves web requests, proxies PHP to the app container |
| voldb-db | MariaDB 10.11 | Database |
Common commands:
# View logs
docker compose logs -f
# Run artisan commands
docker compose exec app php artisan [command]
# Access the database
docker compose exec db mysql -u root -p
# Rebuild after Dockerfile changes
docker compose build
# Stop everything
docker compose down
# Stop and wipe all data (database, vendor, node_modules)
docker compose down -vFor real-time updates when shifts are taken or departments change:
- Install and configure
redisas the broadcast driver in.env - Set
WEBSOCKETS_ENABLED=truein.env - Run
npm installin thenode/directory - Run
node websocket-server.jsin thenode/directory (usepm2orscreento keep it running)