DEV Community

David Sabine
David Sabine

Posted on

Docker Compose, Hello World

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.

  1. Make a new folder on your drive somewhere. Call it anything you want.

  2. Inside that new folder, create ONE file (for now) with the following name:

    .
    └── docker-compose.yml
    
  3. Write these lines into the new docker-compose.yml file.

    services:
      hello_world:
        image: hello-world
    
  4. 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}
  1. 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 by docker-compose up; rather, Docker will attach to the existing container inside the “compose project” made in the previous and will run the command in the hello-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

  1. In the folder you made in #1 above, create another file called “Dockerfile”:

    .
    ├── docker-compose.yml
    └── Dockerfile
    
  2. 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.)

  3. 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…

  4. Modify your docker-compose as follows:

    services:
      my-awesome-app:
        build:
          context: .
    
  5. Run docker-compose up.

    Note the name of the new container is {the folder name}-my-awesome-app-{a number}.

  6. 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: .
    
  7. 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 in Dockerfile.

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)

Collapse
 
tbroyer profile image
Thomas Broyer

Any reason you're not using docker compose and compose.yaml rather than the functionally equivalent but somewhat legacy docker-compose and docker-compose.yml names?

Collapse
 
davidsabine profile image
David Sabine

No reason. If you suggest edits to my article, I'll publish them. Or, someday, I might revise as you suggest.

Collapse
 
tbroyer profile image
Thomas Broyer

All I'm suggesting is s/docker-compose/docker compose/ and s/docker-compose.yml/compose.yaml/