Search code examples
dockerdocker-composevscode-devcontainerdevcontainer

Developing outside vs inside of Docker container?


I'm brand new to Docker so I'm sorry if any of this sounds dumb. I've done a bunch of research on this topic but finding hard to understand what the best practice is. For context, I want to start a new Django project and wanted to incorporate Docker since I've never done it before. To start I think I would want one container for the app and one for a postgres database. It seems there are few paths I could go down but not sure the most optimal one:

  1. Develop my project locally and Dockerize later. Don't think I want to do this because I want to connect to a containerized database instead of installing postgres locally.
  2. Dockerize from the beginning and mount a volume from my local working environment to the Docker working environment. My understanding of this is that whatever changes I make locally will be mirrored in the container. In this case I think I can have a virtual environment as well and develop locally like I normally do and just build the container whenever I want to test?
  3. Develop from inside the container. My understanding here is that I can docker-compose up -d to start the app and db containers and then attach to the app container and develop in a remote VS Code instance? I also know about Dev Containers, but I also don't understand how dev containers work when I want to work with a database or just other containers in general.

So I guess my main question is which of these is the smartest thing to do?

And if it is using a Dev Container, how do I work with a database? Do I have the database in the same Dev container or is it in a separate non-dev container or something?


Solution

  • When developing a project (especially a web application) it is easy to be tempted to create a Docker development environment (i.e. a "dockerized" version of your project but for development), because in the first instance it sounds very convenient to:

    • Having to avoid installing a bunch of dependencies manually.
    • Saving documentation about the installation and execution of the project.
    • Allow others to run the application easily and quickly.
    • Avoid differences between the development environments of the developers in a team.
    • Give yourself the freedom to damage things without having to spend a lot of time deleting and recreating things.
    • Etc.

    However, involving Docker in the development of a project can also introduce complexities:

    • You may have to explain to other developers about Docker and its peculiarities.
    • Dependency on a specific IDE may arise, because not all IDEs have support for Docker, and configuring and using Docker in some IDEs is not trivial.
    • If there is dependency towards a specific IDE, some developers who do not know this IDE will have to adapt.
    • When Docker is used for development, it is easy to fall into file permissions issues.
    • Etc.

    You can use Docker in development without necessarily introducing these complexities, for example, by "dockerizing" certain parts of the project (like the example given by David Maze, where only PostgreSQL runs with Docker), but if you want to "dockerize" the whole project for development, you must have good reasons to do so, for example:

    • Having to support a legacy project, where dependency versions are extremely difficult to install.
    • Having to use custom dependencies by the company.
    • Having to run many steps to initialize the project (such as populating a database with production data).
    • Etc.

    In conclusion, option 1 is the recommended option in most cases, besides, it is best to just be flexible and have good reasons to do things, because at the end of the day the technology should work for us and not us for it.