This guide will help you deploy Rise Together to production at risetogether.tech.
- Pre-Deployment Checklist
- Environment Setup
- Deployment Options
- Domain Configuration
- Post-Deployment
- Troubleshooting
Before deploying, ensure you have:
- All code committed to GitHub
- requirements.txt is up to date
- Environment variables documented
- Database migrations created
- Static files collected
- DEBUG set to False in production settings
- Secret key secured
- Allowed hosts configured
- SSL certificate ready (for HTTPS)
- Domain name (risetogether.tech) registered
Create a production settings file or modify config/settings.py:
import os
from pathlib import Path
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.getenv('DEBUG', 'False') == 'True'
ALLOWED_HOSTS = [
'risetogether.tech',
'www.risetogether.tech',
'localhost',
'127.0.0.1',
]
# Database
if os.getenv('DATABASE_URL'):
import dj_database_url
DATABASES = {
'default': dj_database_url.config(
default=os.getenv('DATABASE_URL'),
conn_max_age=600,
ssl_require=True
)
}
# Static files (CSS, JavaScript, Images)
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'
# WhiteNoise for static files
MIDDLEWARE.insert(1, 'whitenoise.middleware.WhiteNoiseMiddleware')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
# Media files
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# Security settings
SECURE_SSL_REDIRECT = not DEBUG
SESSION_COOKIE_SECURE = not DEBUG
CSRF_COOKIE_SECURE = not DEBUG
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = 'DENY'
# Email configuration
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = os.getenv('EMAIL_HOST', 'smtp.gmail.com')
EMAIL_PORT = int(os.getenv('EMAIL_PORT', 587))
EMAIL_USE_TLS = True
EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD')
DEFAULT_FROM_EMAIL = os.getenv('DEFAULT_FROM_EMAIL', 'noreply@risetogether.tech')# Download from https://devcenter.heroku.com/articles/heroku-cli
# Or use package manager:
# macOS
brew tap heroku/brew && brew install heroku
# Windows (using Chocolatey)
choco install heroku-cliecho "web: gunicorn config.wsgi --log-file -" > Procfilepip install gunicorn dj-database-url psycopg2-binary whitenoise
pip freeze > requirements.txtecho "python-3.11.0" > runtime.txtheroku login
heroku create risetogetherheroku config:set SECRET_KEY="your-secret-key"
heroku config:set DEBUG=False
heroku config:set ALLOWED_HOSTS="risetogether.herokuapp.com,risetogether.tech"
heroku config:set EMAIL_HOST_USER="your-email@gmail.com"
heroku config:set EMAIL_HOST_PASSWORD="your-app-password"git push heroku main
heroku run python manage.py migrate
heroku run python manage.py createsuperuser
heroku run python manage.py collectstatic --noinputheroku addons:create heroku-postgresql:hobby-dev- Log in to DigitalOcean
- Create Ubuntu 22.04 droplet
- Choose appropriate size (starting at $6/month)
ssh root@your_server_ip# Update system
apt update && apt upgrade -y
# Install Python and dependencies
apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl -y
# Install virtualenv
pip3 install virtualenvsudo -u postgres psql
CREATE DATABASE risetogether;
CREATE USER risetogether_user WITH PASSWORD 'your_password';
ALTER ROLE risetogether_user SET client_encoding TO 'utf8';
ALTER ROLE risetogether_user SET default_transaction_isolation TO 'read committed';
ALTER ROLE risetogether_user SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE risetogether TO risetogether_user;
\qcd /var/www
git clone https://github.com/risetogethercommunity/rise-together-web.git
cd rise-together-webvirtualenv venv
source venv/bin/activate
pip install -r requirements.txt
pip install gunicornnano .envAdd:
SECRET_KEY=your-secret-key-here
DEBUG=False
DATABASE_URL=postgresql://risetogether_user:your_password@localhost/risetogether
ALLOWED_HOSTS=risetogether.tech,www.risetogether.tech
sudo nano /etc/systemd/system/gunicorn.serviceAdd:
[Unit]
Description=gunicorn daemon for Rise Together
After=network.target
[Service]
User=root
Group=www-data
WorkingDirectory=/var/www/rise-together-web
ExecStart=/var/www/rise-together-web/venv/bin/gunicorn --workers 3 --bind unix:/var/www/rise-together-web/gunicorn.sock config.wsgi:application
[Install]
WantedBy=multi-user.targetsystemctl start gunicorn
systemctl enable gunicornsudo nano /etc/nginx/sites-available/risetogetherAdd:
server {
listen 80;
server_name risetogether.tech www.risetogether.tech;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /var/www/rise-together-web;
}
location /media/ {
root /var/www/rise-together-web;
}
location / {
include proxy_params;
proxy_pass http://unix:/var/www/rise-together-web/gunicorn.sock;
}
}Enable site:
ln -s /etc/nginx/sites-available/risetogether /etc/nginx/sites-enabled
nginx -t
systemctl restart nginxapt install certbot python3-certbot-nginx
certbot --nginx -d risetogether.tech -d www.risetogether.tech- Install EB CLI
pip install awsebcli- Initialize EB
eb init -p python-3.11 risetogether- Create environment
eb create risetogether-env- Deploy
eb deploy- Set environment variables
eb setenv SECRET_KEY="your-secret-key" DEBUG=False- Sign up at Railway.app
- Click "New Project" → "Deploy from GitHub repo"
- Select your repository
- Railway will auto-detect Django
- Add environment variables in dashboard
- Deploy automatically happens on push
Add railway.json:
{
"build": {
"builder": "NIXPACKS"
},
"deploy": {
"startCommand": "python manage.py migrate && python manage.py collectstatic --noinput && gunicorn config.wsgi",
"restartPolicyType": "ON_FAILURE",
"restartPolicyMaxRetries": 10
}
}-
Add DNS Records (in your domain registrar):
Type: A Name: @ Value: YOUR_SERVER_IP Type: A Name: www Value: YOUR_SERVER_IP -
Wait for DNS Propagation (can take up to 48 hours)
-
Verify:
ping risetogether.tech
python manage.py migratepython manage.py createsuperuserpython manage.py collectstatic- Visit https://risetogether.tech
- Test all major features
- Check admin panel
- Verify email sending
- Test forms
- Configure error tracking (Sentry)
- Set up uptime monitoring (UptimeRobot)
- Enable server monitoring
- Set up automated database backups
- Configure media files backup
- Document restore procedures
python manage.py collectstatic --noinput
# Check STATIC_ROOT in settings- Verify DATABASE_URL
- Check PostgreSQL is running
- Confirm credentials
- Check DEBUG=True temporarily
- Review error logs
- Verify all migrations applied
- Check DNS settings
- Verify A records
- Wait for propagation
Need help? Reach out:
- Email: contact@risetogether.tech
- GitHub Issues: Report Issue
Good luck with your deployment! 🚀