github.com/guilhermebr/docker@v1.4.2-0.20150428121140-67da055cebca/docs/sources/userguide/usingdocker.md (about) 1 page_title: Working with containers 2 page_description: Learn how to manage and operate Docker containers. 3 page_keywords: docker, the docker guide, documentation, docker.io, monitoring containers, docker top, docker inspect, docker port, ports, docker logs, log, Logs 4 5 # Working with containers 6 7 In the [last section of the Docker User Guide](/userguide/dockerizing) 8 we launched our first containers. We launched two containers using the 9 `docker run` command. 10 11 * Containers we ran interactively in the foreground. 12 * One container we ran daemonized in the background. 13 14 In the process we learned about several Docker commands: 15 16 * `docker ps` - Lists containers. 17 * `docker logs` - Shows us the standard output of a container. 18 * `docker stop` - Stops running containers. 19 20 > **Tip:** 21 > Another way to learn about `docker` commands is our 22 > [interactive tutorial](https://www.docker.com/tryit/). 23 24 The `docker` client is pretty simple. Each action you can take 25 with Docker is a command and each command can take a series of 26 flags and arguments. 27 28 # Usage: [sudo] docker [command] [flags] [arguments] .. 29 # Example: 30 $ docker run -i -t ubuntu /bin/bash 31 32 Let's see this in action by using the `docker version` command to return 33 version information on the currently installed Docker client and daemon. 34 35 $ docker version 36 37 This command will not only provide you the version of Docker client and 38 daemon you are using, but also the version of Go (the programming 39 language powering Docker). 40 41 Client version: 0.8.0 42 Go version (client): go1.2 43 44 Git commit (client): cc3a8c8 45 Server version: 0.8.0 46 47 Git commit (server): cc3a8c8 48 Go version (server): go1.2 49 50 Last stable version: 0.8.0 51 52 ### Seeing what the Docker client can do 53 54 We can see all of the commands available to us with the Docker client by 55 running the `docker` binary without any options. 56 57 $ docker 58 59 You will see a list of all currently available commands. 60 61 Commands: 62 attach Attach to a running container 63 build Build an image from a Dockerfile 64 commit Create a new image from a container's changes 65 . . . 66 67 ### Seeing Docker command usage 68 69 You can also zoom in and review the usage for specific Docker commands. 70 71 Try typing Docker followed with a `[command]` to see the usage for that 72 command: 73 74 $ docker attach 75 Help output . . . 76 77 Or you can also pass the `--help` flag to the `docker` binary. 78 79 $ docker attach --help 80 81 This will display the help text and all available flags: 82 83 Usage: docker attach [OPTIONS] CONTAINER 84 85 Attach to a running container 86 87 --no-stdin=false: Do not attach stdin 88 --sig-proxy=true: Proxify all received signal to the process (non-TTY mode only) 89 90 > **Note:** 91 > You can see a full list of Docker's commands 92 > [here](/reference/commandline/cli/). 93 94 ## Running a web application in Docker 95 96 So now we've learnt a bit more about the `docker` client let's move onto 97 the important stuff: running more containers. So far none of the 98 containers we've run did anything particularly useful though. So let's 99 build on that experience by running an example web application in 100 Docker. 101 102 For our web application we're going to run a Python Flask application. 103 Let's start with a `docker run` command. 104 105 $ docker run -d -P training/webapp python app.py 106 107 Let's review what our command did. We've specified two flags: `-d` and 108 `-P`. We've already seen the `-d` flag which tells Docker to run the 109 container in the background. The `-P` flag is new and tells Docker to 110 map any required network ports inside our container to our host. This 111 lets us view our web application. 112 113 We've specified an image: `training/webapp`. This image is a 114 pre-built image we've created that contains a simple Python Flask web 115 application. 116 117 Lastly, we've specified a command for our container to run: `python app.py`. This launches our web application. 118 119 > **Note:** 120 > You can see more detail on the `docker run` command in the [command 121 > reference](/reference/commandline/cli/#run) and the [Docker Run 122 > Reference](/reference/run/). 123 124 ## Viewing our web application container 125 126 Now let's see our running container using the `docker ps` command. 127 128 $ docker ps -l 129 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 130 bc533791f3f5 training/webapp:latest python app.py 5 seconds ago Up 2 seconds 0.0.0.0:49155->5000/tcp nostalgic_morse 131 132 You can see we've specified a new flag, `-l`, for the `docker ps` 133 command. This tells the `docker ps` command to return the details of the 134 *last* container started. 135 136 > **Note:** 137 > By default, the `docker ps` command only shows information about running 138 > containers. If you want to see stopped containers too use the `-a` flag. 139 140 We can see the same details we saw [when we first Dockerized a 141 container](/userguide/dockerizing) with one important addition in the `PORTS` 142 column. 143 144 PORTS 145 0.0.0.0:49155->5000/tcp 146 147 When we passed the `-P` flag to the `docker run` command Docker mapped any 148 ports exposed in our image to our host. 149 150 > **Note:** 151 > We'll learn more about how to expose ports in Docker images when 152 > [we learn how to build images](/userguide/dockerimages). 153 154 In this case Docker has exposed port 5000 (the default Python Flask 155 port) on port 49155. 156 157 Network port bindings are very configurable in Docker. In our last example the 158 `-P` flag is a shortcut for `-p 5000` that maps port 5000 inside the container 159 to a high port (from *ephemeral port range* which typically ranges from 32768 160 to 61000) on the local Docker host. We can also bind Docker containers to 161 specific ports using the `-p` flag, for example: 162 163 $ docker run -d -p 80:5000 training/webapp python app.py 164 165 This would map port 5000 inside our container to port 80 on our local 166 host. You might be asking about now: why wouldn't we just want to always 167 use 1:1 port mappings in Docker containers rather than mapping to high 168 ports? Well 1:1 mappings have the constraint of only being able to map 169 one of each port on your local host. Let's say you want to test two 170 Python applications: both bound to port 5000 inside their own containers. 171 Without Docker's port mapping you could only access one at a time on the 172 Docker host. 173 174 So let's now browse to port 49155 in a web browser to 175 see the application. 176 177 ![Viewing the web application](/userguide/webapp1.png). 178 179 Our Python application is live! 180 181 > **Note:** 182 > If you have used the `boot2docker` virtual machine on OS X, Windows or Linux, 183 > you'll need to get the IP of the virtual host instead of using localhost. 184 > You can do this by running the following outside of the `boot2docker` shell 185 > (i.e., from your comment line or terminal application). 186 > 187 > $ boot2docker ip 188 > The VM's Host only interface IP address is: 192.168.59.103 189 > 190 > In this case you'd browse to http://192.168.59.103:49155 for the above example. 191 192 ## A network port shortcut 193 194 Using the `docker ps` command to return the mapped port is a bit clumsy so 195 Docker has a useful shortcut we can use: `docker port`. To use `docker port` we 196 specify the ID or name of our container and then the port for which we need the 197 corresponding public-facing port. 198 199 $ docker port nostalgic_morse 5000 200 0.0.0.0:49155 201 202 In this case we've looked up what port is mapped externally to port 5000 inside 203 the container. 204 205 ## Viewing the web application's logs 206 207 Let's also find out a bit more about what's happening with our application and 208 use another of the commands we've learnt, `docker logs`. 209 210 $ docker logs -f nostalgic_morse 211 * Running on http://0.0.0.0:5000/ 212 10.0.2.2 - - [23/May/2014 20:16:31] "GET / HTTP/1.1" 200 - 213 10.0.2.2 - - [23/May/2014 20:16:31] "GET /favicon.ico HTTP/1.1" 404 - 214 215 This time though we've added a new flag, `-f`. This causes the `docker 216 logs` command to act like the `tail -f` command and watch the 217 container's standard out. We can see here the logs from Flask showing 218 the application running on port 5000 and the access log entries for it. 219 220 ## Looking at our web application container's processes 221 222 In addition to the container's logs we can also examine the processes 223 running inside it using the `docker top` command. 224 225 $ docker top nostalgic_morse 226 PID USER COMMAND 227 854 root python app.py 228 229 Here we can see our `python app.py` command is the only process running inside 230 the container. 231 232 ## Inspecting our web application container 233 234 Lastly, we can take a low-level dive into our Docker container using the 235 `docker inspect` command. It returns a JSON hash of useful configuration 236 and status information about Docker containers. 237 238 $ docker inspect nostalgic_morse 239 240 Let's see a sample of that JSON output. 241 242 [{ 243 "ID": "bc533791f3f500b280a9626688bc79e342e3ea0d528efe3a86a51ecb28ea20", 244 "Created": "2014-05-26T05:52:40.808952951Z", 245 "Path": "python", 246 "Args": [ 247 "app.py" 248 ], 249 "Config": { 250 "Hostname": "bc533791f3f5", 251 "Domainname": "", 252 "User": "", 253 . . . 254 255 We can also narrow down the information we want to return by requesting a 256 specific element, for example to return the container's IP address we would: 257 258 $ docker inspect -f '{{ .NetworkSettings.IPAddress }}' nostalgic_morse 259 172.17.0.5 260 261 ## Stopping our web application container 262 263 Okay we've seen web application working. Now let's stop it using the 264 `docker stop` command and the name of our container: `nostalgic_morse`. 265 266 $ docker stop nostalgic_morse 267 nostalgic_morse 268 269 We can now use the `docker ps` command to check if the container has 270 been stopped. 271 272 $ docker ps -l 273 274 ## Restarting our web application container 275 276 Oops! Just after you stopped the container you get a call to say another 277 developer needs the container back. From here you have two choices: you 278 can create a new container or restart the old one. Let's look at 279 starting our previous container back up. 280 281 $ docker start nostalgic_morse 282 nostalgic_morse 283 284 Now quickly run `docker ps -l` again to see the running container is 285 back up or browse to the container's URL to see if the application 286 responds. 287 288 > **Note:** 289 > Also available is the `docker restart` command that runs a stop and 290 > then start on the container. 291 292 ## Removing our web application container 293 294 Your colleague has let you know that they've now finished with the container 295 and won't need it again. So let's remove it using the `docker rm` command. 296 297 $ docker rm nostalgic_morse 298 Error: Impossible to remove a running container, please stop it first or use -f 299 2014/05/24 08:12:56 Error: failed to remove one or more containers 300 301 What happened? We can't actually remove a running container. This protects 302 you from accidentally removing a running container you might need. Let's try 303 this again by stopping the container first. 304 305 $ docker stop nostalgic_morse 306 nostalgic_morse 307 $ docker rm nostalgic_morse 308 nostalgic_morse 309 310 And now our container is stopped and deleted. 311 312 > **Note:** 313 > Always remember that deleting a container is final! 314 315 # Next steps 316 317 Until now we've only used images that we've downloaded from 318 [Docker Hub](https://hub.docker.com) now let's get introduced to 319 building and sharing our own images. 320 321 Go to [Working with Docker Images](/userguide/dockerimages). 322