{"id":357,"date":"2020-08-29T22:25:04","date_gmt":"2020-08-29T22:25:04","guid":{"rendered":"https:\/\/lab.rapternet.us\/?p=357"},"modified":"2020-08-29T22:27:53","modified_gmt":"2020-08-29T22:27:53","slug":"jenkins-docker-revisit","status":"publish","type":"post","link":"https:\/\/lab.rapternet.us\/?p=357","title":{"rendered":"Jenkins Docker Revisit"},"content":{"rendered":"\n<p>After my <a rel=\"noreferrer noopener\" href=\"https:\/\/lab.rapternet.us\/?p=246\" target=\"_blank\">initial jenkins setup<\/a>, I thought my system would be good to go for a long time, however I encountered a problem with permissions after my <a href=\"https:\/\/lab.rapternet.us\/?p=354\">docker cluster reboot<\/a>. After all my nodes were back up, and jenkins was running, it could no longer access the docker.sock that it used to handle building and pushing containers. I tried a few things, rebuilding the container, updating it, changing some groups, and found quite a few threads on the topic. Some people had chmod&#8217;d the docker.sock to 777 (<strong>BAD<\/strong>) or had given jenkins root (<strong>ALSO BAD<\/strong>). I ended up finding the solution in using a specific entrypoint script that would determine the group to add to the jenkins user, then launch jenkins using the jenkins user from root.<\/p>\n\n\n\n<p>Most of my additions are from <a href=\"https:\/\/github.com\/sudo-bmitch\/jenkins-docker\">sudo-bmitch&#8217;s jenkins-docker repository<\/a> on GitHub. These include the dockerfile changes and the entrypoint.sh script (as well as the healthcheck mentioned later on).<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Dockerfile<\/h2>\n\n\n\n<p>The first thing I considered doing was to add a bit to the dockerfile that would check the group that had access to the docker.sock and set the jenkins user in the container to have that group. However, since I run a 3 node docker-swarm cluster, if that ownership group has a different GID on any of the nodes, the solution may not have been a complete solution. This solution should be fine for a single node and is included below for reference.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">CMD DOCKER_GID=$(stat -c '%g' \/var\/run\/docker.sock) &amp;&amp; \\\n   groupadd -for -g ${DOCKER_GID} docker &amp;&amp; \\\n   usermod -aG docker jenkins &amp;&amp; \\<\/pre>\n\n\n\n<p>Instead I went with using the script by sudo-bmitch, and adding GOSU to my dockerfile to support that. The main addition here is adding GOSU to the installation, pulling in the entrypoint.sh script from my repo checkout, and updating the entrypoint to be that new script.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">FROM jenkins\/jenkins:lts\nUSER root\nRUN apt-get update &amp;&amp; \\\napt-get -y install apt-transport-https \\\n    ca-certificates \\\n    curl \\\n    ant \\\n    gnupg2 \\\n    software-properties-common &amp;&amp; \\\ncurl -fsSL https:\/\/download.docker.com\/linux\/$(. \/etc\/os-release; echo \"$ID\")\/gpg &gt; \/tmp\/dkey; apt-key add \/tmp\/dkey &amp;&amp; \\\nadd-apt-repository \\\n    \"deb [arch=amd64] https:\/\/download.docker.com\/linux\/$(. \/etc\/os-release; echo \"$ID\") \\\n    $(lsb_release -cs) \\\n    stable\" &amp;&amp; \\\napt-get update &amp;&amp; \\\napt-get -y install docker-ce\nRUN apt-get install -y docker-ce\nRUN usermod -a -G docker jenkins\n\n\nARG GOSU_VERSION=1.10\nRUN dpkgArch=\"$(dpkg --print-architecture | awk -F- '{ print $NF }')\" \\\n &amp;&amp; wget -O \/usr\/local\/bin\/gosu \"https:\/\/github.com\/tianon\/gosu\/releases\/download\/$GOSU_VERSION\/gosu-$dpkgArch\" \\\n &amp;&amp; chmod +x \/usr\/local\/bin\/gosu \\\n &amp;&amp; gosu nobody true\n\nCOPY entrypoint.sh \/entrypoint.sh\nRUN chmod +x \/entrypoint.sh\nENTRYPOINT [\"\/entrypoint.sh\"]\nHEALTHCHECK CMD curl -sSLf http:\/\/localhost:8080\/login &gt;\/dev\/null || exit 1<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">entrypoint.sh<\/h2>\n\n\n\n<p>I&#8217;ve included the entrypoint script here for reference. Its worked well so far, correcting my problem with building\/pushing docker containers, and I&#8217;ve confirmed that the jenkins process is running as the jenkins user, and not root.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/bin\/sh\n\n# By: Brandon Mitchell &lt;public@bmitch.net&gt;\n# License: MIT\n# Source Repo: https:\/\/github.com\/sudo-bmitch\/jenkins-docker\n\nset -x\n\n# configure script to call original entrypoint\nset -- tini -- \/usr\/local\/bin\/jenkins.sh \"$@\"\n\n# In Prod, this may be configured with a GID already matching the container\n# allowing the container to be run directly as Jenkins. In Dev, or on unknown\n# environments, run the container as root to automatically correct docker\n# group in container to match the docker.sock GID mounted from the host.\nif [ \"$(id -u)\" = \"0\" ]; then\n  # get gid of docker socket file\n  SOCK_DOCKER_GID=`ls -ng \/var\/run\/docker.sock | cut -f3 -d' '`\n\n  # get group of docker inside container\n  CUR_DOCKER_GID=`getent group docker | cut -f3 -d: || true`\n\n  # if they don't match, adjust\n  if [ ! -z \"$SOCK_DOCKER_GID\" -a \"$SOCK_DOCKER_GID\" != \"$CUR_DOCKER_GID\" ]; then\n    groupmod -g ${SOCK_DOCKER_GID} -o docker\n  fi\n  if ! groups jenkins | grep -q docker; then\n    usermod -aG docker jenkins\n  fi\n  # Add call to gosu to drop from root user to jenkins user\n  # when running original entrypoint\n  set -- gosu jenkins \"$@\"\nfi\n\n# replace the current pid 1 with original entrypoint\nexec \"$@\"<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Additional Healthcheck<\/h2>\n\n\n\n<p>This is something completely unrelated to the current goal of getting jenkins back up and running, building and deploying containers. Instead, I found in my googling a healthcheck script for the docker container and added it to mine to see how it worked. So far so good, so its shown below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">HEALTHCHECK CMD curl -sSLf http:\/\/localhost:8080\/login &gt;\/dev\/null || exit 1<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>This is a great way to avoid both the docker.sock problems with different GID ownership across different nodes, and also a great way to avoid security problems that simpler solutions have, while not requiring much legwork other than adding a script to load in on the dockerfile.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>After my initial jenkins setup, I thought my system would be good to go for a long time, however I encountered a problem with permissions after my docker cluster reboot. After all my nodes were back up, and jenkins was running, it could no longer access the docker.sock that it used to handle building and &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/lab.rapternet.us\/?p=357\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Jenkins Docker Revisit&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[17,32,16,13,40],"class_list":["post-357","post","type-post","status-publish","format-standard","hentry","category-how-to","tag-ci-cd","tag-clusters","tag-development","tag-docker","tag-jenkins"],"_links":{"self":[{"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=\/wp\/v2\/posts\/357","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=357"}],"version-history":[{"count":6,"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=\/wp\/v2\/posts\/357\/revisions"}],"predecessor-version":[{"id":364,"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=\/wp\/v2\/posts\/357\/revisions\/364"}],"wp:attachment":[{"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=357"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=357"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=357"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}