github.com/portworx/docker@v1.12.1/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 --help Print usage 77 --no-stdin Do not attach stdin 78 --sig-proxy=true Proxy all received signals to the process 79 80 > **Note:** 81 > For further details and examples of each command, see the 82 > [command reference](../reference/commandline/cli.md) in this guide. 83 84 ## Running a web application in Docker 85 86 So now you've learned a bit more about the `docker` client you can move onto 87 the important stuff: running more containers. So far none of the 88 containers you've run did anything particularly useful, so you can 89 change that by running an example web application in Docker. 90 91 For our web application we're going to run a Python Flask application. 92 Start with a `docker run` command. 93 94 $ docker run -d -P training/webapp python app.py 95 96 Review what the command did. You've specified two flags: `-d` and 97 `-P`. You've already seen the `-d` flag which tells Docker to run the 98 container in the background. The `-P` flag is new and tells Docker to 99 map any required network ports inside our container to our host. This 100 lets us view our web application. 101 102 You've specified an image: `training/webapp`. This image is a 103 pre-built image you've created that contains a simple Python Flask web 104 application. 105 106 Lastly, you've specified a command for our container to run: `python app.py`. This launches our web application. 107 108 > **Note:** 109 > You can see more detail on the `docker run` command in the [command 110 > reference](../reference/commandline/run.md) and the [Docker Run 111 > Reference](../reference/run.md). 112 113 ## Viewing our web application container 114 115 Now you can see your running container using the `docker ps` command. 116 117 $ docker ps -l 118 119 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 120 bc533791f3f5 training/webapp:latest python app.py 5 seconds ago Up 2 seconds 0.0.0.0:49155->5000/tcp nostalgic_morse 121 122 You can see you've specified a new flag, `-l`, for the `docker ps` 123 command. This tells the `docker ps` command to return the details of the 124 *last* container started. 125 126 > **Note:** 127 > By default, the `docker ps` command only shows information about running 128 > containers. If you want to see stopped containers too use the `-a` flag. 129 130 We can see the same details we saw [when we first Dockerized a 131 container](dockerizing.md) with one important addition in the `PORTS` 132 column. 133 134 PORTS 135 0.0.0.0:49155->5000/tcp 136 137 When we passed the `-P` flag to the `docker run` command Docker mapped any 138 ports exposed in our image to our host. 139 140 > **Note:** 141 > We'll learn more about how to expose ports in Docker images when 142 > [we learn how to build images](dockerimages.md). 143 144 In this case Docker has exposed port 5000 (the default Python Flask 145 port) on port 49155. 146 147 Network port bindings are very configurable in Docker. In our last example the 148 `-P` flag is a shortcut for `-p 5000` that maps port 5000 inside the container 149 to a high port (from *ephemeral port range* which typically ranges from 32768 150 to 61000) on the local Docker host. We can also bind Docker containers to 151 specific ports using the `-p` flag, for example: 152 153 $ docker run -d -p 80:5000 training/webapp python app.py 154 155 This would map port 5000 inside our container to port 80 on our local 156 host. You might be asking about now: why wouldn't we just want to always 157 use 1:1 port mappings in Docker containers rather than mapping to high 158 ports? Well 1:1 mappings have the constraint of only being able to map 159 one of each port on your local host. 160 161 Suppose you want to test two Python applications: both bound to port 5000 inside 162 their own containers. Without Docker's port mapping you could only access one at 163 a time on the Docker host. 164 165 So you can now browse to port 49155 in a web browser to 166 see the application. 167 168 ![Viewing the web application](webapp1.png). 169 170 Our Python application is live! 171 172 > **Note:** 173 > If you have been using a virtual machine on OS X, Windows or Linux, 174 > you'll need to get the IP of the virtual host instead of using localhost. 175 > You can do this by running the `docker-machine ip your_vm_name` from your command line or terminal application, for example: 176 > 177 > $ docker-machine ip my-docker-vm 178 > 192.168.99.100 179 > 180 > In this case you'd browse to `http://192.168.99.100:49155` for the above example. 181 182 ## A network port shortcut 183 184 Using the `docker ps` command to return the mapped port is a bit clumsy so 185 Docker has a useful shortcut we can use: `docker port`. To use `docker port` we 186 specify the ID or name of our container and then the port for which we need the 187 corresponding public-facing port. 188 189 $ docker port nostalgic_morse 5000 190 191 0.0.0.0:49155 192 193 In this case you've looked up what port is mapped externally to port 5000 inside 194 the container. 195 196 ## Viewing the web application's logs 197 198 You can also find out a bit more about what's happening with our application and 199 use another of the commands you've learned, `docker logs`. 200 201 $ docker logs -f nostalgic_morse 202 203 * Running on http://0.0.0.0:5000/ 204 10.0.2.2 - - [23/May/2014 20:16:31] "GET / HTTP/1.1" 200 - 205 10.0.2.2 - - [23/May/2014 20:16:31] "GET /favicon.ico HTTP/1.1" 404 - 206 207 This time though you've added a new flag, `-f`. This causes the `docker 208 logs` command to act like the `tail -f` command and watch the 209 container's standard out. We can see here the logs from Flask showing 210 the application running on port 5000 and the access log entries for it. 211 212 ## Looking at our web application container's processes 213 214 In addition to the container's logs we can also examine the processes 215 running inside it using the `docker top` command. 216 217 $ docker top nostalgic_morse 218 219 PID USER COMMAND 220 854 root python app.py 221 222 Here we can see our `python app.py` command is the only process running inside 223 the container. 224 225 ## Inspecting our web application container 226 227 Lastly, we can take a low-level dive into our Docker container using the 228 `docker inspect` command. It returns a JSON document containing useful 229 configuration and status information for the specified container. 230 231 $ docker inspect nostalgic_morse 232 233 You can see a sample of that JSON output. 234 235 [{ 236 "ID": "bc533791f3f500b280a9626688bc79e342e3ea0d528efe3a86a51ecb28ea20", 237 "Created": "2014-05-26T05:52:40.808952951Z", 238 "Path": "python", 239 "Args": [ 240 "app.py" 241 ], 242 "Config": { 243 "Hostname": "bc533791f3f5", 244 "Domainname": "", 245 "User": "", 246 . . . 247 248 We can also narrow down the information we want to return by requesting a 249 specific element, for example to return the container's IP address we would: 250 251 $ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nostalgic_morse 252 253 172.17.0.5 254 255 ## Stopping our web application container 256 257 Okay you've seen web application working. Now you can stop it using the 258 `docker stop` command and the name of our container: `nostalgic_morse`. 259 260 $ docker stop nostalgic_morse 261 262 nostalgic_morse 263 264 We can now use the `docker ps` command to check if the container has 265 been stopped. 266 267 $ docker ps -l 268 269 ## Restarting our web application container 270 271 Oops! Just after you stopped the container you get a call to say another 272 developer needs the container back. From here you have two choices: you 273 can create a new container or restart the old one. Look at 274 starting your previous container back up. 275 276 $ docker start nostalgic_morse 277 278 nostalgic_morse 279 280 Now quickly run `docker ps -l` again to see the running container is 281 back up or browse to the container's URL to see if the application 282 responds. 283 284 > **Note:** 285 > Also available is the `docker restart` command that runs a stop and 286 > then start on the container. 287 288 ## Removing our web application container 289 290 Your colleague has let you know that they've now finished with the container 291 and won't need it again. Now, you can remove it using the `docker rm` command. 292 293 $ docker rm nostalgic_morse 294 295 Error: Impossible to remove a running container, please stop it first or use -f 296 2014/05/24 08:12:56 Error: failed to remove one or more containers 297 298 What happened? We can't actually remove a running container. This protects 299 you from accidentally removing a running container you might need. You can try 300 this again by stopping the container first. 301 302 $ docker stop nostalgic_morse 303 304 nostalgic_morse 305 306 $ docker rm nostalgic_morse 307 308 nostalgic_morse 309 310 And now our container is stopped and deleted. 311 312 > **Note:** 313 > Always remember that removing a container is final! 314 315 # Next steps 316 317 Until now you've only used images that you've downloaded from Docker Hub. Next, 318 you can get introduced to building and sharing our own images. 319 320 Go to [Working with Docker Images](dockerimages.md).