# Session 9: WebApp - Deployment (Vercel & Render) ## Overview Welcome to Session 9! In this session, we'll focus on deploying our web application to production environments. We'll learn how to deploy the frontend to Vercel and the backend to Render, configure our application for production, and set up continuous deployment for seamless updates. ## Learning Objectives - Understand the deployment process for web applications - Prepare your Next.js frontend for production deployment - Prepare your Django backend for production deployment - Deploy your frontend to Vercel - Deploy your backend to Render - Configure environment variables for different environments - Set up continuous deployment - Monitor your deployed application ## Topics Covered ### 1. Understanding Web App Deployment Deployment is the process of making your application available to users on the internet. It involves several important considerations: #### Key Deployment Concepts: - **Production vs Development Environments**: Different configurations for different stages - **Environment Variables**: Secure storage of sensitive configuration data - **Static vs Dynamic Content**: Different hosting requirements - **Domain Names and DNS**: How users access your application - **HTTPS**: Secure communication between users and your application - **CI/CD (Continuous Integration/Continuous Deployment)**: Automated testing and deployment - **Monitoring and Logging**: Tracking application performance and errors ### 2. Preparing Your Next.js Frontend for Deployment Before deploying, you need to prepare your Next.js application: #### 1. Configure Environment Variables: Create an `.env.local` file for development and configure environment variables in your deployment platform for production. ``` # .env.local (development) NEXT_PUBLIC_API_URL=http://localhost:8000/api ``` Add environment variables to your Next.js components: ```jsx // Example component using environment variables function TaskList() { const apiUrl = process.env.NEXT_PUBLIC_API_URL; useEffect(() => { fetch(`${apiUrl}/tasks`) .then(response => response.json()) .then(data => setTasks(data)); }, []); // ... } ``` #### 2. Optimize Your Application: ```bash # Install dependencies for production npm install --production # Build your application npm run build ``` #### 3. Test Your Production Build Locally: ```bash # Start the production server locally npm run start ``` ### 3. Preparing Your Django Backend for Deployment Django requires some configuration changes for production: #### 1. Update `settings.py`: ```python # todo_backend/settings.py import os from pathlib import Path # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = os.environ.get('SECRET_KEY', 'your-default-development-key') # SECURITY WARNING: don't run with debug turned on in production! DEBUG = os.environ.get('DEBUG', 'False') == 'True' ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', 'localhost,127.0.0.1').split(',') # Application definition INSTALLED_APPS = [ # ...existing apps ] # Configure CORS for production CORS_ALLOWED_ORIGINS = os.environ.get('CORS_ALLOWED_ORIGINS', 'http://localhost:3000').split(',') # Database configuration DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': os.environ.get('DB_NAME', 'todo_app'), 'USER': os.environ.get('DB_USER', 'todo_user'), 'PASSWORD': os.environ.get('DB_PASSWORD', 'password'), 'HOST': os.environ.get('DB_HOST', 'localhost'), 'PORT': os.environ.get('DB_PORT', '5432'), } } # Static files (CSS, JavaScript, Images) STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') # Security settings for production if not DEBUG: SECURE_HSTS_SECONDS = 3600 SECURE_HSTS_INCLUDE_SUBDOMAINS = True SECURE_HSTS_PRELOAD = True SECURE_SSL_REDIRECT = True SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') ``` #### 2. Create a `requirements.txt` File: ```bash pip freeze > requirements.txt ``` #### 3. Create a `Procfile` for Gunicorn: ``` web: gunicorn todo_backend.wsgi --log-file - ``` #### 4. Create a `runtime.txt` File: ``` python-3.9.6 ``` ### 4. Deploying the Frontend to Vercel Vercel is a cloud platform for static sites and serverless functions, optimized for Next.js. #### Steps to Deploy to Vercel: 1. **Create a Vercel Account**: - Sign up at [vercel.com](https://vercel.com) 2. **Install Vercel CLI**: ```bash npm install -g vercel ``` 3. **Login to Vercel**: ```bash vercel login ``` 4. **Configure Your Project**: Create a `vercel.json` file in your project root: ```json { "version": 2, "builds": [ { "src": "package.json", "use": "@vercel/next" } ] } ``` 5. **Deploy Your Project**: ```bash vercel ``` 6. **For Production Deployment**: ```bash vercel --prod ``` 7. **Configure Environment Variables**: - Go to your project on the Vercel dashboard - Navigate to Settings > Environment Variables - Add your environment variables (e.g., `NEXT_PUBLIC_API_URL`) ### 5. Deploying the Backend to Render Render is a unified cloud for web services with a free tier for small projects. #### Steps to Deploy to Render: 1. **Create a Render Account**: - Sign up at [render.com](https://render.com) 2. **Create a New Web Service**: - Click "New" and select "Web Service" - Connect your GitHub repository - Give your service a name 3. **Configure Your Web Service**: - Environment: Python - Build Command: `pip install -r requirements.txt` - Start Command: `gunicorn todo_backend.wsgi` 4. **Add Environment Variables**: - `SECRET_KEY`: A strong, random secret key - `DEBUG`: 'False' - `ALLOWED_HOSTS`: 'your-app.onrender.com' - `CORS_ALLOWED_ORIGINS`: 'https://your-frontend-url.vercel.app' - `DB_NAME`: Your database name - `DB_USER`: Your database username - `DB_PASSWORD`: Your database password - `DB_HOST`: Your database host - `DB_PORT`: Your database port 5. **Create a PostgreSQL Database**: - Click "New" and select "PostgreSQL" - Choose a name and region - Connect your web service to this database 6. **Deploy Your Service**: - Click "Create Web Service" ### 6. Configuring DNS and Custom Domains To use your own domain name instead of the default ones provided by Vercel and Render: #### For Vercel: 1. Go to your project settings 2. Click on "Domains" 3. Add your custom domain 4. Configure your domain's DNS settings as instructed by Vercel #### For Render: 1. Go to your web service 2. Click on "Settings" 3. Scroll down to "Custom Domains" 4. Add your custom domain 5. Configure your domain's DNS settings as instructed by Render ### 7. Setting Up Continuous Deployment Continuous Deployment (CD) automatically deploys your code when you push changes to your repository. #### Vercel Continuous Deployment: Vercel automatically sets up CD when you connect your GitHub repository. Every time you push to your main branch, Vercel will deploy the changes. You can configure branch deployments in your project settings: - Production: main branch - Preview: other branches #### Render Continuous Deployment: Render also provides automatic deployments when you push to your repository. Configure automatic deployments in your web service settings: - Go to your web service - Click on "Settings" - Scroll to "Auto-Deploy" - Select your branch and deploy method ### 8. Monitoring and Logging Monitoring your deployed application is crucial for identifying and fixing issues quickly. #### Vercel Analytics: - Provides real-time performance metrics - Tracks page views and user engagement - Shows Core Web Vitals scores #### Render Logs: - View logs in real-time from the dashboard - Monitor CPU and memory usage - Set up log drains to external services #### Additional Monitoring Tools: - **Sentry**: For error tracking and performance monitoring - **LogRocket**: For session replay and error tracking - **Google Analytics**: For user behavior tracking - **Uptime Robot**: For monitoring application availability ## Practice Exercises 1. Configure your Next.js application for production 2. Configure your Django application for production 3. Deploy your frontend to Vercel 4. Deploy your backend to Render 5. Set up environment variables in both platforms 6. Test your deployed application end-to-end 7. Set up a custom domain for your application (optional) 8. Configure continuous deployment for your repositories ## Additional Resources - [Next.js Deployment Documentation](https://nextjs.org/docs/deployment) - [Django Deployment Checklist](https://docs.djangoproject.com/en/stable/howto/deployment/checklist/) - [Vercel Documentation](https://vercel.com/docs) - [Render Documentation](https://render.com/docs) - [Free SSL Certificates with Let's Encrypt](https://letsencrypt.org/) - [DNS Configuration Guide](https://www.cloudflare.com/learning/dns/dns-records/) ## Next Steps Now that you've learned how to deploy your web application, you're ready to move on to [Session 10: WebApp - Final Project](Session-10-WebApp-Final-Project.md) where you'll apply everything you've learned to build a complete Todo application from scratch.