{"id":10008118,"date":"2023-08-19T13:59:26","date_gmt":"2023-08-19T05:59:26","guid":{"rendered":"https:\/\/blog.itmax.cn\/?p=10008118"},"modified":"2023-08-19T13:59:26","modified_gmt":"2023-08-19T05:59:26","slug":"%e5%9f%ba%e4%ba%8edocker-jenkins-pipeline%e7%9a%84cicd%e5%ae%9e%e8%b7%b5","status":"publish","type":"post","link":"https:\/\/itmax.cn\/?p=10008118","title":{"rendered":"\u57fa\u4e8eDocker + Jenkins Pipeline\u7684CICD\u5b9e\u8df5"},"content":{"rendered":"<blockquote><p>\u57fa\u4e8eWindows+Docker\u7684\u5355\u673a\u7248\u6d4b\u8bd5\u73af\u5883\u5b9e\u8df5\u3002<br \/>\u9879\u76ee\u4e0d\u5927\uff0c\u5f00\u53d1\u5468\u671f\u4e0d\u957f\u3002\u524d\u671f\u914d\u7f6e\u597d\uff0c\u540e\u7eed\u4f7f\u7528\u6574\u4f53\u6bd4\u8f83\u4e1d\u6ed1\u3002<\/p><\/blockquote>\n<h2>0. \u7b80\u4ecb<\/h2>\n<p>\u4f7f\u7528<code>SpringBoot3 + JDK17<\/code>\u642d\u5efa\u7684\u9879\u76ee\uff0c\u6784\u5efa\u5de5\u5177\u4f7f\u7528<code>Gradle 8.0<\/code>\u3002<\/p>\n<p>\u6d89\u53ca\u5230\u7684\u77e5\u8bc6\u70b9<\/p>\n<ul>\n<li>Docker, Dockerfile, Docker-Compose<\/li>\n<li>Gitlab<\/li>\n<li>Jenkins<\/li>\n<li>IDEA (Jenkins Control plugins)<\/li>\n<\/ul>\n<h2>1. Docker<\/h2>\n<p>\u5047\u8bbeWindows\u73af\u5883\uff0c<code>Docker<\/code>\u5df2\u7ecf\u5b89\u88c5\u5b8c\u6bd5\u3002\u9ed8\u8ba4\u5df2\u5b89\u88c5<code>Docker Compose<\/code><\/p>\n<h3>1.1 Dockerfile<\/h3>\n<p>\u955c\u50cf\u63cf\u8ff0\u6587\u4ef6\uff0c\u6bd4\u8f83\u7b80\u5355\u7684Java SpringBoot\u9879\u76ee<\/p>\n<pre><code class=\"dockerfile\">FROM openjdk:17-alpine\n\nWORKDIR \/home\/app\n\nADD zhgc-web\/build\/libs\/zhgc-web-*.jar web.jar\n\nEXPOSE 8080\n\nCMD java $JAVA_OPTS -jar &quot;web.jar&quot;<\/code><\/pre>\n<h3>1.2 Docker Compose<\/h3>\n<p>\u4f7f\u7528<code>Docker Compose<\/code>\u7684\u76ee\u7684\uff0c\u4e3b\u8981\u662f\u670d\u52a1\u7f16\u6392\u4ee5\u53ca\u8d44\u6e90\u9650\u5236\uff0c\u6bd4\u5355\u7eaf\u7684\u4f7f\u7528Docker\u65b9\u4fbf\u4e00\u4e9b\u3002<\/p>\n<p>\u4e5f\u662f\u6bd4\u8f83\u7b80\u5355\u7684<code>docker-conpose.yml<\/code><\/p>\n<pre><code class=\"yaml\">version: '3'\nservices:\n  zhgc:\n    image: zhgc-web:latest\n    container_name: zhgc-web\n    ports:\n      - '18010:8080'\n    environment:\n      SPRING_PROFILES_ACTIVE: test\n      JAVA_OPTS: '-Xmx2g -Xmx2g'\n    deploy:\n      resources:\n        limits:\n          cpus: '2'\n          memory: 3G\n      restart_policy:\n        condition: on-failure\n        delay: 5s\n        max_attempts: 3\n        window: 120s<\/code><\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"723\" height=\"175\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc9kmx\" alt=\"image.png\" title=\"image.png\"><\/p>\n<h2>2. Jenkins<\/h2>\n<p>\u60f3\u5fc5\u80fd\u770b\u5230\u8fd9\u7bc7\u6587\u7ae0\u7684\uff0c\u5bf9<code>Jenkins<\/code>\u90fd\u4e0d\u4f1a\u964c\u751f\u3002\u57fa\u672c\u7684\u90e8\u7f72\u3001\u914d\u7f6e\u5c31\u4e0d\u518d\u53d9\u8ff0\u3002<\/p>\n<p>\u5047\u8bbe\u5df2\u642d\u5efa\u597d\u73af\u5883\u3002\u5b98\u65b9\u7f51\u7ad9 <a target=\"_blank\" href=\"https:\/\/link.segmentfault.com\/?enc=Ll0w%2BH1pycox7%2Ff8cIJ64A%3D%3D.4J3F%2BWS5XPyF%2BBA6BAm7H0BTMsHebVZ7h6fs6e4njAU%3D\" rel=\"noopener noreferrer\">https:\/\/www.jenkins.io\/<\/a><\/p>\n<h3>2.1 \u63a8\u8350\u63d2\u4ef6 Blue Ocean<\/h3>\n<p>\u754c\u9762\u7b80\u6d01\u4e14\u76f4\u89c2\uff0c\u7279\u522b\u662f\u914d\u5408<code>Pipeline<\/code>\u3002<\/p>\n<h3>2.2 Jenkins Pipeline<\/h3>\n<p>\u5b98\u65b9\u6587\u6863\uff0c\u5df2\u7ecf\u5f88\u8be6\u7ec6\u3002\u53ef\u7c97\u8bfb\u4e00\u904d\uff0c\u540e\u7eed\u6839\u636e\u9700\u8981\u518d\u7ec6\u8bfb\u3002<a target=\"_blank\" href=\"https:\/\/link.segmentfault.com\/?enc=qV24aWrLmYkWus1FXYE9mQ%3D%3D.8%2FY4JoGmyLo015Aq7i0hR2xE6xxH6K2sRIHrzucRXQXUnNigLxSzddrYz3Yy9bPX\" rel=\"noopener noreferrer\">https:\/\/www.jenkins.io\/doc\/book\/pipeline\/<\/a><\/p>\n<p>\u4e00\u4e2a\u76f8\u5bf9\u5b8c\u6574\u4e14\u7b80\u5355\u7684Pipeline\u793a\u4f8b<\/p>\n<pre><code class=\"groovy\">pipeline {\n    agent any\n    tools {\n        \/\/ \u6307\u5b9ajdk17 \u8fd9\u4e2a\u9700\u8981\u5728Jenkins\u7684Tools\u4e2d\u7684JDK\u4e2d\u6dfb\u52a0\n        jdk 'jdk17'\n    }\n    stages {\n        stage('Build-Project') {\n            steps {\n                \/\/\n                echo 'build'\n                bat(\n                        label: 'Gradle',\n                        script: '.\/gradlew build'\n                )\n            }\n            \/\/ reports\n            post {\n                success {\n                    \/\/ publish html \u53d1\u5e03\u5236\u54c1\n                    publishHTML target: [\n                            allowMissing: false,\n                            alwaysLinkToLastBuild: false,\n                            keepAll: true,\n                            reportDir: 'zhgc-web\/build\/reports\/tests\/test',\n                            reportFiles: 'index.html',\n                            reportName: 'Test Report'\n                    ]\n                }\n            }\n        }\n        stage('Build-Docker') {\n            steps {\n                bat(\n                        label: 'Docker',\n                        script: 'docker build -t zhgc-web:latest .'\n                )\n            }\n        }\n        stage('Deploy') {\n            steps {\n                bat(\n                        label: 'Deploy docker-compose',\n                        script: 'docker-compose up -d'\n                )\n            }\n        }\n    }\n    \/\/ \u63a8\u9001 \u6d4b\u8bd5\u6587\u6863\n    post {\n        always {\n            junit 'zhgc-web\/build\/test-results\/**\/*.xml'\n        }\n    }\n}<\/code><\/pre>\n<p><img decoding=\"async\" width=\"723\" height=\"240\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc9kmv\" alt=\"image.png\" title=\"image.png\" loading=\"lazy\"><\/p>\n<h3>2.3 \u53c2\u6570\u5316\u6784\u5efa<\/h3>\n<p>\u6587\u6863\u5730\u5740: <a target=\"_blank\" href=\"https:\/\/link.segmentfault.com\/?enc=uLJA%2BVRSUlHfGA2fGT5i4A%3D%3D.9fPGRBnNwuxVBc9YThB8oLiEfCgJLY2HhDJXiy3NQP16GM3lLY9uA5IxjB7C1zfB6T%2FHHvXRCZuprYoDq4Ma6ZcqG9SPaiNXtY3Sl6Q%2FOfM%3D\" rel=\"noopener noreferrer\">https:\/\/www.jenkins.io\/doc\/book\/pipeline\/syntax\/#parameters-e&#8230;<\/a><\/p>\n<pre><code class=\"groovy\">parameters {\n    choice(name: 'APPS', choices: ['all', 'agent', 'taskcenter'])\n}<\/code><\/pre>\n<p>\u4f7f\u7528<code>stage<\/code>\u914d\u5408<code>when<\/code>\u6765\u51b3\u5b9a\u662f\u5426\u8d70\u67d0\u4e2a\u6784\u5efa\u6b65\u9aa4<\/p>\n<p><img decoding=\"async\" width=\"723\" height=\"341\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc9kmu\" alt=\"image.png\" title=\"image.png\" loading=\"lazy\"><\/p>\n<h2>3 IDEA \u5b89\u88c5Jenkins\u63d2\u4ef6<\/h2>\n<p>\u6d4b\u8bd5\u53d1\u73b0\uff0c\u5bc6\u7801\u53ea\u80fd\u4f7f\u7528<code>API-TOKEN<\/code>\u3002<\/p>\n<p><code>Crumb Data<\/code>\u7684\u83b7\u53d6\u5730\u5740\u4e3a\uff1a<code>http:\/\/xxx.xx\/crumbIssuer\/api\/xml?tree=crumb<\/code> \u8fd4\u56de\u6570\u636e\u4e3a<\/p>\n<pre><code class=\"xml\">&lt;defaultCrumbIssuer _class='hudson.security.csrf.DefaultCrumbIssuer'&gt;\n    &lt;crumb&gt;6cc4228225e28cd67807a3982381ca1efda341672db606c1ca6d29da67f117d3&lt;\/crumb&gt;\n&lt;\/defaultCrumbIssuer&gt;<\/code><\/pre>\n<p>\u5176\u5b9e\u8fd9\u5757\uff0c\u8fd8\u53ef\u4ee5\u4f7f\u7528Gitlab\u548cJenkins\u914d\u5408WebHook\uff0c\u901a\u8fc7\u4e3b\u52a8\u63a8\u9001\u4ee3\u7801\u65f6\u6309\u89c4\u5219\u89e6\u53d1\u81ea\u52a8\u6784\u5efa\u3002<\/p>\n<p><img decoding=\"async\" width=\"723\" height=\"528\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc9kmt\" alt=\"image.png\" title=\"image.png\" loading=\"lazy\"><\/p>\n<p><a href=\"https:\/\/segmentfault.com\/a\/1190000044129888\">https:\/\/segmentfault.com\/a\/1190000044129888<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u57fa\u4e8eWindows+Docker\u7684\u5355\u673a\u7248\u6d4b\u8bd5\u73af\u5883\u5b9e\u8df5\u3002\u9879\u76ee\u4e0d\u5927\uff0c\u5f00\u53d1\u5468\u671f\u4e0d\u957f\u3002\u524d\u671f\u914d\u7f6e\u597d\uff0c\u540e\u7eed\u4f7f\u7528\u6574\u4f53\u6bd4\u8f83\u4e1d\u6ed1 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4],"tags":[],"class_list":["post-10008118","post","type-post","status-publish","format-standard","hentry","category-share"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts\/10008118","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10008118"}],"version-history":[{"count":0,"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts\/10008118\/revisions"}],"wp:attachment":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10008118"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=10008118"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=10008118"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}