Friday, March 22, 2019

Docker Basic Commands


Docker Basic Commands  



Install and use docker application, then view downloaded version


sudo apt-get update
sudo apt install gnupg2 pass
apt install docker.io
apt install docker-compose







In Case of error when using docker compse, download it manulally 
$ sudo apt-get remove docker-compose
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose



Start and Automate Docker
The Docker service needs to be setup to run at startup. To do so, type in each command followed by enter:

sudo systemctl start docker

sudo systemctl enable docker

List available docker images on the current machine
docker images

Search online for base docker image to customize it, for example ubuntu image
docker search ubuntu 

To download docker image from dockerhub, for example download solr image
docker pull solr

Search for docker images that have 1000+ start (-s)
docker search -s 1000 ubuntu


Search for ubuntu image, install, run instance from it  and pass a command to it, ie, run command ./bin/bash
-i to allow capture standard input  
-t to all terminal 
docker run -i -t ubuntu ./bin/bash

Create a script file with name “Installnode.sh” to Install node js on this blank ubuntu image

vi installnode.sh

Then add these command inside the file
apt-get update
apt-get install —yes nodejs
apt-get install —yes nodejs-legacy
apt-get install —yes nom

Then run the script file using
bash Installnode.sh

Exit from current container 
exit


Note: Here is the related vi commands 

List the Current running containers
docker ps 

List the latest running containers (that may not run now)
docker ps -a











How to start a docker?
you can use  
docker start CONTAINER_ID

OR

docker run IMAGE_ID and not docker run CONTAINER_ID

Key difference between run and start
Run: create a new container of an image, and execute the container. You can create N clones of the same image.

Start: Launch a container previously stopped. For example, if you had stopped a database with the command docker stop CONTAINER_ID, you can relaunch the same container with the command docker start CONTAINER_ID, and the data and settings will be the same.

IMAGE_ID vs CONTAINER_ID
- To get a list of IMAGE_IDs, write docker images
- To get a list of CONTAINER_IDs, write docker ps -a
- We can get Image by download it from docker-hub, when we run this image and define that this new image should have hostname xxx and has IP yyy and open ports xyz and mount HD to path abc, then it become a container and these configuration related to ContainerID, and when we stop/start this container,  we will maintain the same configuration.


Run new docker image instance on the background (-d) and assign name to it  “ubuntu1”
docker run -i -t  -d —name=ubuntu1 ./bin/bash

To save modification we make to docker image 
docker commit -a <author> <ContainerID> <ImageName>:<TAG or Version>

ie,
docker commit -a rafie 23wd2ssddd UbuntuWithNode:0.1

Note: we get container ID by run the command docker ps -a and when we enter the docker ID we can just enter the first 3 letters and not the full containerID number


Run new docker image that mound a folder from host inside container and map a port from host to a container port 

docker run -it -v <Host Folder> : <Docker Folder> -p <Host Port> : <Docker Port> <ImageName>:<ImageTag> <Default Command>

Get <ImageName>:<ImageTag> by run “docker images”

The final command will look like 

docker run -it -v /root/rafie : /host-p 80 : 8888 UbuntuWithNode:0.1 ./bib/bash

After login to the container image copy project files from /host directory to final deployed directory inside the docker because the current mounted volume is a temp
cp -r   /host      /var/www




Close the terminal then try to login again to the same container using command
docker attach <<container id>> 
or
docker container exec -it <ContainerID> bash

Get the current docker IP using dockerID/Name

docker inspect. <<container_name_or_id>>

Or

docker inspect <<container_name_or_id>> | grep “IPAddress"

Or as a table

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <<container_name_or_id>>



To Publish the docker modifications on the internet (on docker hub site), login to http://hub.docker.com, create account, then
docker login

Note: make the current image, the final image by add tag= latest
docker tag <ContainerName>:<Tag> <Container New Name>:latest

docker push <IMAGE Name>

To stop the current docker CONTAINER ID image instance
docker stop <CONTAINER ID>



Reboot docker machine
 docker restart <ContainerName>

Docker IP
when start docker machine, it will has its own IP address and connect to Docker host machine through bridge mode, but we can force that all docker machine run as if it is local installed and all shared the local host by add "--network host"

So, if we need to allow "grandnode/grandnode2:latest" to run with name "GNode2"  on port 80 and allow this container to access all container host ports, write the next command
 
docker run -d --network host  -p 80:80 --name GNode2 grandnode/grandnode2:latest



Copying files from Docker container to host

In order to copy a file from a container to the host, you can use the command

docker cp <containerId>:/file/path/within/container /host/path/target

Here's an example:

$ sudo docker cp goofy_roentgen:/out_read.jpg .

Here goofy_roentgen is the container name I got from the following command:

$ sudo docker ps

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                                            NAMES
1b4ad9311e93        bamos/openface      "/bin/bash"         33 minutes ago      Up 33 minutes       0.0.0.0:8000->8000/tcp, 0.0.0.0:9000->9000/tcp   goofy_roentgen

You can also use (part of) the Container ID. The following command is equivalent to the first

$ sudo docker cp 1b4a:/out_read.jpg .













Remove Docker CONTAINER (Instances) and Remove Docker Images

1) Removing All Unused CONTAINER Instances
docker system prune

2) Remove stoped container instances using CONTAINER ID
docker container rm <<CONTAINER ID 1>> <<CONTAINER ID 2>>

3) Stop all running containers
docker container stop $(docker container ls -aq)

4) Remove All Containers Instances
docker container rm $(docker container ls -aq)

5) Removing Docker Images using ImageID
docker image ls
docker image rm <<Image ID 1>> <<Image ID 2>>

6) Remove all images which are not referenced by any existing container
docker image prune -a


Notes:

Stop All Containers
docker stop $(docker ps -a -q)

Remove All Containers
docker rm $(docker ps -a -q)

Remove Docker Images
docker rmi <IMAGE ID>

Export/Import Docker Images
    docker export <container ID> > image-name.tar 
    docker import  <image-name.tar> <new image name> 
Start Image as a container 
docker run -it <image ID> bash
Save Changes
docker commit <container ID> <new image name>
docker commit c3f279d17e0a  mrafie/testimage:version3

Save Docker Image as File (after commit)

docker save -o <path for generated tar file> <image name>
docker save -o c:/myfile.tar centos:16



Load Docker Image from File

docker load -i <path to image tar file>





View docker volume and remove it
docker volume ls docker system prune --volumes


View docker networks and remove it
docker network ls
docker network prune



Automate Creating docker using script file "Dockerfile"




vi Dockerfile




:wq

after create the docker file build your custom docker using 
docker build -t mydocker:latest .

then to run this new docker
docker run -d -p 3000:3000 mydocker


Notes:
Dockerfile commands
1) FROM: to define the base image, ie, ubuntu or alpine (
alpine is small linux image 5 MB only!)
2) MAINTAINER: Name and contact of image creator
3) COPY or ADD : copy files from our machine to target docker folder
4) RUN executes command(s) in a new layer and creates a new image. E.g., it is often used for installing software packages.
5) CMD sets default command and/or parameters, which can be overwritten from command line when docker container runs.
6) ENTRYPOINT configures a container that will run as an executable.

Examples
RUN apt-get install python3
CMD echo "Hello world"
ENTRYPOINT echo "Hello world"

or
Use the preferred form for CMD and ENTRYPOINT, which is ["executable", "param1", "param2", ...]
RUN ["apt-get", "install", "python3"]
CMD ["/bin/echo", "Hello world"]
ENTRYPOINT ["/bin/echo", "Hello world"]


alpine image vs Ubuntu image when used as a base image:
Example
FROM alpine:3.7
RUN apk add --no-cache mysql-client
ENTRYPOINT ["mysql"]
This example has a virtual image size of only 36.8MB. Compare that to our good friend Ubuntu:
FROM ubuntu:18.04
RUN apt-get update \
    && apt-get install -y --no-install-recommends mysql-client \
    && rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["mysql"]
This yields us a virtual image size of about 145MB image.







Create and link docker images together 
(Docker composer)



vi docker-compose.yml

<ServerName1> :
       image: <image name1> : <Tag1>
       ports:
       - "<External Port1> :  <Port inside docker image1>"
       links:
       -  <ServerName2>

<ServerName2>
       image: <image name2> : <Tag2>
       ports:
       - "<External Port2> :  <Port inside docker image2>"


Note:
you can use build: to build image at run time base on Dockerfile exists on the give directory

example for docker-compose.yml content




To compile the given docker-compose.yml file
docker-compose build
or
docker-compose up

and to stop the running images
docker-compose stop

Note:
if the web server need the IP for the database server to connect to it, just use the name define in the yml file, ie, mongodb://mongo:27017/DB1 , because docker-compose will add entry to etc host file define all the linked servers and related IPs





Docker compose V2

the main new advantage that we can get from v2 
1)  create a local network connections between dockers that control which one can connect to which one
2) create shared storage between some of dockers to allow data exchange between them on IO level

example of a network yml file 




example of storage yml file


 




Sample Complete Docker Yaml file

save the next content to "docker-compose.yml" file then run
docker-compose build
docker-compose up
docker-compose down



    
version: '3'

services:
  web:
    restart: always
    image: mrafie/ddl:web
    expose:
      - "80"
    ports:
      - '80:80'
    tty: true
    volumes:
      - /:/data
    networks:            
        front:
            ipv4_address: 172.16.0.20
            ipv6_address: "2001:3984:3989::20"
    #command: service apache2 start 
  solr:
    restart: always
    image: mrafie/ddl:solr
    ports:
      - "8983:8983"
    volumes:
      - /:/data
    networks:            
        front:
            ipv4_address: 172.16.0.3
            ipv6_address: "2001:3984:3989::13"

  db:
    image: mrafie/ddl:sql
    restart: always
    environment:
      MYSQL_DATABASE: 'db'
      MYSQL_USER: 'user'
      MYSQL_PASSWORD: 'P@ssw0rd'
      MYSQL_ROOT_PASSWORD: 'P@ssw0rd'
    ports:
      - '3306:3306'
      - '33060:33060'
    expose:
      - '3306'
      - '33060'
    volumes:
      - my-db:/var/lib/mysql
      - /:/data
    networks:            
        front:
            ipv4_address: 172.16.0.2 
            ipv6_address: "2001:3984:3989::12"

  redis:
    restart: always
    image: mrafie/ddl:redis
    volumes:
      - /:/data
    ports:
      - "6379:6379"
    tty: true
    #command: redis-server /usr/local/etc/redis.conf
    networks:            
        front:
            ipv4_address: 172.16.0.4 
            ipv6_address: "2001:3984:3989::14"

volumes:
  my-db:
networks:
    front:
        # use the bridge driver, but enable IPv6
        driver: bridge
        driver_opts:
            com.docker.network.enable_ipv6: "true"
        ipam:
            driver: default
            config:
                - subnet: 172.16.0.0/24
                - subnet: "2001:3984:3989::/64"

No comments: