React app with FastAPI, SQLAlchemy, PostgreSQL, and Docker-Compose (a tutorial) [part 1: setup]

Joe Min
3 min readMar 3, 2021

--

This will hopefully help you take out most of the guesswork of standing up a fully containerized, multi-page web application with a backing database.

What you know/aren’t scared by:

  • Docker, Docker Compose
  • Python (3.6+ because f-strings are *chef’s kiss*)
  • JavaScript (at least a little, but this is an article about infra, not aesthetics)

What you will have by the end of this:

  • A dynamic, multi-page frontend to display books
  • A simple database to hold said books
  • A clean REST API to shuttle information between the two
  • All of the above, but also in containers

Good to go? Let’s get started. This is part 1, so let’s start with the basics.

Organization

Intro

I hate setting up environments. Because of that, I use containers whenever possible, certainly to a fault, but it has its merits. Skip the rest of this paragraph if you’re not into tech sermons. Docker is SO nice—yes dependency separation is somewhat of a solved problem, but it still puts the burden of setting up a virtual environment or something similar onto each developer. Using Docker for development purposes has its own suite of problems, but for the most part you work through them once and never have to worry about them again, even for deployments! Also I’ve been using it for years, so there’s pretty much no going back now.

High-Level Architecture

The end goal will be to have a full web app that adheres to the micro-service architecture (sorry.. I know, I hate buzzwords too) to make this easily scalable and deployable in the future. Is this necessary? Maybe not, but it’s a heck of a lot easier to do now rather than later. So let’s do it.

The separate pieces:

  • Frontend. This will be the React app, and this will be more or less stateless*.
  • Backend. This will be our API server. This, too, will be stateless*.
  • Database. Pretty self-explanatory what this is; this is where all of our state will be stored!

*Why stateless? It makes our software that much more resilient. Because everything will be stored in the database (which is easily backed up with periodic dumps), we don’t have to worry about our various apps (or, in a scaled architecture, an instance of one of our apps) getting taken down. We can simply spin one up again that has no prior knowledge of what was going on, and it will function fully.

Hey, three separate pieces? I feel like that sounds like it could really easily translate into… that’s right! A docker-compose** file!

**As a disclaimer—yes, it’s true that docker-compose isn’t the best for production deployments. The fact that it spins up all of your services on the same machine defeats the purpose (in terms of resiliency) of having all of our services split out. But, Kubernetes is beyond the scope of this tutorial… maybe it’ll be in a future one!

Architecture -> docker-compose

Cool, now that we conceptually have our architecture planned out, what does the corresponding docker-compose file look like? Let’s start with this:

# /docker-compose.yml
version: '3.9'
services:
backend:
build: ./backend
frontend:
build: ./frontend
database:
image: postgres

With a corresponding file structure of:

/
docker-compose.yml
backend/
Dockerfile
frontend/
Dockerfile

And for each of those Dockerfiles let’s start with something simple.

# /backend/Dockerfile
from python:3
WORKDIR /app

and:

# /frontend/Dockerfile
from node
WORKDIR /app

Okay great! We now have the architectural skeleton of our application, and even though we don’t _really_ have anything here, we have a directory structure and with it, a plan. Let’s call it there for Part 1.

Part 2 will focus on our application’s backend. Read it here!

--

--

Joe Min
Joe Min

No responses yet