Deployment Django App on Vercel
July 24, 2023, 12:39 p.m.
网站开发
Deployment Django App on Vercel to server static files
I got a lot of question when I tried to deployment Django App on vercel,
Fortunately, I did it after I took me over 48 hours. so I want to share it to your for saving your time.
You can see that example site that I host Django App On Vercel.
There are still have a few question for me. Let me know if you know why
Why I still have to set STATIC URL in urls.py when BUG is enable. We Know that django can server static files by itself when DEBUG=True.
Why I have run
python manage.py collectstatic
. This is so weird. We use the path <STATICFILES_DIR> to offer static files when DEBUG=True. Why does I still need to collect static files to <STATIC_ROOT>.Why do I need to enable DEBUG. Ok. I know that. The django is Framework not a web server. But How should I do server static file when DEBUG Is False.
Step 1: configiure vercel.json for python environment on Vercel
You have to create a file vercel.json in your django project root dir. and then You can build python environment on vercel.
otherwise vercel only build front-end files.
## vercel.json
{
"version": 2,
"builds": [
{
"src": "<YOUR PROJECT_NAME>/wsgi.py",
"use": "@vercel/python",
"config": { "maxLambdaSize": "15mb", "runtime": "python3.9" }
},
{
"src": "build_files.sh",
"use": "@vercel/static-build",
"config": {
"distDir": "vercel/static" // YOUR STATIC_ROOT
}
}
],
"routes": [
{
"src": "/vercel/path0/vercel/static/(.*)", // This is a key point. The path = '/vercel/path0' + "STATIC_ROOT"
"dest": "/static/$1"
},
{
"src": "/(.*)",
"dest": "<YOUR PROJECT_NAME>/wsgi.py"
}
]
}
Step 2: Build
There a few questions here you need to be aware of
- Vercel can't support the sqlite3 db. Although I think it is the best database in the world. You have to install driven for your database. I use a free postgres database that is from Vercel. Let me say that you are generous Vercel. So I need to install psycopg2-binary
- Vercel can't server staticfile on STATICFIELS_DIRS.
- I use sass to generate CSS, So I need to generate css in build_files. Be aware of change direction.
## build_files.sh
cd static # My project use SASS to generate CSS files. The path is '/<PROJECT_NAME>/static'
npm install -y # I Have to change dir to generate CSS
npm run sass
cd - # Back on root dir
pip install -r requirements.txt --user
python3.9 manage.py collectstatic --no-input # Your have to collect static file for the project. the files will be on '/vercel/path0/<STATIC_ROOT>'
npm run sass
is mean sass scss:css
## static/package.json
........
"scripts": {
"sass": "sass scss:css"
},
.......
Step 3: Configure Django project
I use ENV variable and django-environ to manange environ of runtime. so it will be a little diffrence from you. You don't have to be surprised.
- We allow "*.vercel.app" subdomains in
ALLOWED_HOSTS
, in addition to 127.0.0.1:
3.1 configure settings.py
## settings.py
if ENV := os.environ.get("ENV") and ENV in ('dev', 'test', 'live', 'vercel'):
if ENV == "dev"
.................
)
elif ENV == "test":
env = environ.Env(
................
)
elif ENV == "live":
env = environ.Env(
............
)
elif ENV == "vercel":
env = environ.Env(
DEBUG=(bool, True),
HOSTS=(
list,
(
"127.0.0.1",
"localhost",
".vercel.app",
".now.sh",
),
),
SECRET_KEY=(str, os.environ.get("SECRET_KEY")),
SQLITE=("db", os.environ.get("DB")),
STATIC_ROOT=(str, BASE_DIR / "vercel" / "static/"),
MEDIA_ROOT=(str, BASE_DIR / "vercel" / "media/"),
)
else:
raise Exception(
"""Please set system variable of ENV before running django.
\n
Example: export ENV='dev'
\n
"""
)
3.2 Add public var for WSGI application
Add app = get_wsgi_application()
to the bottom of the <your_projecte>/wsgi.py
.
The wsgi
module must use a public variable named app
to expose the WSGI application:
3.3 Configure STATIC URL for static files
import os
........
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path("admin/", admin.site.urls),
..........
]
if ENV := os.environ.get("ENV") == "vercel":
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)