JavaOne – Docker 101 Workshop

“Docker 101 Workshop”

Speaker: Eric Smalling

For more blog posts from JavaOne, see the table of contents


Used docker in the cloud on play-with-docker.com. The one used in class won’t be available after JavaOne, but they also have a training site that looks open.

VM vs Container

  • Not a VM – creates a binary artifact, underlying architecture is different
  • A VM is like a house – protection from outsiders (door/lock), own infrastructure (plumbing, foundation), minimum features (bedroom, bathroom). If want new VM, duplicate resources because like getting a new house.
  • Containers like Docker are like an apartment. They have protection (doorman), shared infrastructure (plumbing), come in different sizes within same building (studio, 1 bedroom, penthouse), can be very small (studio), isolate apps from each other (apartment door lock)
  • Containers come with base image, standardized packaging.
  • All containers share same OS Kernel; available for all major Linux distributions, Windows 2016 server and IBM mainframes

Docker

  • Build – dev env, Ship – create and store images, run – deploy/manage/scale
  • Can develop on exactly same container. No differences between Dev/QA/Prod
  • Immutable deployed artifact
  • Store artifacts in registry – repo for Docker images
  • Docker offers a trusted registry for Enterprise customers.

Terms

  • Docker Trusted Registry – store and distribute images
  • Docker Universal Control Plane – Web based management CaaS (containers as a service) – Swarm connects multiple Docker instances. Adds security/access control. Integrates with LDAP.
  • Docker Image – contains everything needed to run
  • Docker Container – standard unit in which app services resides
  • Docker Engine – Creates/ships/runs Docker containers
  • Service – an app or part of an app that provides a specific function
  • Stack – Represents multi-service applications. Made up of one or more services

Basic commands

These are the verbose commands for clarity

  • docker image pull account/dockerName:latest – pull latest dockerName from account – gets from docker web by default
  • docker image ls – list what pulled/built
  • docker container run -d -p portX:portY –name dockerName account/dockerName:latest – run detached (-d) run on port x and send to port y
  • docker container ps – the container running
  • docker container stop dockerName (or container id) – stop from running
  • docker container rm dockerName (or container id) – so don’t pile up
  • docker image rm account/dockerName:latest (or image id) – remove from local system to save space in cache
  • docker build -t account/dockerName:version . – build an image from your machine and tag
  • docker image push account/dockerName:version – push to docker hub

Dockerfile

  • Instructions on how to build a docker image
  • Looks similar to “native” commands
  • Important to optimize
  • Common for run commands to span lines. Can use \ to continue on new line for readability and ; to run multiple commands together
  • Each line in dockerfile adds a new layer. By combining run commands you minimize layers. This makes the image smaller and cleaner.
  • Commands
    • First line is “FROM dockerName:version” – this is the starting point for your image. Like a parent
    • RUN … – run a shell command in image building
    • COPY x y – copy from your machine (or where running the docker file) to VM location
    • EXPOSE port – tell container to expose port
    • CMD [a, b] – run the application

Lab 1

In GitHub, did task 1 together and then task 2 on our own.

Interesting facts

  • Using alpine Linux as base because small
  • If image doesn’t have account name (ex alpine vs joe:alpine), means it is a trusted/official image. Ex: mySql, Jenkins.
  • The Docker store has certified images which is a higher level of validation. Certified means supported/commercial.
  • Important to do all setup in Dockerfile so can recreate image on demand
  • Great learning moment about the dangers of using “latest” – need to use mysql 5.5 instead of latest because “latest” has a bug where mysql doesn’t start

Commands (this lab shows how to run a container for a single command, interactively and for a long running task)

  • docker container run alpine hostname – run hostname command in alpine vm
  • docker container ls – currently running containers
  • docker container ls -a – all containers; not just those running
  • docker container ps – works same as “ls” but only applies to containers. “ls” allows command to be equivalent for images and other types
  • docker container run –interactive –tty –rm ubuntu bash – opens root bash shell in image and remove the container when the container stops
  • docker container run \
    –detach \
    –name mydb \
    -e MYSQL_ROOT_PASSWORD=my-secret-pw \
    mysql:5.5 – run a container in detached mode with an easy to type name and an environment variable [remember to not to use this approach for a real password]
  • docker container logs mydb – see logs
  • docker container top mydb – shows processes
  • docker exec -it mydb \
    mysql \
    –user=root \
    –password=$MYSQL_ROOT_PASSWORD \
    –version – execute command inside the running container in an interactive shell to find out the running version

Lab 2

This lab builds an image from what we pulled from github, run it and delete it.

I learned

  • Our docker hub account id is just used for a namespace here since we aren’t pushing it. Like maven install vs maven deploy. Or like git commit vs git push.
  • Tab autocomplete works for container names!
  • Can run Linux VM on Windows host
  • Can’t run Windows VM on Linux host

Commands in lab 2

  • docker image build –tag boyarsky/linux_tweet_app:1.0 .
  • docker container run –detach –publish 80:80 –name linux_tweet_app boyarsky/linux_tweet_app:1.0
  • docker container rm –force linux_tweet_app

Layers

  • Example layers – kernel, OS, install, upgrade
  • An image is a giant tarball made up of layers
  • When create an image, there is a thin read/write layer on top. It is for things changed while running container.
  • Looks for a file from top to bottom so finds first matching one.
  • This is why layers remove extra files as last command to run. That way don’t have things don’t need. Saves space and search time.
  • When start a container, a writeable layer added on top.
  • When update image, Docker sees that it has all layers but new one so doesn’t need to re-download everything.

Volumes

  • For persisted data like logs or sharing data between containers.
  • Persists after container deleted unless explicitly delete.
  • Ex: Jenkins work directory
  • Can create in Dockerfile or via CLI
  • docker volume create volName – create volume
  • docker run -d -v volName:/path name ls /path – run container and list contents of volume
  • Use volumes to mount local code in running container – docker container run -v $(pwd):/path
  • Improves performance because avoids copy on write

Lab 3

Playing with volumes. (Lab 3 also has pushing to dockerhub but we didn’t get that far)

Commands in lab 3

  • docker container run \
    –detach \
    –publish 80:80 \
    –name linux_tweet_app \
    –mount type=bind,source=”$(pwd)”,target=/usr/share/nginx/html \
    boyarsky/linux_tweet_app:1.0 – use a bind mount which allows container to see directory on the underlying machine
  • cp index-new.html index.html – update file in underlying directory
  • docker rm –force linux_tweet_app – start over
  • docker container run \
    –detach \
    –publish 80:80 \
    –name linux_tweet_app \
    boyarsky/linux_tweet_app:1.0 – start without volume
  • docker rm –force linux_tweet_app – start over again
  • docker image build –tag boyarsky/linux_tweet_app:2.0 . – increment version since last time
  • docker image ls – see both versions 1.0 and 2.0
  • docker container run \
    –detach \
    –publish 80:80 \
    –name linux_tweet_app \
    boyarsky/linux_tweet_app:2.0
  • docker container run \
    –detach \
    –publish 8080:80 \
    –name old_linux_tweet_app \
    boyarsky/linux_tweet_app:1.0 – run with different name and port
  • docker image ls -f reference=”boyarsky/*” – list all with this account
  • docker login
  • docker image push boyarsky/linux_tweet_app:1.0 – push/publish
  • docker image push boyarsky/linux_tweet_app:2.0 – push/publish other version

My take: I was (just barely) able to complete the lab. I feel like I learned the basics and have a good kick off point when ready to acquire more hands on knowledge.

Leave a Reply

Your email address will not be published. Required fields are marked *