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 bash
I 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.sh
did 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 -d
starts the container(s) in the background and 2)docker-compose exec <name> bash
opens a bash in the container with<name>
- enter a running container - just like before,
docker-compose exec <name> bash
opens a bash in the container with<name>
the<name>
is defined in thedocker-compose.yml
file as the service's name - build the image on demand -
docker-compose build
this builds all docker containers as needed,docker-compose build --pull
will 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.yml
file, 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.