Let’s use docker-compose to create containers.
In my previous post, we used the publicly available hello world
image to create Docker containers.
Now, let’s use docker-compose
to do the exact same thing.
Make a new folder on your drive somewhere. Call it anything you want.
-
Inside that new folder, create ONE file (for now) with the following name:
. └── docker-compose.yml
-
Write these lines into the new
docker-compose.yml
file.
services: hello_world: image: hello-world
-
Run the command:
docker-compose up
.Docker will compose a new “compose project” (that’s what they call it) and, inside it, a new container is created using the publicly available
hello-world
image.
And note the name of the new container will be {your folder name}-{the image name}-{a number}.
docker container ls -a
to see list all your containers.-
Important note, the Docker Desktop GUI, will show:
- a compose project named {your foldername}
- a container (as a child of the compose project) named {the image name}-{a number}
-
And try running the command again:
docker-compose up
.Unlike the previous post, wherein a new container is produced each time you run
docker run hello-world
, a new container is not produced bydocker-compose up
; rather, Docker will attach to the existing container inside the “compose project” made in the previous and will run the command in thehello-world
image.
Now, let’s do the same thing, but this time we’ll add Dockerfile.
Why would we want a Dockerfile? Why not do it all in docker-compose.yml
?
A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image. (I stole that sentence from Docker Docs.) Imagine a single computer that you can copy and reuse.
And a docker-compose.yml
file lets us compose applications that use multiple containers. Imagine a network of computers that you can copy and reuse.
Your Turn
-
In the folder you made in #1 above, create another file called “Dockerfile”:
. ├── docker-compose.yml └── Dockerfile
-
In your new
Dockerfile
, add the following:
FROM hello-world
That line will tell Docker to build an image from the publicy available
hello-world
image. (The same image used in #3 above.) -
Now, we can tell docker-compose to use the new Dockerfile, as follows:
services: hello-world: build: context: .
Interesting to note: docker will name the new artifacts exactly as in the previous step: {the folder name}-{the image name}-{a number}. But, we actually have some control of these details. Carry on…
-
Modify your docker-compose as follows:
services: my-awesome-app: build: context: .
-
Run
docker-compose up
.Note the name of the new container is {the folder name}-my-awesome-app-{a number}.
-
Now, to understand the power of
docker-compose
, modify your file as follows:
services: my-awesome-app-1: build: context: . my-awesome-app-2: build: context: .
-
Run
docker-compose up
.Now, when you run
docker-container ls -a
, you’ll see two containers were created with the names:- {the folder name}-my-awesome-app-1-{a number}
- {the folder name}-my-awesome-app-2-{a number}
And both used the same
hello-world
image configured inDockerfile
.
Takeaways
Using
docker-compose
, you downloaded an image, created containers from that image, and ran a program on that image.Incorporating
Dockerfile
, you separated the concerns nicely: one file that describes a reusable computer; another file that describes a network of computers.
Top comments (3)
Any reason you're not using
docker compose
andcompose.yaml
rather than the functionally equivalent but somewhat legacydocker-compose
anddocker-compose.yml
names?No reason. If you suggest edits to my article, I'll publish them. Or, someday, I might revise as you suggest.
All I'm suggesting is
s/docker-compose/docker compose/
ands/docker-compose.yml/compose.yaml/