├── README.adoc ├── asciidoc ├── asciidoc-help.adoc └── asciidoc-to-slides.adoc ├── docker_basic_workshop.adoc ├── docker_basic_workshop_handson.adoc └── pyconapp ├── Dockerfile ├── README.adoc ├── app.py ├── docker-compose.yml ├── entrypoint.sh └── requirements.txt /README.adoc: -------------------------------------------------------------------------------- 1 | docker_basic_workshop.adoc -------------------------------------------------------------------------------- /asciidoc/asciidoc-help.adoc: -------------------------------------------------------------------------------- 1 | // vim: set syntax=asciidoc: 2 | [[Team_Collaboration]] 3 | = Team Collaboration 4 | :data-uri: 5 | :icons: 6 | :toc: 7 | :toclevels 4: 8 | :numbered: 9 | 10 | == Asciidoc Setup 11 | 12 | Please refer to the asciidoc user's guide: http://asciidoctor.org/docs/asciidoc-writers-guide/ 13 | 14 | This cheat sheet is also very helpful: http://powerman.name/doc/asciidoc 15 | 16 | === Linux 17 | 18 | . yum install git asciidoc docbook-xsl fop 19 | . Edit /etc/asciidoc/asciidoc.conf and change the following 20 | + 21 | ---- 22 | iconsdir=./images/icons 23 | ---- 24 | + 25 | To: 26 | + 27 | ---- 28 | iconsdir=/etc/asciidoc/images/icons 29 | ---- 30 | 31 | 32 | == Asciidoc Compiling 33 | * To create a single HTML document: 34 | + 35 | ---- 36 | asciidoc 37 | ---- 38 | + 39 | * To create HTML Slides: 40 | + 41 | ---- 42 | asciidoc --backend slidy 43 | ---- 44 | + 45 | * To create a PDF: 46 | + 47 | ---- 48 | a2x -fpdf -dbook --fop --no-xmllint -v 49 | ---- 50 | + 51 | * To create an EPUB: 52 | + 53 | ---- 54 | a2x -fepub -dbook --no-xmllint -v 55 | ---- 56 | 57 | === Hello World 58 | Create a simple asciidoc document: 59 | 60 | .hello_world.adoc 61 | **** 62 | ---- 63 | = My Document Title 64 | :data-uri: 65 | :icons: 66 | :toc2: 67 | :numbered: 68 | 69 | == Chapter 1 70 | some content 71 | 72 | == Chapter 2 73 | some more content 74 | 75 | .Some Table 76 | |==== 77 | ^| Heading1 ^| Heading2 78 | | row1 column1 content | 79 | | | row2 column2 content 80 | |==== 81 | 82 | .Some Figure 83 | image::screenshot.png[Screenshot Text] 84 | 85 | ---- 86 | **** 87 | 88 | Take a screenshot of something and put it in the same directory as this .adoc and name it +screenshot.png+ 89 | 90 | === Automatic Compiling 91 | Use a Makefile to compile the asciidoc into HTML and PDF. 92 | 93 | Makefile 94 | ---- 95 | DOCS=hello_world.adoc 96 | 97 | all: $(DOCS) html pdf epub 98 | 99 | html: $(DOCS) 100 | asciidoc -v hello_world.adoc 101 | 102 | pdf: $(DOCS) 103 | a2x -fpdf -dbook --fop --no-xmllint -v hello_world.adoc 104 | 105 | epub: $(DOCS) 106 | a2x -fepub -dbook --no-xmllint -v hello_world.adoc 107 | 108 | clean: 109 | rm -f *.html *.pdf *.epub 110 | ---- 111 | 112 | 113 | Compile the doc 114 | ---- 115 | make clean && make 116 | ---- 117 | 118 | 119 | -------------------------------------------------------------------------------- /asciidoc/asciidoc-to-slides.adoc: -------------------------------------------------------------------------------- 1 | // vim: set syntax=asciidoc: 2 | [[asciidoc-to-slides]] 3 | = Generating slides from Asciidoc 4 | :data-uri: 5 | :icons: 6 | :toc: 7 | :toclevels 4: 8 | :numbered: 9 | :Author: Lalatendu Mohanty, Suraj Deshmukh 10 | :Email: lmohanty@redhat.com surajd@redhat.com 11 | 12 | == Installation 13 | 14 | [source, bash] 15 | ----------------- 16 | $ sudo dnf -y install rubygem-asciidoctor rubygem-tilt rubygem-haml 17 | ----------------- 18 | 19 | == Download all github code 20 | 21 | [source, bash] 22 | ----------------- 23 | $ git clone https://github.com/asciidoctor/asciidoctor-deck.js 24 | $ git clone git://github.com/imakewebthings/deck.js.git 25 | ----------------- 26 | 27 | == Add doc attributes 28 | 29 | [source, bash] 30 | ----------------- 31 | // vim: set syntax=asciidoc: 32 | [[docker_basic_workshop]] 33 | = Docker Basics 34 | :data-uri: 35 | :icons: 36 | :toc: 37 | :toclevels 4: 38 | :numbered: 39 | :Author: Lalatendu Mohanty, Suraj Deshmukh 40 | :Email: lmohanty@redhat.com sdeshmuk@redhat.com 41 | :revealjs_theme: beige 42 | :revealjs_slideNumber: true 43 | :revealjs_previewLinks: false 44 | :revealjs_transition: linear 45 | :revealjs_transitionSpeed: slow 46 | ----------------- 47 | 48 | More asciidoc attributes: https://github.com/asciidoctor/asciidoctor-reveal.js/#revealjs-options 49 | 50 | == Convert 51 | 52 | [source, bash] 53 | ----------------- 54 | $ asciidoctor -T asciidoctor-reveal.js/templates/slim docker_basic_workshop.adoc 55 | ----------------- 56 | 57 | 58 | == References 59 | 60 | * Deck.js Backend for Asciidoctor http://asciidoctor.org/docs/install-and-use-deckjs-backend/ 61 | * reveal.js backend for Asciidoctor https://github.com/asciidoctor/asciidoctor-reveal.js/ 62 | 63 | -------------------------------------------------------------------------------- /docker_basic_workshop.adoc: -------------------------------------------------------------------------------- 1 | // vim: set syntax=asciidoc: 2 | [[docker_basic_workshop]] 3 | = Docker Basics 4 | :data-uri: 5 | :icons: 6 | :toc: 7 | :toclevels 4: 8 | :numbered: 9 | :Author: Lalatendu Mohanty, Suraj Deshmukh 10 | :Email: lmohanty@redhat.com surajd@redhat.com 11 | :revealjs_theme: beige 12 | :revealjs_slideNumber: true 13 | :revealjs_previewLinks: false 14 | :revealjs_transition: linear 15 | :revealjs_transitionSpeed: slow 16 | 17 | == What are we looking for? 18 | 19 | * Scalability, Maintainability, Agility, Portability. 20 | * Improved resource utilization. 21 | * A continuum of abstraction levels. 22 | 23 | == Linux containers 24 | 25 | * Using Linux kernel process isolation and resource features to give a VM 26 | like environment. 27 | 28 | * docker project is three years old, but linux containers are older than that e.g. LXC. 29 | 30 | * Some examples of linux container runtime: https://linuxcontainers.org/[LXC], https://github.com/google/lmctfy[lmctfy], https://github.com/docker/docker/[docker], https://github.com/coreos/rkt[rkt], etc. 31 | 32 | == Introducing docker 33 | 34 | * Sand boxing of process/Application 35 | 36 | * It is an application packaging and delivery mechanism. 37 | 38 | * Lightweight container virtualization platform. 39 | 40 | == Why Developers Care? 41 | 42 | * Build once -> run anywhere* 43 | * A clean, safe, hygienic and portable runtime environment. 44 | * No worries about missing dependencies, packages, etc. 45 | * Automate testing, integration, packaging -> anything you can script. 46 | * It is portable* -> so it reduces the concern about portability. 47 | 48 | == Why Operations Care? 49 | 50 | * It reduces the time, from developing an application to putting it in to production. 51 | * The entire lifecycle can made more efficient, consistent and repeatable. 52 | * Reduce the inconsistencies between development, test, production and customer environment. 53 | * Because the containers are so light-weight, they significantly address performance, costs, deployment and portability issues. 54 | 55 | == docker vs Virtual Machine 56 | 57 | * Lighter than Virtual machines. 58 | * Less startup time. 59 | * We can run a lot of containers on a reasonably sized host. 60 | * Deploying and scaling is relatively easy. 61 | 62 | == Kernel Features which enables containrization 63 | 64 | * Control Groups 65 | * Namespaces 66 | * Union filesystem 67 | * Kernel Security features 68 | 69 | === Namespace 70 | 71 | * It helps to create isolated workspace for each process. 72 | * When you run a container, docker creates a set of namespaces for that container. 73 | 74 | 75 | === Cgroup 76 | 77 | * Control Groups are another key component of Linux Containers. 78 | * With Cgroup we can implement resource accounting and limiting. 79 | * Ensure that each container gets its fair share of memory, CPU, disk I/O. 80 | * Thanks to Cgroup, we can make sure that single container cannot bring the system down by exhausting resources. 81 | 82 | === Kernel Security features 83 | 84 | * Capabilities 85 | ** By default docker drops all capabilities except those needed. 86 | ** "root" within a container has much less privileges than the real "root". 87 | ** The best practice for users would be to remove all capabilities except those explicitly required for their processes. 88 | ** Even if an intruder manages to escalate to root within a container, it will be much harder to do serious damage, or to escalate to the host 89 | 90 | * Other kernel security features: https://wiki.archlinux.org/index.php/TOMOYO_Linux[TOMOYO], https://wiki.ubuntu.com/AppArmor[AppArmor], https://wiki.centos.org/HowTos/SELinux[SELinux], https://grsecurity.net/[GRSEC], etc. 91 | 92 | === SELinux 93 | 94 | * https://wiki.centos.org/HowTos/SELinux[SELinux] provides secure separation of containers by applying SELinux policy and labels. 95 | 96 | == docker Components 97 | 98 | * *Image* : It is a template which is used to launch containers. 99 | 100 | * *Container* : Container holds everything that is needed for an application to run. 101 | 102 | * *Registry* : It stores and serves up the actual image assets, and it delegates authentication to the index. 103 | 104 | * *Index* : It is the front end of Registry. It manages user accounts, permissions, search, tagging, and all that nice stuff that’s in the public web interface 105 | 106 | == Prerequisite for the workshop 107 | 108 | * You should be able to run docker command line on your workstation or in a VM or a machine running in public clouds. 109 | 110 | * We will recommend you to run a GNU/Linux distribution of your choice on your laptop or atleast a virtual machine. Then you should install docker on it. 111 | 112 | ** Most of the Linux distributions e.g. Fedora provides you the docker package from the distribution it self. 113 | 114 | ** Refer the below section for commands to install it on Fedora. 115 | 116 | * Before coming for the workshop, pull docker image of Fedora as conferences are not a good place to download stuff from internet. 117 | 118 | --------------------- 119 | $ docker pull fedora 120 | --------------------- 121 | 122 | == Next 123 | 124 | *Go to* : https://github.com/container-workbook/docker-workshop/blob/master/docker_basic_workshop_handson.adoc[Workshop hands-on guide] 125 | 126 | == References 127 | 128 | * http://www.slideshare.net/dotCloud/docker-intro-november 129 | * http://www.slideshare.net/jamtur01/introduction-to-docker-30285720 130 | * http://neependra.net/docker/rootconfWorkshop.html 131 | * https://www.packtpub.com/virtualization-and-cloud/docker-cookbook 132 | * https://github.com/LalatenduMohanty/container-workbook 133 | -------------------------------------------------------------------------------- /docker_basic_workshop_handson.adoc: -------------------------------------------------------------------------------- 1 | // vim: set syntax=asciidoc: 2 | [[docker_basic_workshop_handson]] 3 | = Docker Basics 4 | :data-uri: 5 | :icons: 6 | :toc: 7 | :toclevels 4: 8 | :numbered: 9 | :Author: Lalatendu Mohanty, Suraj Deshmukh 10 | :Email: lmohanty@redhat.com surajd@redhat.com 11 | 12 | === Installing docker 13 | 14 | * There are multiple ways to install docker based on your platform, please read the docs https://docs.docker.com/engine/installation/ 15 | * You can also get a VM on cloud provider like Amazon or Digital Ocean to make things easier for you. 16 | 17 | 18 | Fedora 19 | ^^^^^^ 20 | 21 | [source, bash] 22 | ----------------- 23 | $ sudo dnf -y install docker 24 | $ sudo systemctl start docker 25 | $ sudo systemctl enable docker 26 | ----------------- 27 | 28 | For other Linux distributions or Windows , OS X, refer: https://www.docker.com/products/overview 29 | 30 | == Installing docker-compose 31 | 32 | * We will also look at how to dockerize an existing application and use docker-compose to bring multi-container application. To install docker-compose follow docs here: https://docs.docker.com/compose/install/ 33 | 34 | 35 | == Check your docker installation 36 | 37 | ---------- 38 | $ docker info 39 | Containers: 0 40 | Running: 0 41 | Paused: 0 42 | Stopped: 0 43 | Images: 2 44 | Server Version: 1.10.3 45 | Storage Driver: devicemapper 46 | Pool Name: docker-252:1-1574682-pool 47 | Pool Blocksize: 65.54 kB 48 | Base Device Size: 10.74 GB 49 | Backing Filesystem: xfs 50 | Data file: /dev/loop0 51 | Metadata file: /dev/loop1 52 | Data Space Used: 268.4 MB 53 | Data Space Total: 107.4 GB 54 | Data Space Available: 40.71 GB 55 | Metadata Space Used: 704.5 kB 56 | Metadata Space Total: 2.147 GB 57 | Metadata Space Available: 2.147 GB 58 | Udev Sync Supported: true 59 | Deferred Removal Enabled: false 60 | Deferred Deletion Enabled: false 61 | Deferred Deleted Device Count: 0 62 | Data loop file: /var/lib/docker/devicemapper/devicemapper/data 63 | WARNING: Usage of loopback devices is strongly discouraged for production use. Either use `--storage-opt dm.thinpooldev` or use `--storage-opt dm.no_warn_on_loop_devices=true` to suppress this warning. 64 | Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata 65 | Library Version: 1.02.122 (2016-04-09) 66 | Execution Driver: native-0.2 67 | Logging Driver: journald 68 | Plugins: 69 | Volume: local 70 | Network: host bridge null 71 | Kernel Version: 4.7.3-200.fc24.x86_64 72 | Operating System: Fedora 24 (Cloud Edition) 73 | OSType: linux 74 | Architecture: x86_64 75 | Number of Docker Hooks: 2 76 | CPUs: 4 77 | Total Memory: 3.859 GiB 78 | Name: fedora 79 | ID: Y4OB:3DAQ:MMLV:M7RP:7UFB:KE2U:XAR3:KQIN:MDAY:TEDW:CVR6:WOGW 80 | WARNING: bridge-nf-call-iptables is disabled 81 | WARNING: bridge-nf-call-ip6tables is disabled 82 | Registries: docker.io (secure) 83 | ---------- 84 | 85 | == docker Basic operations 86 | 87 | === Search in public docker index 88 | ---------- 89 | $ docker search fedora 90 | INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED 91 | docker.io docker.io/fedora Official Docker builds of Fedora 429 [OK] 92 | docker.io docker.io/fedora/apache 33 [OK] 93 | docker.io docker.io/dockingbay/fedora-rust Trusted build of Rust programming language... 3 [OK] 94 | docker.io docker.io/gluster/gluster-fedora Official GlusterFS image [ Fedora 21 + Glu... 3 [OK] 95 | docker.io docker.io/startx/fedora Simple container used for all startx based... 2 [OK] 96 | docker.io docker.io/dasrick/fedora-nginx NGINX image - port 80, 443 - based on Fedo... 1 [OK] 97 | docker.io docker.io/fedora/tools Docker image that has systems administrati... 1 [OK] 98 | docker.io docker.io/mattsch/fedora-rpmfusion Base container for Fedora with RPM Fusion ... 1 [OK] 99 | docker.io docker.io/neroinc/fedora-apache Plain and simple image with Apache httpd b... 1 [OK] 100 | docker.io docker.io/pacur/fedora-22 Pacur Fedora 22 1 [OK] 101 | ---------- 102 | 103 | === Pull an image 104 | ---------- 105 | $ docker pull fedora:24 106 | Trying to pull repository docker.io/library/fedora ... 107 | 24: Pulling from docker.io/library/fedora 108 | Digest: sha256:64a02df6aac27d1200c2572fe4b9949f1970d05f74d367ce4af994ba5dc3669e 109 | Status: Downloaded newer image for docker.io/fedora:24 110 | 111 | $ docker pull alpine 112 | Using default tag: latest 113 | Trying to pull repository docker.io/library/alpine ... 114 | latest: Pulling from docker.io/library/alpine 115 | 117f30b7ae3d: Pull complete 116 | Digest: sha256:02eb5cfe4b721495135728ab4aea87418fd4edbfbf83612130a81191f0b2aae3 117 | Status: Downloaded newer image for docker.io/alpine:latest 118 | ---------- 119 | 120 | Try pulling a tagged image i.e. `docker pull fedora:24` 121 | 122 | === Listing images 123 | ---------- 124 | $ docker images 125 | REPOSITORY TAG IMAGE ID CREATED SIZE 126 | docker.io/centos latest 980e0e4c79ec 2 weeks ago 196.7 MB 127 | docker.io/fedora 24 11a5107645d4 5 weeks ago 204.4 MB 128 | docker.io/fedora latest 11a5107645d4 5 weeks ago 204.4 MB 129 | ---------- 130 | 131 | === Start a container from an image 132 | ---------- 133 | $ docker run -it fedora bash 134 | [root@1b65159da55c /]# cat /etc/fedora-release 135 | Fedora release 24 (Twenty Four) 136 | ---------- 137 | 138 | === Listing the containers 139 | 140 | Open another terrminal and run below command while running the container as mentioned in the previous state. 141 | 142 | ---------- 143 | $ docker ps 144 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 145 | 1b65159da55c fedora "bash" 35 seconds ago Up 33 seconds silly_morse 146 | 147 | ---------- 148 | *To list all containers (both running and stopped)* 149 | ---------- 150 | $ docker ps -a 151 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 152 | 23e00a59a9b4 fedora "ls" 6 seconds ago Exited (0) 4 seconds ago adoring_knuth 153 | 1b65159da55c fedora "bash" About a minute ago Exited (0) 12 seconds ago silly_morse 154 | 155 | ---------- 156 | 157 | === Saving a container state 158 | * Start a container 159 | * Modify a file 160 | ---------- 161 | ]$ docker run -i -t fedora /bin/bash 162 | [root@f369268c54cd /]# echo "docker 101" > /etc/motd 163 | 164 | ---------- 165 | 166 | * On a different terminal, save the container as an image 167 | ---------- 168 | $ docker ps 169 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 170 | f369268c54cd fedora "/bin/bash" 37 seconds ago Up 35 seconds amazing_turing 171 | 172 | $ docker commit -a "Lalatendu Mohanty" -m "PyCon 2016" f369268c54cd pycon:motd 173 | sha256:ce9d49c4ff59b756621dd18479a80fbb16eb25595949bc7ad0c1f22430c21397 174 | 175 | $ docker images 176 | REPOSITORY TAG IMAGE ID CREATED SIZE 177 | pycon motd ce9d49c4ff59 16 seconds ago 204.4 MB 178 | docker.io/centos latest 980e0e4c79ec 2 weeks ago 196.7 MB 179 | docker.io/fedora 24 11a5107645d4 5 weeks ago 204.4 MB 180 | docker.io/fedora latest 11a5107645d4 5 weeks ago 204.4 MB 181 | ---------- 182 | 183 | === Looking in to docker metatdata 184 | 185 | ---------- 186 | $ sudo cat /var/lib/docker/image/devicemapper/repositories.json | python -mjson.tool 187 | { 188 | "Repositories": { 189 | "docker.io/centos": { 190 | "docker.io/centos:latest": "sha256:980e0e4c79ec933406e467a296ce3b86685e6b42eed2f873745e6a91d718e37a", 191 | "docker.io/centos@sha256:2ae0d2c881c7123870114fb9cc7afabd1e31f9888dac8286884f6cf59373ed9b": "sha256:980e0e4c79ec933406e467a296ce3b86685e6b42eed2f873745e6a91d718e37a" 192 | }, 193 | "docker.io/fedora": { 194 | "docker.io/fedora:24": "sha256:11a5107645d4ecb36e75d933576f5cdb52358bef385eac2c2d2a91af44ad4ad7", 195 | "docker.io/fedora:latest": "sha256:11a5107645d4ecb36e75d933576f5cdb52358bef385eac2c2d2a91af44ad4ad7", 196 | "docker.io/fedora@sha256:64a02df6aac27d1200c2572fe4b9949f1970d05f74d367ce4af994ba5dc3669e": "sha256:11a5107645d4ecb36e75d933576f5cdb52358bef385eac2c2d2a91af44ad4ad7" 197 | }, 198 | "pycon": { 199 | "pycon:motd": "sha256:ce9d49c4ff59b756621dd18479a80fbb16eb25595949bc7ad0c1f22430c21397" 200 | } 201 | } 202 | } 203 | ---------- 204 | 205 | === Attaching to a container 206 | 207 | ---------- 208 | $ ID=$(sudo docker run -d fedora /bin/sh -c "while true; do echo PyCon 2016 ; sleep 1; done") 209 | $ docker attach $ID 210 | PyCon 2016 211 | PyCon 2016 212 | [SNIP] 213 | ---------- 214 | 215 | === Stop/Start/Restart a conatiner 216 | 217 | ---------- 218 | $ docker stop $ID 219 | $ docker start $ID 220 | $ docker restart $ID 221 | ---------- 222 | 223 | === Looking at the logs of container 224 | 225 | ---------- 226 | $ docker logs $ID 227 | ---------- 228 | 229 | === Killing a container 230 | 231 | ---------- 232 | $ docker stop $ID 233 | $ docker rm $ID 234 | ---------- 235 | 236 | === Delete all stopped containers 237 | 238 | ---------- 239 | $ docker rm $(docker ps -aq) 240 | ---------- 241 | 242 | === Privileged access inside container 243 | 244 | ---------- 245 | $ docker run -t -i fedora /bin/bash 246 | [root@50559bf9ab0a /]# mount -t tmpfs none /mnt 247 | mount: permission denied 248 | [root@50559bf9ab0a /]# exit 249 | ---------- 250 | 251 | To get privilaged access, please run below command 252 | 253 | ---------- 254 | $ docker run --privileged -t -i fedora /bin/bash 255 | ---------- 256 | 257 | === Return low level information about container 258 | 259 | ---------- 260 | $ docker inspect $ID 261 | $ docker inspect --format='{{.NetworkSettings.IPAddress}}' $ID 262 | ---------- 263 | 264 | === Check how much resources are used by the container 265 | 266 | ------------ 267 | $ docker stats 268 | ------------ 269 | 270 | === Controlling resources used by a container 271 | 272 | ------------ 273 | $ docker update -m 512MB 274 | 275 | P:S: You can get the container ID from "docker ps" command output 276 | ------------ 277 | 278 | * You can specify resources while running the container too. Check the docker run command usage. 279 | 280 | ------------ 281 | $ docker run --help 282 | ------------ 283 | 284 | 285 | === Copy files/folders from a PATH on the container to a HOSTDIR on the host 286 | 287 | ---------- 288 | $ docker cp $ID:/etc/motd /tmp/ 289 | ---------- 290 | 291 | === Run a command inside a directory while starting a container 292 | 293 | ---------- 294 | $ docker run -t -i -w /etc fedora ls 295 | ---------- 296 | Note : if the path does not exist, it will get created 297 | 298 | === List the changed files and directories in a container’s filesystem 299 | 300 | --------------- 301 | docker diff $ID 302 | --------------- 303 | 304 | * A Add 305 | * D Delete 306 | * C Change 307 | 308 | === History of the image 309 | 310 | --------------- 311 | $ docker history 312 | --------------- 313 | 314 | === Networking 315 | 316 | *Bind a port to host interface* 317 | 318 | * Bind TCP port 8080 of the container to TCP port 80 on 127.0.0.1 of the host machine. 319 | --------------- 320 | $ docker run -d -i -t -p 127.0.0.1:8080:80 fedora bash 321 | --------------- 322 | 323 | * Bind TCP port 8080 of the container to a dynamically allocated TCP port on 127.0.0.1 of the host machine. 324 | --------------- 325 | $ docker run -d -i -t -p 127.0.0.1::8080 fedora bash 326 | --------------- 327 | 328 | * Bind TCP port 8080 of the container to TCP port 80 on all available interfaces of the host machine. 329 | ---------------- 330 | docker run -d -i -t -p 80:8080 fedora bash 331 | ---------------- 332 | 333 | * Bind TCP port 8080 of the container to a dynamically allocated TCP port on all available interfaces of the host machine. 334 | --------------- 335 | docker run -d -i -t -p 8080 fedora bash 336 | --------------- 337 | 338 | === Exposing a port while starting a container 339 | 340 | --------------- 341 | $ ID=$(docker run --expose=22 -d -i -t pycon:sshd /bin/bash) 342 | --------------- 343 | 344 | *For further study, refer: https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/* 345 | 346 | 347 | === Docker volumes 348 | 349 | * Any uncommitted data or changes in containers get lost as soon as containers are deleted 350 | 351 | ==== Data volumes 352 | 353 | * Data volumes persist even if the container itself is deleted. 354 | 355 | -------------- 356 | $ docker run -i -t --name demo -v /data docker.io/fedora /bin/bash 357 | 358 | Run below command in another terminal 359 | 360 | $ docker inspect 361 | -------------- 362 | 363 | ==== Mount a host directory as a data volume 364 | 365 | --------------- 366 | $ docker run -i -t -v /var/logs:/logs_from_host:ro fedora bash 367 | $ ls logs_from_host/ 368 | --------------- 369 | 370 | * Further study: https://docs.docker.com/engine/tutorials/dockervolumes/* 371 | 372 | === Remove docker image 373 | 374 | --------------- 375 | docker rmi 376 | --------------- 377 | 378 | Remove all images 379 | 380 | --------------- 381 | docker rmi $(docker images -q) 382 | --------------- 383 | 384 | == Dockerfiles 385 | 386 | === Building an image 387 | 388 | ---------- 389 | $ mkdir /tmp/pycon; cd /tmp/pycon 390 | $ echo "FROM fedora" >> Dockerfile 391 | $ echo "MAINTAINER Lalatendu" >> Dockerfile 392 | $ docker build -t pycon/fedora . 393 | $ docker images 394 | REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE 395 | pycon/fedora latest 8ab29ba8abf2 5 seconds ago 204.4 MB 396 | pycon motd f6b39867b3e9 18 minutes ago 204.4 MB 397 | docker.io/fedora 23 5a813a9e051e 31 hours ago 214.4 MB 398 | ---------- 399 | 400 | === DockerFile Instructions 401 | 402 | * FROM | : 403 | 404 | Set the base image 405 | 406 | * MAINTAINER 407 | 408 | Set the author 409 | 410 | * RUN | ["executable", "param1", "param2"] 411 | 412 | Executes any commands in a new layer on top of the current image and commit the results 413 | 414 | * CMD ["executable","param1","param2"] | ["param1","param2"] | command param1 param2 415 | 416 | Provides defaults for an executing container 417 | 418 | * EXPOSE [ …] 419 | 420 | Open up specified network ports at runtime 421 | 422 | * ENV 423 | 424 | This sets the environment variable to the value 425 | 426 | * ADD 427 | 428 | Copy new files from source and add them to the container's filesystem at path 429 | 430 | * ENTYRPOINT ["executable", "param1", "param2"] | command param1 param2 431 | 432 | Helps to configure a container that you can run as an executable. 433 | 434 | * VOLUME ["/data"] 435 | 436 | Creates a mount point with the specified name and mark it as holding externally mounted volumes from native host or other containers. 437 | 438 | * USER 439 | 440 | Sets the username or UID to use when running the image. 441 | 442 | * WORKDIR 443 | 444 | Sets the working directory 445 | 446 | * ONBUILD [INSTRUCTION] 447 | 448 | Adds to the image a "trigger" instruction to be executed at a later time, when the image is used as the base for another build. 449 | 450 | 451 | == Next 452 | 453 | *Go to* : https://github.com/container-workbook/docker-workshop/blob/master/pyconapp/README.adoc[Containerizing Python Flask application] 454 | 455 | == References 456 | 457 | * http://www.slideshare.net/dotCloud/docker-intro-november 458 | * http://www.slideshare.net/jamtur01/introduction-to-docker-30285720 459 | * http://neependra.net/docker/rootconfWorkshop.html 460 | * https://www.packtpub.com/virtualization-and-cloud/docker-cookbook 461 | * https://github.com/LalatenduMohanty/container-workbook 462 | -------------------------------------------------------------------------------- /pyconapp/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM fedora:24 2 | 3 | RUN dnf update -y && \ 4 | dnf install -y python-pip python-devel 5 | 6 | ADD https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh /usr/local/bin/wait-for-it.sh 7 | 8 | RUN chmod +x /usr/local/bin/wait-for-it.sh && mkdir -p /app 9 | 10 | WORKDIR /app 11 | COPY . /app 12 | 13 | RUN pip install -r requirements.txt 14 | 15 | EXPOSE 5000 16 | 17 | ENTRYPOINT /app/entrypoint.sh 18 | -------------------------------------------------------------------------------- /pyconapp/README.adoc: -------------------------------------------------------------------------------- 1 | // vim: set syntax=asciidoc: 2 | [[README]] 3 | = Walkthrough containerizing application 4 | :data-uri: 5 | :icons: 6 | :toc: 7 | :toclevels 4: 8 | :numbered: 9 | :Author: Lalatendu Mohanty, Suraj Deshmukh 10 | :Email: lmohanty@redhat.com surajd@redhat.com 11 | 12 | == Running the app in traditional way 13 | 14 | === Start redis server 15 | 16 | * Install redis 17 | 18 | [source, bash] 19 | ----------------- 20 | $ sudo dnf -y install git redis python2-virtualenv python-pip python-devel 21 | ----------------- 22 | 23 | * Start redis server 24 | 25 | [source, bash] 26 | ----------------- 27 | $ sudo systemctl start redis 28 | ----------------- 29 | 30 | 31 | === Start flask server 32 | 33 | * Clone this repository 34 | 35 | [source, bash] 36 | ----------------- 37 | $ git clone https://github.com/container-workbook/docker-workshop/ 38 | $ cd docker-workshop/pyconapp/ 39 | ----------------- 40 | 41 | 42 | * Create a python virtualenv 43 | 44 | [source, bash] 45 | ----------------- 46 | $ virtualenv venv 47 | $ . venv/bin/activate 48 | (venv) $ 49 | ----------------- 50 | 51 | * Install all the requirements 52 | 53 | [source, bash] 54 | ----------------- 55 | (venv) $ pip install -r requirements.txt 56 | ----------------- 57 | 58 | * Start flask app 59 | 60 | [source, bash] 61 | ----------------- 62 | (venv) $ export REDIS_HOST=127.0.0.1 63 | (venv) $ python app.py 64 | ----------------- 65 | 66 | === Check if app is running 67 | 68 | [source, bash] 69 | ----------------- 70 | $ curl 127.0.0.1:5000 71 |

Hello Pythonistas


Number of Hits: 1
72 | ----------------- 73 | 74 | 75 | == Running app in container 76 | 77 | 78 | === Containerize flask app 79 | 80 | * Create `Dockerfile` that looks like this: 81 | 82 | [source, bash] 83 | ----------------- 84 | $ cat Dockerfile 85 | FROM fedora:24 86 | 87 | RUN dnf update -y && \ 88 | dnf install -y python-pip python-devel 89 | 90 | ADD https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh /usr/local/bin/wait-for-it.sh 91 | 92 | RUN chmod +x /usr/local/bin/wait-for-it.sh && mkdir -p /app 93 | 94 | WORKDIR /app 95 | COPY . /app 96 | 97 | RUN pip install -r requirements.txt 98 | 99 | EXPOSE 5000 100 | 101 | ENTRYPOINT /app/entrypoint.sh 102 | ----------------- 103 | 104 | * Create an `entrypoint.sh` file which looks like this: 105 | 106 | [source, bash] 107 | ----------------- 108 | $ cat entrypoint.sh 109 | #!/bin/bash 110 | 111 | /usr/local/bin/wait-for-it.sh REDIS_HOST:6379 112 | 113 | cd /app 114 | python app.py 115 | ----------------- 116 | 117 | * Add permissions to `entrypoint.sh` 118 | 119 | [source, bash] 120 | ----------------- 121 | $ chmod +x entrypoint.sh 122 | ----------------- 123 | 124 | === Multi-container app definition 125 | 126 | * Create a `docker-compose.yml` file that defines multi-container application 127 | 128 | [source, bash] 129 | ----------------- 130 | $ cat docker-compose.yml 131 | version: '2' 132 | 133 | services: 134 | redis: 135 | image: redis:latest 136 | ports: 137 | - "6379" 138 | 139 | app: 140 | build: . 141 | ports: 142 | - "5000" 143 | environment: 144 | - REDIS_HOST=redis 145 | ----------------- 146 | 147 | === Bring up the application 148 | 149 | 150 | [source, bash] 151 | ----------------- 152 | $ docker-compose up 153 | ----------------- 154 | 155 | === Check if the app is running 156 | 157 | * Find out the port flask app is exposed on: 158 | 159 | [source, bash] 160 | ----------------- 161 | $ docker ps | grep pyconapp_app 162 | ----------------- 163 | 164 | * `curl` on it: 165 | 166 | [source, bash] 167 | ----------------- 168 | $ curl 127.0.0.1:32774 169 |

Hello Pythonistas


Number of Hits: 1
170 | ----------------- 171 | 172 | So that's how you can migrate an app that is monolithic and containerize it. 173 | -------------------------------------------------------------------------------- /pyconapp/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from redis import Redis 3 | import os 4 | 5 | app = Flask(__name__) 6 | redis = Redis(host=os.environ.get('REDIS_HOST', 'redis'), port=6379) 7 | 8 | @app.route('/') 9 | def hello(): 10 | visits = redis.incr('hits') 11 | 12 | html = "

Hello Pythonistas


" \ 13 | "

Number of Hits: {hits}
" 14 | 15 | return html.format(hits=visits) 16 | 17 | if __name__ == "__main__": 18 | app.run(host="0.0.0.0", port=5000, debug=True) 19 | -------------------------------------------------------------------------------- /pyconapp/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | redis: 5 | image: redis:latest 6 | ports: 7 | - "6379" 8 | 9 | app: 10 | build: . 11 | ports: 12 | - "5000" 13 | environment: 14 | - REDIS_HOST=redis 15 | -------------------------------------------------------------------------------- /pyconapp/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | /usr/local/bin/wait-for-it.sh REDIS_HOST:6379 4 | 5 | cd /app 6 | python app.py 7 | -------------------------------------------------------------------------------- /pyconapp/requirements.txt: -------------------------------------------------------------------------------- 1 | flask 2 | redis --------------------------------------------------------------------------------