We can tell by running the previous docker-compose --help
command that there are many subcommands that can be used with the main docker-compose
command. Let's break them down individually and provide examples of each subcommand, starting at the top and working our way down the list. Remember that there are also switches for each subcommand that can be found using the --help
option. For example, docker-compose <subcommand> --help
. These commands will also seem very similar as the commands we saw in the Docker commands section in Chapter 4, Managing Containers. Also, note that some of these commands need to be run in the folder where docker-compose
and/or the Dockerfile for that service are located.
For the command examples, we will be using the following as the contents of our docker-compose.yml
file called example 1
:
master: image: scottpgallagher/galeramaster hostname: master ports: - "3306:3306" node1: image: scottpgallagher/galeranode hostname: node1 links: - master node2: image: scottpgallagher/galeranode hostname: node2 links: - master
We will also be creating this file (example 2
):
web: build: . command: php -S 0.0.0.0:8000 -t /code ports: - "8000:8000" links: - db volumes: - .:/code db: image: orchardup/mysql environment: MYSQL_DATABASE: wordpress
We will create our Dockerfile for this docker-compose.yml
file:
FROM orchardup/php5 ADD . /code
The
build
command of Docker Compose is used when you have changed the contents of a Dockerfile that you are using and need to rebuild one of the systems in the docker-compose.yml
file.
For example, if you review our example 2
code, in the previous section, we have a web
container that we are specifying in our docker-compose.yml
file. Now, if were to update the contents of the Dockerfile, we would need to rebuild the container named web
, so it knows about the change. We may want to change the image we are using or, if the image has been updated, we would want to do a rebuild of the web
container:
$ docker-compose build web
It will look for the name web
in the docker-compose.yml
file, then jump to the Dockerfile, and rebuild the web
container based on the contents of the Dockerfile. This also can be useful; if the container in question has disappeared, you can rebuild just that image. There is just one switch that can be used with this subcommand and that is --no-cache
, which allows you to build the image without using local cache.
The
kill
subcommand does exactly what its name suggests. It will kill a running container without gracefully stopping it. This can have unattended consequences with the data that is being written, such as MySQL database tables, to at the time of issuing this command. Remember that containers are made to be immutable environments; but if you start diving into the volumes, then you are referring to data that is mutable and might change. In an event where you do have a volume and data is being written to it, the best practice would be to use the stop
subcommand.
Using the example 2 code in the The Docker Compose commands section, let's say that both the web
and db
containers are running and we want to stop the web
container. In this case, we could use the kill
subcommand:
$ docker-compose kill web
Next up is logs! This subcommand will print the output from the specified service. Let's take a look at example 1. We have three running containers in this case: master
, node1
, and node2
. We can tell that node2
is doing something strange with its MySQL replication and we need to see whether we can find out why. Our first stop is to check its logs:
$ docker-compose logs node2
You will receive an output similar to the following (but not exactly the same):
node2_1 | at gcomm/src/gmcast.cpp:connect_precheck():282 node2_1 | 150904 16:47:56 [ERROR] WSREP: gcs/src/gcs_core.cpp:long int gcs_core_open(gcs_core_t*, const char*, const char*, bool)():206: Failed to open backend connection: -131 (State not recoverable) node2_1 | 150904 16:47:56 [ERROR] WSREP: gcs/src/gcs.cpp:long int gcs_open(gcs_conn_t*, const char*, const char*, bool)():1379: Failed to open channel 'my_wsrep_cluster' at 'gcomm://master': -131 (State not recoverable) node2_1 | 150904 16:47:56 [ERROR] WSREP: gcs connect failed: State not recoverable node2_1 | 150904 16:47:56 [ERROR] WSREP: wsrep::connect() failed: 7 node2_1 | 150904 16:47:56 [ERROR] Aborting node2_1 | node2_1 | 150904 16:47:56 [Note] WSREP: Service disconnected. node2_1 | 150904 16:47:57 [Note] WSREP: Some threads may fail to exit. node2_1 | 150904 16:47:57 [Note] mysqld: Shutdown complete node2_1 |
We can see that this node has an issue talking to master
and shuts down its MySQL. Now that sure helps us!
You will notice that the output is colored as well. This is something you will see while using Docker Compose, as it separates running containers using different colors. You can get the output of the logs without color as well by appending the --no-color
switch to the command:
$ docker-compose logs --no-color node2 node2_1 | at gcomm/src/gmcast.cpp:connect_precheck():282 node2_1 | 150904 16:47:56 [ERROR] WSREP: gcs/src/gcs_core.cpp:long int gcs_core_open(gcs_core_t*, const char*, const char*, bool)():206: Failed to open backend connection: -131 (State not recoverable) node2_1 | 150904 16:47:56 [ERROR] WSREP: gcs/src/gcs.cpp:long int gcs_open(gcs_conn_t*, const char*, const char*, bool)():1379: Failed to open channel 'my_wsrep_cluster' at 'gcomm://master': -131 (State not recoverable) node2_1 | 150904 16:47:56 [ERROR] WSREP: gcs connect failed: State not recoverable node2_1 | 150904 16:47:56 [ERROR] WSREP: wsrep::connect() failed: 7 node2_1 | 150904 16:47:56 [ERROR] Aborting node2_1 | node2_1 | 150904 16:47:56 [Note] WSREP: Service disconnected. node2_1 | 150904 16:47:57 [Note] WSREP: Some threads may fail to exit. node2_1 | 150904 16:47:57 [Note] mysqld: Shutdown complete node2_1 |
The port
subcommand allows you to use Docker Compose to get you the public-facing port from the private port the server is displaying. This can be useful if you either forget what port privately maps or what port publicly maps. If you have used autoassigned ports, then you might want to be looking that information up as well. The command is very straightforward. Again, looking at example 1, we will this time look at master
. The thing to note with this command is that the container must be running in order to get this information. The structure of this command is:
$ docker-compose <name-from-compose> <port-to-lookup> $ docker-compose port master 3306
There are also two switches to utilize with this subcommand:
--protocol
: This is used to display either the TCP or UDP port to look up the port that you specify on the command line. This will default to display TCP. The reason for this switch would be if you are looking for the UDP port:$ docker-compose --port udp master 3306
--index
: This is used if you have scaled containers and you want to look up what a certain image in the list is using. For example, if we were specifying two masters, we could do:$ docker-compose --index 1 master 3306
: This would display the public-facing port for the master
container in index position 1.$ docker-compose --index 2 master 3306
: This would display the information for the master
container in index spot two.We know for this example that port 3306
is being used for the MySQL service. However, if you don't know what ports it was running on the private or public side, you can use the ps
subcommand that we will be looking at next.
The Docker Compose ps
subcommand can be used to display information on the containers running within a particular Docker Compose folder. For instance, in our last subcommand, we talked about not knowing the private port. This command will help us get that information. We will now take a look at the output of the docker-compose ps
subcommand using example 2 code in the The Docker Compose commands section:
$ docker-compose ps Name Command State Ports --------------------------------------------------------------------------------------------------------- galeracompose_master_1 /entrypoint.sh Up 0.0.0.0:3306->3306/tcp, 4444/tcp, 4567/tcp, 4568/tcp, 53/tcp, 53/udp, 8300/tcp, 8301/tcp, 8301/udp, 8302/tcp, 8302/udp, 8400/tcp, 8500/tcp galeracompose_node1_1 /entrypoint.sh Exit 1 galeracompose_node2_1 /entrypoint.sh Exit 137
We can get a lot of information from this output. We can get the name of the containers running. These names are assigned based upon folder_name
+ _name_used_in_yml_file
+ _<number_of_each_name_running>
. For example, galeracompose_master_1
, where:
galeracompose
is our folder namemaster
is the name being used in the docker-compose.yml
file1
is how many times this container is being runWe also see the command that is running inside the container as well as the state of each container. In our earlier example, we see that one container is up and two are in an Exit
status, which means they are off. From the one that is up, we see all the ports that are being utilized on the backend, including the protocol. Then, we see the ports that are exposed to the outside and also the backend port they are connected to.
When you use various commands with Docker Compose, you can specify either the name given from the output using the ps
subcommand or by the name given in the docker-compose.yml
file.
The pull
subcommand can be used in two ways. One you could run:
$ docker-compose pull
Or you could run:
$ docker-compose pull <service_name>
What's the difference? The difference in the first one is that it will pull all the images that are referenced in the docker-compose.yml
file. In the second one, it will pull just the image that is specified for the service asked to be pulled.
If we look back at example 1 in the Docker Compose commands section, we have master
, node1
, and node2
in our docker-compose.yml
file. If we wanted to retrieve all the images, we would use the first example. If we just wanted the image being used by master
, we would use the second one:
$ docker-compose pull master
Remember that these commands need to be run in the folder where the docker-compose.yml
file is located.
Restart does exactly what it says it does. As with the pull
subcommand, it can be used in two ways. You can run:
$ docker-compose restart
It will restart all the containers that are being used in the docker-compose.yml
file. You can also specify which container to restart:
$ docker-compose restart <service>
Again, using example 1 in the The Docker Compose commands section, we only want to restart one of the node services:
$ docker-compose restart node1
The restart
command will only restart the containers that are currently running. If a container is in an exit state, then it won't start that container up to a running state.
The rm
subcommand can be used to remove containers for specific Docker Compose instances. By default, it will ask you to confirm whether you really want to remove the container in question. It is a good practice to use the subcommand in this way. However, if you are comfortable enough, you can also use the -f
switch with the subcommand to force removal and you won't be prompted to for yes as an answer:
$ docker-compose rm <service> $ docker-compose rm node2 Going to remove galeracompose_node2_1 Are you sure? [yN] y Removing galeracompose_node2_1... done
You can use this command, as we have seen with the previous commands, without specifying a service name. If you do so, it will prompt you to remove each of the stopped containers. It will not try to remove the containers that are running however. Again, you could use the -f
switch to specify the removal of all the stopped containers without asking for approval.
The
run
subcommand is used to run a one-time command against a service, not against an already running container. When you use the run
subcommand, you are actually starting up a new container and executing the specified command. This is one command that you do need to pay attention to, including the switches that are available for the subcommand.
Specifically, there are two to remember:
--no-deps
: This will not start up containers that may be linked to the container being used with the run
subcommand. By default, when you use the run
subcommand, any linked containers will start up as well.--service-ports
: By default, ports that are being specified in the docker-compose.yml
file are not exposed during the execution of the run subcommand. This is to avoid issues with the ports that are already in use. However, this switch will allow you to expose the ports that are being specified. This can be helpful if the ports in question aren't already being exposed.The structure of the subcommand is as follows:
$ docker-compose run <service> <command>
The
scale
subcommand allows you just to do that: scale. With the scale
subcommand, you can specify how many instances you want to start up. Using example 1, if we want to load up a bunch of nodes, we could do that using the scale
subcommand:
$ docker-compose scale node1=3
This would fire up three nodes and link them back to the master
container. You can also specify multiple containers to scale per line as well. If we had a difference in node1
and node2
, we could scale them accordingly on the same line.
$ docker-compose scale node1=3 node2=3
We will use this for our example with the start
subcommand:
$ docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------------------------------- galeracompose_master_1 /entrypoint.sh Exit 137 galeracompose_node2_run_1 /entrypoint.sh Up 3306/tcp, 4444/tcp, 4567/tcp, 4568/tcp, 53/tcp, 53/udp, 8300/tcp, 8301/tcp, 8301/udp, 8302/tcp, 8302/udp, 8400/tcp, 8500/tcp
From the preceding ps
subcommand, we can see that the master
node is stopped. That's not good! We need to get it started as soon as possible:
$ docker-compose start master $ docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------------------------------- galeracompose_master_1 /entrypoint.sh Up 0.0.0.0:3306->3306/tcp, 4444/tcp, 4567/tcp, 4568/tcp, 53/tcp, 53/udp, 8300/tcp, 8301/tcp, 8301/udp, 8302/tcp, 8302/udp, 8400/tcp, 8500/tcp galeracompose_node2_run_1 /entrypoint.sh Up 3306/tcp, 4444/tcp, 4567/tcp, 4568/tcp, 53/tcp, 53/udp, 8300/tcp, 8301/tcp, 8301/udp, 8302/tcp, 8302/udp, 8400/tcp, 8500/tcp
Phew, it is much better now! Let's take a look at what we need to do if we need to stop a running container.
The stop
subcommand stops running containers gracefully. Using our example from the last subcommand, let's stop the master
container:
$ docker-stop master docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------------------------------- galeracompose_master_1 /entrypoint.sh Exit 137 galeracompose_node2_run_1 /entrypoint.sh Up 3306/tcp, 4444/tcp, 4567/tcp, 4568/tcp, 53/tcp, 53/udp, 8300/tcp, 8301/tcp, 8301/udp, 8302/tcp, 8302/udp, 8400/tcp, 8500/tcp
The up
subcommand is used to start all the containers specified in a docker-compose.yml
file. It can also be used to start up a single container as well from a compose file. By default, when you issue the up
subcommand, it will keep everything in the foreground. However, you can use the -d
switch to push all that information into a daemon and just get information on the container names on the screen:
Let's use example 2 in this test case. We will take a look at docker-compose up -d
and docker-compose up
:
$ docker-compose up -d Starting wordpresstest_db_1... Start ing wordpresstest_web_1... $ docker-compose up Starting wordpresstest_db_1... Starting wordpresstest_web_1... Attaching to wordpresstest_db_1, wordpresstest_web_1 db_1 | 150905 14:39:02 [Warning] Using unique option prefix key_buffer instead of key_buffer_size is deprecated and will be removed in a future release. Please use the full name instead. db_1 | 150905 14:39:02 [Warning] Using unique option prefix key_buffer instead of key_buffer_size is deprecated and will be removed in a future release. Please use the full name instead. db_1 | 150905 14:39:03 [Warning] Using unique option prefix key_buffer instead of key_buffer_size is deprecated and will be removed in a future release. Please use the full name instead. db_1 | 150905 14:39:03 [Warning] Using unique option prefix myisam-recover instead of myisam-recover-options is deprecated and will be removed in a future release. Please use the full name instead. ........ db_1 | 150905 14:41:36 [Note] Plugin 'FEDERATED' is disabled. db_1 | 150905 14:41:36 InnoDB: The InnoDB memory heap is disabled db_1 | 150905 14:41:36 InnoDB: Mutexes and rw_locks use GCC atomic builtins db_1 | 150905 14:41:36 InnoDB: Compressed tables use zlib 1.2.3.4 db_1 | 150905 14:41:36 InnoDB: Initializing buffer pool, size = 128.0M db_1 | 150905 14:41:36 InnoDB: Completed initialization of buffer pool db_1 | 150905 14:41:36 InnoDB: highest supported file format is Barracuda. db_1 | 150905 14:41:36 InnoDB: Waiting for the background threads to start db_1 | 150905 14:41:37 InnoDB: 5.5.38 started; log sequence number 1595675 db_1 | 150905 14:41:37 [Note] Server hostname (bind-address): '0.0.0.0'; port: 3306 db_1 | 150905 14:41:37 [Note] - '0.0.0.0' resolves to '0.0.0.0'; db_1 | 150905 14:41:37 [Note] Server socket created on IP: '0.0.0.0'. db_1 | 150905 14:41:37 [Note] Event Scheduler: Loaded 0 events db_1 | 150905 14:41:37 [Note] /usr/sbin/mysqld: ready for connections. db_1 | Version: '5.5.38-0ubuntu0.12.04.1-log' socket: '/var/run/mysqld/mysqld.sock' port: 3306 (Ubuntu)
You can see a huge difference. Remember that, if you don't use the -d
switch and hit Ctrl + C in the terminal window, it will start shutting down the running containers. While it's good for testing purposes, if you are going into a production environment, it is recommended to use the -d
switch.
The
version
subcommand will give you the version of Docker Compose that you are running. It's very straightforward and can also be utilized with the -v
switch:
$ docker-compose version $ docker-compose -v
The difference is that the subcommand version will show you a little more information such as the docker-py
version, Python version, and OpenSSL version, while the -v
switch will just show you the version of Docker Compose.