A free, open source, self-hostable community events platform.
Organize local meetups and interest-based groups without paywalls.
Features • Quick Start • Manual Install • Configuration • Deployment • Contributing
- Groups: Create and join interest-based community groups
- Events: Schedule in-person, online, or hybrid events with RSVP management
- Waitlists: Automatic waitlist with fair FIFO promotion when spots open
- Recurring events: Weekly, biweekly, monthly, or custom recurrence
- Discussions: Threaded group discussions for community conversation
- Real-time chat: Per-event chat powered by WebSockets
- Direct messages: Private 1:1 messaging between members
- Discovery: Search and explore groups/events by interest, keyword, and location
- Attendee check-in: Mark attendance at events
- Event feedback: Post-event ratings and reviews
- Moderation: Report content, block users, admin dashboard for platform management
- Role-based permissions: Organizer, Co-Organizer, Assistant Organizer, Event Organizer, Event Host
- No payments, no paywalls: Every feature is free for every user
- Docker Desktop (for local development via Laravel Sail)
- OR for manual installation: PHP 8.5+, Composer, Node.js 20+, MySQL 8.0+, Redis
Third-party API key required:
- Geocodio API key (free tier: 2,500 lookups/day) -- sign up at geocod.io
The fastest way to get Greetup running locally. Uses Laravel Sail to start all services in Docker.
# Clone the repo
git clone https://github.com/MiniCodeMonkey/greetup.git
cd greetup
# Copy environment file
cp .env.example .env
# Set your Geocodio API key (get one free at https://www.geocod.io)
# Option A: Set it in .env directly
# Option B: Export it in your shell and Sail picks it up automatically:
# export GEOCODIO_API_KEY=your-key-here
# Install PHP dependencies (using a temporary Docker container)
docker run --rm \
-u "$(id -u):$(id -g)" \
-v "$(pwd):/var/www/html" \
-w /var/www/html \
laravelsail/php84-composer:latest \
composer install --ignore-platform-reqs
# Start all services (app, MySQL, Redis, Meilisearch, Mailpit, queue worker, Reverb)
./vendor/bin/sail up -d
# Generate app key
./vendor/bin/sail artisan key:generate
# Install frontend dependencies and build assets
./vendor/bin/sail npm install
./vendor/bin/sail npm run build
# Run migrations and seed the demo data
./vendor/bin/sail artisan migrate --seed
# Import search indexes
./vendor/bin/sail artisan scout:import "App\\Models\\Group"
./vendor/bin/sail artisan scout:import "App\\Models\\Event"
./vendor/bin/sail artisan scout:import "App\\Models\\User"Your Greetup instance is now running at:
| Service | URL |
|---|---|
| Application | http://localhost |
| Mailpit (email UI) | http://localhost:8025 |
| Meilisearch | http://localhost:7700 |
Demo accounts after seeding:
| Account | Password | |
|---|---|---|
| Admin | [email protected] | password |
| Regular user | [email protected] | password |
Useful Sail commands:
./vendor/bin/sail up -d # Start all services
./vendor/bin/sail down # Stop all services
./vendor/bin/sail artisan ... # Run artisan commands
./vendor/bin/sail composer ... # Run composer commands
./vendor/bin/sail npm ... # Run npm commands
./vendor/bin/sail test # Run tests
./vendor/bin/sail artisan queue:restart # Restart queue worker after code changes
./vendor/bin/sail logs reverb # View Reverb (WebSocket) logs
./vendor/bin/sail mysql # Open MySQL CLI
./vendor/bin/sail redis # Open Redis CLIFor developers who prefer not to use Docker, or for production servers.
Prerequisites: PHP 8.5+, Composer, Node.js 20+, npm, MySQL 8.0+, Redis (recommended).
# Clone the repository
git clone https://github.com/MiniCodeMonkey/greetup.git
cd greetup
# Install PHP dependencies
composer install
# Install frontend dependencies and build assets
npm install
npm run build
# Set up environment
cp .env.example .env
php artisan key:generate
# Edit .env to configure:
# - Database credentials (DB_HOST, DB_DATABASE, DB_USERNAME, DB_PASSWORD)
# - Redis connection (REDIS_HOST, REDIS_PORT)
# - Geocodio API key (GEOCODIO_API_KEY) -- get one at https://www.geocod.io
# - Mail settings for production (MAIL_HOST, MAIL_USERNAME, etc.)
# Run migrations and seed demo data
php artisan migrate --seed
# Start the development server
php artisan serve
# In a separate terminal -- start the queue worker
php artisan queue:work
# In a separate terminal -- start the WebSocket server (for real-time chat)
php artisan reverb:start
# In a separate terminal -- start Vite dev server (for hot-reload during development)
npm run devVisit http://localhost:8000 to access Greetup.
# Using Sail (recommended)
./vendor/bin/sail test # Run all tests
./vendor/bin/sail test --parallel # Run tests in parallel (faster)
./vendor/bin/sail test --coverage --min=90 # Run with coverage report
./vendor/bin/sail test --testsuite=Unit # Run only unit tests
./vendor/bin/sail test --testsuite=Feature # Run only feature tests
./vendor/bin/sail artisan dusk # Run browser tests
./vendor/bin/sail test tests/Feature/Groups/ # Run a specific directory
# Without Sail
vendor/bin/pest
vendor/bin/pest --parallel
vendor/bin/pest --coverage --min=90
php artisan duskAll configuration is done via the .env file. Key settings:
# Geocodio -- REQUIRED for location features
# Free: 2,500 lookups/day. Sign up: https://www.geocod.io
GEOCODIO_API_KEY=your-api-key-hereWithout a Geocodio key, the app works normally but location-based features (nearby events, distance sorting, map pins) are disabled. Addresses are stored as text but not geocoded.
# MySQL (default for Sail)
DB_CONNECTION=mysql
DB_HOST=mysql # Use 'mysql' in Sail, '127.0.0.1' otherwise
DB_PORT=3306
DB_DATABASE=greetup
DB_USERNAME=sail
DB_PASSWORD=password
# PostgreSQL (alternative for production)
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=greetup
DB_USERNAME=greetup
DB_PASSWORD=secret# Local dev (Mailpit via Sail -- UI at http://localhost:8025)
MAIL_MAILER=smtp
MAIL_HOST=mailpit
MAIL_PORT=1025
# Production -- use any SMTP provider (Mailgun, Postmark, SES, Resend, etc.)
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailgun.org
MAIL_PORT=587
MAIL_USERNAME=your-username
MAIL_PASSWORD=your-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS[email protected]
MAIL_FROM_NAME="Greetup"# Meilisearch (default, included in Sail)
SCOUT_DRIVER=meilisearch
MEILISEARCH_HOST=http://meilisearch:7700 # Use 'meilisearch' in Sail
MEILISEARCH_KEY=masterKey
# Database fallback (no external dependency, slower)
SCOUT_DRIVER=database# Default: local disk (fine for small instances)
FILESYSTEM_DISK=local
# Production: S3-compatible storage
FILESYSTEM_DISK=s3
AWS_ACCESS_KEY_ID=your-key
AWS_SECRET_ACCESS_KEY=your-secret
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=greetup-uploads
AWS_URL=https://your-cdn.com# Redis (default for Sail, recommended)
QUEUE_CONNECTION=redis
REDIS_HOST=redis # Use 'redis' in Sail, '127.0.0.1' otherwise
# Database fallback (no Redis dependency)
QUEUE_CONNECTION=databaseBROADCAST_CONNECTION=reverb
REVERB_APP_ID=greetup
REVERB_APP_KEY=greetup-key
REVERB_APP_SECRET=greetup-secret
REVERB_HOST=reverb # Use 'reverb' in Sail
REVERB_PORT=8080
# Browser connects to Reverb via localhost (not the Docker hostname)
VITE_REVERB_HOST=localhost
VITE_REVERB_PORT=8080
VITE_REVERB_SCHEME=http- Set
APP_ENV=productionandAPP_DEBUG=false - Generate a strong
APP_KEYwithphp artisan key:generate - Configure a production database (MySQL or PostgreSQL recommended)
- Set up Redis for queue, cache, and session
- Configure SMTP for transactional email
- Set
GEOCODIO_API_KEYfor location features (get a key at https://www.geocod.io) - Set up S3 or equivalent for file uploads (optional, local disk works for small instances)
- Build frontend assets:
npm run build - Run migrations:
php artisan migrate --force - Import search indexes:
php artisan scout:import - Optimize:
php artisan optimize - Set up a queue worker (Supervisor or systemd)
- Set up Reverb as a service for WebSocket support
- Configure a web server (Nginx or Caddy) with HTTPS
- Set up scheduled tasks:
* * * * * php /path/to/greetup/artisan schedule:run
Add this to your crontab:
* * * * * cd /path/to/greetup && php artisan schedule:run >> /dev/null 2>&1
Greetup registers these scheduled tasks:
| Command | Frequency | Purpose |
|---|---|---|
events:generate-recurring |
Daily | Generate upcoming instances of recurring event series |
events:mark-past |
Hourly | Move ended events to past status |
accounts:purge-deleted |
Daily | Hard-delete accounts past their 30-day grace period |
groups:purge-deleted |
Daily | Hard-delete groups past their 90-day grace period |
notifications:send-digests |
Every 5 min | Send batched notification digest emails |
server {
listen 80;
server_name greetup.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name greetup.example.com;
root /var/www/greetup/public;
index index.php;
ssl_certificate /etc/letsencrypt/live/greetup.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/greetup.example.com/privkey.pem;
client_max_body_size 10M;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.5-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
# WebSocket proxy for Reverb
location /app {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}[program:greetup-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/greetup/artisan queue:work --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/greetup/storage/logs/worker.log
stopwaitsecs=3600[program:greetup-reverb]
command=php /var/www/greetup/artisan reverb:start --port=8080
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/var/www/greetup/storage/logs/reverb.logWe welcome contributions! Please see CONTRIBUTING.md for guidelines.
# Set up local development (using Sail is recommended -- see Quick Start above)
composer install
npm install
cp .env.example .env
php artisan key:generate
php artisan migrate --seed
npm run dev # in one terminal
php artisan serve # in another terminal
# Before submitting a PR
vendor/bin/pint # Fix code style
vendor/bin/phpstan analyse # Static analysis
vendor/bin/pest --parallel # Run testsGreetup is open-source software licensed under the MIT License.
