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