{"id":91989,"date":"2020-07-27T15:00:00","date_gmt":"2020-07-27T12:00:00","guid":{"rendered":"https:\/\/examples.javacodegeeks.com\/?p=91989"},"modified":"2020-07-27T13:30:11","modified_gmt":"2020-07-27T10:30:11","slug":"docker-best-practices-tutorial","status":"publish","type":"post","link":"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/","title":{"rendered":"Docker Best Practices Tutorial"},"content":{"rendered":"<p>This tutorial talks about various best practices and examples around the docker containers. <\/p>\n<h2 class=\"wp-block-heading\">1. Introduction<\/h2>\n<p>Docker containers are an essential part of containerization as we moved towards cloud-native applications. Since it is going to massive implementation of containers, it is vital to follow certain best practices based on our past experience, to bring out qualitative containers. The best practices for the docker are around the below classifications:<\/p>\n<ul class=\"wp-block-list\">\n<li>Dockerfile best practices<\/li>\n<li>Docker security best practices<\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">2. Dockerfile best practices<\/h2>\n<h3 class=\"wp-block-heading\">2.1 Keep in mind the caching and the layers<\/h3>\n<p>This section explains the tricks which make your builds lightweight using caching mechanisms. You need to write the Dockerfile in an efficient way to support appropriate caching. Each time the docker builds, it caches layers of the images. However, when it encounters the COPY\/ADD instructions and if the folder or files under the operation have changed then it invalidates the caches the docker builds all the layer thereafter.<\/p>\n<p>Check this example. Here ADD comes after FROM instruction. Let us run <code>mvn clean install<\/code> and then <code>docker build . --file Dockerfile.wrong_order --tag jcg_example:0.0.1<\/code>. Now without running the mvn install command again run the docker build command. It will not take much time as the earlier build.<\/p>\n<p>However, run the install once again and then the docker build command, it would take the same time as new. That is because, the ADD jar file in the ADD command has changed and hence has invalidated the cache.<\/p>\n<p><span style=\"text-decoration: underline\"><em>Dockefile.wrong_order<\/em><\/span><\/p>\n<pre class=\"brush:bash\">FROM ubuntu:18.04\n\nADD target\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar java-docker.jar\n\nRUN apt-get update\nRUN apt-get install -y openjdk-8-jdk\n\nCMD [\"java\", \"-jar\", \"java-docker.jar\"]\n<\/pre>\n<p>Download the code and compile the java code using the instructions given in section 5, below. Execute the below command to generate an example image with version 0.0.1.<\/p>\n<pre class=\"brush:bash\">time docker build . --file Dockerfile.wrong_order --tag jcg_example:0.0.1\n\n# Run Maven clean install again\nmvn clean install\n\n# Run docker image again\ntime docker build . --file Dockerfile.wrong_order --tag jcg_example:0.0.1<\/pre>\n<p>Sample Output:<\/p>\n<pre class=\"brush:bash\">time docker build . --file Dockerfile.wrong_order --tag jcg_example:0.0.1\nSending build context to Docker daemon    128kB\nStep 1\/5 : FROM ubuntu:18.04\n ---&gt; d27b9ffc5667\nStep 2\/5 : ADD target\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar java-docker.jar\n ---&gt; 37171c094f33\nStep 3\/5 : RUN apt-get update\n ---&gt; Running in 20d2c01147c6\nGet:1 http:\/\/security.ubuntu.com\/ubuntu bionic-security InRelease [88.7 kB]\n..\n..\nStep 5\/5 : CMD [\"java\", \"-jar\", \"java-docker.jar\"]\n ---&gt; Running in 469ccf6754a2\nRemoving intermediate container 469ccf6754a2\n ---&gt; aeb0816e2cdb\nSuccessfully built aeb0816e2cdb\nSuccessfully tagged jcg_example:0.0.1\n\nreal    1m55.505s\nuser    0m0.091s\nsys     0m0.141s\n\n~\/projects\/JCGJavaWithDocker$ mvn clean install\nWARNING: An illegal reflective access operation has occurred\nWARNING: Illegal reflective access by com.google.inject.internal.cglib.core.$ReflectUtils$1 (file:\/usr\/share\/maven\/lib\/guice.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)\nWARNING: Please consider reporting this to the maintainers of com.google.inject.internal.cglib.core.$ReflectUtils$1\nWARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations\nWARNING: All illegal access operations will be denied in a future release\n[INFO] Scanning for projects...\n[INFO] \n[INFO] ---------------------------------------\n[INFO] Building JCGJavaWithDocker 1.0-SNAPSHOT\n[INFO] --------------------------------[ jar ]---------------------------------\n[INFO] \n[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ JCGJavaWithDocker ---\n[INFO] Deleting \/home\/...\/projects\/JCGJavaWithDocker\/target\n[INFO] \n[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ JCGJavaWithDocker ---\n[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!\n[INFO] Copying 1 resource\n[INFO] \n[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ JCGJavaWithDocker ---\n[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!\n[INFO] Compiling 1 source file to \/home\/...\/projects\/JCGJavaWithDocker\/target\/classes\n[INFO] \n[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ JCGJavaWithDocker ---\n[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!\n[INFO] skip non existing resourceDirectory \/home\/...\/projects\/JCGJavaWithDocker\/src\/test\/resources\n[INFO] \n[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ JCGJavaWithDocker ---\n[INFO] Nothing to compile - all classes are up to date\n[INFO] \n[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ JCGJavaWithDocker ---\n[INFO] No tests to run.\n[INFO] \n[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ JCGJavaWithDocker ---\n[INFO] Building jar: \/home\/...\/projects\/JCGJavaWithDocker\/target\/JCGJavaWithDocker-1.0-SNAPSHOT.jar\n[INFO] \n[INFO] --- maven-assembly-plugin:2.2-beta-5:single (default) @ JCGJavaWithDocker ---\n[INFO] Building jar: \/home\/...\/projects\/JCGJavaWithDocker\/target\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar\n[INFO] \n[INFO] --- maven-install-plugin:2.4:install (default-install) @ JCGJavaWithDocker ---\n[INFO] Installing \/home\/...\/projects\/JCGJavaWithDocker\/target\/JCGJavaWithDocker-1.0-SNAPSHOT.jar to \/home\/...\/.m2\/repository\/org\/example\/JCGJavaWithDocker\/1.0-SNAPSHOT\/JCGJavaWithDocker-1.0-SNAPSHOT.jar\n[INFO] Installing \/home\/...\/projects\/JCGJavaWithDocker\/pom.xml to \/home\/...\/.m2\/repository\/org\/example\/JCGJavaWithDocker\/1.0-SNAPSHOT\/JCGJavaWithDocker-1.0-SNAPSHOT.pom\n[INFO] Installing \/home\/...\/projects\/JCGJavaWithDocker\/target\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar to \/home\/...\/.m2\/repository\/org\/example\/JCGJavaWithDocker\/1.0-SNAPSHOT\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar\n[INFO] ------------------------------------------------------------------------\n[INFO] BUILD SUCCESS\n[INFO] ------------------------------------------------------------------------\n[INFO] Total time:  2.708 s\n[INFO] Finished at: 2020-07-23T12:27:55+01:00\n[INFO] ------------------------------------------------------------------------\n~\/projects\/JCGJavaWithDocker$ time docker build . --file Dockerfile.wrong_order --tag jcg_example:0.0.1\nSending build context to Docker daemon    128kB\nStep 1\/5 : FROM ubuntu:18.04\n ---&gt; d27b9ffc5667\nStep 2\/5 : ADD target\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar java-docker.jar\n ---&gt; d6274dbfcb70\nStep 3\/5 : RUN apt-get update\n ---&gt; Running in def9d44a2262\n ...\n Removing intermediate container e20b310b89f8\n ---&gt; 78c1ecdfc835\nStep 5\/5 : CMD [\"java\", \"-jar\", \"java-docker.jar\"]\n ---&gt; Running in 67c9afd2ec59\nRemoving intermediate container 67c9afd2ec59\n ---&gt; 1aff615dd35d\nSuccessfully built 1aff615dd35d\nSuccessfully tagged jcg_example:0.0.1\n\nreal    1m57.550s\nuser    0m0.041s\nsys     0m0.251s\n<\/pre>\n<p>Here is the right way of ordering the layers. In this way even we do change the compiled jar, it does not affect the build time of the docker image.<\/p>\n<p><span style=\"text-decoration: underline\"><em>Dockefile.right_order<\/em><\/span><\/p>\n<pre class=\"brush:bash\">FROM ubuntu:18.04\n\nRUN apt-get update\nRUN apt-get install -y openjdk-8-jdk\n\nADD target\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar java-docker.jar\n\nCMD [\"java\", \"-jar\", \"java-docker.jar\"]<\/pre>\n<p>Execute the below commands:<\/p>\n<pre class=\"brush:bash\"># Run Maven clean install again\nmvn clean install\n\ndocker build . --file Dockerfile.right_order --tag jcg_example:0.0.2\n\n# Run Maven clean install again\nmvn clean install\n\n# Run docker image again\ndocker build . --file Dockerfile.right_order --tag jcg_example:0.0.2\n\n# Examine it takes the lesser time as previous<\/pre>\n<p>Sample Output:<\/p>\n<pre class=\"brush:bash\">~\/projects\/JCGJavaWithDocker$ mvn clean install\nWARNING: An illegal reflective access operation has occurred\nWARNING: Illegal reflective access by com.google.inject.internal.cglib.core.$ReflectUtils$1 (file:\/usr\/share\/maven\/lib\/guice.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)\nWARNING: Please consider reporting this to the maintainers of com.google.inject.internal.cglib.core.$ReflectUtils$1\nWARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations\nWARNING: All illegal access operations will be denied in a future release\n[INFO] Scanning for projects...\n[INFO] \n[INFO] ---------------------------------------\n[INFO] Building JCGJavaWithDocker 1.0-SNAPSHOT\n[INFO] --------------------------------[ jar ]---------------------------------\n...\n[INFO] Installing \/home\/...\/projects\/JCGJavaWithDocker\/target\/JCGJavaWithDocker-1.0-SNAPSHOT.jar to \/home\/...\/.m2\/repository\/org\/example\/JCGJavaWithDocker\/1.0-SNAPSHOT\/JCGJavaWithDocker-1.0-SNAPSHOT.jar\n[INFO] Installing \/home\/...\/projects\/JCGJavaWithDocker\/pom.xml to \/home\/...\/.m2\/repository\/org\/example\/JCGJavaWithDocker\/1.0-SNAPSHOT\/JCGJavaWithDocker-1.0-SNAPSHOT.pom\n[INFO] Installing \/home\/...\/projects\/JCGJavaWithDocker\/target\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar to \/home\/...\/.m2\/repository\/org\/example\/JCGJavaWithDocker\/1.0-SNAPSHOT\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar\n[INFO] ------------------------------------------------------------------------\n[INFO] BUILD SUCCESS\n[INFO] ------------------------------------------------------------------------\n[INFO] Total time:  1.919 s\n[INFO] Finished at: 2020-07-23T12:31:21+01:00\n[INFO] ------------------------------------------------------------------------\n\n~\/projects\/JCGJavaWithDocker$ time docker build . --file Dockerfile.right_order --tag jcg_example:0.0.2\nSending build context to Docker daemon    128kB\nStep 1\/5 : FROM ubuntu:18.04\n ---&gt; d27b9ffc5667\nStep 2\/5 : RUN apt-get update\n ---&gt; Using cache\n ---&gt; 8818b118f8d4\nStep 3\/5 : RUN apt-get install -y openjdk-8-jdk\n ---&gt; Using cache\n ---&gt; 967e3b35c6ee\nStep 4\/5 : ADD target\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar java-docker.jar\n ---&gt; 2c9aa1a06388\nStep 5\/5 : CMD [\"java\", \"-jar\", \"java-docker.jar\"]\n ---&gt; Running in ea68774c0b30\nRemoving intermediate container ea68774c0b30\n ---&gt; 0e51dc5a27a9\nSuccessfully built 0e51dc5a27a9\nSuccessfully tagged jcg_example:0.0.2\n\nreal    0m0.436s\nuser    0m0.033s\nsys     0m0.037s\n<\/pre>\n<pre class=\"brush:bash\">~\/projects\/JCGJavaWithDocker$ mvn clean install\nWARNING: An illegal reflective access operation has occurred\nWARNING: Illegal reflective access by com.google.inject.internal.cglib.core.$ReflectUtils$1 (file:\/usr\/share\/maven\/lib\/guice.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)\nWARNING: Please consider reporting this to the maintainers of com.google.inject.internal.cglib.core.$ReflectUtils$1\nWARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations\nWARNING: All illegal access operations will be denied in a future release\n[INFO] Scanning for projects...\n[INFO] \n[INFO] ---------------------------------------\n[INFO] Building JCGJavaWithDocker 1.0-SNAPSHOT\n[INFO] --------------------------------[ jar ]---------------------------------\n...\n[INFO] Installing \/home\/...\/projects\/JCGJavaWithDocker\/target\/JCGJavaWithDocker-1.0-SNAPSHOT.jar to \/home\/...\/.m2\/repository\/org\/example\/JCGJavaWithDocker\/1.0-SNAPSHOT\/JCGJavaWithDocker-1.0-SNAPSHOT.jar\n[INFO] Installing \/home\/...\/projects\/JCGJavaWithDocker\/pom.xml to \/home\/...\/.m2\/repository\/org\/example\/JCGJavaWithDocker\/1.0-SNAPSHOT\/JCGJavaWithDocker-1.0-SNAPSHOT.pom\n[INFO] Installing \/home\/...\/projects\/JCGJavaWithDocker\/target\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar to \/home\/...\/.m2\/repository\/org\/example\/JCGJavaWithDocker\/1.0-SNAPSHOT\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar\n[INFO] ------------------------------------------------------------------------\n[INFO] BUILD SUCCESS\n[INFO] ------------------------------------------------------------------------\n[INFO] Total time:  1.919 s\n[INFO] Finished at: 2020-07-23T12:31:21+01:00\n[INFO] ------------------------------------------------------------------------\n\n~\/projects\/JCGJavaWithDocker$ time docker build . --file Dockerfile.right_order --tag jcg_example:0.0.2\nSending build context to Docker daemon    128kB\nStep 1\/5 : FROM ubuntu:18.04\n ---&gt; d27b9ffc5667\nStep 2\/5 : RUN apt-get update\n ---&gt; Using cache\n ---&gt; 8818b118f8d4\nStep 3\/5 : RUN apt-get install -y openjdk-8-jdk\n ---&gt; Using cache\n ---&gt; 967e3b35c6ee\nStep 4\/5 : ADD target\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar java-docker.jar\n ---&gt; 88eabff6bcb3\nStep 5\/5 : CMD [\"java\", \"-jar\", \"java-docker.jar\"]\n ---&gt; Running in c44ad221562f\nRemoving intermediate container c44ad221562f\n ---&gt; ce30673e6e80\nSuccessfully built ce30673e6e80\nSuccessfully tagged jcg_example:0.0.2\n\nreal    0m0.430s\nuser    0m0.014s\nsys     0m0.063s\n<\/pre>\n<h3 class=\"wp-block-heading\">2.2 Avoid wild characters in ADD or COPY command &#8211; be specific<\/h3>\n<p>Whenever you issue wild charecter like * and dot (.) like the one in the below, it will end copy or adding a lot of files and it would copy a lot of files leading to cache bursts.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p><span style=\"text-decoration: underline\"><em>Dockefile.cacheburst<\/em><\/span><\/p>\n<pre class=\"brush:bash\">FROM ubuntu:18.04\n\nRUN apt-get update\nRUN apt-get install -y openjdk-8-jdk\n\nADD target\/* \/\nCMD [\"java\", \"-jar\", \"JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar\"]<\/pre>\n<h3 class=\"wp-block-heading\">2.3 Reduce Image size<\/h3>\n<p># Tip 1: Use the right base image required for the container to work.<\/p>\n<p>For the java based containers like the example above, instead of using ubuntu using jdk images such as openjdk:8-jdk-alpine and the size of the image becomes almost 10% the image generated. Check the size of the jcg_example:0.0.3 image;it must be in the order of 100s instead of 400+ for other images.<\/p>\n<p><span style=\"text-decoration: underline\"><em>Dockerfile.lessersize<\/em><\/span><\/p>\n<pre class=\"brush:bash\">FROM openjdk:8-jdk-alpine\nADD target\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar java-docker.jar\nCMD [\"java\", \"-jar\", \"java-docker.jar\"]<\/pre>\n<pre class=\"brush:bash\">docker build . --file Dockerfile.lessersize --tag jcg_example:0.0.3\n\n# Check the size by executing the docker image and look for jcg_example\ndocker image ls | grep jcg_example\n\n# Size jcg_example:0.0.3 should be in the order of 100s instead of 400+ for other images<\/pre>\n<p>Sample Output:<\/p>\n<pre class=\"brush:bash\">~\/projects\/JCGJavaWithDocker$ docker build . --file Dockerfile.lessersize --tag jcg_example:0.0.3\nSending build context to Docker daemon    128kB\nStep 1\/3 : FROM openjdk:8-jdk-alpine\n ---&gt; a3562aa0b991\nStep 2\/3 : ADD target\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar java-docker.jar\n ---&gt; ce842dafc94c\nStep 3\/3 : CMD [\"java\", \"-jar\", \"java-docker.jar\"]\n ---&gt; Running in 04dbfd1f9718\nRemoving intermediate container 04dbfd1f9718\n ---&gt; 80d8aec6f234\nSuccessfully built 80d8aec6f234\nSuccessfully tagged jcg_example:0.0.3\n\n\n~\/projects\/JCGJavaWithDocker$ docker image ls | grep jcg_example\njcg_example                                                                                                                                           0.0.3                  80d8aec6f234        57 seconds ago      105MB\njcg_example                                                                                                                                           0.0.2                  ce30673e6e80        5 minutes ago       490MB\njcg_example                                                                                                                                           0.0.1                  1aff615dd35d        About an hour ago   490MB\njcg_example                                                                                                                                           0.0.6                  88614bba2d06        15 hours ago        105MB\njcg_example                                                                                                                                           0.0.5                  9b71834fad7a        19 hours ago        105MB\n\n<\/pre>\n<h3 class=\"wp-block-heading\">2.4 Use standard labels for better traceability<\/h3>\n<p>It is recomended to use OCI labels for standard images. Refer <a href=\"https:\/\/github.com\/opencontainers\/image-spec\/blob\/master\/annotations.md\" target=\"_blank\" aria-label=\"undefined (opens in a new tab)\" rel=\"noreferrer noopener\">specification<\/a> for list of labels that can be used.<\/p>\n<p><span style=\"text-decoration: underline\"><em>Dockerfile.with_labels<\/em><\/span><\/p>\n<pre class=\"brush:bash\">FROM openjdk:8-jdk-alpine\n\nLABEL \\\n    org.opencontainers.image.title=jcg_example \\\n    org.opencontainers.image.vendor=Java Code Geeks \\\n    org.opencontainers.image.version=0.0.5\n\nADD target\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar java-docker.jar\n\nRUN apt-get update\nRUN apt-get install -y openjdk-8-jdk\n\nCMD [\"java\", \"-jar\", \"java-docker.jar\"]<\/pre>\n<pre class=\"brush:bash\">docker build . --file Dockerfile.with_labels--tag jcg_example:0.0.4\n\n# Check the labels in the image\ndocker inspect jcg_example:0.0.4 | grep Label -A 4<\/pre>\n<p>Sample Output:<\/p>\n<pre class=\"brush:bash\">~\/projects\/JCGJavaWithDocker$ docker build . --file Dockerfile.with_labels --tag jcg_example:0.0.4\nSending build context to Docker daemon    128kB\nStep 1\/4 : FROM openjdk:8-jdk-alpine\n ---&gt; a3562aa0b991\nStep 2\/4 : LABEL     org.opencontainers.image.title=jcg_example     org.opencontainers.image.vendor=\"Java Code Geeks\"     org.opencontainers.image.version=0.0.5\n ---&gt; Using cache\n ---&gt; d61342b6d696\nStep 3\/4 : ADD target\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar java-docker.jar\n ---&gt; Using cache\n ---&gt; 2c433b6d996a\nStep 4\/4 : CMD [\"java\", \"-jar\", \"java-docker.jar\"]\n ---&gt; Running in 7b04d5c12198\nRemoving intermediate container 7b04d5c12198\n ---&gt; fdf0bc611bbe\nSuccessfully built fdf0bc611bbe\nSuccessfully tagged jcg_example:0.0.4\n\n~\/projects\/JCGJavaWithDocker$ docker inspect jcg_example:0.0.4 | grep Label -A 4\n            \"Labels\": {\n                \"org.opencontainers.image.title\": \"jcg_example\",\n                \"org.opencontainers.image.vendor\": \"Java Code Geeks\",\n                \"org.opencontainers.image.version\": \"0.0.5\"\n            }\n--\n            \"Labels\": {\n                \"org.opencontainers.image.title\": \"jcg_example\",\n                \"org.opencontainers.image.vendor\": \"Java Code Geeks\",\n                \"org.opencontainers.image.version\": \"0.0.5\"\n            }\n<\/pre>\n<h3 class=\"wp-block-heading\">2.5 Use ARGS wherever possible<\/h3>\n<p>Use ARGS for the dynamic content such as jar name, build date, commit hash etc.,.[ulp id=&#8217;6PVIvOz3kDbYmNRn&#8217;]<\/p>\n<p><span style=\"text-decoration: underline\"><em>Dockerfile<\/em><\/span><\/p>\n<pre class=\"brush:bash\">FROM openjdk:8-jdk-alpine\n\nARG COMMIT\nARG BUILD_DATE\nARG APP_VERSION\nARG JAR_NAME\n\nLABEL \\\n    org.opencontainers.image.title=jcg_example \\\n    org.opencontainers.image.created=$BUILD_DATE \\\n    org.opencontainers.image.revision=$COMMIT \\\n    org.opencontainers.image.vendor=\"Java Code Geeks\" \\\n    org.opencontainers.image.version=$APP_VERSION\n\nADD target\/$JAR_NAME java-docker.jar\n\nCMD [\"java\", \"-jar\", \"java-docker.jar\"]<\/pre>\n<pre class=\"brush:bash\"># Build the docker\ntime docker build --build-arg COMMIT=b34eab --build-arg BUILD_DATE=22-JUL-2020 --build-arg APP_VERSION=0.0.5 --build-arg JAR_NAME=JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar --file Dockerfile.with_args . --tag jcg_example:0.0.5 \n\n# Check the availability of images\ndocker image ls | grep jcg_example\n\n<\/pre>\n<p>Sample Output:<\/p>\n<pre class=\"brush:bash\">~\/projects\/JCGJavaWithDocker$ time docker build --build-arg COMMIT=b34eab --build-arg BUILD_DATE=22-JUL-2020 --build-arg APP_VERSION=0.0.5 --build-arg JAR_NAME=JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar --file Dockerfile . --tag jcg_example:0.0.5\nSending build context to Docker daemon    128kB\nStep 1\/8 : FROM openjdk:8-jdk-alpine\n ---&gt; a3562aa0b991\nStep 2\/8 : ARG COMMIT\n ---&gt; Using cache\n ---&gt; 71c6a6a00594\nStep 3\/8 : ARG BUILD_DATE\n ---&gt; Using cache\n ---&gt; fb62a3145fea\nStep 4\/8 : ARG APP_VERSION\n ---&gt; Using cache\n ---&gt; 8fc4365d0cbb\nStep 5\/8 : ARG JAR_NAME\n ---&gt; Using cache\n ---&gt; 792d4dbee6b5\nStep 6\/8 : LABEL     org.opencontainers.image.title=jcg_example     org.opencontainers.image.created=$BUILD_DATE     org.opencontainers.image.revision=$COMMIT     org.opencontainers.image.vendor=\"Java Code Geeks\"     org.opencontainers.image.version=$APP_VERSION\n ---&gt; Using cache\n ---&gt; b6cfa98420eb\nStep 7\/8 : ADD target\/$JAR_NAME java-docker.jar\n ---&gt; 230212c73cee\nStep 8\/8 : CMD [\"java\", \"-jar\", \"java-docker.jar\"]\n ---&gt; Running in 30d2a52ae47c\nRemoving intermediate container 30d2a52ae47c\n ---&gt; 9acb3c756cef\nSuccessfully built 9acb3c756cef\nSuccessfully tagged jcg_example:0.0.5\n\nreal    0m0.466s\nuser    0m0.019s\nsys     0m0.034s\n\n~\/projects\/JCGJavaWithDocker$ docker image ls | grep jcg_example\njcg_example                                                                                                                                           0.0.5                  9acb3c756cef        About a minute ago   105MB\njcg_example                                                                                                                                           0.0.4                  fdf0bc611bbe        5 minutes ago        105MB\njcg_example                                                                                                                                           0.0.3                  80d8aec6f234        8 minutes ago        105MB\njcg_example                                                                                                                                           0.0.2                  ce30673e6e80        13 minutes ago       490MB\njcg_example                                                                                                                                           0.0.1                  1aff615dd35d        About an hour ago    490MB\njcg_example\n<\/pre>\n<h2 class=\"wp-block-heading\">3. Docker security best practices<\/h2>\n<p>These are the best practices to be followed while running the containers.<\/p>\n<h3 class=\"wp-block-heading\">3.1 Mind the memory and CPU usage<\/h3>\n<p>Any application needs memory and CPU for running. Applications are prone to programming errors which may lead to over usage of available resources and may hinder the performance of other containers. Hence it is good to cap the resources used by the containers at the time execution. Here is an example of how to cap the resources. For more information check the docker <a href=\"https:\/\/docs.docker.com\/config\/containers\/resource_constraints\/\">documentation<\/a>.<\/p>\n<p>Reusing the docker image from the previous section. <\/p>\n<pre class=\"brush:bash\">docker run -m 10m --cpus 1.5 jcg_example:0.0.5<\/pre>\n<h3 class=\"wp-block-heading\">3.2 Run as non-root user<\/h3>\n<p>It is not at all a good practice to run a container as a root. When you do not mention any user to run, the container run by default as root. There are a couple of options to not to run as root.<\/p>\n<p>One of the options is to set the user in the Dockerfile, so that when the image is run, it automatically run as specified user. Or alternatively, specify at the time of execution of the containers as per below example:<\/p>\n<pre class=\"brush:bash\">docker run --user $(id -u):$(id -g) -m 10m --cpus 1.5 jcg_example:0.0.5<\/pre>\n<h3 class=\"wp-block-heading\">3.3 Use only trusted Docker Registries<\/h3>\n<p>It is always good to use containers from a secure and trusted docker registries. In the industry, there are a lot of generally available docker images for commonly used images. For example, to run nginx, the image is available at <a href=\"https:\/\/hub.docker.com\/_\/nginx\">hub.docker.com<\/a> with the image name as nginx with label 1.19.1. <\/p>\n<p>However, security experts at the enterprises, do no recommend using the global image. Instead, the image has to be downloaded, duly tested for security vulnerabilities, and to be uploaded into an industry-wide image repository. These repositories are protected by firewalls and role-based authentication mechanisms to percent unauthorized access.<\/p>\n<h3 class=\"wp-block-heading\">3.4 Do not include sensitive information in the containers<\/h3>\n<p>I have seen many developers irresponsibly leave the sensitive information such user names, passwords, security tokens for the REST APIs they use in the containers. Some use AWS resources to upload information\/files from the containers and they need AWS CLI tokens. It is bad to burn the image with tokens and distribute across the world.<\/p>\n<p>Since it is not good to bake images with secrets (tokens, passwords, API keys). we have to design containers to accept injected secrets or containers must directly fetch the secret. Here are the various options to inject secrets into the container:<\/p>\n<ul class=\"wp-block-list\">\n<li><em>Inject as environment variables:<\/em> This is not a recommended way as the containers might be hacked and environment values might be inspected and easily secrets be retrieved<\/li>\n<li><em>Mount the folder containing files with secrets:<\/em> This is better way than environmental variables. you can write all secrets into a file and mount that folder as volume as secrets. However, its not good from the maintenability perspective to write sensitive information on machine where the docker containers are run.<\/li>\n<li><em>Fetch the sensitive information from a centralized repository:<\/em> In this method you can use a predefined side car to fetch the tokens dynamically from a centralised stored password manager such a vault.<\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">4. Setup for Execution<\/h2>\n<p>In this section we will execute the programs and see how it is working.<\/p>\n<p>Prerequisites:<\/p>\n<ul class=\"wp-block-list\">\n<li>Java 1.8 installed in the system. Environment variables&nbsp;<code>JAVA_HOME<\/code>&nbsp;set to the Java location and&nbsp;<code>PATH<\/code>&nbsp;set to the directory containing javac and java binaries (&nbsp;<code>%JAVA_HOME%\/bin<\/code>&nbsp;on windows or&nbsp;<code>$JAVA_HOME\/bin<\/code>&nbsp;on Linux machines)<\/li>\n<li>Maven 3 installed. Refer <a href=\"https:\/\/maven.apache.org\/install.html\">documentation <\/a>for instructions on how to install.<\/li>\n<li>Docker engine installed using the <a href=\"https:\/\/docs.docker.com\/get-docker\/\">documentation<\/a> from the docker site. For Linux OS,  add user into the docker group using the <a href=\"https:\/\/docs.docker.com\/engine\/install\/linux-postinstall\/\">steps<\/a> (this might require a restart).<\/li>\n<li>Source code zip and unzipped to a location (say,&nbsp;<code>C:\\JavaCodeGeeks<\/code>. This would be different for Linux)<\/li>\n<li>Command-line is used for example<\/li>\n<\/ul>\n<h3 class=\"wp-block-heading\">4.1 Execution using command line<\/h3>\n<p>Step 1: Open the command line<br \/>Step 2: Go the folder where examples are unzipped &nbsp;<code>C:\\JavaCodeGeeks<\/code><br \/>Step 3: Compile the project using the command <code>mvn clean install<\/code><\/p>\n<p>Sample Output: <\/p>\n<pre class=\"brush:bash\">~\/projects\/JCGJavaWithDocker$ mvn clean install\nWARNING: An illegal reflective access operation has occurred\nWARNING: Illegal reflective access by com.google.inject.internal.cglib.core.$ReflectUtils$1 (file:\/usr\/share\/maven\/lib\/guice.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)\nWARNING: Please consider reporting this to the maintainers of com.google.inject.internal.cglib.core.$ReflectUtils$1\nWARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations\nWARNING: All illegal access operations will be denied in a future release\n[INFO] Scanning for projects...\n[INFO] \n[INFO] ---------------------------------------\n[INFO] Building JCGJavaWithDocker 1.0-SNAPSHOT\n[INFO] --------------------------------[ jar ]---------------------------------\n...\n[INFO] Installing \/home\/...\/projects\/JCGJavaWithDocker\/target\/JCGJavaWithDocker-1.0-SNAPSHOT.jar to \/home\/...\/.m2\/repository\/org\/example\/JCGJavaWithDocker\/1.0-SNAPSHOT\/JCGJavaWithDocker-1.0-SNAPSHOT.jar\n[INFO] Installing \/home\/...\/projects\/JCGJavaWithDocker\/pom.xml to \/home\/...\/.m2\/repository\/org\/example\/JCGJavaWithDocker\/1.0-SNAPSHOT\/JCGJavaWithDocker-1.0-SNAPSHOT.pom\n[INFO] Installing \/home\/...\/projects\/JCGJavaWithDocker\/target\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar to \/home\/...\/.m2\/repository\/org\/example\/JCGJavaWithDocker\/1.0-SNAPSHOT\/JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar\n[INFO] ------------------------------------------------------------------------\n[INFO] BUILD SUCCESS\n[INFO] ------------------------------------------------------------------------\n[INFO] Total time:  1.919 s\n[INFO] Finished at: 2020-07-23T12:31:21+01:00\n[INFO] ------------------------------------------------------------------------<\/pre>\n<p>Step 4: Generate the latest image and check if it is created.<\/p>\n<pre class=\"brush:bash\"># Generate the image\ntime docker build --build-arg COMMIT=b34eab --build-arg BUILD_DATE=22-JUL-2020 --build-arg APP_VERSION=0.0.5 --build-arg JAR_NAME=JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar --file Dockerfile . --tag jcg_example:latest\n\n# Check the availability of image\ndocker image ls | grep jcg_example | grep latest\n<\/pre>\n<p>Sample Output: <\/p>\n<pre class=\"brush:bash\">time docker build --build-arg COMMIT=b34eab --build-arg BUILD_DATE=22-JUL-2020 --build-arg APP_VERSION=0.0.5 --build-arg JAR_NAME=JCGJavaWithDocker-1.0-SNAPSHOT-jar-with-dependencies.jar --file Dockerfile . --tag jcg_example:latest\nSending build context to Docker daemon    128kB\nStep 1\/8 : FROM openjdk:8-jdk-alpine\n ---&gt; a3562aa0b991\nStep 2\/8 : ARG COMMIT\n ---&gt; Using cache\n ---&gt; 71c6a6a00594\nStep 3\/8 : ARG BUILD_DATE\n ---&gt; Using cache\n ---&gt; fb62a3145fea\nStep 4\/8 : ARG APP_VERSION\n ---&gt; Using cache\n ---&gt; 8fc4365d0cbb\nStep 5\/8 : ARG JAR_NAME\n ---&gt; Using cache\n ---&gt; 792d4dbee6b5\nStep 6\/8 : LABEL     org.opencontainers.image.title=jcg_example     org.opencontainers.image.created=$BUILD_DATE     org.opencontainers.image.revision=$COMMIT     org.opencontainers.image.vendor=\"Java Code Geeks\"     org.opencontainers.image.version=$APP_VERSION\n ---&gt; Using cache\n ---&gt; b6cfa98420eb\nStep 7\/8 : ADD target\/$JAR_NAME java-docker.jar\n ---&gt; Using cache\n ---&gt; 230212c73cee\nStep 8\/8 : CMD [\"java\", \"-jar\", \"java-docker.jar\"]\n ---&gt; Using cache\n ---&gt; 9acb3c756cef\nSuccessfully built 9acb3c756cef\nSuccessfully tagged jcg_example:latest\n\nreal    0m0.119s\nuser    0m0.039s\nsys     0m0.012s\n\n# Check the availability of images\n~\/projects\/JCGJavaWithDocker$ docker image ls | grep jcg_example | grep latest\njcg_example                                                                                                                                           latest                 9acb3c756cef        4 minutes ago       105MB\n<\/pre>\n<h2 class=\"wp-block-heading\">5. Download the Project<\/h2>\n<div class=\"download\"><strong>Download<\/strong><br \/>\nYou can download the full source code of this example here: <a href=\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2020\/07\/JCGJavaWithDocker.zip\"><strong>Docker Best Practices Tutorial<\/strong><\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial talks about various best practices and examples around the docker containers. 1. Introduction Docker containers are an essential part of containerization as we moved towards cloud-native applications. Since it is going to massive implementation of containers, it is vital to follow certain best practices based on our past experience, to bring out qualitative &hellip;<\/p>\n","protected":false},"author":222,"featured_media":31013,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1354],"tags":[],"class_list":["post-91989","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-docker"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Docker Best Practices Tutorial - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"This tutorial talks about various best practices and examples around the docker containers. 1. Introduction Docker containers are an essential part of\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Docker Best Practices Tutorial - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"This tutorial talks about various best practices and examples around the docker containers. 1. Introduction Docker containers are an essential part of\" \/>\n<meta property=\"og:url\" content=\"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/\" \/>\n<meta property=\"og:site_name\" content=\"Examples Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2020-07-27T12:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/12\/docker-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Shivakumar Ramannavar\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Shivakumar Ramannavar\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"18 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/\"},\"author\":{\"name\":\"Shivakumar Ramannavar\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/2b71c417a9bb1e9bd863d4ff7d37f1ce\"},\"headline\":\"Docker Best Practices Tutorial\",\"datePublished\":\"2020-07-27T12:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/\"},\"wordCount\":1149,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/12\/docker-logo.jpg\",\"articleSection\":[\"Docker\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/\",\"url\":\"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/\",\"name\":\"Docker Best Practices Tutorial - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/12\/docker-logo.jpg\",\"datePublished\":\"2020-07-27T12:00:00+00:00\",\"description\":\"This tutorial talks about various best practices and examples around the docker containers. 1. Introduction Docker containers are an essential part of\",\"breadcrumb\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/#primaryimage\",\"url\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/12\/docker-logo.jpg\",\"contentUrl\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/12\/docker-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/examples.javacodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"DevOps\",\"item\":\"https:\/\/examples.javacodegeeks.com\/category\/devops\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Docker\",\"item\":\"https:\/\/examples.javacodegeeks.com\/category\/devops\/docker\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Docker Best Practices Tutorial\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#website\",\"url\":\"https:\/\/examples.javacodegeeks.com\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Examples and Code Snippets\",\"publisher\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/examples.javacodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/examples.javacodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/examples.javacodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/javacodegeeks\",\"https:\/\/x.com\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/2b71c417a9bb1e9bd863d4ff7d37f1ce\",\"name\":\"Shivakumar Ramannavar\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2020\/05\/shivakumar.-ramannavar-96x96.jpg\",\"contentUrl\":\"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2020\/05\/shivakumar.-ramannavar-96x96.jpg\",\"caption\":\"Shivakumar Ramannavar\"},\"description\":\"Shivakumar has 16+ years of experience in Java Development, Cloud and also has a lot of passion in Cloud-native Applications and Kubernetes. Shiva has a Bachelor's Degree from Visweswaraiah Technological University, India. Shiva has been involved in the development of IT systems using Java\/J2EE, Kubernetes, and has designed tonnes of applications both on-premise and on-cloud. Shiva strongly believes there is a great revolution of cloud-native technologies and that we can create a world of difference through learning, sharing, and caring among the community.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/shivakumar-ramannavar\/\"],\"url\":\"https:\/\/examples.javacodegeeks.com\/author\/shivakumar-ramannavar\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Docker Best Practices Tutorial - Java Code Geeks","description":"This tutorial talks about various best practices and examples around the docker containers. 1. Introduction Docker containers are an essential part of","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/","og_locale":"en_US","og_type":"article","og_title":"Docker Best Practices Tutorial - Java Code Geeks","og_description":"This tutorial talks about various best practices and examples around the docker containers. 1. Introduction Docker containers are an essential part of","og_url":"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/","og_site_name":"Examples Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2020-07-27T12:00:00+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/12\/docker-logo.jpg","type":"image\/jpeg"}],"author":"Shivakumar Ramannavar","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Shivakumar Ramannavar","Est. reading time":"18 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/#article","isPartOf":{"@id":"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/"},"author":{"name":"Shivakumar Ramannavar","@id":"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/2b71c417a9bb1e9bd863d4ff7d37f1ce"},"headline":"Docker Best Practices Tutorial","datePublished":"2020-07-27T12:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/"},"wordCount":1149,"commentCount":0,"publisher":{"@id":"https:\/\/examples.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/#primaryimage"},"thumbnailUrl":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/12\/docker-logo.jpg","articleSection":["Docker"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/","url":"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/","name":"Docker Best Practices Tutorial - Java Code Geeks","isPartOf":{"@id":"https:\/\/examples.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/#primaryimage"},"image":{"@id":"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/#primaryimage"},"thumbnailUrl":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/12\/docker-logo.jpg","datePublished":"2020-07-27T12:00:00+00:00","description":"This tutorial talks about various best practices and examples around the docker containers. 1. Introduction Docker containers are an essential part of","breadcrumb":{"@id":"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/#primaryimage","url":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/12\/docker-logo.jpg","contentUrl":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2015\/12\/docker-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/examples.javacodegeeks.com\/docker-best-practices-tutorial\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/examples.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"DevOps","item":"https:\/\/examples.javacodegeeks.com\/category\/devops\/"},{"@type":"ListItem","position":3,"name":"Docker","item":"https:\/\/examples.javacodegeeks.com\/category\/devops\/docker\/"},{"@type":"ListItem","position":4,"name":"Docker Best Practices Tutorial"}]},{"@type":"WebSite","@id":"https:\/\/examples.javacodegeeks.com\/#website","url":"https:\/\/examples.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Examples and Code Snippets","publisher":{"@id":"https:\/\/examples.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/examples.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/examples.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/examples.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/examples.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/examples.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/2b71c417a9bb1e9bd863d4ff7d37f1ce","name":"Shivakumar Ramannavar","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/examples.javacodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2020\/05\/shivakumar.-ramannavar-96x96.jpg","contentUrl":"https:\/\/examples.javacodegeeks.com\/wp-content\/uploads\/2020\/05\/shivakumar.-ramannavar-96x96.jpg","caption":"Shivakumar Ramannavar"},"description":"Shivakumar has 16+ years of experience in Java Development, Cloud and also has a lot of passion in Cloud-native Applications and Kubernetes. Shiva has a Bachelor's Degree from Visweswaraiah Technological University, India. Shiva has been involved in the development of IT systems using Java\/J2EE, Kubernetes, and has designed tonnes of applications both on-premise and on-cloud. Shiva strongly believes there is a great revolution of cloud-native technologies and that we can create a world of difference through learning, sharing, and caring among the community.","sameAs":["https:\/\/www.linkedin.com\/in\/shivakumar-ramannavar\/"],"url":"https:\/\/examples.javacodegeeks.com\/author\/shivakumar-ramannavar\/"}]}},"_links":{"self":[{"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/91989","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/users\/222"}],"replies":[{"embeddable":true,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=91989"}],"version-history":[{"count":0,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/91989\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/media\/31013"}],"wp:attachment":[{"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=91989"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=91989"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/examples.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=91989"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}