DOCKER 101 - BACKGROUND AND BASICS
Docker can run inside or outside Virtual Machines like Hyper-V or VMWare
If you’re familiar with object-oriented principles, another way to look at images and containers is to view images as classes and containers as objects. In the same way that objects are concrete instantiations of classes, containers are instantiations of images. You can create multiple containers from a single image, and they are all iso- lated from one another in the same way objects are.
https://www.docker.com/sites/default/files/Docker_CheatSheet_08.09.2016.pdf
Sample Dockerfile
Set a tag to ID of container
So, how does a sysadmin backup a Docker container? They don’t. The application data doesn’t live in the container, it lives in a Docker volume that is shared between 1-N containers as defined by the application architecture. Sysadmins backup the data volume, and forget about the container. Optimally Docker containers are completely stateless and immutable.
// learn docker version
# docker version
//Running Your First Image
# docker run debian echo "Hello World"
// getting a shell inside centos image
# docker run -ti centos /bin/bash
// getting a shell inside centos with 7.2.1511 tag image
# docker run -ti centos:7.2.1511 /bin/bash
// learn centos tagged images on:
// https://hub.docker.com/r/library/centos/tags/
// inside image learn which linux distribution works:
# cat /etc/*release
// getting a shell inside debian image
# docker run -ti debian /bin/bash
// getting a shell inside ubuntu image
# docker run -ti ubuntu /bin/bash
// launch a new container with a hostname : ”myAPPLE”
# docker run -h myAPPLE -ti centos /bin/bash
// => [root@myAPPLE /]#
// list running containers
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7d9ad738a77a centos "/bin/bash" 5 minutes ago Up 5 minutes kickass_ritchie
// ContainerID ⇒ 7d9ad738a77a
// Container Name ⇒ kickass_ritchie
// Container ID and containerName must be unique.
// learn info about container in JSON format
# docker inspect (ConcainerID | Containername)
# docker inspect 7d9ad738a77a
# docker inspect kickass_ritchie
// learn IPAddress of a container on Host
# docker inspect <ContainerID | ContainerName> | grep IPAddress
# docker inspect --format {{.NetworkSettings.IPAddress}} <ContainerID | ContainerName>
// learn difference between container and the image which container had created from.
# docker diff <ContainerID | ContainerName>
# docker diff kickass_ritchie
A /orhan1
A /orhan1/selam.txt
A /orhan3
A /orhan2
D /bin
// Docker uses a union file system (UFS) for containers, which allows multiple filesystems to be mounted in a hierarchy and to appear as a single filesystem. The filesystem from the image has been mounted as a read-only layer, and any changes to the running container are made to a read- write layer mounted on top of this. Because of this, Docker only has to look at the topmost read-write layer to find the changes made to the running system
// learn everything that happened inside container
# docker logs <ContainerID | ContainerName>
// to see logs continiously from a container. Add -f parameter
# docker logs -f <ContainerID | ContainerName>
// started exited container again
# container start <ContainerID | ContainerName>
// A container can be stop or start. A uniquely named container saves its state. So, if a container stop
// then start again, new files or directory, etc.. will be still there. But if a container delete with // “docker rm <ContainerID | container name>” everything will be gone with container.
// THE IMPORTANT THING IS THAT WE CAN STOP AND START SAME CONTAINER AND EVERYTHING WILL BE SAVED INSIDE // CONTAINER
# container start <ContainerID | ContainerName>
# container stop <ContainerID | ContainerName>
// list all containers which runs or exited.
# docker ps -a
// delete a container forever
# docker rm <ContainerID | ContainerName>
// delete all stopped containers with a single command
// -v argument will delete any Docker-managed volumes that aren’t referenced by other contain‐ ers.
# docker rm -v $(docker ps -aq -f status=exited)
// very simple speaking cow example with Dockerfile
// ⇒ START[1478614735]
# mkdir cowsay
# cd cowsay
# touch Dockerfile ⇒ file content is below
FROM ubuntu
MAINTAINER Orhan Doğan <orhan@orhandogan.net>
RUN apt-get update && apt-get install -y cowsay fortune
COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
# touch entrypoint.sh ⇒ file content is below
#!/bin/bash
if [ $# -eq 0 ]; then
/usr/games/fortune | /usr/games/cowsay
else
/usr/games/cowsay "$@"
fi
# docker build -t test/cowsay-dockerfile .
# docker run test/cowsay-dockerfile ⇒ random text
# docker run test/cowsay-dockerfile "Mööööö" ⇒ entered text
// ⇒ END[1478614735]
// Images, Containers, and the Union File System
// Union file systems allow multiple file systems to be overlaid, appearing to the user as a
// single filesytem. Folders may contain files from multiple filesystems, but if two files
// have the exact same path, the last mounted file will hide any previous files. Docker
// supports several different UFS implentations, including AUFS, Overlay, devicemapper, BTRFS,
// and ZFS. Which implementation is used is system dependent and can be checked by running
// docker info where it is listed under “Storage Driver.”
// Docker images are made up of multiple layers. Each of these layers is a read-only fil‐
// eystem. A layer is created for each instruction in a Dockerfile and sits on top of the
// previous layers. When an image is turned into a container (from a docker run or docker
// create command), the Docker engine takes the image and adds a read-write filesystem on top
// (as well as initializing various settings such as the IP address, name, ID, and resource
// limits).
// Because unnecessary layers bloat images (and the AUFS filesystem has a hard limit of 127
// layers), you will notice that many Dockerfiles try to minimize the number of lay‐ ers by
// specifying several UNIX commands in a single RUN instruction.
// A ontainer can be in one of several states:
// created, restarting, running, paused, or exited.
// A “created” container is one that has been initialized with the docker create command but
// hasn’t been started yet.
// The exited status is commonly referred to as “stopped” and indicates there are no running // processes inside the container (this is also true of a “created” container, but an exited // container will have already been started at least once).
// A container exits when its main processes exits. An exited container can be restarted with
// the docker start command. A stopped container is not the same as an image. A stopped
// container will retain changes to its settings, metadata, and filesystem, including runtime
// configuration such as IP address that are not stored in images.
// The restarting state is rarely seen in practice and occurs when the Docker engine attempts
// to restart a failed container.
// Listing docker images
# docker images
// committing a container which still running or exited to local image cache
# git commit <ContainerID | ContainerName>
// login a docker Registry
# docker login
# docker login localhost:8080
# cat $HOME/.docker/config.json ⇒ login credentials stor in here
// sending local image to a registery
# docker push odogan/cowsay
// pulling an image from repository
# docker pull odogan/cowsay
// pulling redis and connecting 2 redis instance
# docker pull redis
# docker run --name RedisSrv1 --hostname RedisServer1Host -d redis
⇒ --name RedisServer1: sets a container name
⇒ --hostname RedisServer1Host: sets a hostname of the container
⇒ -d: runs container and de-attach as a daemon
# docker run --rm -ti --name RedisSrv2 --hostname RedisSrv2Host --link RedisSrv1:RedisSrv1Tag redis /bin/bash
⇒ --rm: delete container after exit
⇒ --name RedisServer1: sets a container name
⇒ --link <ContainerId | name> links to a container. So we can ping
root@RedisSrv2Host:/data# cat /etc/hosts
127.0.0.1 localhost
...
172.17.0.2 RedisSrv1Tag RedisServer1Host RedisSrv1
172.17.0.3 RedisSrv2Host
root@RedisSrv2Host:/data# redis-cli -h RedisSrv1 -p 6379
RedisSrv1:6379> set "a" 1234
OK
RedisSrv1:6379> get a
"1234"
RedisSrv1:6379> exit
root@RedisSrv2Host:/data#
// create volume via Dockerfile and “docker run” command
# docker run -v MyDirectory centos /bin/bash ⇒ -v DirectoryName: creates a directory inside container
# docker run -v /HostDirectory:/ContainerDirectory centos /bin/bash
⇒ -v /HostDirectory:/ContainerDirectory : creates a directory inside container named
ContainerDirectory and maps it with HostDirectory
# docker run --rm -it -v ~/.bash_history:/root/.bash_history ubuntu /bin/bash
⇒ The -v flag can also be used to mount a single file - instead of just directories - from the host machine. In this example we shares host machine’s history to container.
// inside a Dockerfile use:
VOLUME ["/container_dir_1"]
VOLUME ["/container_dir_1","/container_dir_2","/container_dir_3"]
Keep in mind the placement of your VOLUME declarations in your Dockerfile as it does create essentially immutable directories in your image.
// backup a file from container
# docker run --rm --volumes-from <ContainerID|Name> -v $(pwd)/yedek/yedek centos cp /orhan/data.zip /yedek
⇒ --volumes-from <ContainerID | Name> : Connected this containers File sytem to reach its data
// stop a container
# docker stop <ContainerID | ContainerName>
// delete all containers
# docker rm $(docker ps -aq)
In Figure 4-1, we can see the major components of a Docker installation:
At the center is the Docker daemon, which is responsible for creating, running, and monitoring containers, as well as building and storing images, both of which are represented on the right of the diagram. The Docker daemon is launched by running docker daemon, which is normally taken care of by the host OS.
The Docker client is on the left-hand side and is used to talk to the Docker dae‐ mon via HTTP. By default, this happens over a Unix domain socket, but it can also use a TCP socket to enable remote clients or a file descriptor for systemd- managed sockets. Since all communication has to be done over HTTP, it is easy connect to remote Docker daemons and develop programming language bind‐ ings, but it also has implications for how features are implemented, such as requiring a build context for Dockerfiles as explained in “The Build Context”). The API used for communication with daemon is well defined and documented, allowing developers to write programs that interface directly with the deamon, without using the Docker client. The Docker client and daemon are distributed as a single binary.
Docker registries store and distribute images. The default registry is the Docker Hub, which hosts thousands of public images as well as curated “official” images. Many organizations run their own registries that can be used to store commercial or sensitive images as well as avoiding the overhead of needing to download images from the Internet. See “Running Your Own Registry” for information on running your own registry. The Docker daemon will download images from reg‐ istries in response to docker pull requests. It will also automatically download images specified in docker run requests and in the FROM instruction of Docker‐ files if they are not available locally.
// Dockerfile Introductions
// docker build -f /path/to/a/Dockerfile . ⇒ -f PATH_OF_Dockerfile (.) point shows context
// docker build -t odogan/myapp . ⇒ -t [RegisteryUrl:]repo[:tag]
// docker build -t odogan/myapp:1.0.2 -t odogan/myapp:latest . ⇒ To tag the image into multiple repositories after the build, add multiple -t parameters
// FROM <image>
The FROM instruction sets the Base Image for subsequent instructions
// MAINTAINER <name>
The MAINTAINER instruction allows you to set the Author field of the generated image
MAINTAINER Orhan Doğan <orhan@orhandogan.net>
// RUN
RUN <command> (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)
RUN ["executable", "param1", "param2"] (exec form) Docker uses JSON form. So, use double-quotes (“)
The RUN instruction will execute any commands in a new layer on top of the current image and commit the results. The resulting committed image will be used for the next step in the Dockerfile.
Best practice: Below RUN command is a single run command so, it creates one middle-layer
RUN apt-get update && apt-get install -y \
aufs-tools \
automake \
build-essential \
curl \
dpkg-sig \
libcap-dev \
libsqlite3-dev \
mercurial \
reprepro \
ruby1.9.1 \
ruby1.9.1-dev \
s3cmd=1.1.* \
&& rm -rf /var/lib/apt/lists/*
// CMD <src>... <dest>
CMD ["executable","param1","param2"] (exec form) ⇒ use this. This is prefered usage
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)
CMD Runs the given instruction when the container is started. If an ENTRYPOINT has been defined, the instruction will be interpreted as an argument to the ENTRY POINT (in this case, make sure you use the exec format). The CMD instruction is overridden by any arguments to docker run after the image name. Only the last CMD instruction will have an effect, and any previous CMD instructions will be overridden (including those in base images).
There can only be one CMD instruction in a Dockerfile. If you list more than one CMD then only the last CMD will take effect.
The main purpose of a CMD is to provide defaults for an executing container. These defaults can include an executable, or they can omit the executable, in which case you must specify an ENTRYPOINT instruction as well.
// LABEL <key>=<value> <key>=<value> <key>=<value> …
The LABEL instruction adds metadata to an image. A LABEL is a key-value pair. To include spaces within a LABEL value, use quotes and backslashes as you would in command-line parsing.
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
LABEL multi.label1="value1" multi.label2="value2" other="value3"
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
// EXPOSE
EXPOSE <port> [<port>...]
The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. EXPOSE does not make the ports of the container accessible to the host. To do that, you must use either the -p flag to publish a range of ports or the -P flag to publish all of the exposed ports.
// ENV
ENV <key> <value>
ENV <key>=<value> ...
ENV myName="John Doe" myDog=Rex\ The\ Dog \ ⇒ myDog değeri “Rex The dog” dur. Boşluk için \ kullandım
myCat=fluffy \
version=1.5 \
stage=test
The ENV instruction has two forms. The first form, ENV <key> <value>, will set a single variable to a value. The second form, ENV <key>=<value> ..., allows for multiple variables to be set at one time. Notice that the second form uses the equals sign (=) in the syntax, while the first form does not.
Like command line parsing, quotes and backslashes can be used to include spaces within values.
// ADD <src>... <dest> ⇒ use COPY instead this one.
Copies files from the build context or remote URLs into the image. If an archive file is added from a local path, it will automatically be unpacked. As the range of functionality covered by ADD is quite large, it’s generally best to prefer the simpler COPY command for copying files and directories in the build context and RUN instructions with curl or wget to download remote resources (which retains the possibility of processing and deleting the download in the same instruction).
// COPY
COPY <src>... <dest>
COPY ["<src>",... "<dest>"] (this form is required for paths containing whitespace)
The COPY instruction copies new files or directories from <src> and adds them to the filesystem of the container at the path <dest>.
COPY hom* /mydir/ # adds all files starting with "hom". Mydir will be created automaticaly
COPY hom?.txt /mydir/ # ? is replaced with any single character, e.g., "home.txt"
COPY test relativeDir/ # adds "test" to `WORKDIR`/relativeDir/
COPY test /absoluteDir/ # adds "test" to /absoluteDir/
The <src> path must be inside the context of the build; you cannot COPY ../something
// ENTRYPOINT
ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred)
ENTRYPOINT command param1 param2 (shell form)
An ENTRYPOINT allows you to configure a container that will run as an executable.
Dockerfile example:
FROM ubuntu:trusty
ENTRYPOINT ["/bin/ping","-c","3"]
CMD ["orhandogan.net"]
# docker build -t demo . ⇒ ENTRYPOINT and CMD will be combined : /bin/ping -c 3 orhandogan.net
# docker run demo localhost ⇒ ENTRYPOINT will use and CMD will be overwrited. /bin/ping -c 3 localhost
If a Dockerfaile has ENTRYPOINT and CMD, even in a different, CMD will be appened after ENTRYPOINT.
If docker run.. Has command it will be replaced with CMD.
// VOLUME
VOLUME ["/container_dir_1"]
VOLUME ["/container_dir_1","/container_dir_2","/container_dir_3"]
In Dockerfile we can’t specify HostDirectory, because of each mid-level layer will be empty
// USER
USER daemon
The USER instruction sets the user name or UID to use when running the image and for any RUN, CMD and ENTRYPOINT instructions that follow it in the Dockerfile.
// WORKDIR
WORKDIR /path/to/workdir
The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile. If the WORKDIR doesn’t exist, it will be created even if it’s not used in any subsequent Dockerfile instruction.
It can be used multiple times in the one Dockerfile. If a relative path is provided, it will be relative to the path of the previous WORKDIR instruction. For example:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
The output of the final pwd command in this Dockerfile would be /a/b/c.
The WORKDIR instruction can resolve environment variables previously set using ENV. You can only use environment variables explicitly set in the Dockerfile. For example:
ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
The output of the final pwd command in this Dockerfile would be /path/$DIRNAME
// ARG
ARG <name>[=<default value>]
The ARG instruction defines a variable that users can pass at build-time to the builder with the docker build command using the --build-arg <varname>=<value> flag. If a user specifies a build argument that was not defined in the Dockerfile, the build outputs an error.
A Dockerfile author may optionally specify a default value for an ARG instruction:
FROM busybox
ARG user1=someuser
ARG buildno=1
...
// ONBUILD
ONBUILD [INSTRUCTION]
The ONBUILD instruction adds to the image a trigger instruction to be executed at a later time, when the image is used as the base for another build. The trigger will be executed in the context of the downstream build, as if it had been inserted immediately after the FROM instruction in the downstream Dockerfile.
Specifies an instruction to be executed later, when the image is used as the base layer to another image. This can be useful for processing data that will be added in a child image (e.g., the instruction may copy in code from a chosen directory and run a build script on the data).
// STOPSIGNAL
STOPSIGNAL signal
The STOPSIGNAL instruction sets the system call signal that will be sent to the container to exit. This signal can be a valid unsigned number that matches a position in the kernel’s syscall table, for instance 9, or a signal name in the format SIGNAME, for instance SIGKILL.
// HEALTHCHECK
The HEALTHCHECK instruction has two forms:
HEALTHCHECK [OPTIONS] CMD command (check container health by running a command inside the container)
HEALTHCHECK NONE (disable any healthcheck inherited from the base image)
The HEALTHCHECK instruction tells Docker how to test a container to check that it is still working. This can detect cases such as a web server that is stuck in an infinite loop and unable to handle new connections, even though the server process is still running.
The HEALTHCHECK feature was added in Docker 1.12.
// docker port CONTAINER [PRIVATE_PORT[/PROTO]]
List port mappings or a specific mapping for the container
// create mysqldata volume and master mysql server
# docker create --name mysqldata mysql:5.7.13 echo "Data-only container for MySQL 5.7.13"
# docker run -d --volumes-from mysqldata --name mysql-master --hostname mysql-master -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7.13
// commandline set environment varilbles
# docker run -e var1=123 -e var2=456 -e var3=789 centos /usr/bin/env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=28d9eb74edac
var1=123
var2=456
var3=789
HOME=/root
// docker run --help
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container
-a, --attach=[] Attach to STDIN, STDOUT or STDERR
--add-host=[] Add a custom host-to-IP mapping (host:ip)
#docker run -it --add-host="orhandogan.net:78.46.71.9" ubuntu cat /etc/hosts
#docker run -it --add-host "orhandogan.net:78.46.71.9" ubuntu cat /etc/hosts
#docker run -it --add-host "orhandogan.net:78.46.71.9" --add-host "mail.odbh.net:192.168.5.10" ubuntu cat /etc/hosts
--blkio-weight=0 Block IO (relative weight), between 10 and 1000. Defautlt 500
# docker run -it --name c1 --blkio-weight 250 ubuntu:14.04 /bin/bash
# docker run -it --name c2 --blkio-weight 1000 ubuntu:14.04 /bin/bash
# time dd if=/dev/zero of=test.out bs=4M count=1024 oflag=direct
-c, --cpu-shares=0 CPU shares (relative weight 1--1024) Default:1024
--cap-add=[] Add Linux capabilities
--cap-drop=[] Drop Linux capabilities
--cgroup-parent= Optional parent cgroup for the container
--cidfile= Write the container ID to the file
--cpu-period=0 Limit CPU CFS (Completely Fair Scheduler) period
--cpu-quota=0 Limit the CPU CFS quota
--cpuset-cpus= CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems= MEMs in which to allow execution (0-3, 0,1)
-d, --detach=false Run container in background and print container ID
--device=[] Add a host device to the container
docker run --device=/dev/snd:/dev/snd ...
--dns=[] Set custom DNS servers
--dns-search=[] Set custom DNS search domains
-e, --env=[] Set environment variables
--entrypoint= Overwrite the default ENTRYPOINT of the image
--env-file=[] Read in a file of environment variables
--expose=[] Expose a port or a range of ports
-h, --hostname= Container host name
--help=false Print usage
-i, --interactive=false Keep STDIN open even if not attached
--ipc= IPC namespace to use
-l, --label=[] Set meta data on a container
--label-file=[] Read in a line delimited file of labels
--link=[] Add link to another container
--log-driver= Logging driver for container
--log-opt=[] Log driver options
--lxc-conf=[] Add custom lxc options
-m, --memory= Memory limit
--mac-address= Container MAC address (e.g. 92:d0:c6:0a:29:33)
--memory-swap= Total memory (memory + swap), '-1' to disable swap
--name= Assign a name to the container
--net=bridge Set the Network mode for the container
--oom-kill-disable=false Disable OOM Killer
-P, --publish-all=false Publish all exposed ports to random ports
-p, --publish=[] Publish a container's port(s) to the host
--pid= PID namespace to use
--privileged=false Give extended privileges to this container
--read-only=false Mount the container's root filesystem as read only
--restart=no Restart policy to apply when a container exits
--rm=false Automatically remove the container when it exits
--security-opt=[] Security Options
--sig-proxy=true Proxy received signals to the process
-t, --tty=false Allocate a pseudo-TTY
-u, --user= Username or UID (format: <name|uid>[:<group|gid>])
--ulimit=[] Ulimit options
--uts= UTS namespace to use
-v, --volume=[] Bind mount a volume
--volumes-from=[] Mount volumes from the specified container(s)
-w, --workdir= Working directory inside the container
// docker attach [OPTIONS] CONTAINER
# ID=$(docker run -d centos sh -c "while true; do echo 'orhandogan.net'; sleep 1; done;")
# docker attach $ID
orhandogan.net
orhandogan.net
orhandogan.net
orhandogan.net
// Docker Commands
usage: docker #command#
Help: docker help
attach Attach to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders from a container's filesystem to the host path
create Create a new container
diff Inspect changes on a container's filesystem
events Get real time events from the server
exec Run a command in a running container
export Stream the contents of a container as a tar archive
history Show the history of an image
images List images
import Create a new filesystem image from the contents of a tarball
info Display system-wide information
inspect Return low-level information on a container or image
kill Kill a running container
load Load an image from a tar archive
login Register or log in to a Docker registry server
logout Log out from a Docker registry server
logs Fetch the logs of a container
pause Pause all processes within a container
port Lookup the public-facing port that is NAT-ed to PRIVATE_PORT
ps List containers
pull Pull an image or a repository from a Docker registry server
push Push an image or a repository to a Docker registry server
rename Rename an existing container
restart Restart a running container
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save an image to a tar archive
search Search for an image on the Docker Hub
start Start a stopped container
stats Display a stream of a containers' resource usage statistics
stop Stop a running container
tag Tag an image into a repository
top Lookup the running processes of a container
unpause Unpause a paused container
version Show the Docker version information
wait Block until a container stops, then print its exit code
////////////////////////////////////////////////////////////////////////////////////////////////////
/// Notes starting from 2016-11-28 ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
// un a container forever, and use it later with docker exec
# ID=(docker run -d ubuntu sh -c “while true; do sleep 1; done;”)
# docker exec $ID echo “hellooop :)”
# docker exec $ID ps -aux
# docker exec -ti $ID /bin/bash
// docker commit: Creates an image from the specified container.
# ID=$(docker run -d redis touch /orhan-file)
# docker commit -a “My author orhan doğan” -m “hello comment” $ID odredis:testcommit
# docker images odredis
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
odredis testcommit a84244687aa3 About a minute ago 182.9 MB
// docker tag : Associates a repository and tag name with an image.
# docker tag faa2b75ce09a newname
# docker tag newname:latest amouat/newname
# docker tag newname:latest amouat/newname:newtag
# docker tag newname:latest orhanregistry.com:5000/newname:newtag
// You want to share your container’s bash history with your host’s history.
# docker run -e HOST_FILE=/root/.bash_history -v=$HOME/.bash_history:/root/.bash_history -ti ubuntu /bin/bash
DOCKER 102 - SOFTWARE LIFECYCLE WITH DOCKER
//
#
//
#
//
#
//
#
//
#
//
#
//
#
//
#
//
#
//
#
//
#
//
#
//
#
//
#
//
#
//
#
//
#
//
#