docker





docker start CONTAINER_NAME    # start an exited container using its name
docker exec -it CONTAINER_NAME bash  # get a shell of your container

docker run to start a container, it actually creates a new container based on the image you have specified.

Besides the other useful answers here, note that you can restart an existing container after it exited and your changes are still there.

docker start f357e2faab77 # restart it in the background
docker attach f357e2faab77 # reattach the terminal & stdin
docker run -p 8888:5000 --name myfirstapp mshahriarinia/myfirstapp



$ docker run hello-world
$ docker pull alpine
$ docker images
$ docker run alpine ls -l  # runs hte command and exits


$ docker stop CONTAINERID;   docker rm CONTAINERID
OR docker rm -f CONTAINERID

$ docker images -a # list all images
$ docker rmi mshahriarinia/myfirstapp      To delete image

$ docker attach CONTAINERID    # if you lost access to its shell due to wifi issues. Attach local standard input, output, and error streams to a running container. if you attach multiple times to same container all of them get same thing, not multiple bashes
$ docker exec -it CONTAINERID /bin/bash      # let you run arbitrary commands inside an existing container.

$ docker run --it alpine  # runs image and gives you interactive shell and does not exit immediately like before


-it is a combination of -i and -t which is --interactive ("Keep STDIN open even if not attached") respectively --tty (" Allocate a pseudo-TTY").

Ctrl-p Ctrl-q        detaches from docker

When you call run,
  1. The Docker client contacts the Docker daemon
  2. The Docker daemon checks local store if the image (alpine in this case) is available locally, and if not, downloads it from Docker Store. (Since we have issued docker pull alpine before, the download step is not necessary)
  3. The Docker daemon creates the container and then runs a command in that container.
  4. The Docker daemon streams the output of the command to the Docker client
$ docker run alpine echo "hello from alpine"
$ docker run alpine /bin/sh  

nothing happened! Is that a bug? Well, no. These interactive shells will exit after running any scripted commands, unless they are run in an interactive terminal - so for this example to not exit, you need to:

$ docker run -it alpine /bin/sh

morteza@DI-MBP:~$ docker run -it alpine /bin/sh
/ # ls -l
....
/ # uname -a
Linux 424642a5236a 4.9.87-linuxkit-aufs #1 SMP Wed Mar 14 15:12:16 UTC 2018 x86_64 Linux
/ # exit

$ docker ps     # shows you all containers that are currently running.
morteza@DI-MBP:~$ docker ps -a 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
424642a5236a        alpine              "/bin/sh"                2 minutes ago       Exited (0) 58 seconds ago                       epic_pike
cdc55823dee6        alpine              "/bin/sh"                3 minutes ago       Exited (0) 3 minutes ago                        musing_austin
47ed17ee64fb        alpine              "echo 'hello from al…"   5 minutes ago       Exited (0) 5 minutes ago                        quizzical_raman
e534f098d25e        alpine              "ls -l"                  6 minutes ago       Exited (0) 6 minutes ago                        hopeful_beaver
a6832838c80c        hello-world         "/hello"                 11 minutes ago      Exited (0) 11 minutes ago                       happy_albattani
f92421411aec        hello-world         "/hello"                 11 minutes ago      Exited (0) 11 minutes ago                       thirsty_beaver

a list of all containers that you ran. Notice that the STATUS column shows that these containers exited a few minutes ago.

$ docker inspect alpine   # Images - The file system and configuration of our application which are used to create containers. To find out more about a Docker image,

  • Images - The file system and configuration of our application which are used to create containers. To find out more about a Docker image, run docker inspect alpine. In the demo above, you used the docker pull command to download the alpine image. When you executed the command docker run hello-world, it also did a docker pull behind the scenes to download the hello-world image.
  • Containers - Running instances of Docker images — containers run the actual applications. A container includes an application and all of its dependencies. It shares the kernel with other containers, and runs as an isolated process in user space on the host OS. You created a container using docker run which you did using the alpine image that you downloaded. A list of running containers can be seen using the docker ps command.
  • Docker daemon - The background service running on the host that manages building, running and distributing Docker containers.
  • Docker client - The command line tool that allows the user to interact with the Docker daemon.
  • Docker Store - A registry of Docker images, where you can find trusted and enterprise ready containers, plugins, and Docker editions. You'll be using this later in this tutorial.

$ docker run -d dockersamples/static-site   # -d flag enables detached mode, which detaches the running container from the terminal/shell and returns your prompt after the container starts.
$ docker ps




to attach to a detached container:   $ docker attach CONTAINERID




Launch a container in detached mode:
$ docker run --name static-site -e AUTHOR="Morteza Shahriari Nia" -d -P dockersamples/static-site

-d will create a container with the process detached from our terminal
-P will publish all the exposed container ports to random ports on the Docker host
--name allows you to specify a container name   
-e is how you pass environment variables to the container
    AUTHOR is the environment variable name and Your Name is the value that you can pass

$ docker port static-site # to see what posts it's forwarding
443/tcp -> 0.0.0.0:32770
80/tcp -> 0.0.0.0:32771

you can open http://localhost:[YOUR_PORT_FOR 80/tcp]. For our example this is http://localhost:32771

Images can be committed with changes and have multiple versions. When you do not provide a specific version number, the client defaults to latest.
Pull a specific version of ubuntu image as follows:
$ docker pull ubuntu:12.04          # docker pull ubuntu    ===    ubuntu:latest


find docker images on https://store.docker.com/



Create your first image

It's a Flask web app that shows random cat images.

mkdir catApp

app.py
from flask import Flask, render_template
import random

app = Flask(__name__)

# list of cat images
images = [
    "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26388-1381844103-11.gif",
    "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr01/15/9/anigif_enhanced-buzz-31540-1381844535-8.gif",
    "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26390-1381844163-18.gif",
    "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr06/15/9/anigif_enhanced-buzz-25158-1381844793-0.gif",
    "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr03/15/10/anigif_enhanced-buzz-11980-1381846269-1.gif"
]

@app.route('/')
def index():
    url = random.choice(images)
    return render_template('index.html', url=url)

if __name__ == "__main__":
    app.run(host="0.0.0.0")

requirements.txt
Flask==0.10.1

templates/index.html
<html>
  <body>
      <h4>Cat Gif of the day</h4>
      <img src="{{url}}" />
  </body>
</html>


Dockerfile
# our base image  or pick base from cloud username/imagename:version
FROM alpine:3.5

# Install python and pip and their dependencies. For each RUN command, Docker will run the command then create a new layer of the image. This way you can roll back your image to previous states easily. The syntax for a RUN instruction is to place the full text of the shell command after the RUN (e.g., RUN mkdir /user/local/foo). This will automatically run in a /bin/sh shell. You can define a different shell like this: RUN /bin/bash -c 'mkdir /user/local/foo'
RUN apk add --update py2-pip

# copies local files into the container.
COPY requirements.txt /usr/src/app/
RUN pip install --no-cache-dir -r /usr/src/app/requirements.txt

COPY app.py /usr/src/app/
COPY templates/index.html /usr/src/app/templates/

# creates a hint for users of an image which ports provide services. Since our flask app is running on 5000 that's what we'll expose. It is included in the information which can be retrieved via $ docker inspect <container-id> The EXPOSE command does not actually make any ports accessible to the host! Instead, this requires publishing ports by means of the -p flag when using $ docker run.
EXPOSE 5000

# defines the commands that will run on the Image at start-up   $ python ./app.py   There can only be one CMD per a Dockerfile/Image. If you need to run multiple commands, the best way to do that is to have the CMD run a script.
CMD ["python", "/usr/src/app/app.py"]

# PUSH pushes your image to Docker Cloud, or alternately to a private registry

$ docker build -t mshahriarinia/myfirstapp .

$ docker run -p 8888:5000 --name myfirstapp mshahriarinia/myfirstapp






Push docker image to cloud:
$ docker login
$ docker push mshahriarinia/myfirstapp            # pushes all the files and binary of the created docker image to the cloud!



Docker Swarm

Create 4 Virtual machines on Azure that are on the same subnet (so that they can communicate to each other). Install same version of docker on all the machines
docker-swarm-0[0-3].azure.com

$ ssh docker-swarm-00.azure.com
docker-swarm-00$ docker version
docker-swarm-00$ ifconfig # to get the ip address (10.0.0.4)
docker-swarm-00$ docker swarm init --listen-addr 10.0.0.4:2377   # Creates a swarm and Sets the current docker machine as the swarm manager. ONLY the manager has admin commands
docker-swarm-00$ docker node ls   # list docker nodes in this swarm. currently only has one node which is hte current node  (manager). Contaioner can run manager and workers

$ ssh docker-swarm-01.azure.com
docker-swarm-01$ docker swarm join 10.0.0.4:2377      # this node joins hte swarm as a worker

$ ssh docker-swarm-02.azure.com
docker-swarm-02$ docker swarm join 10.0.0.4:2377

$ ssh docker-swarm-03.azure.com
docker-swarm-03$ docker swarm join 10.0.0.4:2377

$ ssh docker-swarm-00.azure.com      # manager
docker-swarm-00$ docker node ls       # lists all nodes one a manager

---------
schedule works on the swarms by creating services. ensures same # of tasks are still running even if a node fails
docker-swarm-00$ docker service create --replicas 5 nginx

OR
docker-swarm-00$ docker service create --name ping00 alpine ping docker-swarm-00      # create a container based on alpine that runs ping docker-swarm-00 at the startup as task

docker-swarm-00$ docker service ls     # list all services

docker-swarm-00$ docker service tasks ping00     # check how many instances of the task are running. It shows that the created service is running on ssh docker-swarm-02
$ ssh docker-swarm-02.azure.com
docker-swarm-02$ docker ps       # view the container
docker-swarm-02$ docker logs -f CONTAINERID    # shows the log of the container (ping) and that it can ping the manager node's ip

To find the internal name of the container: $ docker exec -it CONTAINERID hostname       # and notice hostname is the same as container id

docker-swarm-00$ docker service rm ping00 to get rid of the service
docker-swarm-00$ docker service ls  # make sure its not there

----------

docker-swarm-00$ docker service create --name website --publish 80:80 sixeyed/docker-swarm-walkthrough    # a simple webapp
docker-swarm-00$ docker service inspect website --pretty    # to get some detail of the docker image. it lists open ports and Replicas which shows the # of tasks when run as a Service
docker-swarm-00$ docker service tasks website     # only one task and its on hte manager node by chance

If you go to the ip of the node that hosts the container you can view the website. You can also view the website on other node addresses even though they don't contain the docker image, the swarm correct;y identifies the node  that can handle hte request and assign to it and return response;

docker-swarm-00$ docker service update --replicas 10 website       # create 10 replicas of the the image
docker-swarm-00$ docker service tasks website    # 10 tasks

if you go a machine and shut it down

$ docker node ls      # shows hte shut down image among others
docker-swarm-00$ docker service tasks website    # 10 tasks. dead tasks are recreated to maintain scalability but distributed on alive nodes







Kubernetes and Docker Swarm are probably two most commonly used tools to deploy containers inside a cluster.





-----------------------

While developing on docker images you can sync your file system tothe docker file system so you don;'t have to rebuild the whole image for every change.
- Click on docker and specify the shared drive
- $ docker run -it -p 3000:80 -v //c/user/thomas/Desktop/hs/.:/usr/source/app --name hi hello-ducker




Docker host is what you install on the machine that does the image download, etc.
Docker client is a CLI that is state-less and under the hood generates REST API calls to the hosts and prints responses.









Comments