Docker vs. docker-compose
After clarifying why I use Docker for every project I set up let me try to clarify also: Why would I use a docker-compose setup over a single Dockerfile setup? I had been doing the single Dockerfile setup for quite a while. I was doing a lot of manual work, that made the setup work. But I don't regret it, it taught me a lot! But that was not sustainable, and it didn't scale.
How I Automate every Projects' Setup
My setup with one docker container always contained a run.sh file, and a Dockerfile. The run.sh file grew over time and taught me a lot of bash, but docker-compose does all I need without any bash scripting. More about that in a bit. The run.sh had the following purposes:
- start and enter a container - via
./run.sh bashI built, started, entered a container and landed on the command line inside that container - enter a running container - the above command also detected if a container was already running and just entered it, basically opening a second shell inside the container (via
docker exec) - build the image on demand - when I changed the
Dockerfile(the definition of the container) docker needs to rebuild the container, myrun.shdid this (more or less well) on demand - configure the docker runtime - when running a docker container you might need to expose a port (for a web server running inside the container) or you need to map a folders into the container, so you can work with the files inside the container. All these things were inside my
run.sh.
docker-compose ftw
Long story short: docker-compose does all that. A bit different, maybe not as convinient, but in a standardized and consistent way. Additionally docker-compose does it for any number of containers!
For using docker-compose I use this docker-compose.yml file. All things I configured in my run.sh before are in this file. Using docker-compose I do the above like this:
- start and enter a container - this needs two commands with
docker-compose, 1)docker-compose up -dstarts the container(s) in the background and 2)docker-compose exec <name> bashopens a bash in the container with<name> - enter a running container - just like before,
docker-compose exec <name> bashopens a bash in the container with<name>the<name>is defined in thedocker-compose.ymlfile as the service's name - build the image on demand -
docker-compose buildthis builds all docker containers as needed,docker-compose build --pullwill try to find newer docker images, e.g. when you just used the image "node" - configure the docker runtime - all the configuration of mapping ports or volumes are done in the
docker-compose.ymlfile, normally located at the root of the project's directory.
In the README.md
I also described how I am using docker-compose for this project.
Finally
I am quite happy with that setup now. Every project works the same. I am thinking of using the same name "app" for the main container, so I can always do
docker-compose exec app bash to enter the app (or main) container. This could make it even more unified and easier. The docker-compose.yml file
I use for this site the container is called "picostitch" right now, which I need to know. Not as ideal as using "app" every time.