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
If your combined application consists of exactly these two components, then you should put
Dockerfile
in the root directory of the React application, next to itspackage.json
fileDockerfile
in the root directory of the Flask application, next to itsPipfile
/setup.cfg
/requirements.txt
filedocker-compose.yml
in the root directory of the entire project, launching both containers and the databaseOther 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:
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.
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 theserver
running apython
base image, and one for thefrontend
running a basenode
ornginx
image.Thus, for simpler usage create a
docker-compose
file to run both images.