the fact of real shit

SSL implementation for Django project in custom port

Here I’m going to implement SSL in Django project which will access through custom port. To do this I’m going to use Apache, for SSL I’m going to use letsencrypt and my Django project containerize in docker. I’m going to bring content through Apache proxy technique.

First of all we need to execute (any) Django project. Please follow Create Docker Container for Hello World with Django and uWsgi Server to create a simple Hello World Django project. We are going to uwsgi socket instead of http server. So, in Dockerfile last line need to change as follows –

ENTRYPOINT ["uwsgi", "--socket", ":9000", "--workers", "4", "--master", "--enable-threads", "--module", "helloworlddjango.wsgi"]

Now we have our project up and running. Now in Apache create entry for our domain and using certbot of letsencrypt install SSL. Please point document root in any safe location, we will use that document root to install SSL and then we will point our uWsgi server to bring content from our project. There has a lot of resource in internet to achieve this. Please configure such way that domain will redirect non-ssl to ssl url automatically.

After successfully access of domain securely we can move to change SSL port. To do this we need to change listen of Apache configuration. In my server I need to change /etc/apache2/ports.conf (it may vary server to server). Following commands need to use to access custom port –

<IfModule ssl_module>
	Listen 443
	Listen 59222
</IfModule>

Now we need to install “libapache2-mod-proxy-uwsgi” module to access content through Apache proxy technique.

sudo apt-get install libapache2-mod-proxy-uwsgi

We are ready to access our Django project content. We need to append following configuration into our domain configuration of Apache server. In my case file location is /etc/apache2/sites-enabled/helpabodessltest.shahadathossain.com-le-ssl.conf

SSLProxyEngine on
SSLProxyVerify none 
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off

ProxyRequests Off
ProxyPreserveHost On
ProxyPass / uwsgi://127.0.0.1:9000/ keepalive=On
ProxyPassReverse / uwsgi://127.0.0.1:9000/

Please note, we need to put these code inside “VirtualHost” block. Also need to change “VirtualHost” tag like as follows –

<VirtualHost *:59222>

Also we can put redirect code in Apache from http to https with custom port like following code. Note that we need to put this code into general (80) configuration of the domain (also inside VirtualHost block)

RewriteEngine on
RewriteCond %{SERVER_NAME} =helpabodessltest.shahadathossain.com
RewriteRule ^ https://%{SERVER_NAME}:59222%{REQUEST_URI} [END,NE,R=permanent]

That’s all, we need to restart Apache server. If everything goes fine we can visit our domain with custom port to see “Hello World” output in browser. Thanks.

Posted in apache, PythonTagged ,

Create Docker Container for Hello World with Django and uWsgi Server

I was searching a Hello World implementation for Django of Python in Docker container, but can’t find any good resource at online. So, I plan to code it myself and document it.

This is pure Docker implementation, you don’t need to create any project for Django. You just need Dockerfile to see “Hello World” at browser which powered by Django and uWsgi module.

Here is high level explanation that I’m going TODO –

  • Python, Pip and setuptools installation and upgrade
  • Create requirement.txt file
  • Execute requirement.txt file with Pip
  • Create Django project
  • Modify project settings to allow our domain in Django
  • Replace project’s urls.py to send “Hello World” string to output
  • Code to run server through uWsgi module

Entire steps I’ll do into a single Dockerfile, which we need to build and run through Docker. Here is step by step implementation of Dockerfile.

FROM python:3.11.3
WORKDIR /code
RUN pip install --upgrade pip
RUN pip install setuptools
RUN pip install -U setuptools

Its pretty straight forward, we are using Python 3.11.3 and install Pip and setuptools here.

RUN echo "Django==4.2" >> requirements.txt
RUN echo "uWSGI==2.0.25" >> requirements.txt
RUN pip install -r requirements.txt

Here we create requirement.txt file where we instruct to install Django version 4.2 and uWSGI module version 2.0.25 and then we execute the newly created requirements.txt through Pip.

RUN django-admin startproject helloworlddjango
WORKDIR /code/helloworlddjango
RUN echo "ALLOWED_HOSTS = ['127.0.0.1', 'localhost', 'helpabodessltest.shahadathossain.com']" >> helloworlddjango/settings.py

In this stage we created helloworld project with django-admin (we already Django installed) also we append our project’s settings.py to allow our domain. For this we just append “ALLOWED_HOSTS” variable value.

RUN echo "from django.urls import path" > helloworlddjango/urls.py
RUN echo "from django.shortcuts import HttpResponse" >> helloworlddjango/urls.py
RUN echo "def home_page_view_hello_world(request):" >> helloworlddjango/urls.py
RUN echo "    return HttpResponse('Hello World')" >> helloworlddjango/urls.py
RUN echo "urlpatterns = [path('', home_page_view_hello_world, name='helloworld'),]" >> helloworlddjango/urls.py

This part actually pure Python code we (re)writing our urls.py file where we actually put “Hello World” string when user visit home page of our project.

RUN adduser --disabled-password --no-create-home django
USER django
ENTRYPOINT ["uwsgi", "--http", ":9000", "--workers", "4", "--master", "--enable-threads", "--module", "helloworlddjango.wsgi"]

This is another part where we run our project through uwsgi module. We can run straightly by Django’s builtin server by “manage.py” but here I covered to run uwsgi server.

Here is link https://github.com/razonklnbd/django-hello-world-with-docker where you found complete Dockerfile

To build docker container you have to have docker in your system. After ensuring docker into system you can use following commands to build and run –

sudo docker build -t django-hello-world-mshk .
sudo docker run --name djangohelloworldmshk -d --network=host django-hello-world-mshk:latest

You need to execute into the location where you put your Dockerfile. Please feel free to change container tag and name. You may like following command of docker to see the log and to delete running container (in case you are debugging something)

sudo docker logs djangohelloworldmshk
sudo docker rm $(sudo docker stop $(sudo docker ps -a -q --filter ancestor=django-hello-world-mshk --format="{{.ID}}"))
sudo docker rmi django-hello-world-mshk

That’s all for today! Thanks.

Posted in linux, Python, webdevelopmentTagged , , , ,

Apache Python3 Gunicorn

My journey to install Gunicorn to server Python project is not pleasant because of old Ubuntu system where Python version 3.5 installed but default Gunicorn not compatible with this version.

So, as suggested from gunicorn.org I need to install Gunicorn version 3 for Python 3 … The point is, I need to install this Gunicorn 3 at outside of my virtual environment.

First of all we need to change wsgi.py file in Python project in my case – “<project root>/helloworld/wsgi.py”

import os, sys
# add the hellodjango project path into the sys.path
sys.path.append('/home/django-helloworld/helloworld')

# add the virtualenv site-packages path to the sys.path
sys.path.append('/home/django-helloworld/myvenv/lib/python3.5/site-packages')

from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'helloworld.settings')
application = get_wsgi_application()

Above file I added two lines because while executing from gunicorn 3 (which installed outside of virtual environment i.e. into OS) Python can’t find Django or other project related package.

Posted in apache, linux, PythonTagged , , , ,