I found a great place to deploy my AI projects — Modal.com. It’s nice because it provides access to GPU-powered hosting for a hourly price, and it if nobody is using my app, I’m not paying for the hosting. They give $30/mo in credits, which is more than enough for me.
This is a much better deal than getting a $7/mo Render or Heroku with 512MB of RAM that can’t even load pytorch models I’m using into memory without crashing.
My recent AI TODO project is built using Django. Deploying it to Modal was a bit tricky, so I decided to write this blog post about my experience.
In theory, Modal supports WSGI-compatible apps and Django exports WSGI-compatible module. So the simplest implementation could looks like this:
@stub.function()
@wsgi_app()
def run():
from todoApp.wsgi import application
return application
However, I found a few issues that I had to work around:
copy_local_dir
instructions. copy_local_dir('.')
was a bad idea because it pulled too much data (e.g. .git repo, sqlite db, etc.)manage.py migrate
. However, the code requires some environment variables to be present during the build phase, so I needed to use secrets
to make sure they are present.The final modal_app.py
looks like this:
import os
from modal import Image, Secret, Stub, wsgi_app
image = (
Image.debian_slim(python_version="3.11")
.pip_install_from_requirements("requirements.txt")
.copy_local_dir('staticfiles', '/root/staticfiles')
.copy_local_dir('todoApp', '/root/todoApp')
.copy_local_dir('todos', '/root/todos')
.copy_local_file('manage.py', '/root/manage.py')
.run_commands(
"python /root/manage.py migrate",
secrets=[Secret.from_name("my-app-secret")],
)
)
stub = Stub(name="my-app", image=image)
@stub.function(
secret=Secret.from_name("my-app-secret"),
gpu="T4",
concurrency_limit=1,
container_idle_timeout=300,
)
@wsgi_app()
def run():
from todoApp.wsgi import application
return application
And to run and deploy I use
$ python -m modal deploy modal_app.py
After successful deployment I get a URL I can send to anyone. If the container is not running, it might take 5-15 seconds to boot up. I can also see the logs and metrics in the Modal console:
[ TODO : INCLUDE SCREENSHOT ]