I was facing the question: How can I deploy my Django project on Vercel?
My requirements:
- Ubuntu 22.04.3 (Linux)
- Django project with 3 apps
- change for the deployment on Vercel the SQLite database to PostgreSQL
- my static files are in one app (ui) and not in the root directory
# project tree (short version):
.
├── accounts
├── build_files.sh
├── db.sqlite3
├── project
│ ├── asgi.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
├── README.md
├── requirements.txt
├── second_app
├── ui
│ ├── static
│ │ └── css
│ │ └── styles.css
└── vercel.json
1) deployment on Vercel
I had already an account on Vercel and the vercel-cli installed.
step 1
create in root directory of your project the file: build_files.sh
and add these lines of code
# build_files.sh
pip install -r requirements.txt
python3.9 manage.py collectstatic --noinput
step 2
create in root a versel.json
file, which is the configuration for the versel deployment:
# versel.json
{
"version": 2,
"builds": [
{
"src": "<projectname>/wsgi.py",
"use": "@vercel/python",
"config": { "maxLambdaSize": "15mb", "runtime": "python3.9" }
},
{
"src": "build_files.sh",
"use": "@vercel/static-build",
"config": {
"distDir": "ui/staticfiles"
}
}
],
"routes": [
{
"src": "/static/(.*)",
"dest": "/static/$1"
},
{
"src": "/(.*)",
"dest": "<projectname>/wsgi.py"
}
],
"outputDirectory": "ui/staticfiles"
}
make sure to update the "projectname" _
_"src": "<projectname>/wsgi.py",
points to the wsgi.py file of your project
"outputDirectory": "ui/staticfiles"
tells vercel where to look because I have the static and staticfiles directories in the app called ui instead of root directory
step 3
tell where the static and staticfiles directories are located:
# settings.py
STATICFILES_DIRS = [os.path.join(BASE_DIR, "ui/static")]
STATIC_URL = "static/"
STATIC_ROOT = os.path.join(BASE_DIR, "ui/staticfiles")
NOTE: If in your project the static directory is in root directory:
# versel.json
{
"version": 2,
"builds": [
{
"src": "<projectname>/wsgi.py",
"use": "@vercel/python",
"config": { "maxLambdaSize": "15mb", "runtime": "python3.9" }
},
{
"src": "build_files.sh",
"use": "@vercel/static-build",
"config": {
"distDir": "staticfiles"
}
}
],
"routes": [
{
"src": "/static/(.*)",
"dest": "/static/$1"
},
{
"src": "/(.*)",
"dest": "<projectname>/wsgi.py"
}
]
}
# settings.py
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]
STATIC_URL = "static/"
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
step 4
Integrate the PostgreSQL database into the Django project:
# settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': '<mydb>',
'USER': '<myuser>',
'PASSWORD': '<mypass>',
'HOST': 'localhost',
'PORT': '5432',
}
}
to create a PostgreSQL database look at the end of this article
step 5
update the allowed hosts to give vercel access and being a valid host name:
# settings.py
ALLOWED_HOSTS = ["127.0.0.1", ".vercel.app", ".now.sh"]
step 6
create the vercel variable app
in your Django project
# wsgi.py
application = get_wsgi_application()
# add this vercel variable
app = application
step 7
add the static folder to the urls of your project
# your_project/urls.py
urlpatterns = [
path("admin/", admin.site.urls),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
step 8
open terminal:
vercel
The vercel cli will ask you:
Set up and deploy “~/<path_of_your_project>”? [Y/n] y
? Which scope do you want to deploy to? <your_github_name>
? Link to existing project? [y/N] n
? What’s your project’s name? <name_of_project>
? In which directory is your code located? ./
🔗 Linked to <your_github_name>/<name_of_project> (created .vercel and added it to .gitignore)
🔍 Inspect: https://vercel.com/<your_github_name>/<name_of_project>/<vercel_specifics> [5s]
To deploy to production (<name_of_project>.vercel.app), run `vercel --prod`
❗️ Due to `builds` existing in your configuration file, the Build and Development Settings defined in your Project Settings will not apply. Learn More: https://vercel.link/unused-build-settings
to run the deployed Django app on vercel, run:
vercel --prod
2) create and set up the PostgreSQL database:
We need to install several libraries and dependancies:
A) install PostgreSQL:
sudo apt-get install postgresql postgresql-contrib
B) install dependencies necessary for Linux:
sudo apt-get install libpq-dev python3-dev
C) install the PostgreSQL database adapter to communicate to the database:
# install inside the virtual environment of your project:
pip install psycopg2
pip freeze > requirements.txt
use the pip freeze > requirements.txt
to save the new installed package inside the requirements.txt file
D) Create the database and a user:
We use the PostgreSQL database adapter to create a database and a user:
sudo -u postgres psql
first we create the database named: "mydb"
CREATE DATABASE <mydb>;
end the command with a semicolon!
create a user "myuser" with password "mypass":
CREATE USER <myuser> WITH ENCRYPTED PASSWORD '<mypass>';
optimize PostgreSQL's settings:
ALTER ROLE <myuser> SET client_encoding TO 'utf8';
ALTER ROLE <myuser> SET default_transaction_isolation TO 'read committed';
ALTER ROLE <myuser> SET timezone TO 'UTC';
these parameter are recommended by Django docs
grant permission to the user:
GRANT ALL PRIVILEGES ON DATABASE <mydb> TO <myuser>;
addapt the name of the database and the user name
quit the SQL prompt
\q
E) Integrate the PostgreSQL database into the Django project:
# settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': '<mydb>',
'USER': '<myuser>',
'PASSWORD': '<mypass>',
'HOST': 'localhost',
'PORT': '',
}
}
For production or hosting on Vercel the better version will be to store sensitive information in the .env
file in root of your project.
To be able to use a .env
file in your project we need to install:
pip install python-dotenv
pip freeze > requirements.txt
use the pip freeze > requirements.txt
to save the new installed package inside the requirements.txt file
# settings.py
from dotenv import load_dotenv
load_dotenv()
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
"NAME": os.environ.get("DB_NAME"),
"USER": os.environ.get("DB_USER"),
"PASSWORD": os.environ.get("DB_PASSWORD"),
"HOST": os.environ.get("DB_HOST"),
"PORT": os.environ.get("DB_PORT"),
}
}
add a new file .env
in root of your project:
# .env
DB_NAME= "<mydb>"
DB_USER= "<myuser>"
DB_PASSWORD= "<mypass>"
DB_HOST= "localhost"
DB_PORT= "5432"
finish the creation of the PostgreSQL database with
python manage.py makemigrations
python manage.py migrate
Hope this post helps!