github.com/fcwu/docker@v1.4.2-0.20150115145920-2a69ca89f0df/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 $ sudo 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 $ sudo 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 $ sudo 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 $ sudo docker attach 75 Help output . . . 76 77 Or you can also pass the `--help` flag to the `docker` binary. 78 79 $ sudo 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 $ sudo 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 $ sudo 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 158 example the `-P` flag is a shortcut for `-p 5000` that maps port 5000 159 inside the container to a high port (from the range 49153 to 65535) on 160 the local Docker host. We can also bind Docker containers to specific 161 ports using the `-p` flag, for example: 162 163 $ sudo docker run -d -p 5000:5000 training/webapp python app.py 164 165 This would map port 5000 inside our container to port 5000 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 your container. 171 Without Docker's port mapping you could only access one at a time. 172 173 So let's now browse to port 49155 in a web browser to 174 see the application. 175 176 . 177 178 Our Python application is live! 179 180 > **Note:** 181 > If you have used the boot2docker virtual machine on OS X, Windows or Linux, 182 > you'll need to get the IP of the virtual host instead of using localhost. 183 > You can do this by running the following in 184 > the boot2docker shell. 185 > 186 > $ boot2docker ip 187 > The VM's Host only interface IP address is: 192.168.59.103 188 > 189 > In this case you'd browse to http://192.168.59.103:49155 for the above example. 190 191 ## A Network Port Shortcut 192 193 Using the `docker ps` command to return the mapped port is a bit clumsy so 194 Docker has a useful shortcut we can use: `docker port`. To use `docker port` we 195 specify the ID or name of our container and then the port for which we need the 196 corresponding public-facing port. 197 198 $ sudo docker port nostalgic_morse 5000 199 0.0.0.0:49155 200 201 In this case we've looked up what port is mapped externally to port 5000 inside 202 the container. 203 204 ## Viewing the Web Application's Logs 205 206 Let's also find out a bit more about what's happening with our application and 207 use another of the commands we've learnt, `docker logs`. 208 209 $ sudo docker logs -f nostalgic_morse 210 * Running on http://0.0.0.0:5000/ 211 10.0.2.2 - - [23/May/2014 20:16:31] "GET / HTTP/1.1" 200 - 212 10.0.2.2 - - [23/May/2014 20:16:31] "GET /favicon.ico HTTP/1.1" 404 - 213 214 This time though we've added a new flag, `-f`. This causes the `docker 215 logs` command to act like the `tail -f` command and watch the 216 container's standard out. We can see here the logs from Flask showing 217 the application running on port 5000 and the access log entries for it. 218 219 ## Looking at our Web Application Container's processes 220 221 In addition to the container's logs we can also examine the processes 222 running inside it using the `docker top` command. 223 224 $ sudo docker top nostalgic_morse 225 PID USER COMMAND 226 854 root python app.py 227 228 Here we can see our `python app.py` command is the only process running inside 229 the container. 230 231 ## Inspecting our Web Application Container 232 233 Lastly, we can take a low-level dive into our Docker container using the 234 `docker inspect` command. It returns a JSON hash of useful configuration 235 and status information about Docker containers. 236 237 $ sudo docker inspect nostalgic_morse 238 239 Let's see a sample of that JSON output. 240 241 [{ 242 "ID": "bc533791f3f500b280a9626688bc79e342e3ea0d528efe3a86a51ecb28ea20", 243 "Created": "2014-05-26T05:52:40.808952951Z", 244 "Path": "python", 245 "Args": [ 246 "app.py" 247 ], 248 "Config": { 249 "Hostname": "bc533791f3f5", 250 "Domainname": "", 251 "User": "", 252 . . . 253 254 We can also narrow down the information we want to return by requesting a 255 specific element, for example to return the container's IP address we would: 256 257 $ sudo docker inspect -f '{{ .NetworkSettings.IPAddress }}' nostalgic_morse 258 172.17.0.5 259 260 ## Stopping our Web Application Container 261 262 Okay we've seen web application working. Now let's stop it using the 263 `docker stop` command and the name of our container: `nostalgic_morse`. 264 265 $ sudo docker stop nostalgic_morse 266 nostalgic_morse 267 268 We can now use the `docker ps` command to check if the container has 269 been stopped. 270 271 $ sudo docker ps -l 272 273 ## Restarting our Web Application Container 274 275 Oops! Just after you stopped the container you get a call to say another 276 developer needs the container back. From here you have two choices: you 277 can create a new container or restart the old one. Let's look at 278 starting our previous container back up. 279 280 $ sudo docker start nostalgic_morse 281 nostalgic_morse 282 283 Now quickly run `docker ps -l` again to see the running container is 284 back up or browse to the container's URL to see if the application 285 responds. 286 287 > **Note:** 288 > Also available is the `docker restart` command that runs a stop and 289 > then start on the container. 290 291 ## Removing our Web Application Container 292 293 Your colleague has let you know that they've now finished with the container 294 and won't need it again. So let's remove it using the `docker rm` command. 295 296 $ sudo docker rm nostalgic_morse 297 Error: Impossible to remove a running container, please stop it first or use -f 298 2014/05/24 08:12:56 Error: failed to remove one or more containers 299 300 What's happened? We can't actually remove a running container. This protects 301 you from accidentally removing a running container you might need. Let's try 302 this again by stopping the container first. 303 304 $ sudo docker stop nostalgic_morse 305 nostalgic_morse 306 $ sudo docker rm nostalgic_morse 307 nostalgic_morse 308 309 And now our container is stopped and deleted. 310 311 > **Note:** 312 > Always remember that deleting a container is final! 313 314 # Next steps 315 316 Until now we've only used images that we've downloaded from 317 [Docker Hub](https://hub.docker.com) now let's get introduced to 318 building and sharing our own images. 319 320 Go to [Working with Docker Images](/userguide/dockerimages). 321