skip to Main Content

I have a repository with two folders, one for a React app in the client directory and one for a Flask app using Postgres in the server directory. I am unsure where I should place my Docker and YAML files – one for the entire project or separated for each service. My goal for using Docker is to learn how to use it during development. If I need to use separate files, does that mean I should have them in each folder and run the image with docker-compose up or should the images be placed in one folder and then run? I understand the concept behind Docker, but I am struggling to figure out how to use it properly while developing.

2

Answers


  1. If your combined application consists of exactly these two components, then you should put

    • A Dockerfile in the root directory of the React application, next to its package.json file
    • A Dockerfile in the root directory of the Flask application, next to its Pipfile/setup.cfg/requirements.txt file
    • docker-compose.yml in the root directory of the entire project, launching both containers and the database

    Other filesystem layouts are certainly possible, but this layout will work most naturally with Compose. With these exact filenames and paths you won’t generally have to directly mention the filenames.

    The Compose file might look like:

    version: '3.8'
    services:
      frontend:
        build: ./react
        ports: ['3000:3000']
      backend:
        build: ./flask
        ports: ['5000:5000']
        environment:
          PGHOST: database
          PGUSER: postgres
          PGPASSWORD: passw0rd
        depends_on: [database]
      database:
        image: postgres:15
        ports: ['5432:5432']
        environment:
          POSTGRES_PASSWORD: passw0rd
        volumes:
          - dbdata:/var/lib/postgresql/data
    volumes:
      dbdata:
    

    use it during development

    For the frontend, run docker-compose up -d backend to start the backend and the database. Then use whatever IDE you normally use to work with Node on your host system. The frontend will always need to call the backend via its published port, so its behavior is the same whether you’re running it in a container or doing development.

    For the backend, run docker-compose up -d database to start only the database container. Set the PostgreSQL environment variables to point at that database; export PGHOST=localhost PGUSER=postgres PGPASSWORD=passw0rd, or make these values be the default in your configuration if the environment variables aren’t set. Then use an ordinary Python virtual environment, or normal tools like Poetry or Pipenv.

    I do not recommend trying to inject your host code into a container and trying to make Docker simulate a local environment. IDE support for working with this is mixed, and if your IDE doesn’t specifically support tools in a container then you’ll lost functionality. I also regularly see SO questions around live reloading not working in the isolated Docker environment, and with volume mounts not providing the right filesystem layout inside the container. On the flip side, I’ve generally found a well-structured project easy to package into an image, and for deployments you usually do not want to deploy the source code separately from the Docker images.

    Login or Signup to reply.
  2. It really depends on what you’re trying to do.

    In production, you can have your back serve the static JS files.
    This isn’t very efficient in case you need load balancing of some kind, but for a basic environment it does make your production build much simpler.
    In that case, I would have a single dockerfile at the top level of my project.

    If you want two images, e.g. for development with hot reloads or for a more advanced production environment, you indeed would create two dockerfiles, one for the server running a python base image, and one for the frontend running a base node or nginx image.
    Thus, for simpler usage create a docker-compose file to run both images.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search