AI Agents from Idea to Live Product: Build a Two-App Django Website and Deploy It on Hostinger
Follow the 18-day journey from a business model canvas to working AI agents, then take the next step: put two apps on one Django website, run it on a Hostinger KVM VPS with your own domain and free HTTPS, and share it with the world.
Subscribe on YouTubePlan the business first, design the screens, build a prototype, add AI agents, control costs, then deploy. For deployment, put both apps in one Django project (for example /agent/ and /analytics/), run it with Gunicorn behind Nginx on a Hostinger KVM VPS running Ubuntu, point your domain’s A records to the VPS’s public IP, and add free HTTPS with Certbot. KVM 2 is a comfortable plan for a first product; KVM 1 is enough to learn.
| What you build | One Django project with two apps: an AI assistant at /agent/ and a CSV analytics app at /analytics/ |
|---|---|
| Server | Hostinger KVM VPS with Ubuntu 24.04 LTS (KVM 2 recommended, KVM 1 to learn) |
| Software stack | Python, Django, Gunicorn, Nginx, systemd, Certbot |
| Domain | Two DNS A records (@ and www) pointing to the VPS’s public IP |
| HTTPS | Free Let’s Encrypt certificate with automatic renewal |
| Time needed | About 1–2 hours the first time, a minute for later updates |
| Running cost | VPS from about $6.49/month on promotion, plus LLM API usage |
Most students I meet can follow a tutorial and build an AI agent in a notebook. Far fewer can answer the questions that come after: who will pay for it, what should the screen look like, how much will the API cost, and how do I put it on the internet with my own domain? That gap, between “it works on my laptop” and “people use it”, is where most AI projects quietly die.
So I recorded an 18-day series that goes through the whole journey with one real product, the Datajin data analytics app: business model, design, prototype, AI agents, costs, subscriptions and deployment. This guide brings that series together in one place, and then adds the step that students ask me about most: how to build a website with two apps in Django and run it on a Hostinger VPS, with a domain and HTTPS, using a complete example you can copy.
If you are new to Python or AI, start with the free AI and data science roadmap. If you want structured lessons, live help and a community, join Python ka Chilla: Build AI Agents.
In this guide
- The 18-day journey: from idea to AI product
- Python ka Chilla: Build AI Agents (the course)
- The example: one Django website, two apps
- Build the Django project on your laptop
- Which Hostinger KVM plan do you need?
- Start your KVM VPS and find its public IP
- Set up the server and run Django with Gunicorn and Nginx
- Connect your domain
- Add HTTPS and go live
- Updates, logs, troubleshooting and the production checklist
- All 18 videos
- Links and related guides
- Key terms
- FAQ
How do you go from an idea to a working AI product? The 18-day journey
Work in six phases: plan the business (Business Model Canvas), design the user experience (personas, wireframes, UI elements), build a prototype with Claude Code, add AI agents with Python and LangGraph, make the numbers work (LLM costs and subscriptions), and deploy. The playlist covers each phase with one real product, the Datajin data analytics app.
Here is the whole series, grouped by phase. Each lesson is in Urdu/Hindi with practical screens and code. You can also open the full playlist on YouTube.
- Day 1PlanBusiness Model Canvas
- Days 2–6DesignUI/UX, personas, wireframes
- Days 7–8PrototypeBuilt with Claude Code
- Days 9–14AI agentsPython, LangGraph, agent teams
- Days 15–18Business & shipCosts, subscriptions, deployment
Plan the business
Every product starts as a business question: who pays, for what, and why. On Day 1 we turn a raw idea into a Business Model Canvas and set up the tools: Python, VS Code and Claude Code.
Design what users will see
Before writing code we design: UI and UX principles, user personas, wireframes and the components users expect. This is the cheapest place to fix mistakes.
Build the prototype
With designs ready, Claude Code helps us turn them into a working prototype, which we then test live.
Add AI agents
The prototype becomes smart: what agents are, how to build one in plain Python, then a stateful agent with LangGraph, eleven example agents, and finally a team of four agents inside the Datajin data analytics app.
Make it a business
Two short but important lessons: control your LLM costs, and charge users a subscription instead of asking for their API keys.
Ship it
Five more ready-made research agents with source code, and the full journey from development to deployment with a live example.
- Business model and design come before code.
- Build a prototype first, then add agents.
- Plan costs and subscriptions before launch, not after.
Want to learn all of this step by step? Python ka Chilla: Build AI Agents
Python ka Chilla: Build AI Agents is my course on Codanics. It starts from Python basics and goes through AI, LLMs, RAG, prompt engineering, local models, data analysis and machine learning, to building agentic AI projects with Claude Code, with live Zoom classes and a Discord community.
- Python from scratch: setup, VS Code, GitHub, Copilot, core data types and control flow
- AI, generative AI, LLMs, RAG and CAG, and what makes AI “agentic”
- Prompt engineering, context, tools, RAG vs skills vs MCP, and loop engineering
- Online and local LLMs (Ollama), and choosing the right model and subscription
- Data gathering, cleaning, visualisation and machine learning crash courses
- Claude Code and agentic AI for real project development
- Live Zoom sessions, a Discord community and weekly AI news
The 18-day playlist above shows the product journey in public. The course goes deeper, with assignments, troubleshooting help and the foundations you need to build your own agents instead of only copying mine.
The example: what are we building and deploying?
A Django website called AgentSite with two apps under one domain: an AI Assistant at yourdomain.com/agent/ that answers questions with an LLM, and a Data Analytics app at yourdomain.com/analytics/ that summarises an uploaded CSV with pandas. Both run in one Django project, served by Gunicorn behind Nginx on a Hostinger KVM VPS, with HTTPS from Let’s Encrypt.
Why two apps in one project? In Django, a project is the website and an app is one feature with its own views, URLs and templates. Putting several apps in one project means one server process, one database, one login system and one domain, which is exactly how most real SaaS products start. Later you can replace the simple assistant with your LangGraph agents from Days 11–14 without touching the deployment.
| URL | App | What it does |
|---|---|---|
yourdomain.com/ | Home page | Links to both apps |
yourdomain.com/agent/ | agent | AI assistant: the user asks a question, the server calls the LLM API and shows the answer |
yourdomain.com/analytics/ | analytics | Upload a CSV, get the first rows and summary statistics with pandas |
yourdomain.com/admin/ | Django admin | Manage users and data |
yourdomain.com with your domain and 203.0.113.10 with your VPS’s IP address (203.0.113.10 is a reserved example address).How do you build a Django website with two apps?
Create one Django project, add two apps with startapp, register them in INSTALLED_APPS, include each app’s urls.py under its own path in the project’s urls.py, keep secrets in a .env file, test locally with runserver, and push the code to a private GitHub repository.
Step 1: create the project and the two apps
mkdir agentsite && cd agentsite python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install django anthropic python-dotenv pandas gunicorn django-admin startproject config . python manage.py startapp agent python manage.py startapp analytics pip freeze > requirements.txt
agentsite/ ├── config/ # project settings and main urls.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── agent/ # App 1: AI assistant (your agent lives here) │ ├── services.py │ ├── urls.py │ └── views.py ├── analytics/ # App 2: CSV data analytics │ ├── urls.py │ └── views.py ├── templates/ │ ├── base.html │ ├── home.html │ ├── agent/chat.html │ └── analytics/upload.html ├── .env # secrets, never commit this ├── .gitignore ├── manage.py └── requirements.txt
Step 2: settings that are ready for production
Read every secret and server-specific value from environment variables. That way the same code runs on your laptop and on the VPS, and your API key never goes to GitHub.
# config/settings.py (only the parts you change)
import os
from pathlib import Path
from dotenv import load_dotenv
BASE_DIR = Path(__file__).resolve().parent.parent
load_dotenv(BASE_DIR / ".env")
SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]
DEBUG = os.getenv("DJANGO_DEBUG", "False") == "True"
ALLOWED_HOSTS = os.getenv("DJANGO_ALLOWED_HOSTS", "127.0.0.1,localhost").split(",")
CSRF_TRUSTED_ORIGINS = [f"https://{h}" for h in ALLOWED_HOSTS if "." in h and not h[0].isdigit()]
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"agent", # App 1
"analytics", # App 2
]
TEMPLATES[0]["DIRS"] = [BASE_DIR / "templates"]
STATIC_URL = "static/"
STATIC_ROOT = BASE_DIR / "staticfiles" # filled by collectstatic, served by Nginx
CLAUDE_MODEL = os.getenv("CLAUDE_MODEL", "claude-opus-5-5")
# Turn these on only after HTTPS works (Section 9)
if os.getenv("DJANGO_HTTPS", "False") == "True":
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_HSTS_SECONDS = 3600Step 3: one domain, two apps (URL routing)
# config/urls.py: one domain, two apps
from django.contrib import admin
from django.urls import include, path
from django.views.generic import TemplateView
urlpatterns = [
path("", TemplateView.as_view(template_name="home.html"), name="home"),
path("agent/", include("agent.urls")), # yourdomain.com/agent/
path("analytics/", include("analytics.urls")), # yourdomain.com/analytics/
path("admin/", admin.site.urls),
]# agent/urls.py
from django.urls import path
from . import views
app_name = "agent"
urlpatterns = [path("", views.chat, name="chat")]
# analytics/urls.py
from django.urls import path
from . import views
app_name = "analytics"
urlpatterns = [path("", views.upload, name="upload")]Step 4: App 1, the AI assistant
Keep the AI logic in its own file. Today it is a single call to Claude through the official Anthropic Python SDK; tomorrow you can swap in a LangGraph agent with tools, memory and a team of sub-agents, and the rest of the site stays the same. The code handles rate limits, API errors and declined requests so the page never crashes.
# agent/services.py: the AI part of App 1
# Replace ask_agent() with your LangGraph agent from Days 11-14 when you are ready.
import logging
import os
import anthropic
from django.conf import settings
logger = logging.getLogger(__name__)
# Reads ANTHROPIC_API_KEY from the environment.
# timeout x (max_retries + 1) = 100 s, which stays below Gunicorn's 120 s timeout,
# so a slow answer returns a friendly message instead of a 502 error.
client = anthropic.Anthropic(timeout=50.0, max_retries=1)
SYSTEM_PROMPT = (
"You are a helpful research assistant for students. "
"Answer clearly and briefly. If you are not sure, say so."
)
def ask_agent(question: str) -> str:
if not os.environ.get("ANTHROPIC_API_KEY"):
return "The AI assistant is not configured yet: ANTHROPIC_API_KEY is missing in .env."
try:
response = client.beta.messages.create(
model=settings.CLAUDE_MODEL,
max_tokens=16000,
output_config={"effort": "low"}, # fast, cheaper answers for chat
system=SYSTEM_PROMPT,
messages=[{"role": "user", "content": question}],
# If a request is declined, Anthropic retries it on a suitable fallback model
betas=["server-side-fallback-2026-07-01"],
fallbacks="default",
)
except anthropic.RateLimitError:
return "The assistant is busy right now. Please try again in a minute."
except anthropic.APIStatusError as e:
logger.warning("Claude API error %s: %s", e.status_code, e.message)
return f"The AI service returned an error ({e.status_code}). Please try again later."
except anthropic.APIConnectionError: # includes timeouts
logger.warning("Claude API connection error or timeout")
return "The AI service did not respond in time. Please try again."
if response.stop_reason == "refusal":
return "Sorry, I can't help with that request."
return "".join(block.text for block in response.content if block.type == "text")# agent/views.py
from django.shortcuts import render
from .services import ask_agent
def chat(request):
question, answer = "", None
if request.method == "POST":
question = request.POST.get("question", "").strip()[:2000]
if question:
answer = ask_agent(question)
return render(request, "agent/chat.html", {"question": question, "answer": answer})Step 5: App 2, the data analytics app
A small taste of Datajin: upload a CSV and get a preview and summary statistics. If pandas is new to you, my pandas mastery guide covers everything used here.
# analytics/views.py
import pandas as pd
from django.shortcuts import render
MAX_MB = 5
def upload(request):
context = {}
csv_file = request.FILES.get("csv_file")
if request.method == "POST" and csv_file:
if csv_file.size > MAX_MB * 1024 * 1024:
context["error"] = f"Please upload a CSV smaller than {MAX_MB} MB."
else:
try:
df = pd.read_csv(csv_file)
context["shape"] = df.shape
context["preview"] = df.head(10).to_html(index=False, classes="table")
context["summary"] = df.describe(include="all").fillna("").to_html(classes="table")
except Exception as exc:
context["error"] = f"Could not read this file: {exc}"
return render(request, "analytics/upload.html", context)Step 6: templates
<!-- templates/base.html -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}AgentSite{% endblock %}</title>
</head>
<body style="font-family:system-ui;max-width:860px;margin:auto;padding:20px">
<nav><a href="/">Home</a> · <a href="/agent/">AI Assistant</a> · <a href="/analytics/">Data Analytics</a></nav>
<hr>
{% block content %}{% endblock %}
</body>
</html>
<!-- templates/home.html -->
{% extends "base.html" %}
{% block content %}
<h1>AgentSite</h1>
<p>Two apps, one website:</p>
<ul>
<li><a href="/agent/">AI Assistant</a>: ask a research question</li>
<li><a href="/analytics/">Data Analytics</a>: upload a CSV and get a summary</li>
</ul>
{% endblock %}
<!-- templates/agent/chat.html -->
{% extends "base.html" %}
{% block content %}
<h1>AI Assistant</h1>
<form method="post">{% csrf_token %}
<textarea name="question" rows="4" style="width:100%" required>{{ question }}</textarea>
<button type="submit">Ask</button>
</form>
{% if answer %}<h3>Answer</h3><div style="white-space:pre-wrap">{{ answer }}</div>{% endif %}
{% endblock %}
<!-- templates/analytics/upload.html -->
{% extends "base.html" %}
{% block content %}
<h1>Data Analytics</h1>
<form method="post" enctype="multipart/form-data">{% csrf_token %}
<input type="file" name="csv_file" accept=".csv" required>
<button type="submit">Analyse</button>
</form>
{% if error %}<p style="color:#b00">{{ error }}</p>{% endif %}
{% if shape %}
<p>{{ shape.0 }} rows × {{ shape.1 }} columns</p>
<h3>First 10 rows</h3>{{ preview|safe }}
<h3>Summary statistics</h3>{{ summary|safe }}
{% endif %}
{% endblock %}Step 7: secrets, local test and GitHub
# .env (on your laptop now, and later on the server) DJANGO_SECRET_KEY=paste-a-long-random-string-here DJANGO_DEBUG=True DJANGO_ALLOWED_HOSTS=127.0.0.1,localhost DJANGO_HTTPS=False ANTHROPIC_API_KEY=your-anthropic-api-key CLAUDE_MODEL=claude-opus-5-5
# create a secret key python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())" python manage.py migrate python manage.py runserver # open http://127.0.0.1:8000, then /agent/ and /analytics/
# .gitignore .venv/ .env db.sqlite3 staticfiles/ __pycache__/ # push to a PRIVATE GitHub repository git init git add . git commit -m "AgentSite: Django project with agent and analytics apps" git branch -M main git remote add origin https://github.com/<your-username>/agentsite.git git push -u origin main
- One project, two apps, two URL prefixes: that is all it takes to put two apps on one domain.
- Secrets live in .env, never in Git.
- Keep the AI logic in services.py so you can upgrade the agent later.
Which Hostinger KVM VPS plan do you need for your audience?
Start with KVM 2 (2 vCPU, 8 GB RAM, 100 GB NVMe) for a first real product. KVM 1 (1 vCPU, 4 GB RAM) is enough for learning, demos and early users, because the LLM runs on the provider’s servers, not on your VPS. Choose KVM 4 for a growing SaaS with background workers and several projects, and KVM 8 for heavy traffic or experiments with small local models.
Why a VPS and not shared hosting? Shared hosting is built mainly for PHP and WordPress. Django needs a long-running Python process (Gunicorn), Nginx and your own packages, which means you need root access. A Hostinger KVM VPS gives you a full Linux server with root access and its own public IP address. Get 20% off Hostinger KVM VPS with my referral link when you buy.
Learning and demos. Your portfolio, a class project, or a beta with a small group of users.
Your first real product. A launched SaaS with steady daily users, PostgreSQL and room for a second project.
Growing SaaS. Background workers (Celery, Redis), Docker, several sites, heavier data processing.
High traffic or local models. Many concurrent users, or small open models with Ollama (CPU only, so expect slow answers).
| Plan | Promo price (24-month term) | Renews at |
|---|---|---|
| KVM 1 | $6.49/mo | $11.99/mo |
| KVM 2 | $8.79/mo | $14.99/mo |
| KVM 4 | $12.99/mo | $28.99/mo |
| KVM 8 | $25.99/mo | $49.99/mo |
Specs and prices from Hostinger’s VPS page, checked on 6 November 2026. Prices change with promotions, currency and term length, so confirm on the Hostinger site before you buy.
What every plan includes (and what you will use)
- Full root access: install Python, Nginx, PostgreSQL, anything you need
- A public IP address: for SSH and for your domain’s DNS records
- AMD EPYC CPUs and NVMe storage, with a 1 Gbps network
- Free weekly backups and snapshots you can restore from hPanel
- Firewall management and DDoS protection
- Data centres on four continents: choose the one closest to your users
- A browser terminal in hPanel, useful if SSH ever locks you out
How do you start a Hostinger KVM VPS and find its public IP?
Buy a KVM plan, open the VPS setup in hPanel, choose the data centre nearest your users, select the plain Ubuntu 24.04 LTS operating system, set a strong root password and add your SSH key, then finish setup. After a few minutes the VPS Overview page shows your public IP address and the SSH command to connect.
- Buy the plan. Choose KVM 1 or KVM 2 and a term. Longer terms are cheaper per month. Open Hostinger with my referral link for an extra 20% off before checkout.
- Open the setup. In hPanel, go to VPS and click Setup (or Manage) on your new server.
- Pick a location. Choose the data centre closest to most of your users. Lower distance means faster pages.
- Choose the operating system. Pick a plain OS and select Ubuntu 24.04 LTS. Skip the control panel templates for this guide; we will set everything up ourselves, which teaches you more and keeps the server lean.
- Set credentials. Create a strong root password and add your SSH public key (generate one on your laptop with
ssh-keygen -t ed25519). - Finish and wait. Setup takes a few minutes. Then open VPS → Overview: you will see the public IP address, the SSH username (root) and a ready-made SSH command.
How do you set up the server and run Django with Gunicorn and Nginx?
Log in over SSH with the public IP, update Ubuntu, create a non-root user, install Python, Nginx and Git, enable the ufw firewall, clone your project into a virtual environment, add the server .env, run migrations and collectstatic, then let systemd run Gunicorn on a Unix socket and let Nginx serve static files and forward requests to Gunicorn.
Step 1: first login and a safe user
# from your laptop (use the IP shown in hPanel → VPS → Overview) ssh root@203.0.113.10 # update the server apt update && apt upgrade -y # create a normal user for the app and give it sudo adduser deploy usermod -aG sudo deploy # if you added an SSH key in hPanel, copy it to the new user rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy
Step 2: install packages and turn on the firewall
# install Python tools, Nginx and Git apt install -y python3-venv python3-pip python3-dev build-essential nginx git # firewall: allow SSH, HTTP and HTTPS only ufw allow OpenSSH ufw allow 'Nginx Full' ufw enable ufw status
Step 3: install your project
# log in as the app user from now on ssh deploy@203.0.113.10 cd ~ git clone https://github.com/<your-username>/agentsite.git cd agentsite python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt nano .env # paste your .env, with DEBUG=False and the server values below
# /home/deploy/agentsite/.env on the server DJANGO_SECRET_KEY=a-different-long-random-string DJANGO_DEBUG=False DJANGO_ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com,203.0.113.10 DJANGO_HTTPS=False ANTHROPIC_API_KEY=your-anthropic-api-key CLAUDE_MODEL=claude-opus-5-5
chmod 600 .env python manage.py migrate python manage.py collectstatic --noinput python manage.py createsuperuser # quick test on port 8000 (close it again afterwards) sudo ufw allow 8000 gunicorn --bind 0.0.0.0:8000 config.wsgi # open http://203.0.113.10:8000 in your browser, then press Ctrl+C sudo ufw delete allow 8000
Step 4: run Gunicorn as a service
Gunicorn is the program that runs your Django code. systemd starts it at boot and restarts it if it crashes, so your site stays up even after a server reboot.
# /etc/systemd/system/gunicorn.socket [Unit] Description=gunicorn socket [Socket] ListenStream=/run/gunicorn.sock [Install] WantedBy=sockets.target
# /etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon for agentsite
Requires=gunicorn.socket
After=network.target
[Service]
User=deploy
Group=www-data
WorkingDirectory=/home/deploy/agentsite
ExecStart=/home/deploy/agentsite/.venv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--timeout 120 \
--bind unix:/run/gunicorn.sock \
config.wsgi:application
Restart=on-failure
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload sudo systemctl enable --now gunicorn.socket sudo systemctl status gunicorn.socket # test: this should print your home page HTML curl --unix-socket /run/gunicorn.sock localhost
2 × CPU cores + 1: three on KVM 1, five on KVM 2. Change --workers, then run sudo systemctl daemon-reload && sudo systemctl restart gunicorn.Step 5: Nginx in front of Gunicorn
Nginx receives every request on ports 80 and 443, serves CSS and images directly from staticfiles/, and passes everything else to Gunicorn. Because both apps live in one Django project, a single Nginx block serves /agent/, /analytics/ and every other path.
# /etc/nginx/sites-available/agentsite
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
client_max_body_size 10M; # allow CSV uploads up to 10 MB
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
alias /home/deploy/agentsite/staticfiles/;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
proxy_read_timeout 120s; # AI answers can take a while
}
}sudo ln -s /etc/nginx/sites-available/agentsite /etc/nginx/sites-enabled/ sudo rm /etc/nginx/sites-enabled/default sudo chmod 755 /home/deploy # lets Nginx read the static files sudo nginx -t sudo systemctl restart nginx
Open http://203.0.113.10 in your browser. You should see the AgentSite home page with links to both apps. If not, jump to the troubleshooting table.
- Never run the app as root: use a deploy user.
- Gunicorn runs Django, systemd keeps Gunicorn alive, Nginx faces the internet.
- One Nginx server block serves both apps because they share one project.
How do you connect your domain to the Hostinger VPS?
Create two A records in your domain’s DNS zone: @ (the bare domain) and www, both pointing to the VPS’s public IP. If you bought the domain at Hostinger, do it in hPanel under Domains → DNS / Nameservers. Wait until nslookup returns your VPS IP, which usually takes minutes but can take up to 24–48 hours.
- Get a domain. Many Hostinger VPS plans include a free domain for the first year; otherwise buy one at Hostinger or any registrar.
- Open the DNS zone. At Hostinger: hPanel → Domains → your domain → DNS / Nameservers → DNS records. At another registrar, open its DNS settings.
- Remove old A records for
@andwwwthat point to a parking page. - Add the new records shown below, then save.
- Check propagation with
nslookupor an online DNS checker until both names show your VPS IP.
# DNS records (hPanel → Domains → yourdomain.com → DNS / Nameservers → DNS records) Type Name Points to TTL A @ 203.0.113.10 3600 A www 203.0.113.10 3600 # check from your laptop (repeat until it shows your VPS IP) nslookup yourdomain.com nslookup www.yourdomain.com
How do you add HTTPS and run the app on your domain?
Once the domain points to the VPS, install Certbot with the Nginx plugin and run sudo certbot –nginx -d yourdomain.com -d www.yourdomain.com. Certbot gets a free Let’s Encrypt certificate, adds HTTPS to your Nginx block and renews it automatically. Then set DJANGO_HTTPS=True and restart Gunicorn so Django uses secure cookies and redirects HTTP to HTTPS.
sudo apt install -y certbot python3-certbot-nginx sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com # check that automatic renewal works sudo certbot renew --dry-run
When Certbot asks, allow it to redirect HTTP to HTTPS. Then switch on Django’s secure settings:
# now switch Django to HTTPS mode nano ~/agentsite/.env # set DJANGO_HTTPS=True sudo systemctl restart gunicorn
Now open https://yourdomain.com. You should see the padlock, and both apps should work:
https://yourdomain.com/agent/: ask a question and get an AI answerhttps://yourdomain.com/analytics/: upload a CSV and see the summaryhttps://yourdomain.com/admin/: log in with the superuser you createdhttp://yourdomain.comredirects to HTTPS automatically
DJANGO_HTTPS=True only after Certbot succeeds. If you turn it on earlier, Django redirects every visitor to an HTTPS address that does not exist yet, and you get a “too many redirects” or “connection refused” error.Optional: a second, separate app on a subdomain
Sometimes the second app is not a Django app, for example a Streamlit dashboard or a FastAPI service for your agents. Run it on the same VPS as its own systemd service on a local port, and give it a subdomain:
# Optional: a separate Streamlit app on app.yourdomain.com
# (DNS: add an A record "app" → 203.0.113.10, run Streamlit on 127.0.0.1:8501 with its own systemd service)
server {
listen 80;
server_name app.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:8501;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # Streamlit uses websockets
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
}
# then: sudo certbot --nginx -d app.yourdomain.com- DNS first, then Certbot, then DJANGO_HTTPS=True.
- Certificates renew automatically; test with certbot renew –dry-run.
- Use paths for apps inside Django, subdomains for separate programs.
How do you update, monitor and secure the live app?
Update with a small deploy script (git pull, install requirements, migrate, collectstatic, restart Gunicorn), read logs with journalctl and the Nginx error log, take a snapshot before big changes, and work through a production checklist: DEBUG off, secrets in .env, HTTPS, firewall, non-root user, backups, PostgreSQL for real users and limits on AI usage.
Deploy updates in one command
#!/usr/bin/env bash # ~/agentsite/deploy.sh: run this after every git push set -e cd /home/deploy/agentsite git pull source .venv/bin/activate pip install -r requirements.txt python manage.py migrate --noinput python manage.py collectstatic --noinput sudo systemctl restart gunicorn echo "Deployed ✓"
Make it executable once with chmod +x deploy.sh, then run ./deploy.sh after every push. It asks for the deploy user's password once, for the sudo systemctl restart line.
Read the logs
sudo journalctl -u gunicorn -f # Django / Gunicorn logs (live) sudo tail -f /var/log/nginx/error.log # Nginx errors sudo systemctl status gunicorn nginx # are both running?
Troubleshooting
| You see | Likely cause | Fix |
|---|---|---|
| 502 Bad Gateway | Gunicorn is not running or crashed on start | sudo journalctl -u gunicorn; often a missing package or a typo in .env |
| 400 Bad Request | The domain is not in ALLOWED_HOSTS | Add it to DJANGO_ALLOWED_HOSTS in .env and restart Gunicorn |
| 403 CSRF verification failed | HTTPS origin not trusted | Check the domain spelling in DJANGO_ALLOWED_HOSTS (it builds CSRF_TRUSTED_ORIGINS) |
| Page has no styling | Static files not collected or not readable | Run collectstatic, check the alias path ends with /, chmod 755 /home/deploy |
| 413 Request Entity Too Large | CSV larger than Nginx allows | Raise client_max_body_size and reload Nginx |
| 504 Gateway Timeout on the AI page | The LLM answer took longer than the timeouts | Keep --timeout 120 and proxy_read_timeout 120s, use lower effort, or move long jobs to a background worker |
| Too many redirects | DJANGO_HTTPS=True before HTTPS works | Set it to False, run Certbot, then set it back to True |
| Domain does not load, IP does | DNS not updated yet, or wrong DNS zone | Check with nslookup; edit records where your nameservers point |
Production checklist: the features a live AI app needs
DEBUG=Falseand a uniqueSECRET_KEYon the server- API keys only in
.env(chmod 600), never in Git - HTTPS with automatic renewal, and Django’s secure cookie settings on
- Firewall allows only 22, 80 and 443 (ufw and, if used, the hPanel firewall)
- App runs as a non-root user; SSH keys instead of passwords
- Weekly backups on, plus a manual snapshot before every big change
- PostgreSQL instead of SQLite once you have real users, logins or payments
- Login, rate limits or subscriptions on the AI features to control API costs
- Automatic security updates (
sudo apt install unattended-upgrades) and an uptime monitor - Run
python manage.py check --deployand fix what it reports - Remove the VPS IP from
DJANGO_ALLOWED_HOSTSonce the domain works, so the site only answers on your domain
Want to go further? Containerise the project with Docker for repeatable deployments (see my Docker guide for AI developers) and learn how teams ship and monitor models in the MLOps beginner’s guide.
- One deploy script makes updates safe and boring.
- Most errors are explained in the Gunicorn or Nginx logs.
- Limit AI usage before you share the link widely.
All 18 videos: Product Development A-Z
- 1
- 2Day-2: UI & UX Design for AI Products using Claude CodeLesson · 37:00
- 3
- 4
- 5Day-5: Build Better AI Apps with WireframesLesson · 1:16:10
- 6Day-6: Essential UI/UX Elements & ComponentsLesson · 1:22:05
- 7Day-7: Build an App Prototype with Claude CodeLesson · 1:10:25
- 8Day-8: Our App Prototype is Ready with Claude CodeLesson · 11:14
- 9Day-9: Use of AI Agents in Data Analytics AppLesson · 1:42:15
- 10Day-10: How to Build an AI Agent in Python & Claude CodeLesson · 1:07:20
- 11Day-11: Build an AI Agent A-Z with Python & LangGraphLesson · 1:16:50
- 12
- 13
- 14Day-14: 4 AI Agents Team Integrated in Datajin AppLesson · 39:39
- 15Day-15: Cost Balancing for LLMs in AI AppsShort lesson · 3:17
- 16Day-16: Collect Subscriptions Instead of API KeysShort lesson · 2:40
- 17
- 18Day-18: AI Agent Development to Deployment A-Z (Live Example)Lesson · 1:02:47
No videos match. Try another word.
Links and tools
- 1Hostinger KVM VPS: 20% off with my referral linkKVM plans, specs and current prices
- 2Django deployment checklistOfficial settings to review before going live
- 3CertbotFree HTTPS certificates from Let’s Encrypt
- 4Product Development A-Z playlistAll 18 videos on YouTube
- 5Complete Django tutorials playlistLearn Django from zero, in Urdu/Hindi
- 6Top five AI agents (GitHub)Source code from Day 17
- 7Five Research AI Agents (free book)The companion book for Day 17
Related guides on Codanics
- 1Python ka Chilla: Build AI AgentsThe full course behind this guide
- 2Free AI & data science roadmapWhere to start if you are new
- 3Prompt engineering guideWrite better system prompts for your agents
- 4Docker for AI developersPackage your app for repeatable deployments
- 5What is MLOps?How teams ship and monitor AI in production
- 6Pandas mastery guideThe data skills behind the analytics app
- 7VS Code as your IDEThe editor used throughout the series
- 8AI tools for students and academicsMore AI tools to speed up your work
- 9NLP with Hugging FaceOpen models and NLP pipelines in Python
More AI, data science and career guides on the Codanics blog.
Key terms explained
- AI agent
- A program that uses a language model to plan steps, call tools and act towards a goal, not just answer a question.
- LangGraph
- A Python framework for building stateful, multi-step and multi-agent AI workflows as graphs.
- VPS (virtual private server)
- Your own virtual Linux server with root access, sharing physical hardware with others but isolated from them.
- KVM
- Kernel-based Virtual Machine: the virtualisation technology behind Hostinger's VPS plans, giving each server dedicated resources.
- Public IP address
- The internet address of your VPS. You use it for SSH and in your domain's DNS A records.
- A record
- A DNS entry that points a domain name, such as yourdomain.com, to an IPv4 address.
- Gunicorn
- A Python WSGI server that runs your Django code and handles requests with several worker processes.
- Nginx
- A web server and reverse proxy that faces the internet, serves static files and forwards requests to Gunicorn.
- Certbot
- A free tool that gets and renews Let's Encrypt HTTPS certificates and configures Nginx for you.
- Django app vs project
- A project is the whole website; an app is one feature inside it with its own URLs, views and templates.
Frequently asked questions
Which Hostinger VPS plan do I need for a Django AI agent app?
For a first product, KVM 2 (2 vCPU, 8 GB RAM, 100 GB NVMe) is a comfortable start. KVM 1 (1 vCPU, 4 GB RAM) is enough for learning, demos and a small number of users, because the language model runs on the provider's servers, not on your VPS. Move to KVM 4 or KVM 8 when you add background workers, more projects or many concurrent users. Watch CPU and RAM in hPanel and upgrade when you need to. You can get an extra 20% off with my referral link: https://www.hostinger.com?REFERRALCODE=1MUHAMMADAA70
Can I host a Django app on Hostinger shared hosting instead of a VPS?
Shared web hosting is built mainly for PHP and WordPress sites. To run Django with Gunicorn, Nginx and your own Python packages you need root access, which a VPS gives you. That is why this guide uses a KVM VPS.
Does a Hostinger VPS have a public IP address?
Yes. Each VPS gets its own public IP address, shown in hPanel under VPS → Overview. You use it to connect over SSH and point your domain's A records to the server.
How do I connect my domain to the VPS?
Add two A records in your domain's DNS: @ pointing to the VPS IP and www pointing to the same IP. If the domain is at Hostinger, do this in hPanel under Domains → DNS / Nameservers. Changes usually work within minutes but can take up to 24–48 hours to spread everywhere.
How do I add HTTPS to my Django site?
Install Certbot with the Nginx plugin and run sudo certbot –nginx -d yourdomain.com -d www.yourdomain.com. It gets a free Let's Encrypt certificate, updates your Nginx configuration and renews automatically. Then turn on Django's secure settings.
Can two apps run under one URL?
Yes. Inside one Django project, each app gets its own path, such as yourdomain.com/agent/ and yourdomain.com/analytics/, through the main urls.py. If the second app is a different program, such as Streamlit or FastAPI, run it as its own service and point a subdomain such as app.yourdomain.com to it in Nginx.
Where should I keep my API key?
In a .env file on the server that is not committed to Git, readable only by your user (chmod 600). Django reads it with python-dotenv, and the Anthropic SDK picks up ANTHROPIC_API_KEY automatically.
How many Gunicorn workers should I use?
A common starting point is 2 × number of CPU cores + 1: three workers on KVM 1 and five on KVM 2. Use a longer timeout, such as 120 seconds, because AI answers can take longer than normal web requests.
Should I use SQLite or PostgreSQL in production?
SQLite is fine for a demo or a small internal tool. For a product with real users, logins or payments, install PostgreSQL on the VPS and point Django's DATABASES setting to it.
What is an AI agent?
An AI agent is a program that uses a large language model to decide what to do next: it reads a goal, plans steps, calls tools such as search, code or databases, checks the results and continues until the task is done. A chatbot only answers; an agent acts.
How much does it cost to deploy an AI agent app on Hostinger?
Two costs: the VPS and the LLM API. A Hostinger KVM 1 VPS started at about $6.49 per month on a 24-month promotion and KVM 2 at about $8.79 (checked November 2026, before any referral discount). API costs depend on how many questions users ask and which model you use, so add logins, limits or subscriptions before launch.
How long does it take to deploy a Django app on a VPS?
About one to two hours the first time if your code is ready: around 30 minutes to set up the server, 20 minutes for Gunicorn and Nginx, and a few minutes for DNS and HTTPS, plus waiting for DNS to update. Later updates take a minute with a deploy script.
Do I need Docker to deploy Django on Hostinger?
No. This guide uses a plain Ubuntu server with Gunicorn, Nginx and systemd, which is simpler to learn. Docker becomes useful when you run several services or want identical environments on every machine.
How do I update the live app after changing my code?
Push to GitHub, SSH into the VPS and run a small deploy script: git pull, install requirements, migrate, collectstatic and restart Gunicorn. Take a snapshot in hPanel before big changes so you can roll back.
No questions match. Try another word.
About the author. Dr. Muhammad Aammar Tufail is the founder of Codanics and completed his PhD in a Marie Skłodowska-Curie programme. He teaches Python, AI agents, data science and bioinformatics in Urdu and Hindi, and builds AI products such as the Datajin data analytics app.
Follow him on Facebook, Instagram, TikTok and LinkedIn, see his code on GitHub and Kaggle, and his research on Google Scholar and ResearchGate.
Hostinger plan specs and prices were checked on 6 November 2026 and change often. Commands were written for Ubuntu 24.04 LTS. Always test on your own server and read the official documentation for Django, Nginx and Certbot.



















