惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cloudbric
Cloudbric
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
量子位
A
About on SuperTechFans
宝玉的分享
宝玉的分享
小众软件
小众软件
T
Tor Project blog
The Hacker News
The Hacker News
WordPress大学
WordPress大学
IT之家
IT之家
L
LINUX DO - 热门话题
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
酷 壳 – CoolShell
酷 壳 – CoolShell
NISL@THU
NISL@THU
D
Darknet – Hacking Tools, Hacker News & Cyber Security
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Latest news
Latest news
Martin Fowler
Martin Fowler
F
Full Disclosure
爱范儿
爱范儿
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Application and Cybersecurity Blog
Application and Cybersecurity Blog
W
WeLiveSecurity
C
Cisco Blogs
Recorded Future
Recorded Future
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - Franky
美团技术团队
N
Netflix TechBlog - Medium
Know Your Adversary
Know Your Adversary
Hacker News - Newest:
Hacker News - Newest: "LLM"
H
Help Net Security
雷峰网
雷峰网
G
Google Developers Blog
人人都是产品经理
人人都是产品经理
Microsoft Azure Blog
Microsoft Azure Blog
Security Latest
Security Latest
M
MIT News - Artificial intelligence
J
Java Code Geeks
Project Zero
Project Zero
Jina AI
Jina AI
P
Palo Alto Networks Blog
Vercel News
Vercel News
腾讯CDC
N
News | PayPal Newsroom
V
Visual Studio Blog
Cisco Talos Blog
Cisco Talos Blog
V
Vulnerabilities – Threatpost
AWS News Blog
AWS News Blog

DigitalOcean Community Questions

Droplet stuck: "Power on" and "Snapshot" both in Executing state for hours - what are my options? | DigitalOcean Referral Link Not Working anymore | DigitalOcean Recent console change has destroyed capacity to connect to legacy FreeBSD installs | DigitalOcean issue after moving app from aws to digitalocean | DigitalOcean issue after moving app from aws to digitalocean | DigitalOcean Container registry auomated garbage cillection sign in | DigitalOcean Billings And Free Tier Offer | DigitalOcean Switch hostinger to digitalocean? | DigitalOcean Unable to connect to Droplet via Console – “Failed to get droplet info” error | DigitalOcean billing problem | DigitalOcean How do I migrate an old Xen DomU VM, backed by a DRBD volume, to Digital Ocean? | DigitalOcean How to fix website not loading issue on VPS server (Nginx + WordPress) | DigitalOcean Account Locked After Payment Method Attempt (Hatch Program) - No Clear Reason | DigitalOcean Ghost Blog Marketplace Droplet is Ubuntu 22.04, not Ubuntu 24.04 | DigitalOcean How to setup browser with openclaw | DigitalOcean unable to load CA private key | DigitalOcean unable to load CA private key.. | DigitalOcean Add additional billing contact | DigitalOcean Digital Ocean Cloud Firewall? | DigitalOcean Mongodb auditing and compliance | DigitalOcean How much you're spending on AI tools? | DigitalOcean I can't create a managed MySQL cluster | DigitalOcean Please unblock SMTP (ports 25/465/587) for my droplet | DigitalOcean Reported promotional profile still accessible on DigitalOcean | DigitalOcean Change DNS server on Ubuntu 24 | DigitalOcean cannot add promotion of github student pack | DigitalOcean Do I need to use a Load Balancer on DigitalOcean for HTTPS or can I handle it on the Droplet? | DigitalOcean Best way to deploy a small Docker app on DigitalOcean without overengineering? | DigitalOcean Why is my DigitalOcean Droplet bandwidth usage so high all of a sudden? | DigitalOcean smtpout.secureserver.net 587 is blocked | DigitalOcean How do I disable AI? | DigitalOcean Is it safe to run production apps on a single DigitalOcean Droplet? | DigitalOcean Should I use Managed PostgreSQL or just run Postgres on my Droplet? | DigitalOcean IPv6 configuration issue | DigitalOcean Account locked after adding payment method | DigitalOcean 403 Forbidden on DigitalOcean App Platform with FastAPI Backend & Streamlit Frontend | DigitalOcean Not able to see access control panel | DigitalOcean Web Hosting Expiration | DigitalOcean When will OpenSearch v3 be available on DigitalOcean Managed Databases? | DigitalOcean Renew Your Hosting Now? | DigitalOcean How are you handling the Axios supply chain attack in your deployments? | DigitalOcean Create a DNS TXT record with multiple lines? | DigitalOcean Report multiple promotional pages | DigitalOcean Request to remove user pages containing unwanted links | DigitalOcean How can developers build a scalable video streaming solution using DigitalOcean? | DigitalOcean Request review of multiple promotional user profiles on DigitalOcean Community | DigitalOcean Can't configure CORS configuration in Spaces Object Storage | DigitalOcean Load Balancers dropping requests with a fixed pattern | DigitalOcean Billing question - payment restored account but droplet had already been purged | DigitalOcean URGENT: GitHub Student Promo stuck - Failed sign-up crash | DigitalOcean How do check my GitHub Student pack credits and Duration? | DigitalOcean Where to Buy Dedicated Server in India | DigitalOcean Android app for DigitalOcean - OceanNex | DigitalOcean how to change password of the droplet's ssh | DigitalOcean How are you backing up your Droplets and databases on DigitalOcean? | DigitalOcean Why am I being charged $14 when adding a payment method if I should receive $200 credit? | DigitalOcean Availability of Dedicated CPU Droplets in AMS3 datacenter | DigitalOcean What’s your typical stack for launching a startup on DigitalOcean? | DigitalOcean Email From my vps | DigitalOcean Can you make it possible to send via SMTP using ports 465 and 587 | DigitalOcean Why the Digital Ocean K8s Cluster provisioning is taking long ( 4 hours and still in progress ) | DigitalOcean Response not successful: Received status code 428 | DigitalOcean Why does the Digital Ocean K8s take long to provision the cluster ( 4 hrs and still in progress ) | DigitalOcean How to setup ssl for Spaces CDN | DigitalOcean How does DigitalOcean afford to give 4TB of bandwidth on a $24 Droplet? Are they losing money? | DigitalOcean Cilium DNS-based egress rules don’t work on DOKS | DigitalOcean Request to unblock outbound port 587 for SMTP | DigitalOcean Registry showing wrong limit | DigitalOcean Cancel Account because no longer needed | DigitalOcean What does your production stack on DigitalOcean look like? | DigitalOcean GitHub education | DigitalOcean OpenClaw Prompt Caching with Gradient AI | DigitalOcean Prompt Caching with OpenClaw and Gradient AI? | DigitalOcean Any discounts or trials going? | DigitalOcean App Platform - update DB pool without detach | DigitalOcean Is Kubernetes overkill for small projects in 2026? | DigitalOcean Report promotional user profiles not aligned with community guidelines | DigitalOcean App Platform: how to make routes add prefix back in case of 301 redirects? | DigitalOcean What are you using to deploy apps to DigitalOcean these days? | DigitalOcean No Response from Digital Ocean Team | DigitalOcean Report promotional user profile not related to DigitalOcean topics | DigitalOcean Droplet NGINX serving old cached content after deploy how to clear cache reliably? | DigitalOcean Is there any problem in getting a VPS service from Digital Ocean and using it from Russia? | DigitalOcean What's your current production setup on DigitalOcean? | DigitalOcean Keeps signing me out (even more frequently than before) | DigitalOcean Unable to Access DigitalOcean Community Page on iOS Safari – Application Error | DigitalOcean How to change existing certbot/nginx to wildcard domain? | DigitalOcean shh add to existing project | DigitalOcean ssl error on my website with cloundpannel | DigitalOcean How do I access bigger machines (more CPU’s and memory).? My current account seems limited. | DigitalOcean Choice of models limited | DigitalOcean Best practices for deploying a Next.js SaaS app with PostgreSQL on DigitalOcean App Platform? | DigitalOcean MOODLE INSTALLATION | DigitalOcean Being charged while adding payment method | DigitalOcean Problems with the OpenClaw droplet | DigitalOcean My account is blocked and i dont know why | DigitalOcean App platform deployment is hanging for almost 1 hour on Build step | DigitalOcean Deploying a Letter Boxed-Style Word Puzzle Game on DigitalOcean — Best Practices & Deployment Questions | DigitalOcean How do I safely give my OpenClaw droplet permission to access the internet and LinkedIn for research purposes? | DigitalOcean Intermittent system unresponsiveness requiring reboot on WordPress droplet | DigitalOcean
How to Deploy a Django + Next.js Application on DigitalOcean App Platform | DigitalOcean
By KFSysSystem Administrator · 2026-03-15 · via DigitalOcean Community Questions

Step 1 — Setting Up the Django Backend

First, create a project directory and set up the Django backend.

Create the project structure:

mkdir django-nextjs-app && cd django-nextjs-app
mkdir backend && cd backend

Create and activate a Python virtual environment:

python3 -m venv venv
source venv/bin/activate

Install Django and the required packages:

pip install django djangorestframework django-cors-headers gunicorn psycopg2-binary dj-database-url python-decouple whitenoise

Create a new Django project and app:

django-admin startproject config .
python manage.py startapp events

Your backend/ directory should now look like this:

backend/
├── config/
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── events/
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── models.py
│   ├── views.py
│   └── ...
├── manage.py
└── venv/

Step 2 — Configuring Django for Production

Open backend/config/settings.py and update it to support environment variables and production deployment:

# backend/config/settings.py

import os
from pathlib import Path
from decouple import config, Csv
import dj_database_url

BASE_DIR = Path(__file__).resolve().parent.parent

SECRET_KEY = config('DJANGO_SECRET_KEY', default='change-me-in-production')

DEBUG = config('DJANGO_DEBUG', default=False, cast=bool)

ALLOWED_HOSTS = config('DJANGO_ALLOWED_HOSTS', default='localhost,127.0.0.1', cast=Csv())

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Third party
    'rest_framework',
    'corsheaders',
    # Local
    'events',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'config.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'config.wsgi.application'

# Database
DATABASES = {
    'default': dj_database_url.config(
        default=config('DATABASE_URL', default=f'sqlite:///{BASE_DIR / "db.sqlite3"}'),
        conn_max_age=600,
    )
}

# Static files
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STORAGES = {
    "staticfiles": {
        "BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
    },
}

# CORS
CORS_ALLOWED_ORIGINS = config(
    'CORS_ALLOWED_ORIGINS',
    default='http://localhost:3000',
    cast=Csv()
)

# REST Framework
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny',
    ],
}

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

This configuration uses python-decouple to read environment variables, dj-database-url to parse the database connection string, and whitenoise to serve static files efficiently in production.

Step 3 — Creating the Events API

Define the Event model in backend/events/models.py:

# backend/events/models.py

from django.db import models


class Event(models.Model):
    title = models.CharField(max_length=200)
    description = models.TextField()
    date = models.DateTimeField()
    location = models.CharField(max_length=200)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['date']

    def __str__(self):
        return self.title

Create a serializer in backend/events/serializers.py:

# backend/events/serializers.py

from rest_framework import serializers
from .models import Event


class EventSerializer(serializers.ModelSerializer):
    class Meta:
        model = Event
        fields = ['id', 'title', 'description', 'date', 'location', 'created_at']

Create the API view in backend/events/views.py:

# backend/events/views.py

from rest_framework import generics
from .models import Event
from .serializers import EventSerializer


class EventListView(generics.ListAPIView):
    queryset = Event.objects.all()
    serializer_class = EventSerializer

Wire up the URLs in backend/events/urls.py:

# backend/events/urls.py

from django.urls import path
from .views import EventListView

urlpatterns = [
    path('events/', EventListView.as_view(), name='event-list'),
]

Include the events URLs in backend/config/urls.py:

# backend/config/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('events.urls')),
]

Run the migrations and create some sample data:

python manage.py makemigrations events
python manage.py migrate
python manage.py createsuperuser

Start the development server and add a few events through the admin at http://localhost:8000/admin/:

python manage.py runserver

Verify the API works by visiting http://localhost:8000/api/events/ in your browser.

Step 4 — Preparing the Django Backend for Deployment

Create a backend/requirements.txt file:

pip freeze > requirements.txt

Create a backend/runtime.txt to specify the Python version:

python-3.11.7

Create a backend/.env.example for reference (do not commit your actual .env file):

DJANGO_SECRET_KEY=your-secret-key
DJANGO_DEBUG=False
DJANGO_ALLOWED_HOSTS=.ondigitalocean.app
DATABASE_URL=postgresql://user:password@host:port/dbname
CORS_ALLOWED_ORIGINS=https://your-frontend.ondigitalocean.app

Step 5 — Building the Next.js Frontend

Navigate back to the root directory and create the Next.js app:

cd ..
npx create-next-app@latest frontend --typescript --tailwind --app --eslint --src-dir --no-import-alias
cd frontend

Create an API utility to fetch data from the Django backend. Create frontend/src/lib/api.ts:

// frontend/src/lib/api.ts

const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000';

export interface Event {
  id: number;
  title: string;
  description: string;
  date: string;
  location: string;
  created_at: string;
}

export async function getEvents(): Promise<Event[]> {
  const res = await fetch(`${API_BASE_URL}/api/events/`, {
    next: { revalidate: 60 },
  });

  if (!res.ok) {
    throw new Error('Failed to fetch events');
  }

  return res.json();
}

Replace the contents of frontend/src/app/page.tsx with the events listing page:

// frontend/src/app/page.tsx

import { getEvents } from '@/lib/api';

export default async function Home() {
  const events = await getEvents();

  return (
    <main className="min-h-screen bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
      <div className="max-w-4xl mx-auto">
        <h1 className="text-4xl font-bold text-gray-900 mb-2">
          Upcoming Events
        </h1>
        <p className="text-gray-600 mb-8">
          Browse the latest events happening near you.
        </p>

        {events.length === 0 ? (
          <p className="text-gray-500 text-center py-12">
            No events found. Check back later!
          </p>
        ) : (
          <div className="grid gap-6">
            {events.map((event) => (
              <article
                key={event.id}
                className="bg-white rounded-lg shadow-sm border border-gray-200 p-6 hover:shadow-md transition-shadow"
              >
                <div className="flex justify-between items-start">
                  <div>
                    <h2 className="text-xl font-semibold text-gray-900">
                      {event.title}
                    </h2>
                    <p className="text-gray-600 mt-2">{event.description}</p>
                  </div>
                </div>
                <div className="mt-4 flex flex-wrap gap-4 text-sm text-gray-500">
                  <span className="flex items-center gap-1">
                    📅{' '}
                    {new Date(event.date).toLocaleDateString('en-US', {
                      weekday: 'long',
                      year: 'numeric',
                      month: 'long',
                      day: 'numeric',
                    })}
                  </span>
                  <span className="flex items-center gap-1">
                    📍 {event.location}
                  </span>
                </div>
              </article>
            ))}
          </div>
        )}
      </div>
    </main>
  );
}

Update frontend/src/app/layout.tsx:

// frontend/src/app/layout.tsx

import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import './globals.css';

const inter = Inter({ subsets: ['latin'] });

export const metadata: Metadata = {
  title: 'Event Listings — Django + Next.js on DigitalOcean',
  description: 'A demo event listing app built with Django and Next.js, deployed on DigitalOcean App Platform.',
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={inter.className}>{children}</body>
    </html>
  );
}

Test the frontend locally (make sure your Django server is running on port 8000):

npm run dev

Visit http://localhost:3000 to confirm events render correctly.

Step 6 — Preparing the Next.js Frontend for Deployment

DigitalOcean App Platform needs Next.js to run in standalone mode to minimize the deployed bundle size. Update frontend/next.config.ts:

// frontend/next.config.ts

import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  output: 'standalone',
};

export default nextConfig;

Step 7 — Setting Up the GitHub Repository

Initialize a Git repository from the project root:

cd ..  # back to django-nextjs-app/
git init

Create a .gitignore in the root:

# Python
backend/venv/
backend/__pycache__/
backend/**/__pycache__/
backend/db.sqlite3
backend/.env
*.pyc

# Node
frontend/node_modules/
frontend/.next/
frontend/.env.local

# OS
.DS_Store

Commit and push:

git add .
git commit -m "Initial commit: Django + Next.js event app"
git remote add origin https://github.com/your-username/django-nextjs-app.git
git branch -M main
git push -u origin main

Replace your-username with your actual GitHub username.

Step 8 — Creating a Managed PostgreSQL Database on DigitalOcean

Before deploying the app, set up a managed database:

  1. Log in to your DigitalOcean Cloud Panel
  2. Click Databases in the left sidebar
  3. Click Create Database Cluster
  4. Choose PostgreSQL (version 16)
  5. Select a datacenter region close to your users
  6. Choose the Basic Plan ($15/month — suitable for development and small production workloads)
  7. Name it events-db
  8. Click Create Database Cluster

Once provisioning completes (typically 3–5 minutes):

  1. Click into your database cluster
  2. Under Connection Details, note the values for host, port, username, password, and database
  3. Copy the full Connection String — you’ll need it shortly

Step 9 — Deploying to DigitalOcean App Platform

Now deploy both the Django backend and Next.js frontend as components of a single App Platform application.

Create the App

  1. Navigate to App Platform in the DigitalOcean dashboard
  2. Click Create App
  3. Select GitHub as the source and authorize DigitalOcean to access your repository
  4. Select the django-nextjs-app repository and the main branch

Configure the Backend Component

  1. Click Edit on the detected component, or Add ResourceService

  2. Set the following:

    • Name: backend
    • Source Directory: /backend
    • Build Command: pip install -r requirements.txt && python manage.py collectstatic --noinput && python manage.py migrate
    • Run Command: gunicorn config.wsgi --bind 0.0.0.0:8080
    • HTTP Port: 8080
    • Instance Size: Basic ($5/month)
  3. Under Environment Variables, add:

Variable Value
DJANGO_SECRET_KEY (click “Generate” or paste a strong random string)
DJANGO_DEBUG False
DJANGO_ALLOWED_HOSTS .ondigitalocean.app
DATABASE_URL (paste the connection string from Step 8)
CORS_ALLOWED_ORIGINS (leave blank for now — you’ll update this after the frontend deploys)

Tip: Mark DJANGO_SECRET_KEY and DATABASE_URL as Encrypted to keep them secure.

Configure the Frontend Component

  1. Click Add ResourceService

  2. Set the following:

    • Name: frontend
    • Source Directory: /frontend
    • Build Command: npm ci && npm run build
    • Run Command: node .next/standalone/server.js
    • HTTP Port: 3000
    • Instance Size: Basic ($5/month)
  3. Under Environment Variables, add:

Variable Value
NEXT_PUBLIC_API_URL https://backend-xxxxx.ondigitalocean.app (use the backend’s URL from App Platform)
PORT 3000

Attach the Database

  1. Click Add ResourceDatabase
  2. Select Previously Created Database and choose the events-db cluster from Step 8
  3. App Platform will automatically inject the DATABASE_URL environment variable

Deploy

Click Create Resources. DigitalOcean will now:

  • Pull your code from GitHub
  • Build both components
  • Run database migrations
  • Start serving your application

The first deployment takes approximately 5–10 minutes.

Step 10 — Updating CORS After Deployment

Once both components are live, you need to update the backend’s CORS configuration with the frontend’s actual URL.

  1. Go to your app in the App Platform dashboard
  2. Click on the backend component → SettingsEnvironment Variables
  3. Update CORS_ALLOWED_ORIGINS to your frontend URL, for example:
    https://frontend-xxxxx.ondigitalocean.app
    
  4. Click Save — this triggers a redeployment of the backend

After the redeployment finishes, visit your frontend URL. You should see your events listed, rendered server-side by Next.js and served from your Django API.

Step 11 — Setting Up Automatic Deployments

DigitalOcean App Platform supports automatic deployments out of the box. Every time you push to the main branch, both components rebuild and redeploy automatically.

To verify this:

# Make a small change, then push
git add .
git commit -m "Update event listing styles"
git push origin main

Within minutes, your live application reflects the changes — no manual intervention required.

Step 12 — Adding a Custom Domain (Optional)

To serve your app on a custom domain:

  1. In App Platform, go to SettingsDomains
  2. Click Add Domain
  3. Enter your domain name
  4. Add the provided CNAME record in your domain’s DNS settings
  5. DigitalOcean automatically provisions a free Let’s Encrypt SSL certificate

Remember to update DJANGO_ALLOWED_HOSTS and CORS_ALLOWED_ORIGINS with your custom domain as well.

This approach of pairing Django with Next.js on a managed platform is well-suited for content-driven and event-driven applications — it’s a similar architecture behind production sites like extratime.world, which serves sports event data to users worldwide.

Conclusion

In this tutorial, you built a full-stack application with a Django REST Framework backend and a Next.js frontend, then deployed both to DigitalOcean App Platform with a managed PostgreSQL database.

Your deployed application now has:

  • Server-side rendering via Next.js for fast initial page loads and SEO
  • Automatic HTTPS via DigitalOcean’s managed SSL
  • CI/CD with automatic deployments on every Git push
  • Managed database with automated backups and failover
  • Independent scaling — backend and frontend can be scaled separately

From here, you can extend the application by adding user authentication with Django’s auth system and Next.js middleware, implementing real-time updates with WebSockets via Django Channels, or adding an admin interface to manage events through the Django admin panel.