{"id":6025,"date":"2022-03-08T16:50:45","date_gmt":"2022-03-08T11:20:45","guid":{"rendered":"https:\/\/opstree.com\/blog\/\/?p=6025"},"modified":"2022-03-15T17:34:10","modified_gmt":"2022-03-15T12:04:10","slug":"introducing-opstree-tomcat-image","status":"publish","type":"post","link":"https:\/\/opstree.com\/blog\/2022\/03\/08\/introducing-opstree-tomcat-image\/","title":{"rendered":"Introducing OpsTree Tomcat Image"},"content":{"rendered":"\n<p class=\"has-text-align-justify\">Docker is a platform for developers and sysadmins to develop, deploy, and run applications with containers. And, as we all know Docker image is a read-only template that contains a set of instructions for creating a container that wraps up the software and its dependencies into a standardized unit for software development to run on the Docker platform.<\/p>\n\n\n\n<p class=\"has-text-align-justify\">In this post, we are going to step through describing some of the best practices and common pitfalls we encountered while developing our first <strong>Dockerfile for Tomcat.<\/strong><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2022\/02\/image-2.png?w=1024\" alt=\"\" class=\"wp-image-9990\" width=\"800\" \/><\/figure><\/div>\n\n\n<!--more-->\n\n\n\n<h3 class=\"wp-block-heading\" id=\"let-s-get-started\">Let&#8217;s Get Started<\/h3>\n\n\n\n<p class=\"has-text-align-justify\">Refreshing basic concepts about Docker Images and Dockerfiles<\/p>\n\n\n\n<h6 class=\"wp-block-heading\" id=\"what-is-dockerfile-and-docker-image\">What is Dockerfile and Docker<strong> Image?<\/strong><\/h6>\n\n\n\n<p class=\"has-text-align-justify\">A Dockerfile is just a text file that contains the set of instructions to build a Docker image. Docker Image is a template that allows you to initiate running containers.<\/p>\n\n\n\n<h6 class=\"wp-block-heading\" id=\"what-is-docker-layer-and-docker-build-cache\">What is Docker Layer and Docker build cache?<\/h6>\n\n\n\n<p class=\"has-text-align-justify\">Each layer in a Docker context represents an instruction included in a Docker image&#8217;s Dockerfile. The layers can also be referred to as &#8220;<em><strong>build steps<\/strong><\/em>.&#8221;<\/p>\n\n\n\n<p class=\"has-text-align-justify\">Every time you build a Docker image, each build step is cached. Reuse cached layers that do not change in the image rebuild process to improve the build time.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"concerns-when-building-images\">Concerns when building images<\/h5>\n\n\n\n<ul><li><strong>Consistency:<\/strong> If we are consistently writing our Dockerfiles for our images, will be easier to maintain and we will reduce the time spent when developing new releases of the image<\/li><li><strong>Build Time<\/strong>: Especially when our builds are integrated into a Continuous Integration pipeline (CI), reducing the build time can significantly reduce our apps&#8217; development cost.<\/li><li><strong>Image Size<\/strong>: Reduce the size of our images to improve the security, performance, efficiency, and maintainability of our containers.<\/li><li><strong>Security<\/strong>: Critical for production environments, securing our containers is very important to protect our applications from external threats and attacks.<\/li><\/ul>\n\n\n\n<p>Can find more on <a href=\"https:\/\/docs.docker.com\/develop\/develop-images\/dockerfile_best-practices\" target=\"_blank\" rel=\"noopener\">Docker best practices<\/a><\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"prerequsistes-docker-linter\">Prerequsistes : Docker Linter<\/h5>\n\n\n\n<p class=\"has-text-align-justify\">A Linter helped us to detect syntax errors in our docker file and give us suggestions based on some best practices. We used <a href=\"https:\/\/github.com\/opstree\/OT-Dockerlinter\" target=\"_blank\" rel=\"noopener\">OT-Dockerlinter<\/a> developed by our own team.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"case-setting-up-a-java-application-onto-tomcat-using-docker-form-scratch\">Case : Setting Up a Java Application onto Tomcat using Docker form Scratch<\/h5>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"being-specific-about-your-base-image-tag\"><span class=\"uppercase\"><strong>Being specific about your base image tag<\/strong> : <\/span><\/h5>\n\n\n\n<p class=\"has-text-align-justify\">Maintained images usually have different tags, used to specify their different flavors. For application, the <code>maven<\/code> image is built as a base image. Maven has multiple versions in which it has a slim flavor that includes the minimal needed packages to run a Maven application (see multiple <a href=\"https:\/\/hub.docker.com\/_\/maven\" target=\"_blank\" rel=\"noopener\">Supported Tags<\/a>).<\/p>\n\n\n\n<p class=\"has-text-align-justify\">Following this case, we used MVN_JDK_VERSION=3.6.0-jdk-11-slim with the minimal packages:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2021\/03\/1.png?w=480\" alt=\"\" class=\"wp-image-6105\" width=\"800\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-justify\">This results in a lesser size of the whole image. Thanks to that finespun but important change, but don&#8217;t worry we can use any as per our requirements as we taking it as an Argument.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"using-multi-stage-builds-to-separate-build-and-runtime-environments\"><strong><span class=\"uppercase\">Using multi-stage builds to separate build and runtime environments :<\/span><\/strong><\/h5>\n\n\n\n<p class=\"has-text-align-justify\">To continue improving the efficiency, readability, and size of the image, we split the process into different stages : <\/p>\n\n\n\n<ul><li><strong>Build Stage<\/strong> : Building the application from source code<\/li><li><strong>Running Stage<\/strong> : Copy  the application artifacts needed in the final stage and running the application.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2022\/02\/image-3.png?w=1024\" alt=\"\" class=\"wp-image-9997\" width=\"800\" height=\"514\" \/><\/figure>\n\n\n\n<p>This is a short summary of what we have done :<\/p>\n\n\n\n<p class=\"has-text-align-justify\">Using maven:3.6.0-jdk-11-slim to build our application, we added <code>AS build<\/code> to name our first stage <strong>&#8220;build&#8221;<\/strong>. Then, we used <code>COPY --from=build<\/code> to copy artifacts from that stage. That way, the artifacts copied are only the ones needed to run the minimal image. This approach is extremely effective when building images for compiled applications.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"using-the-non-root-approach-to-enforce-container-security\"><strong><span class=\"uppercase\">Using the Non-Root Approach to Enforce Container Security<\/span><\/strong> <strong>:<\/strong><\/h5>\n\n\n\n<p class=\"has-text-align-justify\">Non-root containers add an extra layer of security. To put this in perspective, ask this:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote has-text-align-left is-layout-flow wp-block-quote-is-layout-flow\"><p>&#8220;Would we run any process or application as root in my server?&#8221; The answer, would be no, right? So why would we do so in our containers?<\/p><\/blockquote>\n\n\n\n<p class=\"has-text-align-justify\">Running our containers as non-root prevents from gaining sudo privileges in the container host and if not so the repercussion could be bad when the application is deployed and made public, hackers can manipulate just not the application but the entire filesystem of the Docker container.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2021\/03\/4.png?w=762\" alt=\"\" class=\"wp-image-6113\" width=\"800\" height=\"358\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"setting-the-workdir-instruction\"><strong><span class=\"uppercase\">Setting the WORKDIR instruction<\/span><\/strong> :<\/h5>\n\n\n\n<p class=\"has-text-align-justify\">The default value for the working directory is <code>\/<\/code>. However, unless we use <code>FROM <\/code>scratch images, it is likely that the base image we are using set it. It is a good practice to set the WORKDIR instruction to adapt it to our application characteristics.<\/p>\n\n\n\n<p class=\"has-text-align-justify\">Our application server to get installed is under the directory <code>\/opt<\/code>. Therefore, it makes sense to adapt the working directory to it :<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2021\/03\/5.png?w=709\" alt=\"\" class=\"wp-image-6117\" width=\"800\" \/><\/figure>\n\n\n\n<p> And not only here, but we have also used WORKDIR at many more places.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"say-hello-to-buildkit\">Say Hello to BuildKit <\/h5>\n\n\n\n<p class=\"has-text-align-justify\">As our Dockerfile is a Multi-stage Build, when BuildKit comes across a multi-stage build it get concurrency, it analyzes the docker file and create a graph of the dependencies between build steps and uses this to determine which elements of the build can be ignored; which can be executed in parallel; and which need to be executed sequentially. To read more features of <a href=\"https:\/\/opstree.com\/blog\/\/2021\/04\/20\/docker-buildkit-faster-builds-mounts-and-features\/\">BuildKit<\/a><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2022\/02\/image-1.png?w=1024\" alt=\"\" class=\"wp-image-9986\" width=\"800\" \/><\/figure><\/div>\n\n\n<p class=\"has-text-align-justify\">Till the time, maven builds the artifact in the first stage, our second stage of downloading Tomcat of the specific version given as per user&#8217;s input is ready.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"dockle-container-image-linter-for-security\">Dockle  &#8211; Container Image Linter for Security<\/h5>\n\n\n\n<p class=\"has-text-align-justify\">Dockle performs multiple CIS benchmark checks, as well as more generic checks that are considered recommended best practices. Docker CIS Benchmark focuses on ensuring Docker containers runtimes are configured as securely as possible such as <strong><em>Host Configuration<\/em><\/strong>, <strong><em>Docker Daemon Configuration<\/em><\/strong>, <strong><em>Container<\/em><\/strong> <strong><em>Images,<\/em><\/strong> and <strong><em>Build File Configuration, etc. We have multiple tools for such security use cases<\/em><\/strong> Trivy, DockerSlim for latest CIS practices check the <a href=\"https:\/\/www.cisecurity.org\/benchmark\/docker\" target=\"_blank\" rel=\"noopener\">link<\/a><\/p>\n\n\n\n<figure class=\"wp-block-video wp-block-embed is-type-video is-provider-videopress\"><div class=\"wp-block-embed__wrapper\">\n<iframe title=\"VideoPress Video Player\" aria-label='VideoPress Video Player' width='840' height='483' src='https:\/\/videopress.com\/embed\/1yARYzPN?cover=1&amp;autoPlay=1&amp;loop=1&amp;preloadContent=metadata&amp;useAverageColor=1&amp;hd=0' frameborder='0' allowfullscreen data-resize-to-parent=\"true\" allow='clipboard-write'><\/iframe><script src='https:\/\/v0.wordpress.com\/js\/next\/videopress-iframe.js?m=1674852142'><\/script>\n<\/div><\/figure>\n\n\n\n<p class=\"has-text-align-justify\">These were some of the practices which we followed, but these don&#8217;t end here. There are many more which can bring  the best for you docker images suggested by the docker community for example :<\/p>\n\n\n\n<ul><li>Order the steps in the Dockerfile from least to most frequently changing content.<\/li><li>Only install what you need. For example, use the&nbsp;<code>--no-install-recommends<\/code> option<\/li><li>Don\u2019t install SSH or similar services that may expose your containers.<\/li><li>Minimize the number of layers.<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"conclusion\">Conclusion<\/h3>\n\n\n\n<p class=\"has-text-align-justify\">Try following best practices when writing Dockerfile; use linters. Include these checks in your workflow. Create and standardize organization-wide custom policies to make your workflow consistent and predictable. Add these checks to your CI\/CD pipelines to enable and validate security best practices. Extend these practices besides Dockerfile, and implement them in each workflow layer. <\/p>\n\n\n\n<p class=\"has-text-align-justify\">Finally, if you have come across any other practices, please comment below. Thanks for reading !!<\/p>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/www.behance.net\/gallery\/78318737\/isometric-illustration-for-web\" target=\"_blank\">Image Reference<\/a><\/p>\n\n\n\n<p><br><strong style=\"font-weight:bold;\">Blog Pundit:<\/strong><a href=\"https:\/\/opstree.com\/blog\/\/author\/naveenverma023\/\"> <\/a><a rel=\"noreferrer noopener\" href=\"https:\/\/opstree.com\/blog\/\/author\/naveenverma023\/\" target=\"_blank\"><strong>Naveen Verma<\/strong><\/a> and <strong>Sanjeev Pandey<\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/www.opstree.com\/contact-us?utm_source=blog&amp;utm_medium=wordpress+&amp;utm_campaign=Introducing-OpsTree-Tomcat-Image\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Opstree<\/strong> <\/a>is an End to End DevOps solution provider<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button is-style-fill\"><a class=\"wp-block-button__link\" href=\"https:\/\/www.opstree.com\/contact-us\" target=\"_blank\" rel=\"noreferrer noopener\">CONTACT US<\/a><\/div>\n<\/div>\n\n\n\n<p class=\"has-text-align-center\"><strong>Connect Us <\/strong><\/p>\n\n\n\n<ul class=\"wp-block-social-links aligncenter is-content-justification-right is-layout-flex wp-container-core-social-links-is-layout-1 wp-block-social-links-is-layout-flex\"><li class=\"wp-social-link wp-social-link-linkedin  wp-block-social-link\"><a href=\"https:\/\/www.linkedin.com\/company\/opstree-solutions\" class=\"wp-block-social-link-anchor\" target=\"_blank\" rel=\"noopener\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z\"><\/path><\/svg><span class=\"wp-block-social-link-label screen-reader-text\">LinkedIn<\/span><\/a><\/li>\n\n<li class=\"wp-social-link wp-social-link-youtube  wp-block-social-link\"><a href=\"https:\/\/www.youtube.com\/channel\/UCeLma6SpNYH7jjYKSBNSexw\" class=\"wp-block-social-link-anchor\" target=\"_blank\" rel=\"noopener\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z\"><\/path><\/svg><span class=\"wp-block-social-link-label screen-reader-text\">YouTube<\/span><\/a><\/li>\n\n<li class=\"wp-social-link wp-social-link-github  wp-block-social-link\"><a href=\"https:\/\/github.com\/OpsTree\" class=\"wp-block-social-link-anchor\" target=\"_blank\" rel=\"noopener\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z\"><\/path><\/svg><span class=\"wp-block-social-link-label screen-reader-text\">GitHub<\/span><\/a><\/li>\n\n<li class=\"wp-social-link wp-social-link-facebook  wp-block-social-link\"><a href=\"https:\/\/www.facebook.com\/opstree\" class=\"wp-block-social-link-anchor\" target=\"_blank\" rel=\"noopener\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z\"><\/path><\/svg><span class=\"wp-block-social-link-label screen-reader-text\">Facebook<\/span><\/a><\/li>\n\n<li class=\"wp-social-link wp-social-link-medium  wp-block-social-link\"><a href=\"https:\/\/medium.com\/buildpiper\" class=\"wp-block-social-link-anchor\" target=\"_blank\" rel=\"noopener\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M20.962,7.257l-5.457,8.867l-3.923-6.375l3.126-5.08c0.112-0.182,0.319-0.286,0.527-0.286c0.05,0,0.1,0.008,0.149,0.02 c0.039,0.01,0.078,0.023,0.114,0.041l5.43,2.715l0.006,0.003c0.004,0.002,0.007,0.006,0.011,0.008 C20.971,7.191,20.98,7.227,20.962,7.257z M9.86,8.592v5.783l5.14,2.57L9.86,8.592z M15.772,17.331l4.231,2.115 C20.554,19.721,21,19.529,21,19.016V8.835L15.772,17.331z M8.968,7.178L3.665,4.527C3.569,4.479,3.478,4.456,3.395,4.456 C3.163,4.456,3,4.636,3,4.938v11.45c0,0.306,0.224,0.669,0.498,0.806l4.671,2.335c0.12,0.06,0.234,0.088,0.337,0.088 c0.29,0,0.494-0.225,0.494-0.602V7.231C9,7.208,8.988,7.188,8.968,7.178z\"><\/path><\/svg><span class=\"wp-block-social-link-label screen-reader-text\">Medium<\/span><\/a><\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Docker is a platform for developers and sysadmins to develop, deploy, and run applications with containers. And, as we all know Docker image is a read-only template that contains a set of instructions for creating a container that wraps up the software and its dependencies into a standardized unit for software development to run on &hellip; <a href=\"https:\/\/opstree.com\/blog\/2022\/03\/08\/introducing-opstree-tomcat-image\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Introducing OpsTree Tomcat Image&#8221;<\/span><\/a><\/p>\n","protected":false},"author":198919067,"featured_media":29900,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","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","enabled":false},"version":2}},"categories":[28070474],"tags":[460,2291981,182564,768739305,456217398,4996032,730834466],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2025\/11\/DevSecOps-1.jpg","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pfDBOm-1zb","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/6025"}],"collection":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/users\/198919067"}],"replies":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/comments?post=6025"}],"version-history":[{"count":24,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/6025\/revisions"}],"predecessor-version":[{"id":12145,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/6025\/revisions\/12145"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media\/29900"}],"wp:attachment":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media?parent=6025"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/categories?post=6025"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/tags?post=6025"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}