Use the arrow keys to navigate
Everett Toews | @everett_toews |
Ash Wilson | @smashwilson |
Bash and PowerShell
$ # bash command
> # powershell equivalent command
Replace multi-line backslash (\) delmininators with with backticks (`)
$ docker run \
--name mycontainer
> docker run `
-- name mycontainer
dvm install 1.11.1
carina ls
Get a feel for the Carina website.
Setup a cluster where we can run Docker containers
VMs | Containers |
The CLI for the Docker API
$ cd Downloads/mycluster
$ source docker.env
> . .\docker.ps1
$ env | grep DOCKER
> dir env:DOCKER*
DOCKER_HOST=tcp://146.20.68.14:2376
DOCKER_TLS_VERIFY=1
DOCKER_CERT_PATH=/Users/everett/Downloads/mycluster
DOCKER_VERSION=1.11.1
$ dvm use
Now using Docker 1.11.1
$ docker
Usage: docker [OPTIONS] COMMAND [arg...]
docker [ --help | -v | --version ]
A self-sufficient runtime for containers...
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ docker run --interactive --tty alpine:3.3 /bin/sh
/ # uname -a
Linux d020582f8e97 3.18.21-1-rackos #1 SMP Tue Oct 6 18:37:31 UTC 2015 x86_64 Linux
/ # ps
PID USER TIME COMMAND
1 root 0:00 /bin/sh
17 root 0:00 ps
/ # exit
$ docker ps --latest
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d020582f8e97 alpine:3.3 "/bin/sh" 5 minutes ago Exited (0) 1 seconds ago 96afcb76-6483-443e-941d-df9f803a4628-n2/pedantic_yalow
$ docker ps --latest --quiet
d020582f8e97
$ docker start $(docker ps -l -q)
d020582f8e97
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d020582f8e97 alpine:3.3 "/bin/sh" 6 minutes ago Up 10 seconds 96afcb76-6483-443e-941d-df9f803a4628-n2/pedantic_yalow
$ docker attach $(docker ps -l -q)
(Press enter if you just get a blank line)
/ # exit
$ docker rm $(docker ps -l -q)
d020582f8e97
$ docker run --detach --name ghost --publish 8080:2368 ghost:0.7
fbe7b7f520e8ba08925f4a2df1cd7d66bbacd25164656e25fca34e24127e7c73
$ docker logs ghost
...
Migrations: Complete
Ghost is running in development...
Listening on 0.0.0.0:2368
Url configured as: http://localhost:2368
Ctrl+C to shut down
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fbe7b7f520e8 ghost:0.7 "/entrypoint.sh npm s" About a minute ago Up About a minute 172.99.77.191:8080->2368/tcp 96afcb76-6483-443e-941d-df9f803a4628-n2/ghost
$ open http://$(docker port ghost 2368/tcp)
> start http://$(docker port ghost 2368/tcp)
$ docker rm --force ghost
ghost
nginx:1.9
container in detached modedocker cp
and a file from your laptopdocker commit
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine 3.3 90239124c352 31 hours ago 4.794 MB
cirros latest f8ce316a37a7 6 weeks ago 7.735 MB
nginx 1.9 69203b7cd029 7 days ago 134.6 MB
swarm 1.1.0 4b5b33ba4e4f 2 weeks ago 18.11 MB
ghost 0.7 c39498b8f953 2 weeks ago 352.2 MB
carina/consul latest 2a49945a93ab 2 weeks ago 28.49 MB
$ docker pull alpine:3.3
96afcb76-6483-443e-941d-df9f803a4628-n1: Pulling alpine:3.3... : downloaded
$ mkdir -p workshop/ex1
> mkdir -path workshop/ex1
$ cd workshop/ex1
$ touch Dockerfile
$ touch entrypoint.sh
Edit Dockerfile
FROM alpine:3.3
MAINTAINER Firstname Lastname "firstname.lastname@example.com"
ARG BUILD_TIME_VAR="Default Build Time Message"
ENV RUN_TIME_VAR="Default Run Time Message"
RUN apk --no-cache add nginx
COPY entrypoint.sh /entrypoint.sh
RUN chmod u+x entrypoint.sh
WORKDIR /usr/share/nginx/html/
RUN echo $BUILD_TIME_VAR >> index.html
EXPOSE 80
ENTRYPOINT ["/entrypoint.sh"]
CMD ["Default CMD Message"]
Edit entrypoint.sh
#!/bin/sh
set -euo pipefail
echo $RUN_TIME_VAR >> /usr/share/nginx/html/index.html
echo $1 >> /usr/share/nginx/html/index.html
exec nginx -g "daemon off;"
$ docker build --build-arg BUILD_TIME_VAR="Chop Wood," --tag="nginx-message:1.0" .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM alpine:3.3
---> 90239124c352
...
Successfully built 3f7493082af2
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx-message 1.0 3f7493082af2 About a minute ago 6.249 MB
...
$ docker run --detach \
--name nginx \
--publish 80:80 \
--env RUN_TIME_VAR="Carry Water," \
nginx-message:1.0 \
"Mow Lawn"
3f98a5832b79fe43f97aa07aaa9e425fa33cb7e195e61a6b0d39dfdd4dc0195e
$ open http://$(docker port nginx 80/tcp)
> start http://$(docker port nginx 80/tcp)
$ docker rm --force nginx
nginx
$ cd ..
PowerShell: Replace \ with `
$ docker create --name data --volume /var/lib/mysql cirros
162bf49dbc24245a53095b5be611da3e820862dc8e837a66dab83d7e3f9d5b5a
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
162bf49dbc24 cirros "/bin/true" 12 seconds ago 96afcb76-6483-443e-941d-df9f803a4628-n2/data
$ docker run --name mysql \
--detach \
--volumes-from data \
--env MYSQL_ROOT_PASSWORD=my-root-pw --env MYSQL_DATABASE=test --env MYSQL_USER=test-user --env MYSQL_PASSWORD=test-password \
mysql:5.6
6c38ad9739c47933e0a415912fbec83190bc519650dcb1412091d207f09a040d
$ docker run --rm \
--volumes-from data \
cirros \
ls /var/lib/mysql
auto.cnf
ib_logfile0
ib_logfile1
ibdata1
mysql
performance_schema
test
PowerShell: Replace \ with `
$ docker rm -f mysql
mysql
$ docker run --rm \
--volumes-from data \
cirros \
ls /var/lib/mysql
auto.cnf
ib_logfile0
ib_logfile1
ibdata1
mysql
performance_schema
test
$ docker rm --volumes data
data
docker volume
?
$ docker network create mynet
0b1194e03c4747be069eef05b6db67c13974d9717ebd859fcff7aa322aa48d9b
$ docker network ls
NETWORK ID NAME DRIVER
0b1194e03c47 mynet overlay
33a440068243 96afcb76-6483-443e-941d-df9f803a4628-n1/none null
3b126dcfc9ea 96afcb76-6483-443e-941d-df9f803a4628-n1/bridge bridge
60cecf066b00 96afcb76-6483-443e-941d-df9f803a4628-n1/host host
c3a94fdde28f 96afcb76-6483-443e-941d-df9f803a4628-n1/docker_gwbridge bridge
$ docker run --name mysql \
--detach \
--net mynet \
--env MYSQL_ROOT_PASSWORD=my-root-pw \
mysql:5.6
60d49ac074902a721d6a90af5c4bd85363bed0a998fd4b19da61198f5340b73d
$ docker port mysql 3306
Error: No public port '3306/tcp' published for mysql
PowerShell: Replace \ with `
$ docker run --name wordpress \
--detach \
--net mynet \
--publish 80:80 \
--env WORDPRESS_DB_HOST=mysql \
--env WORDPRESS_DB_PASSWORD=my-root-pw \
wordpress:4.4
c7ebba7f81c1cf48bddbea6d3080713bea58b9de38ee7e7d422b0010b33daf12
$ open http://$(docker port wordpress 80/tcp)
> start http://$(docker port wordpress 80/tcp)
$ docker rm -f mysql wordpress
mysql
wordpress
$ docker ps --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7573f6685549 swarm:1.2.0 "/swarm manage -H=tcp" 30 hours ago Up 30 hours 1dba0f72-75bc-4825-a5a0-b2993c535599-n1/swarm-manager
1d4f3859f9da swarm:1.2.0 "/swarm join --addr=1" 30 hours ago Up 30 hours 1dba0f72-75bc-4825-a5a0-b2993c535599-n1/swarm-agent
d563be543c55 cirros "/sbin/init" 30 hours ago Created 1dba0f72-75bc-4825-a5a0-b2993c535599-n1/swarm-data
326c0fd484d8 swarm:carina-consul "/entrypoint.sh agent" 30 hours ago Up 30 hours 1dba0f72-75bc-4825-a5a0-b2993c535599-n1/carina-svcd
dc0538bd0134 cirros "/sbin/init" 30 hours ago Created 1dba0f72-75bc-4825-a5a0-b2993c535599-n1/carina-svcd-data
# No need to run the following commands
$ docker rm container-name-1 container-name-2
$ docker rm $(docker ps -qf "status=exited")
See installation and configuration instructions
$ carina ls
ClusterName Flavor nodes AutoScale Status
mycluster container1-4G 1 false active
* DO NOT run the commands below *
$ carina create --wait foobar
ClusterName Flavor nodes AutoScale Status
foobar container1-4G 1 false active
$ carina rebuild foobar
ClusterName Flavor nodes AutoScale Status
foobar container1-4G 1 false rebuilding-swarm
$ carina env mycluster
source /Users/caro8994/.carina/clusters/carolynvsrax/mycluster/docker.env
# Run the command below to get your Docker environment variables set:
# eval $(carina env mycluster)
PS> carina env mycluster --shell powershell
. C:\Users\caro8994\carina\clusters\carolynvsrax\mycluster\docker.ps1
# Run the command below to get your Docker environment variables set:
# carina env mycluster --shell powershell | iex
$ eval $(carina env mycluster)
PS> carina env mycluster --shell powershell | iex
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
ab668e03cafb logjam "tail -f /var/log/foo" 3 seconds ago Up 3 seconds
$ carina ls
ClusterName Flavor nodes AutoScale Status
mycluster container1-4G 1 false active
# Don't run these commands right now
$ carina grow --by 1 mycluster
ClusterName Flavor nodes AutoScale Status
mycluster container1-4G 1 false growing
$ carina ls
ClusterName Flavor nodes AutoScale Status
mycluster container1-4G 2 false active
$ docker run --name whoa1 --detach --publish 80:8080 rackerlabs/whoa
44aff6801d136ae7ba49ad074d94a7ba94740326f8d9099d7830ec8095abdf72
$ docker port whoa1 8080
104.130.0.119:80
$ docker run --name whoa2 --detach --publish 80:8080 rackerlabs/whoa
docker: Error response from daemon: Unable to find a node that satisfies the following conditions
[port 80 (Bridge mode)].
$ curl $(docker port whoa1 8080/tcp)
🎉 Whoa! 🎉
$ docker rm -f whoa1
whoa1
rackerlabs/whoa
on port 80Factors that implicitly influence container placement
--publish
finds a node with the published port free--volumes-from
uses the same node as the named containerExplicitly influence where your containers run
Set by environment variables or build arguments
# Run on the same node as another container
$ docker run --env affinity:container==backend ...
# Run on a node where image is available
$ docker run --env affinity:image==myapp ...
# Explicit node name
$ docker run --env constraint:node==*n1 ...
# Build a new image on the same node as an existing container
$ docker build --build-arg affinity:image==myapp -t myapp:v2 .
docker info
$ docker info
Containers: 9
Running: 5
Paused: 0
Stopped: 4
Images: 13
Server Version: swarm/1.2.0
Role: primary
Strategy: spread
Filters: health, port, dependency, affinity, constraint
Nodes: 2
...
tldr: You don't have access to the underlying Docker host
--volume HOST:CONTAINER
--privileged
--cap-add/drop
git clone https://github.com/getcarina/jupyterhub-tutorial.git
If you don't have git, download the repository.
Get your node IP address
$ docker run --rm --net=host --env constraint:node==*n1 racknet/ip public ipv4
146.20.68.51
Copy your secrets
Yes, I reset my secret after this screenshot...
$ cd jupyterhub-tutorial/jupyterhub-launch
$ export DNSNAME=$(docker run --rm --net=host --env constraint:node==*n1 racknet/ip public ipv4)
$ export JUPYTERHUB_USERS=[github-user]
$ export GITHUB_CLIENT_ID=[github-client-id]
$ export GITHUB_CLIENT_SECRET=[github-client-secret]
$ ./launch.sh
PS> carina env jupyterhub --shell powershell | iex
PS> $env:DNSNAME=$(docker run --rm --net=host racknet/ip public ipv4); `
$env:JUPYTERHUB_USERS="[github-user]"; `
$env:GITHUB_CLIENT_ID="[github-client-id]"; `
$env:GITHUB_CLIENT_SECRET="[github-client-secret]"; `
.\launch.ps1
Your web browser should automatically open to display JupyterHub.
docker cp welcome-to-python.ipynb jupyter-[github-user]:/home/jovyan/work
$ carina rm mycluster
ClusterName Flavor Nodes AutoScale Status
mycluster container1-4G 2 false deleting
Everett Toews | @everett_toews |
Ash Wilson | @smashwilson |