I am currently in the process of learning Docker. After reading the docs and a few articles I obviously have more questions than answers. Most intriguing one for me at the moment is: what is the difference between
FROM some:docker-image
In Dockerfile and
image: digitalocean.com/php
In docker-compose.yml
I do understand that they should grab the image and create a container from it. What I don’t understand is what happens if we will specify both at the same time, for example:
version: '3' services: #PHP Service app: build: context: . dockerfile: Dockerfile image: digitalocean.com/php
Both docker-compose.yml and Dockerfile have images specified in them. What happens when those images are different? Will docker-compose.yml always win and for that one service? Will it use only this ‘top’ image? Will they overlap somehow? Or maybe I got it all wrong?
I did see this but I am still not sure if I understand what is going on.
Advertisement
Answer
The difference is build vs. run
Think of images as apps and containers as a process running an app. Running an app does not change the app. Running a container likewise does not change the image. Images are built from Dockerfiles
using docker build
and are persistent. Containers are created as needed by docker run
, docker-compose
, kubernetes, or similar tools from images and are intended to be temporary.
The Dockerfile
is used by the docker build
command to build a new image.
In the Dockerfile
the first line usually specifies the base image with FROM
, i.e. FROM nginx
. Subsequent RUN
lines in the Dockerfile
provide the additional steps that docker build
will execute in a shell, within the context of the FROM
image, to create the new image. Note that the Dockerfile
does not specify the name of the new image. Instead, the new image is named in the -t some/name
option to docker build
The docker-compose.yml
file specifies a group of images to download and run together as part of a combined service. For example, the docker-compose.yml
for a blog could consist of a web server image, an application image, and a database image and would specify not only the images but also possibly how they communicate.
Since docker builds and docker compose are separate operations, there is no conflict or detection of differences. The docker-compose.yml
controls what is going to be download and run, and you can also build whatever you like.
Also, as @David Maze mentioned in comments:
If you use both options then Docker Compose will build the image as specified and then tag it using the image: name; this can be confusing if you’re putting a “standard” image name there.
My guess is if you do that, you might end up with an image, say nginx
on your own machine that does not match the Dockerhub image. Don’t do that. Instead, use unique names for any images that you build.