I'm having difficulties understanding docker. No matter how many tutorials I watch, guides I read, for me docker-compose is like being able to define multiple Dockerfiles, ie multiple containers. I can define environment variables in both, ports, commands, base images.
I read in other questions/discussions that Dockerfile defines how to build an image, and docker-compose is how to run an image, but I don't understand that. I can build docker containers without having to have a Dockerfile.
It's mainly for local development though. Does Dockerfile have an important role when deploying to AWS for example (where it's probably coming out of the box for example for EC2)?
So the reason why I can work locally with docker-compose only is because the base image is my computer (sorting out the task Dockerfile is supposed to do)?
CodePudding user response:
Think about how you'd run some program, without Docker involved. Usually it's two steps:
- Install it using a package manager like
apt-get
orbrew
, or build it from source - Run it, without needing any of its source code locally
In plain Docker without Compose, similarly, you have the same two steps:
docker pull
a prebuilt image with the software, ordocker build
it from sourcedocker run
it, without needing any of its source code locally
I'd aim to have a Dockerfile that creates an immutable copy of your image, with all of its source code and library dependencies as part of the image. The ideal is that you can docker run
your image without -v
options to inject source code or providing the command at the docker run
command line.
The reality is that there are a lot of moving parts: you probably need to docker network create
a network to get containers to communicate with each other, and use docker run -e
environment variables to specify host names and database credentials, and launch multiple containers together, and so on. And that's where Compose comes in: instead of running a series of very long docker
commands, you can put all of the details you need in a docker-compose.yml
file, check it in, and run docker-compose up
to get all of those parts put together.
So, do:
- Use Compose to start multiple containers together
- Use Compose to write down complex runtime options like port mappings or environment variables with host names and credentials
- Use Compose to build your image and start a container from it with a single command
- Build your application code and a standard
CMD
to run it into your Dockerfile.