Add https to my Django website in Linode server

I'm new in Linode and in programming. I created a website using Django and deployed it in Linode with the automatic Django server creation in the marketplace. It all worked well and I could see and use the website with the new IP. I wanted to add domain and https to learn how it works. So I bought a domain in GoDaddy and tried to link it with my IP. I followed the instructions on Linode Doc to use Certbot and Let's Encrypt but did not have success. First I tried installing the certificate with nginx and them with apache. With Apache2 I could make the website domain link to my IP with https. But my DjangoApp stopped working. It was only showing the files and folders and not running Googling again I tried to install mod_wsgi and direct it to my DjangoApp folder and it started appearing "403 error Forbidden". I found a suggestion to solve this by changing permissions to the root folder and it seemed just to make things worse. So I decided to start anew: created a new Django server in the marketplace, connected it with Github again and deleted the first server. Now my new IP is working fine again (when I type it directly I can see my website). And I changed DNS configuration in Linode Domain to my new IP. When I type <dig +short="""" a=""> in the server terminal I can see my IP, but when I type my domain <> in the browser it is not linking to my IP. Also I would like to know how to use Certbot to get https without installing Apache or Nginx in the server. </dig>

4 Replies

Also I would like to know how to use Certbot to get https without installing Apache or Nginx in the server.

See my responses here:

Also, you can go here:

and fill out the form for detailed instructions from the certbot mavens themselves.

-- sw

Generally speaking, in order to serve your application on the internet you will need to do so using Apache or Nginx over ports 80 or 443. There are alternative web server utilities but these are relatively standard.

With that in mind, and as an alternative to @stevewi's suggestion, I want to share how you can serve your Django App using Nginx as a reverse proxy.

1. Deploy Django

Deploy the Django application from the Linode Marketplace. Use the Deploying Django through the Linode Marketplace guide as a reference. Check the Linode Shell (Lish) about 5 minutes after provisioning to ensure the application has been fully installed. You will see the following message:

Installation complete!

Your application should now be available in your browser at http://<your.ip.address>:8000. If you don't see this message, login to your instance and check the /var/log/stackscript.log file for errors.

2. Configure Your DNS Records

Since DNS records will take some time to propagate, go ahead and get your A record pointed to your IP first. You'll also need the A record configured to get the certificate authenticator to pass. By the time we're done, your domain should be good to go.

3. Install Nginx

Following the guide on NGINX as a Reverse Proxy, login to your instance and install Nginx. You don't need to install Node though since our app in this case is Django and it's already running.

Next, you will create an Nginx reverse proxy file:/etc/nginx/conf.d/<your-file-name>:

server {
  listen 80;
  listen [::]:80;

  server_name <>;

  location / {
      proxy_pass http://<your.ip.address>:8000/;


4. Edit Host File

Along with the proper domain configurations, you need to update your system's /etc/hosts file in order get an SSL certificate.

# /etc/hosts       localhost
<your.ip.address>  <> <your-hostname>


5. Install Certbot

Now you can follow the instructions on the certbot site to install certbot on a Debian system using Nginx. The utility should discover your domain on its own. And voila! Your SSL cert will be installed:

Deploying certificate
Successfully deployed certificate for <your-domain-name> to /etc/nginx/sites-enabled/default
Congratulations! You have successfully enabled HTTPS on https://<>

and your Nginx reverse proxy files should now look like this:

server {

  server_name <>;

  location / {
      proxy_pass http://<your.ip.address>:8000/;

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/<your-domain->/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/<your-domain->/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by 
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by 

server {
    if ($host = <>) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

  listen 80;
  listen [::]:80;

server_name <>;
    return 404; # managed by Certbot


You can now open your domain in your browser and find your app be served securely!

BUT! http://<your.ip.address>:8000 is still serving your app unsecurly. 😕 What to do?

6. Enable Cloud Firewalls

Create Cloud Firewall rules to Drop incoming and outgoing connections on port 8000. This will disallow connections on the original port while still allowing HTTPS connections. This solves the issue of possible insecure connections being made to your application. Hooray!

Corrected the location of the Nginx reverse proxy configuration file

When I follow the steps and browse to my domain name, it says Welcome to nginx! How do I make sure it is redirected to my Django app? The Django app still runs on the ip address+port 8000. And the DNS of the domain name connects to the right ip address.

Linode Staff

I double checked the guide and noticed an error in the path of the Nginx reverse proxy configuration file that may have been causing an error for you. That's been updated to the proper file path now:


You will also want to ensure that your A records are pointing to your IP address and you've left enough time for DNS propagation.


Please enter an answer

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct