Splitting front end, back end, and DB in a single "app"

I have an existing application hosted on Fly: fairly vanilla Django with a SQLite backend. However I’d like to split the app into a more pure “frontend” (via Angular) and backend (using Django Rest Framework). I’d also like to introduce an actual RDBMS (preferably MySQL). This app is very low traffic (a few thousand visits in an entire day) and ideally I’d love to just have a single Fly pod/container for simplicity.

Could anyone offer insights into how I’d:

  1. Replace SQLite in my existing application
  2. Split my app into backend and frontend
    1. Note I’m not asking for code samples, I can do the actual splitting on my own. I just mean how to arrange is so that it works in Docker/Fly.

Thanks in advance.

Edit: I forgot to mention that I’ve already got the app running in a Docker file using the 3.10-slim-buster Python image.

By coincidence this came up recently, see here.

I’d do this in parts; stick with SQLite for now, and split the app, and get all of that into production. You can then move to another database from there.

1 Like

Here’s the angular specific guidance on deployment: Angular

If you stick with SQLite3, it would be a good idea to use Litestream to give you continuous backups. There is nothing wrong with sqlite3, particularly for apps that get only a few thousand visits a day.

If you want to switch, consider Fly Managed Postgres. Using it is as easy as telling Django to use env.db('DATABASE_URL') in your settings.py

1 Like

That could be nice. At the moment this app gets used literally once a year, for a single day. However, I’d like to build it out so that I can offer it to other people with the same need. So feature development first, then scaling second.

There are two ways to think about this.

One is to not use a single fly “app” - what fly calls an app is often more like a component of a full application. You’d then have one app for your REST backend, which would likely resemble your current Dockerfile - spin up Python, install dependencies, prepare any assets, serve the API at an endpoint.

You’d separately write your Angular client. The build stage for this would output, effectively, a pile of static HTML/CSS/JS, that you would serve as a second app - either served directly off Tigris as static files, or via a second Dockerfile describing lightweight HTML server. You’d setup environment variables to make it easier for clients to automatically point at server URLs.

You could keep this in the same repo if you want - although I’d argue that once you decouple client/server into different stacks, they are now separate projects - but you’d have to have separate directories, Dockerfiles, and fly.toml files for each.

There is an alternative, which is you describe a single Dockerfile that could run client or server, depending on what command you run, and you specify that with process groups. I don’t think this makes sense if the two applications are different stacks (eg: Python backend, static HTML frontend); its real use case is, say, using one process to run the full Django stack, and another to just run background tasks via workers (still in your main Python code).

I think the contradiction that’s tripping things up is trying to decouple your application, and then have a single contain “for simplicity”.

You already have a setup that is simple: a single, full-stack application, handling client and server. Decoupling front and backend adds complexity; given that, trying to server two very different stacks from a single container image doesn’t, actually, keep things simple - it makes things harder, as this image is now trying to server two purposes, not one.

Follow the grain of the wood: having two container images (Dockerfiles and toml configs), two apps, and letting them talk to each other, reflects the complexity of the new two-app solution, whilst keeping it as simple as possible.

Things that shape my opinions: I’m a big fan of monoliths and end-to-end full stack development. I also do enjoy more modern, isomorphic-shape development (huge fan of Sveltekit), but it’s inevitably more complex. There’s nothing wrong with Django/Rails/Phoenix to do everything, esp in the era of modern HATEOAS shaped libraries (that can give you some very slick UI without decoupling everything - htmx, Turbo/Stimulus, Phoenix Liveview, etc).

2 Likes

Or directly by Django: How to manage static files (e.g. images, JavaScript, CSS) | Django documentation | Django

Or by fly.io itself: App configuration (fly.toml) · Fly Docs

1 Like

Of course, I’d forgotten about [[statics]]!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.