Self-host your SaaS app
video version: video_linkIn the online forums that I am in, I often see people asking how to host their application. And specifically, which cloud provider to use? In this blog post, I will show you how to self-host your Django web application on your own laptop using Docker and Cloudflare Tunnel. This approach is cost-effective and gives you full control over your application. Additionally, this setup costs no money, as Cloudflare Tunnel has a free tier that is sufficient for most applications. And you are not going to have any cloud bill.
Eventhough this blog post focuses on Django, you can apply similar principles to other web frameworks as well. The key is to use Docker to containerize your application and Cloudflare Tunnel to expose it to the internet securely.
This is the easiest way to self-host your web application and let the world access it. This is not going to be step by step guide, but I will provide you with the necessary steps and code snippets to get you started.
Table of Contents
Install django and create a project
Ok so step one is the have your web application running locally. Add the database setttings, static files settings etc. Provide proper settings for allowed hosts in the database to allow connections from localhost.
Docker
Create container
Once you have your application running locally, the next step is to containerize it using Docker. Create a Dockerfile in the root of your Django project with the following contents (you can ask chatgpt to explain this and modify as per your needs):
# Use an official Python runtime as a parent image
FROM python:latest
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Set environment variables
ENV Debug=False
# Add requirements.txt
ADD requirements.txt /app/requirements.txt
# Update and install dependencies
RUN apt-get update && apt-get install -y libpq-dev build-essential python3-dev libffi-dev
RUN pip install --no-cache-dir uv
RUN uv pip install --no-cache-dir --system -r /app/requirements.txt
RUN uv pip install --system browser-use
RUN uvx playwright install chromium --with-deps
RUN apt-get autoremove -y && apt-get clean && rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Install dependencies
COPY requirements.txt /app/
RUN pip install --no-cache-dir gunicorn && pip install --no-cache-dir -r requirements.txt
# Copy the rest of the application code
COPY . /app/
# Expose the port the app runs on
EXPOSE 8082
# Run gunicorn
CMD ["gunicorn", "--bind", "0.0.0.0:8082", "app_website.wsgi:application"]
Notice the port number 8082 in the above file. You can change it to any port you want, just make sure to update it in the Cloudflare Tunnel configuration later. Now build the Docker image using the following command:
docker build -t my_django_app .
Run container
Now run the Docker container using the following command:
docker run -d -p 8082:8082 my_django_app --restart=always --network=cloudflare_app_net
Cloudflare tunnel setup
You can get the latest details here - https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/
You need to be able to own a domain name and control its DNS settings using Cloudflare to make it the most easy.
So based on the latest Cloudflare Tunnel documentation, you need to install cloudflared on your laptop. Then authenticate it with your Cloudflare account.
Then add the hostname in cloudflare tunnel configuration, this is going to be your website address. Make sure to point it to localhost and the port number you used in the Dockerfile. Another thing to keep in mind is the network mode of the Docker container. You need to make sure that the container is running in the same network as the Cloudflare Tunnel. You can create a custom network using the following command:
docker network create cloudflare_app_net
Then run the Docker container with the --network flag as shown in the previous section.
And that should be it. You should now be able to access your Django web application using the hostname you configured. The world can access your web application securely without exposing your laptop's IP address. Hoorah!
If you face any errors, just Google it, or use ChatGPT to help you debug it. Most likely, you will find a solution quickly.