“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.