Hello! I am going to deploy a django app with nginx and gunicorn. The site (example.com) has language subdomains (fr.example etc), which is managed directly by my django app (it detects the subdomains and sets the proper language). So this gona be one app for several subdomains. So I have questions about settings:
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
The following solution will work as long as you are not hosting separate sites that also use a name.example.com subdomain on the same server and all requests for *.example.com that come to that server are expected to be served by your django app.
In the examples below 0.0.0.0 should be replaced with your IP address and example.com with your domain name
What to write in Networking panel in DO?
Create the following DNS records:
@ A 0.0.0.0
* CNAME @
The first record points your domain (example.com) to your droplet’s IP address. This record handles any request for example.com without a subdomain. The second record says that any subdomain name should point to the same address as the domain without a subdomain. In our system this wildcard should be processed after any other defined subdomain records and act as a catch all. This means that existing records for things like mail.example.com can remain and should not pose a problem.
How to configure Nginx?
If this is the only site configured in nginx and has a default_server setting attached to it’s listen directive you wont have to make any changes at all since this will pass all requests on to your django application. If you have more than one site defined you’ll need to make a very minor configuration change. Open your site’s configuration file in /etc/nginx/sites-enabled/ and inside the server{} block you should see a server_name directive. Setting this to .example.com instead of example.com is all that is needed.
To deploy your Django app with Nginx and Gunicorn on DigitalOcean, with language-specific subdomains, you’ll need to set up the networking and configure Nginx appropriately. Here’s a step-by-step guide to answer your questions:
Firewall: If you’re using a firewall in the DigitalOcean panel, make sure to allow the necessary ports for HTTP (80) and HTTPS (443). You may also want to open the port that Gunicorn will use (usually 8000, but this will be proxied by Nginx).
VPC (Optional): If you’re deploying multiple droplets (for example, separating your database and app), you can create a Virtual Private Cloud (VPC) to ensure private networking between droplets.
DNS Configuration: Ensure that your subdomains (fr.example.com, de.example.com, etc.) are pointing to your server’s IP address in the DigitalOcean DNS settings.
Here’s how to configure Nginx to serve your Django app on multiple subdomains, while handling language detection and redirection.
Make sure you have Nginx installed on your server:
sudo apt update
sudo apt install nginx
Create a new configuration file for your Django app in /etc/nginx/sites-available and link it to /etc/nginx/sites-enabled.
sudo nano /etc/nginx/sites-available/example.com
Here’s a basic example of how you can configure Nginx for your setup. We’ll assume Gunicorn is running on port 8000, and we will configure it for multiple subdomains.
server {
listen 80;
server_name example.com *.example.com;
location / {
proxy_pass http://127.0.0.1:8000; # Gunicorn will serve the app on this port
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Static and media files
location /static/ {
alias /path/to/your/project/static/;
}
location /media/ {
alias /path/to/your/project/media/;
}
# Additional configurations for HTTPS (optional)
# Uncomment the following if you're using SSL
# listen 443 ssl;
# ssl_certificate /etc/ssl/certs/your_certificate.crt;
# ssl_certificate_key /etc/ssl/private/your_certificate_key.key;
# Redirect non-www to www (optional)
# if ($host = 'example.com') {
# return 301 http://www.example.com$request_uri;
# }
}
This configuration allows any subdomain (e.g., fr.example.com, de.example.com, etc.) to be routed to the same Django app. The Django app will handle the logic for setting the language based on the subdomain.
Once your config is set up, you need to enable the Nginx site:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
Then test your Nginx configuration to ensure there are no syntax errors:
nginx -t
If the test is successful, restart Nginx:
sudo systemctl restart nginx
Now, configure Gunicorn to serve your Django app. Here’s an example command to run Gunicorn for your app:
gunicorn --workers 3 --bind 127.0.0.1:8000 example.wsgi:application
You can also create a Gunicorn service to run it automatically as a background process:
sudo nano /etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon for Django project
After=network.target
[Service]
User=your-username
Group=your-group
WorkingDirectory=/path/to/your/project
ExecStart=/path/to/your/venv/bin/gunicorn --workers 3 --bind 127.0.0.1:8000 example.wsgi:application
[Install]
WantedBy=multi-user.target
sudo systemctl start gunicorn
sudo systemctl enable gunicorn
To handle subdomains for different languages, you can use the django-hosts package or manually detect the subdomain in your Django middleware.
a) Install django-hosts (optional):
pip install django-hosts
settings.py:Add the following settings for language and subdomain handling:
LANGUAGES = [
('en', 'English'),
('fr', 'French'),
# Add more languages as needed
]
MIDDLEWARE = [
'django_hosts.middleware.HostsRequestMiddleware', # For django-hosts
# Your other middleware here
]
ROOT_URLCONF = 'your_project.urls'
# If you're using django-hosts
HOSTS = {
'example.com': 'your_project.urls',
'fr.example.com': 'your_project.urls_fr',
# Add more subdomains as needed
}
If you aren’t using django-hosts, you can create custom middleware to set the language based on the subdomain.
from django.utils import translation
from django.http import HttpResponse
class SubdomainLanguageMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
host = request.get_host()
subdomain = host.split('.')[0] # Extract subdomain
if subdomain == 'fr':
translation.activate('fr')
else:
translation.activate('en')
response = self.get_response(request)
return response
python manage.py collectstatic to gather all static files into the correct directory.Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.