Feature request: Better Django support

Hello there!

Yesterday I attempted to migrate my “hobby/pet” project from Heroku to fly.io. I appreciate fly.io’s features and trial plan, those are good and fit my needs.

My project is a “traditional” Python/Django web service, with no weird setup nor strange usage of the stack. Yet, following the docs for “Run a Python App” there were many things that were left missconfigured and thus not working. While I was able to finally solve all the issues and have my site running properly, I still feel like fly.io could benefit from having a better integration and explicit doc support for Django web services.

Below a list of things that I was assuming were going to be autoconfigured but weren’t (yes, I’m spoiled coming from Heroku where all these things were solved automagically):

1- Files from .gitignore are not ignored. Specifically, I have a local_settings.py file under my Django app folder that would set DEBUG = True and change the DATABASE settings to point at localhost. When I first ran fly deploy and visited my site, I was shocked to see the Django site was running with DEBUG enabled because I was absolutely certain that the regular settings.py file had DEBUG = False. After realizing this came from my local settings file, and after lots and lots of googling for fly.io ignore files, fly.io exclude files, fly.io to honor .gitignore files (which lead to nothing), I ended up in a post where ignoring node_modules was discussed (in the context of Node.js apps) and in there I found that I needed to define a .dockerignore file. Which is unfortunate since my Django project does not use Docker at all, so now I need this file just for the sole purpose of ignoring the same list of files that are in .gitignore (no I did not try yet if a symlink would do the trick).

2- The DB migrations are not run on deploy: the solution I found after some googling is to use the [deploy] section in the fly.toml file. This worked perfectly.

3- Static resources are not collected on deploy. Fair, so the I wanted to also do this explicitely using the [deploy] section of the toml file, but I couldn’t find documentation on how to run multiple commands in this stage so I ended up doing this hack:

[deploy]
  release_command = "bash -c \"python manage.py migrate && python manage.py collectstatic --noinput\""

4- The static resources were a 404. This may have been a combination of issues: the fact that it took me a whole to to do 3 above properly, and that my project was still using a deprecated library to server the static files (I was still using dj_static). The solution for this was moving to whitenoise and ensuring the assets were indeed collected.

5- SSH-ing to the console would lead me in a shell with no python in the PATH. This means that running fly ssh console would drop me in a shell where Python was not in the PATH nor I was at the root of my deploy source. It would be great if Fly would have an extra layer of intelligence that would set the right variables (bonus point if DJANGO_SETTINGS_MODULE is set as well) so a fly ssh console would leave the developer in a terminal where python manage.py <command> could be run without further configuration.

Anyways, this was a fun exercise, thank you for Fly.io!

4 Likes

Django is on our to-be-well-supported list! I’m guessing we’ll hire people with a Python focus in the next 6 months, specifically to address this kind of feedback. Thanks for sharing it. :slight_smile:

2 Likes

Thank you @kurt for your quick response. I’m looking forward to those new features, please keep me posted! I’m also happy to be an early/beta tester.

Cheers!

I’m not affiliated in any way with Fly, but I thought I’ll give you some insights as I went through a similar process a few days ago as I was testing deployment to Fly. Probably for the same reasons you did :smiley:

re 1: I know Heroku does respect .gitignore but I don’t see why anyone would assume other PaaS providers would. Fly is Docker-first. Even deploy command looks like docker build. Heroku started with ‘deploying with git’, hence they implemented the support for .gitignore.

re 2: Heroku also has release command phase, so you run migrations exactly the same on Fly.

re 3: Heroku deploys statics automatically. I’d say it’s neither bad nor good. Django and Static Assets | Heroku Dev Center I think moving both to a shell script would be best, which is also something Heroku recommends when running multiple release commands. Release Phase | Heroku Dev Center

re 4: dj_static is archaic. whitenoise just works and is great for MVPs. It supports deployments to CDN so if you set it up correctly, you’re good, Another alternative is django-storages. Fly.io doesn’t offer object storage yet (afaik that’s on their roadmap).

re 5: I agree, that’s weird. But it should work fine if your app was dockerized :slight_smile:

Here’s an example of a dockerized Django app. GitHub - tomwojcik/django-fly.io-example-project: Example Django project to test the deployment on Fly.io let me know if you have some questions. You’re welcome to contribute/open tickets and ask questions.

2 Likes

Hi @tomwojcik, thank you for taking the time to add to this post.

While I completely understand your points, I think you may be assuming that all/most Django projects are dockerized. I don’t have enough information to deny or verify that assumption, but I do know that the natural flow in Heroku would not use docker at all for Django apps. So I would not quickly think that Django apps have a docker setup within (while assuming that there is a git setup within it feels like a more “robust” assumption, IMHO).

And (this is my personal opinion) I think that fly.io would be restricting themselves/the tool if they would expect that whatever is deployed is already dockerized.

In any case, thank you everyone for the work and the tool and the help.