Self-Hosting Monica CRM: Personal Relationship Manager with Docker
You’ve forgotten your partner’s coworker’s name for the third time. Your friend mentioned their kid’s allergy last month and you can’t remember which one. Your uncle told you about his surgery and you didn’t follow up. Sound familiar?
Monica is an open-source personal CRM (Customer Relationship Management — except the “customers” are the people you actually care about). It gives you a structured place to record details about people in your life: what you talked about, their birthdays, their kids’ names, food preferences, important life events, and the things that make relationships feel intentional rather than accidental.
The concept sounds clinical until you use it. Then it feels like having a better memory.
Why Self-Host Monica?
Monica had a hosted version at monicahq.com, but it shut down its paid hosting in 2023. Self-hosting is now the primary way to run Monica. That’s actually good news for privacy — your relationship data is some of the most personal information you have, and keeping it on your own server means it stays yours.
What Monica Does Well
- Contact management — Store details about people: relationships, employers, how you met
- Activity logging — Record conversations, meals, phone calls, gifts
- Reminders — Birthday alerts, follow-up reminders, custom dates
- Journal — Daily entries linked to your contacts and activities
- Debt tracking — Who owes whom (surprisingly useful among friends)
- Gift tracking — Ideas, gifts given, gift occasions
- Tasks — To-dos associated with specific contacts
- Notes — Free-form notes per contact
- API access — Full REST API for integrations and automation
Monica vs Other Tools
| Feature | Monica | Google Contacts | Apple Contacts | Notion CRM Template |
|---|---|---|---|---|
| Activity logging | ✅ Built-in | ❌ No | ❌ No | ⚠️ Manual setup |
| Reminders | ✅ Native | ⚠️ Basic birthday | ⚠️ Basic birthday | ⚠️ Manual |
| Conversation tracking | ✅ Yes | ❌ No | ❌ No | ⚠️ Manual |
| Gift management | ✅ Yes | ❌ No | ❌ No | ⚠️ Manual |
| Self-hosted | ✅ Yes | ❌ No | ❌ No | ❌ No |
| Privacy | ✅ Full control | ❌ Google has it | ⚠️ iCloud | ❌ Notion servers |
| Open source | ✅ Yes | ❌ No | ❌ No | N/A |
Prerequisites
Before you start, you’ll need:
- A Linux server (VPS or home server) with at least 1GB RAM and 10GB disk space
- Docker and Docker Compose installed (install guide)
- A domain name (optional but recommended for HTTPS access)
- A reverse proxy like Caddy, Nginx Proxy Manager, or Traefik (for remote access)
- Basic comfort with the terminal
Step 1: Create the Project Directory
mkdir -p ~/docker/monica
cd ~/docker/monica
Keep your Docker services organized. One directory per service makes backups and troubleshooting much simpler.
Step 2: Set Up the Docker Compose File
Create docker-compose.yml:
services:
monica:
image: monica:4
container_name: monica
restart: unless-stopped
depends_on:
- monica-db
ports:
- "8085:80"
environment:
- APP_ENV=production
- APP_KEY=${APP_KEY}
- APP_URL=${APP_URL}
- DB_HOST=monica-db
- DB_DATABASE=monica
- DB_USERNAME=monica
- DB_PASSWORD=${DB_PASSWORD}
- MAIL_MAILER=${MAIL_MAILER:-log}
- MAIL_HOST=${MAIL_HOST:-}
- MAIL_PORT=${MAIL_PORT:-587}
- MAIL_USERNAME=${MAIL_USERNAME:-}
- MAIL_PASSWORD=${MAIL_PASSWORD:-}
- MAIL_ENCRYPTION=${MAIL_ENCRYPTION:-tls}
- MAIL_FROM_ADDRESS=${MAIL_FROM_ADDRESS:-}
- MAIL_FROM_NAME=${MAIL_FROM_NAME:-Monica}
volumes:
- monica-data:/var/www/html/storage
networks:
- monica-net
monica-db:
image: mariadb:11
container_name: monica-db
restart: unless-stopped
environment:
- MYSQL_RANDOM_ROOT_PASSWORD=true
- MYSQL_DATABASE=monica
- MYSQL_USER=monica
- MYSQL_PASSWORD=${DB_PASSWORD}
volumes:
- monica-db:/var/lib/mysql
networks:
- monica-net
networks:
monica-net:
driver: bridge
volumes:
monica-data:
monica-db:
A few notes on this configuration:
- Port 8085 is mapped to Monica’s internal port 80. Change
8085if it conflicts with another service. - MariaDB 11 is used instead of MySQL for better performance and open-source licensing.
- Volumes are named Docker volumes, which Docker manages automatically. This makes backups clean.
- The
monica-netbridge network keeps Monica and its database isolated from other containers.
Step 3: Configure Environment Variables
Create a .env file in the same directory:
# Generate a secure app key
APP_KEY=base64:$(openssl rand -base64 32)
# Your Monica URL (use your domain or server IP)
APP_URL=https://monica.yourdomain.com
# Database password — generate something strong
DB_PASSWORD=$(openssl rand -hex 20)
# Email settings (optional — for reminders)
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=[email protected]
MAIL_PASSWORD=your-app-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=[email protected]
MAIL_FROM_NAME=Monica
Important: Don’t run the commands inside the .env file literally. Generate the values first, then paste them in:
# Run these in your terminal, then paste results into .env
echo "APP_KEY=base64:$(openssl rand -base64 32)"
echo "DB_PASSWORD=$(openssl rand -hex 20)"
Your .env should look like:
APP_KEY=base64:K7r3x...your-generated-key...==
APP_URL=https://monica.yourdomain.com
DB_PASSWORD=a1b2c3d4e5...your-generated-password
MAIL_MAILER=log
Setting MAIL_MAILER=log disables email sending. Configure SMTP later when you want birthday reminders delivered to your inbox.
Step 4: Start Monica
docker compose up -d
Watch the logs to make sure everything starts cleanly:
docker compose logs -f monica
You’ll see Laravel bootstrapping, database migrations running, and eventually the application becoming ready. This first startup takes 1-2 minutes as Monica runs its initial migration.
Once you see lines about the web server listening, open your browser and navigate to http://your-server-ip:8085.
Step 5: Create Your Account
On first load, Monica presents a registration page. Create your account with:
- Your name
- Email address
- A strong password
After creating your first account, you should disable public registration to prevent anyone else from signing up on your instance. Add this to your docker-compose.yml environment section:
- APP_DISABLE_SIGNUP=true
Then restart:
docker compose up -d
Step 6: Set Up a Reverse Proxy (Recommended)
For HTTPS access, put Monica behind a reverse proxy. Here’s a quick Caddy configuration:
Or if you’re using Nginx Proxy Manager, add a new proxy host pointing to your server’s IP on port 8085, and enable the SSL certificate.
Make sure your APP_URL in .env matches the URL you’re accessing Monica through — this affects links in emails and the application’s internal routing.
Step 7: Configure Email for Reminders
Monica’s reminder system is one of its best features, but it needs working email to deliver notifications. If you skipped email setup earlier, update your .env:
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=[email protected]
MAIL_PASSWORD=your-app-specific-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=[email protected]
MAIL_FROM_NAME=Monica
For Gmail, you’ll need an App Password since regular passwords don’t work with SMTP.
Restart after changes:
docker compose up -d
Alternatives to Gmail SMTP:
- Mailgun — Free tier handles reminder volume easily
- Amazon SES — Pennies per thousand emails
- Self-hosted mail — If you’re already running Mailcow or similar
Using Monica Effectively
Getting Monica running is the easy part. The challenge is building the habit. Here are patterns that work:
Start With Your Inner Circle
Don’t try to import your entire phone’s contact list on day one. Start with 10-15 people you interact with regularly. Add details as you remember them or as conversations happen.
Log Activities After They Happen
Had coffee with a friend? Log it. They mentioned their mom is sick? Note it. The five seconds it takes to record this pays off enormously the next time you see them and can ask “How’s your mom doing?”
Use Reminders Strategically
Beyond birthdays (which Monica handles automatically once you add birth dates), set reminders for:
- Following up after someone mentions a big event (job interview, medical procedure)
- Reaching out to friends you haven’t talked to in a while
- Anniversary dates for close friends and family
- Seasonal check-ins (“Ask Dave about his garden in spring”)
The Journal
Monica’s journal isn’t just a diary — entries can be linked to contacts and activities. Use it to capture the emotional context that pure contact data misses. “Had a great dinner with Sarah and Tom — they’re thinking about moving to Portland” is the kind of thing that makes your next conversation richer.
Backup Strategy
Your relationship data is irreplaceable. Set up automated backups:
#!/bin/bash
# backup-monica.sh
BACKUP_DIR=~/backups/monica
DATE=$(date +%Y-%m-%d)
mkdir -p $BACKUP_DIR
# Database backup
docker exec monica-db mysqldump -u monica -p"$(grep DB_PASSWORD ~/docker/monica/.env | cut -d= -f2)" monica > "$BACKUP_DIR/monica-db-$DATE.sql"
# Application storage backup
docker run --rm -v monica-data:/data -v $BACKUP_DIR:/backup alpine tar czf "/backup/monica-storage-$DATE.tar.gz" -C /data .
# Keep last 30 days
find $BACKUP_DIR -name "*.sql" -mtime +30 -delete
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
echo "Monica backup completed: $DATE"
Make it executable and add to cron:
chmod +x backup-monica.sh
crontab -e
# Add: 0 3 * * * /home/user/backup-monica.sh
Troubleshooting
Monica Shows a Blank Page or 500 Error
Usually an APP_KEY issue. Regenerate it:
docker exec -it monica php artisan key:generate
docker compose restart monica
Database Connection Refused
Check that the database container is healthy:
docker compose ps
docker compose logs monica-db
MariaDB needs 10-20 seconds to initialize on first run. If Monica started before the database was ready, restart it:
docker compose restart monica
Emails Not Sending
Test your mail configuration:
docker exec -it monica php artisan tinker
# Then in tinker:
Mail::raw('Test email from Monica', function($msg) { $msg->to('[email protected]')->subject('Test'); });
Check your SMTP credentials and make sure your email provider allows SMTP access.
Slow Performance
Monica runs well on modest hardware, but if it feels sluggish:
- Add Redis caching — Add a Redis container and set
CACHE_DRIVER=redisin your environment - Increase PHP memory — Set
PHP_MEMORY_LIMIT=256Min the environment - Database optimization — Run
docker exec -it monica php artisan optimize
Upgrading Monica
When a new version releases:
cd ~/docker/monica
docker compose pull
docker compose up -d
docker exec -it monica php artisan migrate --force
Always backup before upgrading. Database migrations occasionally introduce breaking changes.
Security Considerations
Monica stores deeply personal information. Take security seriously:
- Always use HTTPS — Never access Monica over plain HTTP, especially remotely
- Strong passwords — Use a unique, complex password for your Monica account
- Disable registration — Set
APP_DISABLE_SIGNUP=trueafter creating your account - Firewall rules — Don’t expose port 8085 publicly; use a reverse proxy
- Regular updates — Keep Monica and MariaDB updated for security patches
- VPN access — Consider putting Monica behind a VPN like WireGuard for extra protection
- 2FA — Monica supports two-factor authentication; enable it in Settings > Security
API and Integrations
Monica has a comprehensive REST API that opens up interesting automation possibilities:
# Get all contacts
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
https://monica.yourdomain.com/api/contacts
# Add an activity
curl -X POST -H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"summary":"Coffee catch-up","date":"2026-03-21","contacts":[1]}' \
https://monica.yourdomain.com/api/activities
Generate your API token in Settings > API. Some ideas for automation:
- Import contacts from your phone’s VCF export
- Sync birthdays to your calendar
- Daily digest script that emails you today’s reminders
- Integration with Home Assistant for greeting guests by name
Conclusion
Monica solves a problem most people don’t realize they have until they start using it. Relationships take effort, and that effort gets harder as your social circle grows. Having a system that remembers the details lets you focus on what actually matters — being present and showing people you care.
Self-hosting Monica means your most personal data stays on your hardware. No subscription fees, no data mining, no company pivoting away from the product. Just a simple, effective tool for being a better friend, partner, and family member.
The setup takes about 15 minutes. Building the habit takes longer. But once you’ve used Monica for a month, you’ll wonder how you managed without it.
Further reading: