4

I am attempting to build a simple app with FastAPI and React. I have been advised by our engineering dept, that I should Dockerize it as one app instead of a front and back end...

I have the app functioning as I need without any issues, my current directory structure is.

.
├── README.md
├── backend
│   ├── Dockerfile
│   ├── Pipfile
│   ├── Pipfile.lock
│   └── main.py
└── frontend
    ├── Dockerfile
    ├── index.html
    ├── package-lock.json
    ├── package.json
    ├── postcss.config.js
    ├── src
    │   ├── App.jsx
    │   ├── favicon.svg
    │   ├── index.css
    │   ├── logo.svg
    │   └── main.jsx
    ├── tailwind.config.js
    └── vite.config.js

I am a bit of a Docker noob and have only ever built an image for projects that don't arent split into a front and back end.

I have a .env file in each, only simple things like URLs or hosts.

I currently run the app, with the front end and backend separately as an example.

> ./frontend
> npm run dev
> ./backend
> uvicorn .... 

Can anyone give me tips /advice on how I can dockerize this as one?

0

2 Answers 2

6

As a good practice, one docker image should contain one process. Therefore you should dockerize them separatly (have one Dockerfile per app).

Then, you can add a docker-compose.yml file at the root of your project in order to link them together, it could look like that:

version: '3.3'

services:
  app:
    build:
      context: ./frontend/
      dockerfile: ./Dockerfile
    ports:
      - "127.0.0.1:80:80"

  backend:
    env_file:
      - backend/.env
    build:
      context: ./backend/
      dockerfile: ./Dockerfile
    ports:
      - "127.0.0.1:8000:80"

The backend would be running on http://localhost:8000 and the frontend on http://localhost:80

In order to start the docker-compose you can just type in your shell:

$> docker-compose up

This implies that you already have your Dockerfile for both apps. You can find many example online of different implementations of Dockerfile for the different technologies. For example :

  • For ReactJS you can configure it like this
  • For FastAPI Like that
Sign up to request clarification or add additional context in comments.

Comments

3

Following up on Vinalti's answer. I would also recommend using one Dockerfile for the backend, one for the frontend and a docker-compose.yml file to link them together. Given the following project structure, this is what worked for me.

Project running fastapi (backend) on port 8000 and reactjs (frontend) on port 3006.

.
├── README.md
├── docker-compose.yml
├── backend
│   ├── .env
│   ├── Dockerfile
│   ├── app/
│   ├── venv/
│   ├── requirements.txt
│   └── main.py
└── frontend
    ├── .env
    ├── Dockerfile
    ├── package.json
    ├── package-lock.json
    ├── src/
    ├── ...

backend/Dockerfile

FROM python:3.10
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY ./ /code/
CMD ["uvicorn", "app.api:app", "--host", "0.0.0.0", "--port", "8000"]

frontend/Dockerfile

# pull official base image
FROM node:latest as build
# set working directory
WORKDIR /app
# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
# install app dependencies
COPY package.json ./
COPY package-lock.json ./
# Silent clean install of npm
RUN npm ci --silent
RUN npm install [email protected] -g --silent
# add app
COPY . /app/

# Build production
RUN npm run build
RUN npm install -g serve

## Start the app on port 3006
CMD serve -s build -l 3006

docker-compose.yml

version: '3.8'
services:
  backend:
    env_file:
      - backend/.env
    build:
      context: ./backend/
      dockerfile: ./Dockerfile
    restart: always
    ports:
      - "127.0.0.1:8000:8000"
    expose:
      - 8000

  frontend:
    env_file:
      - frontend/.env
    build:
      context: ./frontend/
      dockerfile: ./Dockerfile
    restart: always
    ports:
      - "127.0.0.1:3006:3006"
    expose:
      - 3006

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.