skip to Main Content

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?

2

Answers


  1. 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
    Login or Signup to reply.
  2. 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
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search