-
Notifications
You must be signed in to change notification settings - Fork 24
Home
Welcome to the exercises from my Docker, FROM scratch
talk. You'll find each exercise is tagged in the git repository using step-*
to step through, and each step is a progression on the last one. (Almost) All of the steps will use run.bat
in the root of the git repo, so this is obviously intended to run on Windows (using Linux containers though), if you're on a non-Windows OS you'll need to pull the commands out of the run.bat
file.
Here we'll explain each step and the intended run sheet from the talk.
Goal: Start a basic container from an Ubuntu
image.
You'll be dropped into an interactive Ubuntu container running /bin/bash
.
- Run
ls
to see what's on the file system - Run
mkdir /foo
to make a new folder at the root of the container - On the Host run
docker ps
and see the running container - On the container run
exit
to stop the process and shutdown the container - On the Host run
docker ps
and see the container isn't listed, add a--all
flag to see the stopped container - On the Host run
docker start <container id>
to start the container - On the Host run
docker attach <container id>
to connect back into the container - On the container run
ls /
and see that the/foo
folder is still there
Goal: Start multiple containers that run in isolation of each other, and will remove themselves when stopped.
You'll start three containers, ubuntu1
, ubuntu2
and ubuntu3
, all detached.
- Start three terminals and run
docker attach ubuntu1/2/3
in each to connect to each container - Pick a container and run
mkdir /foo
on it - On a different container run
ls
, the/foo
directory won't exist - On the Host run
docker stop ubuntu2
- On the Host run
docker ps --all
andubuntu2
is no longer listed
Goal: Learn how to mount a volume into a running container
Note: If you're on a non-Windows OS you'll need to change %CD%
to your OS's approach of getting the current working directory.
There are no explicit exercises here other than running the docker run
command and observing the output.
Goal: Run a single process in a container
Note: You're dropped into a Node.js REPL, not /bin/bash
.
- Run
console.log('Hello World');
- Run
const fs = require('fs'); fs.readdir('/', (err, paths) => console.log(paths));
and see the file system info
Goal: Run an application in a node.js container
Note: If you're on a non-Windows OS you'll need to change %CD%
to your OS's approach of getting the current working directory.
- (After the container is started) On the Host run
curl http://localhost:3000
to get the response from the webserver- This will result in an error, that's expected
- On the Host run
docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' node
- No port bindings are listed
Goal: See how we can use port bindings from host to container.
Note: If you're on a non-Windows OS you'll need to change %CD%
to your OS's approach of getting the current working directory.
- (After the container is started) On the Host run
curl http://localhost:8080
to get the response from the webserver - On the Host run
docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' node
- See that the port
3000
ontcp
in the container is bound to8080
on the host
- See that the port
Goal: Introduce the Dockerfile
and create an image.
- Open the
Dockerfile
in an editor- Inspect the different commands in the Dockerfile, see the reference to understand them
- On the Host run
docker images
- There is a new image called
nodejs-app
which we just created
- There is a new image called
- On the Host run
docker ps
and see thenode
container uses thenodejs-app
image
Goal: Introduce docker-compose
for defining environments.
- Open the
docker-compose.yml
in an editor- Inspect the different parts of the file relative to the
docker run
commands, see the reference to understand it
- Inspect the different parts of the file relative to the
Goal: See how we can combine docker-compose
and a Dockerfile
- See the differences in the
docker-compose.yml
now that we use theDockerfile
Goal: Learn about environment variables in docker.
- Open a SQL Server management tool (LINQPad, SQL Server Management Studio, etc.) and connect using
sa
and the password from the environment variable
Goal: Using a compose file to represent multiple services that talk to each other
Note: This step assumes you have access to Visual Studio 2017
- Set the
docker-compose
project to the startup project in Visual Studio and launch - In your browser register a new account
- Open a SQL Server management tool (LINQPad, SQL Server Management Studio, etc.) and connect using
sa
and the password from the environment variable - In your browser apply the EF migrations
- Refresh your SQL explorer and see the new DB was created
Goal: Using a compose file to represent multiple services that talk to each other, but without port binding SQL
Note: This step assumes you have access to Visual Studio 2017
- Set the
docker-compose
project to the startup project in Visual Studio and launch - In your browser register a new account
- In your browser apply the EF migrations
- Open a SQL Server management tool (LINQPad, SQL Server Management Studio, etc.) and connect using
sa
and the password from the environment variable, which will timeout - On the Host run
docker network ls
and find the two networks created by the compose file, they are suffixed_web
and_db
- Run an interactive container with
ubuntu
and connect to the_db
networkdocker run -it --rm --network <network name> Ubuntu /bin/bash
- Install
ping
in the containerapt-get update && apt-get install iputils-ping -y
- Ping the SQL server using its network alias
ping sql
- Run an interactive container with
ubuntu
and connect to the_web
networkdocker run -it --rm --network <network name> Ubuntu /bin/bash
- Install
ping
in the containerapt-get update && apt-get install iputils-ping -y
- Ping the SQL server using its network alias (which will timeout)
Goal: Create a docker image that uses the scratch
base image.
No exercises, just running a Go lang app in the smallest image possible!
Goal: Combine build and app into a single Dockerfile
There's no explicit exercise, just a reformatted Dockerfile
that has a build image created and then the application
image.