Dockerfile vs docker-compose.yml
Dockerfile
:
- is a recipe for a Docker Image
- only supports portable options (others options have to be specified at container run time)
docker-compose.yaml
:
- is a recipe for a group of running services
- supports overriding portable options that were defined in the
Dockerfile
- supports non-portable options
- supports creating and configuring networks and volumes
- can also configure the build of an Image by using
build:
It is common to use both together.
A Dockerfile
is almost always used to create a custom image. Some images might be used to run services (long running processes), but some images might be used to run short-lived interactive processes (like running unit tests).
docker-compose.yaml
is useful when you want to run one or more services.
Docker creates isolated machine (container). Each container contains only one process (Apache or Mysql or another); And Dockerfile defines how to build a image.
Docker compose allows run, links and configure the bunch of containers together.
In your case apache needs to know "where" a mysql. And mysql needs to be waked up before you run apache container.
Dockerfile
defines how to create app image. App image contains you application and web-browser.
FROM apache:php5.6ADD /src /var/www/awesome_project #add a project src codeADD /config/apache/awesome_project.conf /etc/apache2/sites-available/ # add a configuration# make any things
Then you need to build image docker build my_app:latest .
At this point you have created image, and you need to run app and links it to db
you have 2 ways to do this:
1) Native docker approach. you run db container
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:latest
and after you need to run app container (image was created before)
docker run --name my_app --link some-mysql:mysql -P -d my_app
at this point we have worked application. Bit this simple thing cause us make 2 long command. If you need copy application to another machine you need to repeat this command exactly.
2) docker-compose way allows create a configuration for running the containers. It described how exactly run containers.
Simple docker-compose.yml
config illustrate this approach
db: image: mysql environment: - MYSQL_USER=root - MYSQL_PASSWORD=rootapp: image: my_app:latest ports: - 80:80 depends_on: - db environment: # Database - DB_USER_NAME=root - DB_USER_PASSWORD=root
This config allows you run 2 container together, links and configure them.
This is very easy example. and pros of using docker compose not apparent, but if you have 5+ containers it is too hard to run them together without compose.
It's fundamentally about a separation of concerns and a simple way to conceive this is by thinking in terms of what vrs how.
Dockerfile defines what goes on within a container.
Docker-compose.yml defines how that container is run within a host. This is why they say in docs - "services are just containers in production".
The container doesn't care how or where it is run, its just concerned with what it is running. The host doesn't care about what it is running only how it is run .e.g. multiple instances, this much RAM, that much CPU, make sure you start this service before that one, etc.
So we create two separate configuration docs for each of these purposes.