{"id":12264,"date":"2018-11-29T11:35:23","date_gmt":"2018-11-29T16:35:23","guid":{"rendered":"http:\/\/jianmingli.com\/wp\/?p=12264"},"modified":"2022-09-07T12:46:52","modified_gmt":"2022-09-07T17:46:52","slug":"docker","status":"publish","type":"post","link":"https:\/\/jianmingli.com\/wp\/?p=12264","title":{"rendered":"Docker"},"content":{"rendered":"<div class='toc wptoc'>\n<h2>Contents<\/h2>\n<ol class='toc-odd level-1'>\n\t<li>\n\t\t<a href=\"#Online_Playground\">Online Playground<\/a>\n\t<\/li>\n\t<li>\n\t\t<a href=\"#Overview\">Overview<\/a>\n\t\t<ol class='toc-even level-2'>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Docker_Advantages\">Docker Advantages<\/a>\n\t\t\t<\/li>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Windows_Docker_Containers\">Windows Docker Containers<\/a>\n\t\t\t<\/li>\n\t\t<\/ol>\n\t<li>\n\t\t<a href=\"#Install_Docker_Engine_CE\">Install Docker Engine CE<\/a>\n\t\t<ol class='toc-even level-2'>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Ubuntu_Manual_Install\">Ubuntu Manual Install<\/a>\n\t\t\t<\/li>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Download_and_Install_Docker_Image\">Download and Install Docker Image<\/a>\n\t\t\t<\/li>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Docker_Lifecycle_Commands\">Docker Lifecycle Commands<\/a>\n\t\t\t<\/li>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Troubleshooting\">Troubleshooting<\/a>\n\t\t\t<\/li>\n\t\t<\/ol>\n\t<li>\n\t\t<a href=\"#Manage_Docker_Containers\">Manage Docker Containers<\/a>\n\t\t<ol class='toc-even level-2'>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Terms\">Terms<\/a>\n\t\t\t\t<ol class='toc-odd level-3'>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Docker_Image\">Docker Image<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Docker_Container\">Docker Container<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Docker_Registry\">Docker Registry<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t<\/ol>\n<\/ol>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Building_Images_using_Dockerfile\">Building Images using Dockerfile<\/a>\n\t\t\t\t<ol class='toc-even level-2'>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Example\">Example<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Dockfile_Instructions\">Dockfile Instructions<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t<\/ol>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Publishing_Images\">Publishing Images<\/a>\n\t\t\t\t<ol class='toc-even level-2'>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Docker_Hub\">Docker Hub<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Private_Docker_Infrastructure\">Private Docker Infrastructure<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Docker_Registry_1\">Docker Registry<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t<\/ol>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Sharing_Data_with_Container\">Sharing Data with Container<\/a>\n\t\t\t\t<ol class='toc-even level-2'>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Data_Volume\">Data Volume<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Volume_Management\">Volume Management<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Sharing_Host_Data\">Sharing Host Data<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t<\/ol>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Sharing_Data_Between_Containers\">Sharing Data Between Containers<\/a>\n\t\t\t\t<ol class='toc-even level-2'>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Data_Only_Container\">Data Only Container<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Pit_Falls\">Pit Falls<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t<\/ol>\n\t\t\t<li>\n\t\t\t\t<a href=\"#Container_Orchestration\">Container Orchestration<\/a>\n\t\t\t\t<ol class='toc-even level-2'>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Internal_DNS\">Internal DNS<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Linking_Containers\">Linking Containers<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Container_Orchestration_with_docker-compose\">Container Orchestration with docker-compose<\/a>\n\t\t\t\t\t<\/li>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#Example_1\">Example<\/a>\n\t\t\t\t\t\t<ol class='toc-odd level-3'>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a href=\"#Files\">Files<\/a>\n\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a href=\"#Commands\">Commands<\/a>\n\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t<\/ol>\n<\/ol>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a href=\"#References\">References<\/a>\n\t\t\t\t\t<\/li>\n<\/ol>\n<\/ol>\n<\/div>\n<div class='wptoc-end'>&nbsp;<\/div>\n<span id=\"Online_Playground\"><h2>Online Playground<\/h2><\/span>\n<p>* Play with Docker: <a href=\"https:\/\/labs.play-with-docker.com\/\">https:\/\/labs.play-with-docker.com\/<\/a><\/p>\n<span id=\"Overview\"><h2>Overview<\/h2><\/span>\n<p>* Docker leverages Linux OS features (x64\/3.10):<br \/>\n&#8211; process isolation<br \/>\n&#8211; filesystem isolation<br \/>\n* Docker editions:<br \/>\n&#8211; Docker EE (Enterprise Edition)<br \/>\n&#8211; Docker CE (Community Edition)<br \/>\n* Default port: 3275<br \/>\n* Socket file: \/var\/run\/docker.sock<\/p>\n<span id=\"Docker_Advantages\"><h3>Docker Advantages<\/h3><\/span>\n<p>* No OS virtualization for Docker means:<br \/>\n&#8211; Smaller disk footprint<br \/>\n&#8211; Faster setup\/startup\/stop time<br \/>\n&#8211; Can be pulled from repository and pushed to targets<br \/>\n&#8211; Cost savings<br \/>\n* Supports:<br \/>\n&#8211; Microservices<\/p>\n<span id=\"Windows_Docker_Containers\"><h3>Windows Docker Containers<\/h3><\/span>\n<p>* Different from Linux based containers<br \/>\n* Supported in:<br \/>\n&#8211; all versions of Windows Server 2016 (Full, Core, Nano)<br \/>\n&#8211; Windows 10 Enterprise\/Professional edtions<br \/>\n&#8211; Azure<br \/>\n* Containers can be deployed\/managed from any Docker client, e.g.<br \/>\n&#8211; command line<br \/>\n&#8211; Powershell<br \/>\n* Supports:<br \/>\n&#8211; Docker image format\/Docker API<br \/>\n* Two types:<br \/>\n&#8211; Windows Server container (on Windows Server)s<br \/>\n|- shared OS kernel<br \/>\n|- pros: performance\/efficiency<br \/>\n|- cons: weak isolation\/security<br \/>\n&#8211; Hyper-V container (on Windows Nano Server)<br \/>\n|- dedicated OS kernel\/memory<br \/>\n|- pros: strong isolation\/security<\/p>\n<span id=\"Install_Docker_Engine_CE\"><h2>Install Docker Engine CE<\/h2><\/span>\n<p>* Auto install script:<\/p>\n<pre lang=\"bash\">\r\nsudo curl -sSL https:\/\/get.docker.io\/ # -s: silent, -S: show errors, -L: location\r\nsudo wget -qO- https:\/\/get.docker.io\/ # -q: quiet, O-: output to stdout\r\n<\/pre>\n<span id=\"Ubuntu_Manual_Install\"><h3>Ubuntu Manual Install<\/h3><\/span>\n<pre lang=\"bash\">\r\n# Update repo\r\nsudo apt-get update\r\n\r\n# Add Docker repo to apt sources\r\nsudo sh -c \"echo deb https:\/\/apt.dockerproject.org\/repo \\\r\n  ubuntu-xenial main > \/etc\/apt\/sources.list.d\/docker.list\"\r\n\r\n\t# Add GPG key\r\nsudo apt-key adv --keyserver \\\r\n\t hkp:\/\/p80.pool.sks-keyservers.net:80 --recv-keys \\    \r\n\t 58118E89F3A912897C070ADBF76221572C52609D\r\n\r\n\t # Resync repo\r\nsudo apt-get update\r\n\r\n# Install Docker and start Docker service\r\nsudo apt-get install -y docker-engine\r\n\r\n# Verify install\r\nsudo docker version\r\nsudo docker info\r\n<\/pre>\n<span id=\"Download_and_Install_Docker_Image\"><h3>Download and Install Docker Image<\/h3><\/span>\n<pre lang=\"bash\">\r\n# Download and install hello-world image\r\nsudo docker pull hello-world\r\n\r\n# Show\/verify install\/images\r\nsudo docker images\r\n\r\n# Run hello-world image\r\ndocker run hello-world\r\n\r\n# Download\/install\/Run ubuntu in interactive mode\r\ndocker run -it ubuntu bash\r\n<\/pre>\n<span id=\"Docker_Lifecycle_Commands\"><h3>Docker Lifecycle Commands<\/h3><\/span>\n<pre lang=\"bash\">\r\n# List docker processes\r\ndocker ps -a\r\n\r\nCONTAINER ID        IMAGE               COMMAND             CREATED             STATUS          PORTS               NAMES\r\n16d1621a6ceb        ubuntu              \"bash\"              3 minutes ago       Exited (0) 6 seconds ago            happy_tesla\r\n\r\n# Start by ID\r\nsudo docker start 16d1621a6ceb\r\n\r\n# Start by Name\r\nsudo docker start happy_tesla\r\n\r\n# Attach\r\nsudo docker attach id\/name\r\n\r\n# Detach:\r\nCtrlP + CtrlQ\r\n\r\n# Start but remove when state is exited\r\nsudo docker run -it --rm ubuntu:16.04 \/bin\/bash\r\n\r\n# Restart\r\nsudo docker restart id\/name\r\n\r\n# Pause\r\nsudo docker pause id\/name\r\n\r\n# UnPause\r\nsudo docker unpause id\/name\r\n\r\n# Remove docker image\r\nsudo docker rm id\/name\r\n\r\n# Remove all stoped images\r\nsudo docker rm $(sudo docker ps -aq -f status=exited)\r\nsudo docker container prune\r\n\r\n<\/pre>\n<span id=\"Troubleshooting\"><h3>Troubleshooting<\/h3><\/span>\n<pre lang=\"bash\">\r\n# Check status\r\nsudo service docker status\r\n\r\n# Restart Docker\r\nsudo service docker restart\r\n\r\n# Extract Docker log\r\njournalctl -u docker\r\n\r\n# List Docker processes\r\nsudo docker ps\r\nsudo docker ps -a\r\n<\/pre>\n<span id=\"Manage_Docker_Containers\"><h2>Manage Docker Containers<\/h2><\/span>\n<span id=\"Terms\"><h3>Terms<\/h3><\/span>\n<span id=\"Docker_Image\"><h4>Docker Image<\/h4><\/span>\n<p>* Docker image is:<br \/>\n&#8211; a collection of all the files that make up an executable software app (compare to dll and jar files for software but at app level)<br \/>\n&#8211; readonly template (compare to Java class)<br \/>\n* Includes:<br \/>\n&#8211; libraries<br \/>\n&#8211; binaries<br \/>\n&#8211; other dependencies<br \/>\n* Capabilities can be added as layers to existing image<\/p>\n<span id=\"Docker_Container\"><h4>Docker Container<\/h4><\/span>\n<p>* Running instance of a Docker image (compare to Java class instance)<br \/>\n&#8211; A writeable layer is added on top of the image to maintain the app state<\/p>\n<span id=\"Docker_Registry\"><h4>Docker Registry<\/h4><\/span>\n<p>* Images can be pushed to or pulled from registry<br \/>\n* Can be public or private<br \/>\n* Example registries:<br \/>\n&#8211; Docker Hub: index.docker.io<br \/>\n&#8211; Quay<br \/>\n&#8211; Google Container Registry<br \/>\n&#8211; AWS Container Registry<\/p>\n<p>* Search for an image<\/p>\n<pre lang=\"bash\">\r\nsudo docker search mysql | head -10\r\n<\/pre>\n<p>* Pull an image<\/p>\n<pre lang=\"bash\">\r\n# Pull busybox image from Docker Hub\r\nsudo docker pull busybox\r\n\r\n# Pull version 1.2 of busybox image from Docker Hub\r\nsudo docker pull busybox:1.2\r\n\r\n# Pull version 1.2 of busybox image from Docker Hub under developer named dockerguy\r\nsudo docker pull dockerguy\/busybox:1.2\r\n\r\n# Pull version 1.2 of busybox image from my local registry\r\nsudo docker pull registry.mylocal.com\/busybox:1.2\r\n\r\n# Examing pulled image\r\nsudo docker images\r\n\r\n# You can diff images\r\nsudo docker diff id\/name\r\n\r\n# Commit image\r\nsudo docker commit id mydocker\/ubuntu_wget # Don't use\r\n\r\n<\/pre>\n<p>* Run image in interactive mode<\/p>\n<pre lang=\"bash\">\r\n-a=[]           : Attach to `STDIN`, `STDOUT` and\/or `STDERR`\r\n-t              : Allocate a pseudo-tty\r\n--sig-proxy=true: Proxy all received signals to the process (non-TTY mode only)\r\n-i              : Keep STDIN open even if not attached\r\n<\/pre>\n<p>&#8211; Example:<\/p>\n<pre lang=\"bash\">\r\n# Run Ubuntu image in interactive mode\r\nsudo docker run -it ubunbu:16.04 # -i: interactive, -t: terminal emulation\r\n\r\n# Detach from interactive session with CtrlP + CtrlQ\r\n\r\n# Attach back into interactive session\r\nsudo docker attach id\/name\r\n\r\n# Terminate Docker container with exit command\r\n<\/pre>\n<p>* Run image in detached mode<\/p>\n<pre lang=\"bash\">\r\nsudo docker run -d ubuntu\r\n<\/pre>\n<span id=\"Building_Images_using_Dockerfile\"><h2>Building Images using Dockerfile<\/h2><\/span>\n<span id=\"Example\"><h3>Example<\/h3><\/span>\n<p>* Create a file named: Dockerfile<\/p>\n<pre lang=\"bash\">\r\nFROM busybox:latest\r\nCMD echo Hello World!!\r\n<\/pre>\n<p>* Build using Dockerfile file in current directory with name busybox2<\/p>\n<pre lang=\"bash\">\r\nsudo docker build -t mybusybox . \r\n<\/pre>\n<span id=\"Dockfile_Instructions\"><h3>Dockfile Instructions<\/h3><\/span>\n<p>* Specify escaple character, default is \\<\/p>\n<pre lang=\"bash\">\r\n# escape=' \r\n<\/pre>\n<p>* FROM<\/p>\n<pre lang=\"bash\">\r\nFROM <image>[:<tag>|@<digest>]\r\n\r\n# Examples\r\nFROM centos\r\nFROM ubuntu:16.04\r\nFROM ubuntu@sha256:xxxxxx\r\n<\/pre>\n<p>* MAINTAINER<\/p>\n<pre lang=\"bash\">\r\nMAINTAINER <author's detail>\r\n\r\n# Example\r\nMAINTAINER Jimmy LI <jimmy@yahoo.com>\r\n<\/pre>\n<p>* COPY<\/p>\n<pre lang=\"bash\">\r\nCOPY <src> ... <dst>\r\n\r\n# Examples\r\nCOPY html \/var\/www\/html\r\n<\/pre>\n<p>* ADD<br \/>\n&#8211; handles tar and remote files in addition to copy<\/p>\n<pre lang=\"java\">\r\nADD <src> ... <dst>\r\n\r\ne.g.\r\nADD web-page-config.tar \/\r\n<\/pre>\n<pre lang=\"bash\">\r\n# ENV: sets env var\r\nENV DEBUG_LVL 3 \r\nENV APACHE_LOG_DIR \/var\/log\/apache\r\n\r\n# ARG: defines build arguments\r\nARG usr \r\nARG uid=1000\r\n#Usage: docker build --build-arg usr=app --build-arg uid=100 .\r\nARG BUILD_VERSION \r\n#Usage: LABEL com.example.app.build_version=${BUILD_VERSION} \r\n\r\n# USER: setup startup user ID or username\r\n#USER <UID>|<UName> \r\nUSER 73\r\n\r\n# WORKDIR: setup working dir\r\nWORKDIR \/var\/log\r\n\r\n# VOLUME\r\nVOLUME [\"<mountpoint>\"]\r\nVOLUME <mountpoint>\r\n\r\n# EXPOSE: opens up a container network port\r\n# Defaults to TCP port\r\nEXPOSE 7373\/udp 8080\r\n\r\n# LABEL\r\nLABEL org.label-schema.schema-version=\"1.0\"  \r\n      org.label-schema.version=\"2.0\"  \r\n      org.label-schema.description=\"Learning Docker Example\"\r\n\r\n# RUN: executed during build process\r\nRUN apt-get update && \\ \r\n\t\tapt-get install -y apache2 && \\\r\n\t\tapt-get clean \r\n\r\n# CMD: executed when container is launched\r\nCMD [\"echo\", \"Dockerfile CMD demo\"]\r\n\r\n# ENTRYPOINT: \r\n# - executed when container is launched\r\n# - container is terminated when command stops\r\nENTRYPOINT [\"echo\", \"Dockerfile ENTRYPOINT demo\"]\r\n\r\n# HEALTHCHECK\r\n# - runs health check command\r\n# HEALTHCHECK [<options>] CMD <command> \r\nHEALTHCHECK --interval=5m --timeout=3s  \r\n  CMD curl -f http:\/\/localhost\/ || exit 1\r\nHEALTHCHECK NONE \r\n\r\n# ONBUILD\r\n# - triggered at next build\r\n#ONBUILD <INSTRUCTION>\r\nONBUILD ADD config \/etc\/appconfig\r\n\r\n# STOPSIGNAL\r\n#STOPSIGNAL <signal>\r\n\r\n# SHELL\r\n# - overrides the default shell\r\n# SHELL [\"<shell>\", \"<arg-1>\", ..., \"<arg-n>\"]\r\n\r\n\r\n<\/pre>\n<p>* .dockerignore file<\/p>\n<pre lang=\"bash\">\r\n# Ignore .git directory and all files ending with .tmp\r\n.git \r\n*.tmp \r\n<\/pre>\n<p>* Check image history<\/p>\n<pre lang=\"bash\">\r\nsudo docker history apache2\r\n<\/pre>\n<p>* Best practices for writing a Dockerfile:<br \/>\nhttps:\/\/docs.docker.com\/articles\/dockerfile_best-practices\/.<\/p>\n<span id=\"Publishing_Images\"><h2>Publishing Images<\/h2><\/span>\n<span id=\"Docker_Hub\"><h3>Docker Hub<\/h3><\/span>\n<p>* Can be used for:<br \/>\n&#8211; public<br \/>\n&#8211; private<br \/>\n* Features:<br \/>\n&#8211; image repo<br \/>\n&#8211; user auth<br \/>\n&#8211; manage org and groups<br \/>\n&#8211; auto image build<br \/>\n&#8211; integrate with GibHub and Bitbucket<br \/>\n* URL: https:\/\/hub.docker.com<br \/>\n&#8211; Docker ID: jxxliextpie1<br \/>\n* Automate build process for images<br \/>\n* Local repo<br \/>\n&#8211; see ref: https:\/\/github.com\/docker\/docker-registry<br \/>\n* Supports REST API<\/p>\n<span id=\"Private_Docker_Infrastructure\"><h3>Private Docker Infrastructure<\/h3><\/span>\n<span id=\"Docker_Registry_1\"><h3>Docker Registry<\/h3><\/span>\n<p>* Listening on: TCP 5000<br \/>\n* Storage path: \/var\/lib\/registry<br \/>\n* Install and start registry<\/p>\n<pre lang=\"bash\">\r\n# Start\r\nsudo docker run -d -p 5000:5000 \\\r\n--restart=always --name registry registry:2\r\n\r\n# Check\r\nsudo docker ps -a\r\n<\/pre>\n<p>* Get and tag an image<\/p>\n<pre lang=\"bash\">\r\n# Get image\r\nsudo docker pull hello-world\r\n\r\n# Tag image\r\nsudo docker tag hello-world localhost:5000\/hello-world\r\n<\/pre>\n<p>* Push image<\/p>\n<pre lang=\"bash\">\r\nsudo docker push localhost:5000\/hello-world\r\n<\/pre>\n<p>* Pull image<\/p>\n<pre lang=\"bash\">\r\nsudo docker pull localhost:5000\/hello-world\r\n<\/pre>\n<p>* Stop and delete registry<\/p>\n<pre lang=\"bash\">\r\nsudo docker stop registry  && sudo docker rm -v registry\r\n<\/pre>\n<p>* Restart registry<\/p>\n<pre lang=\"bash\">\r\nsudo docker run -d -p 5000:5000 --restart=always --name registry -v `pwd`\/data:\/var\/lib\/registry registry:2\r\n<\/pre>\n<span id=\"Sharing_Data_with_Container\"><h2>Sharing Data with Container<\/h2><\/span>\n<p>* Data persistence approaches:<br \/>\n&#8211; use volumes created using Docker&#8217;s volume management<br \/>\n&#8211; mount host directory inside container<br \/>\n&#8211; use data-only container<\/p>\n<span id=\"Data_Volume\"><h3>Data Volume<\/h3><\/span>\n<p>* Mount data volume manually<\/p>\n<pre lang=\"bash\">\r\ndocker run -v \/datavol -it ubuntu:16.04\r\n<\/pre>\n<p>* Or create Dockerfile and specify a data volume:<\/p>\n<pre lang=\"bash\">\r\nFROM ubuntu:16.04\r\nVOLUME \/datavol\r\n<\/pre>\n<p>* Build image<\/p>\n<pre lang=\"bash\">\r\ndocker build -t datavol1 .\r\n<\/pre>\n<p>* Check<\/p>\n<pre lang=\"bash\">\r\ndocker inspect datavol1\r\n<\/pre>\n<p>* Test run<\/p>\n<pre lang=\"bash\">\r\ndocker run --rm -it datavol1\r\n\r\n# List datavol1\r\nls -ld \/datavol\r\ndrwxr-xr-x 2 root root 6 Apr 10 18:32 \/datavol\r\n\r\n# Check mount\r\nmount|grep datavol\r\n\/dev\/sdb on \/datavol type xfs (rw,relatime,attr2,inode64,prjquota)\r\n\r\n# Check host dir\r\ndocker inspect -f '{{json .Mounts}}' 52c437babf62\r\n\r\n{\"Type\":\"volume\",\"Name\":\"15a7fecfbca850863cbfa61e679d9b33bf765c1087ddf621115ee82da4ab545a\",\"Source\":\"\/var\/lib\/docker\/volumes\/15a7fecfbca850863cbfa61e679d9b33bf765c1087ddf621115ee82da4ab545a\/_data\",\"Destination\":\"\/datavol\",\"Driver\":\"local\",\"Mode\":\"\",\"RW\":true,\"Propagation\":\"\"}]\r\n<\/pre>\n<p>* Remove host directory for associtated volume when shutting down container<\/p>\n<pre lang=\"bash\">\r\ndocker rm -v 52c437babf62\r\n\r\n# Force removal of volume when removing container\r\ndocker rm -fv 52c437babf62\r\n<\/pre>\n<span id=\"Volume_Management\"><h3>Volume Management<\/h3><\/span>\n<p>* Volume plugins:<br \/>\nhttps:\/\/docs.docker.com\/engine\/extend\/legacy_plugins\/#volume-plugins<br \/>\n* docker volume<\/p>\n<pre lang=\"bash\">\r\n# Create a volume named datavol2\r\ndocker volume create --name datavol2\r\n\r\n# List volumes\r\ndocker volume list\r\n\r\n# Inspect volumes\r\ndocker volume inspect datavol2\r\n\r\n[\r\n    {\r\n        \"CreatedAt\": \"2018-04-10T19:05:30Z\",\r\n        \"Driver\": \"local\",\r\n        \"Labels\": {},\r\n        \"Mountpoint\": \"\/var\/lib\/docker\/volumes\/datavol2\/_data\",\r\n        \"Name\": \"datavol2\",\r\n        \"Options\": {},\r\n        \"Scope\": \"local\"\r\n    }\r\n]\r\n\r\n# Remove volume\r\ndocker volume rm datavol2\r\n<\/pre>\n<span id=\"Sharing_Host_Data\"><h3>Sharing Host Data<\/h3><\/span>\n<p>* docker run -v options:<\/p>\n<pre lang=\"bash\">\r\n-v <container mount path>\r\n-v <host path>:<container mount path>\r\n-v <host path>:<container mount path>:<read write mode>\r\n-v <volume name>:<container mount path>\r\n-v <volume name>:<container mount path>:<read write mode>\r\n<\/pre>\n<p>* Example, mount host \/datavol as \/datavol inside container:<\/p>\n<pre lang=\"bash\">\r\ndocker run -v \/datavol:\/datavol -it ubuntu:16.04\r\n<\/pre>\n<span id=\"Sharing_Data_Between_Containers\"><h2>Sharing Data Between Containers<\/h2><\/span>\n<p>* Use run &#8211;volume-from option:<br \/>\n&#8211;volumes-from=&#8221;&#8221;: Mount all volumes from the given container(s)<\/p>\n<span id=\"Data_Only_Container\"><h3>Data Only Container<\/h3><\/span>\n<p>* Launch a busybox image as a data only container<br \/>\n&#8211; container in stopped state<\/p>\n<pre lang=\"bash\">\r\ndocker run --name datavol -v \/DataMount busybox:latest \/bin\/true\r\n<\/pre>\n<p>* Launch an ubuntu image and mount all volumes from datavol container<\/p>\n<pre lang=\"bash\">\r\ndocker run -it --volumes-from datavol ubuntu:latest \/bin\/bash\r\n<\/pre>\n<span id=\"Pit_Falls\"><h3>Pit Falls<\/h3><\/span>\n<p>* Directory leaks<br \/>\n&#8211; always inspect images for data volumes<br \/>\n&#8211; always use docker rm -v option to remove any data volume created for the container<br \/>\n&#8211; keep a log of data volumes to keep<br \/>\n* Don&#8217;t use data volume as a storage during the build process<\/p>\n<span id=\"Container_Orchestration\"><h2>Container Orchestration<\/h2><\/span>\n<span id=\"Internal_DNS\"><h3>Internal DNS<\/h3><\/span>\n<p>* Container DNS: 127.0.0.11<\/p>\n<p>* Create a network bridge<br \/>\ndocker network create mybridge<br \/>\ndocker network inspect mybridge<br \/>\n* Launch a container using mybridge<br \/>\ndocker container run -itd &#8211;net mybridge &#8211;name testdns ubuntu<br \/>\n&#8211; Check network setup<br \/>\ndocker container inspect &#8211;format &#8216;{{.NetworkSettings.Networks.mybridge.IPAddress}}&#8217; testdns<br \/>\ndocker container exec testdns cat \/etc\/resolv.conf<\/p>\n<p>* Ping from another container<br \/>\ndocker container run &#8211;rm &#8211;net mybridge busybox ping -c 2 testdns<\/p>\n<span id=\"Linking_Containers\"><h3>Linking Containers<\/h3><\/span>\n<span id=\"Container_Orchestration_with_docker-compose\"><h3>Container Orchestration with docker-compose<\/h3><\/span>\n<p>* docker-compose file: docker-compose.yml<br \/>\n&#8211; see <a href='https:\/\/docs.docker.com\/compose\/compose-file\/'>Compose file version 3 reference<\/a><\/p>\n<pre lang=\"xml\">\r\nversion: \"<version>\" \r\nservices: \r\n  <service>: \r\n    <key>: <value> \r\n    <key>: \r\n       - <value> \r\n       - <value> \r\nnetworks: \r\n  <network>: \r\n    <key>: <value> \r\n\r\nvolumes: \r\n  <volume>: \r\n    <key>: <value> \r\n<\/pre>\n<p>* docker-compose command<br \/>\n&#8211; see <a href='https:\/\/docs.docker.com\/compose\/reference\/overview\/'>here<\/a><\/p>\n<pre lang=\"bash\">\r\ndocker-compose [<options>] <command> [<args>...]\r\n<\/pre>\n<span id=\"Example_1\"><h3>Example<\/h3><\/span>\n<span id=\"Files\"><h4>Files<\/h4><\/span>\n<p>* <a href='https:\/\/github.com\/thedocker\/learning-docker\/blob\/master\/chap08\/orchestrate-using-compose\/Dockerfile'>Dockerfile<\/a><\/p>\n<pre lang=\"bash\">\r\nFROM node:latest\r\nRUN npm install redis\r\nADD example.js \/myapp\/example.js \r\n<\/pre>\n<p>* <a href='https:\/\/github.com\/thedocker\/learning-docker\/blob\/master\/chap08\/orchestrate-using-compose\/docker-compose.yml'>docker-compose.yml<\/a><\/p>\n<pre lang=\"bash\">\r\nversion: \"3.1\"\r\nservices:\r\n  web:\r\n    build: .\r\n    command: node \/myapp\/example.js\r\n    depends_on:\r\n    - redis\r\n    ports:\r\n    - 8080:80\r\n  redis:\r\n    image: redis:latest\r\n<\/pre>\n<p>* <a href='https:\/\/github.com\/thedocker\/learning-docker\/blob\/master\/chap08\/orchestrate-using-compose\/example.js'>example.js<\/a><\/p>\n<pre lang=\"bash\">\r\n\/\/ A Simple Request\/Response web application\r\n\r\n\/\/ Load all required libraries\r\nvar http = require('http');\r\nvar url = require('url');\r\nvar redis = require('redis');\r\n\r\n\/\/ Connect to redis server running\r\n\/\/ createClient API is called with\r\n\/\/  -- 6379, a well-known port to which the\r\n\/\/           redis server listens to\r\n\/\/  -- redis, is the name of the service (container)\r\n\/\/            that runs redis server\r\nvar client = redis.createClient(6379, 'redis');\r\n\r\n\/\/ Set the key value pair in the redis server\r\n\r\n\/\/ Here all the keys proceeds with \"\/\", because\r\n\/\/ URL parser always have \"\/\" as its first character\r\nclient.set(\"\/\", \"Welcome to Docker-Compose helper\\nEnter the docker-compose command in the URL for help\\n\", redis.print);\r\nclient.set(\"\/build\", \"Build or rebuild services\", redis.print);\r\nclient.set(\"\/kill\", \"Kill containers\", redis.print);\r\n\r\nvar server = http.createServer(function (request, response) {\r\n  var href = url.parse(request.url, true).href;\r\n  response.writeHead(200, {\"Content-Type\": \"text\/plain\"});\r\n\r\n  \/\/ Pull the response (value) string using the URL\r\n  client.get(href, function (err, reply) {\r\n    if ( reply == null ) response.write(\"Command: \" + href.slice(1) + \" not supported\\n\");\r\n    else response.write(reply + \"\\n\");\r\n    response.end();\r\n  });\r\n});\r\n\r\nconsole.log(\"Listening on port 80\");\r\nserver.listen(80);\r\n<\/pre>\n<span id=\"Commands\"><h4>Commands<\/h4><\/span>\n<pre lang=\"bash\">\r\ncd exmaple\r\ndocker-compose build\r\ndocker-compose pull\r\ndocker-compose up\r\n<\/pre>\n<span id=\"References\"><h2>References<\/h2><\/span>\n<p>* Learning Docker &#8211; Second Edition by Jeeva S. Chelladhurai; Pethuru Raj; Vinod Singh<br \/>\n* <a href='https:\/\/docs.docker.com\/engine\/reference\/run\/#general-form'>Docker run reference<\/a><br \/>\n* <a href='https:\/\/labs.play-with-docker.com\/'>Play with Docker<\/a> <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Online Playground * Play with Docker: https:\/\/labs.play-with-docker.com\/ Overview * Docker leverages Linux OS features (x64\/3.10): &#8211; process isolation &#8211; filesystem isolation * Docker editions: &#8211; Docker EE (Enterprise Edition) &#8211; Docker CE (Community Edition) * Default port: 3275 * Socket &hellip; <a href=\"https:\/\/jianmingli.com\/wp\/?p=12264\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[798],"tags":[799],"class_list":["post-12264","post","type-post","status-publish","format-standard","hentry","category-docker","tag-docker"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/s8cRUO-docker","_links":{"self":[{"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/posts\/12264","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=12264"}],"version-history":[{"count":5,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/posts\/12264\/revisions"}],"predecessor-version":[{"id":12269,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/posts\/12264\/revisions\/12269"}],"wp:attachment":[{"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=12264"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=12264"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=12264"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}