The Right Way to Use Docker — Why Docker-Compose.yml Has No ‘CP’ Command

Boris Chen
3 min readMar 5, 2021

As the name implied Docker-Compose means compose. It aimed at run from multiple images as various containers. Then compose these containers together through network sharing or volume sharing.

However, many developers has searched on Internet for ‘cp’ command in docker-compose.yml file just like dockerFile. I have been one of them. But the docker maintenance team decline to add such features to docker-compose.yml. After some time of figuring out, I came to realize ‘cp’ command is anti-pattern. But why so many developers searched for it. I guess it may be misleading by the official guide of using docker.

Check this link.

Yeah. In the example within the official docs show how easy it is to use docker-compose.yml to build to deploy node.js web app by a single command. Just type ‘docker-compose up -d’ and press ‘ENTER’

Actually, this example is for the purpose to attract newbies to raise interests about Docker.

But strictly, this example is not anti-pattern as well. Why? The example is a node.js web app with javascript. It’s not required to build. So just run from node:12-alpine. It has a bind volume that bind working_dir to project root directory. So in this example. It is not required to copy source file to the image. Just run directly. Such processes should only be done on development stage. Must avoid in production time. When we build an image and run it as a container for production deployment. We need the container’s behavior to be stable, predictable. And free from influence of external sources change. So don’t use bind volume to share source code to a container. Especially in production time.

Then, what’s the right way to deal with docker & docker-compose in production. In a word. Docker for build image. Docker-Compose for deployment.

In real practice, many developers try to be as easy as guide doc showed in the example. And they were taught to avoid bind volume in production also by the official doc. So they pursue for a ‘cp’ command in docker-compose.yml file.

In production. To build the image first, and give it a version tag. Then in docker-compose.yml. To run from the image. Yeah, run from the image we builded. NOT run from the image our project based on. So the official document is really easily misleading. It has mislead the second thing, run directly from node:12-alpine. Node:12-alpine is just the base image. The image we should make, reserved and run from is our own project image. For example ‘to-do-list-app:v1.0.0-rc’.

I claimed it is misleading. But strictly saying, it is not misleading actually. For docker newbies. They are easy misunderstanding the intention of the example.

There are two right way to use docker & docker-compose for dev & pro.

First type. In development stage, test, debug, code as usual without docker suite. When it’s ready for alpha-version-testing or beta-version-testing. Then use docker suite for local docker deployment and test. And finally, deploy it to cloud server for production or final testing before open to public.

Second type. Use bind volume and docker-compose.yml for easy run test in the docker. And debug, code to reduce error. When it’s ready for more widely test. Remove bind volume definition. Then do it as first type’s, build image with version tag, make another docker-compose.yml for production start up.

So why ‘cp’ command in docker-compose.yml is anti-pattern? Docker-Compose should only care about the arrangements between image, container, volume, network and the start up entry point. The inside logic is what dockerFile concern about. docker-compose.yml should avoid.

--

--

Boris Chen
0 Followers

Code is arts. Build up in elegant way.