{"id":973,"date":"2019-03-20T19:03:44","date_gmt":"2019-03-20T16:03:44","guid":{"rendered":"https:\/\/artem.services\/?p=973"},"modified":"2019-03-20T19:12:48","modified_gmt":"2019-03-20T16:12:48","slug":"jenkins-node-js","status":"publish","type":"post","link":"https:\/\/artem.services\/?p=973","title":{"rendered":"Jenkins &#8212; NodeJS + Nginx"},"content":{"rendered":"<p><img loading=\"lazy\" class=\"size-full wp-image-819 aligncenter\" src=\"https:\/\/artem.services\/wp-content\/uploads\/2019\/02\/Jenkins-Logo.png\" alt=\"\" width=\"1280\" height=\"412\" srcset=\"https:\/\/artem.services\/wp-content\/uploads\/2019\/02\/Jenkins-Logo.png 1280w, https:\/\/artem.services\/wp-content\/uploads\/2019\/02\/Jenkins-Logo-300x97.png 300w, https:\/\/artem.services\/wp-content\/uploads\/2019\/02\/Jenkins-Logo-768x247.png 768w, https:\/\/artem.services\/wp-content\/uploads\/2019\/02\/Jenkins-Logo-1024x330.png 1024w, https:\/\/artem.services\/wp-content\/uploads\/2019\/02\/Jenkins-Logo-954x307.png 954w\" sizes=\"(max-width: 1280px) 100vw, 1280px\" \/><\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 <strong>MultibranchPipeline<\/strong> \u0441\u0431\u043e\u0440\u043a\u0438 \u0438 \u0434\u0435\u043f\u043b\u043e\u044f <strong>NodeJS<\/strong> \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <strong>Jenkins<\/strong>&#39;\u0430, \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 <strong>Nginx<\/strong>&#39;\u043e\u043c \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043e\u0431\u0440\u0430\u0437\u0430 \u0432 <strong>Kubernetes<\/strong>. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <strong>AWS ECR<\/strong>, \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043e \u0441\u0431\u043e\u0440\u043a\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 <strong>SLACK<\/strong> \u043a\u0430\u043d\u0430\u043b.<\/p>\n<h4>Jenkinsfile:<\/h4>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\npipeline{\r\n    parameters {\r\n        booleanParam(name: 'del_cache', defaultValue: false, description: 'Toggle this value to build with cache clearing.')\r\n    }\r\n    agent any\r\n    environment {\r\n        SLACK_CHANNEL = '#maintenance-test'\r\n        IMAGE_REPO = 'XXXXXXXXXXXX.dkr.ecr.eu-west-1.amazonaws.com\/artem'\r\n        KUBECTL = 'kubectl --kubeconfig=\/var\/lib\/jenkins\/.kube\/k8s-artem.yml'\r\n        PROJECT_NAME = 'test-web'\r\n        REPO = 'https:\/\/git.artem.services\/scm\/dev\/test-web.git'\r\n        REPO_CRED = 'svc-bitbucket'\r\n    }\r\n    options {\r\n        ansiColor('xterm')\r\n        timeout(time: 30, unit:'MINUTES')\r\n        timestamps()\r\n    }\r\n    stages {\r\n        stage ('Authorization in repo') {\r\n            steps {\r\n                script {\r\n                    sh 'eval &quot;$(aws ecr get-login --profile artem --region eu-west-1 --no-include-email)&quot; &amp;&gt; \/dev\/null'\r\n                }\r\n            }\r\n        }\r\n        stage ('Delete Work Dir') {\r\n            when { expression { return params.del_cache } }\r\n            steps {\r\n                deleteDir()\r\n                git branch: &quot;${BRANCH_NAME}&quot;, credentialsId: &quot;${REPO_CRED}&quot;, url: &quot;${REPO}&quot;\r\n            }\r\n        }\r\n        stage ('Build app') {\r\n            agent {\r\n                docker {\r\n                    image 'node:latest'\r\n                    args &quot;--name ${BUILD_TAG}-app \\\r\n                    -v \/etc\/passwd:\/etc\/passwd:ro&quot;\r\n                    reuseNode true                \r\n                }\r\n            }\r\n            environment {\r\n                HOME = &quot;${WORKSPACE}&quot;\r\n            }\r\n            steps {\r\n                sh &quot;npm install&quot;\r\n                sh &quot;npm run build&quot;\r\n            }\r\n        }\r\n        stage ('Build app image') {\r\n            steps {\r\n                script {\r\n                    withDockerServer([uri:'tcp:\/\/127.0.0.1:4243']) {\r\n                        sh 'eval &quot;$(aws ecr get-login --profile artem --region eu-west-1 --no-include-email)&quot; &amp;&gt; \/dev\/null'\r\n                        echo &quot;Debug: Building  with docker.build(${IMAGE_REPO}:${PROJECT_NAME}-${JOB_BASE_NAME}-${BUILD_NUMBER})&quot;\r\n                        sh &quot;cp .\/.jenkins\/Dockerfile .\/Dockerfile&quot;\r\n                        def image = docker.build (&quot;${IMAGE_REPO}:${PROJECT_NAME}-${JOB_BASE_NAME}-${BUILD_NUMBER}&quot;)\r\n                        echo &quot;Debug: Before push to registry&quot;\r\n                        image.push ()\r\n                        echo &quot;Debug: After push to registry&quot;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        stage ('Deploy on staging.') {\r\n            when { branch 'staging' }\r\n            steps {\r\n                sh &quot;${KUBECTL} -n staging set image deployment.v1.apps\/${PROJECT_NAME}-app ${PROJECT_NAME}=${IMAGE_REPO}:${PROJECT_NAME}-${JOB_BASE_NAME}-${BUILD_NUMBER} --record&quot;\r\n            }\r\n        }\r\n    }\r\n    post {\r\n        success {\r\n            slackSend channel: &quot;${SLACK_CHANNEL}&quot;, color: 'good', message: &quot;Job: ${JOB_NAME}${BUILD_NUMBER} build was successful.&quot;\r\n        }\r\n        failure {\r\n            slackSend channel: &quot;${SLACK_CHANNEL}&quot;, color: 'danger', message: &quot;Job: ${JOB_NAME}${BUILD_NUMBER} was finished with some error. It may occurs because of the build was rollbacked by docker swarm, or because of other error (watch the Jenkins Console Output): ${JOB_URL}${BUILD_ID}\/consoleFull&quot;\r\n        }\r\n        unstable {\r\n            slackSend channel: &quot;${SLACK_CHANNEL}&quot;, color: 'warning', message: &quot;Job: ${JOB_NAME}${BUILD_NUMBER} was finished with some error. Please watch the Jenkins Console Output: ${JOB_URL}${BUILD_ID}\/console.&quot;\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p><!--more--><\/p>\n<h4>Dockerfile:<\/h4>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nFROM nginx:latest\r\n\r\nRUN rm -f \/etc\/nginx\/nginx.conf \/etc\/nginx\/sites-enabled\/default\r\n\r\nCOPY .\/.jenkins\/nginx.conf \/etc\/nginx\r\nCOPY .\/.jenkins\/app.conf \/etc\/nginx\/conf.d\/default.conf\r\nCOPY .\/build\/ \/usr\/src\/app\r\n\r\nCMD \/usr\/sbin\/nginx -c \/etc\/nginx\/nginx.conf\r\n\r\nWORKDIR \/usr\/src\/app\r\n\r\nEXPOSE 80\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h4>nginx.conf<\/h4>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nuser root;\r\nworker_processes auto;\r\npid \/run\/nginx.pid;\r\n\r\nevents {\r\n\tworker_connections 2048;\r\n\t# multi_accept on;\r\n}\r\n\r\nhttp {\r\n\r\n\t##\r\n\t# Basic Settings\r\n\t##\r\n\tclient_body_buffer_size 256K;\r\n\tclient_max_body_size 0;\r\n\r\n\t\r\n\tsend_timeout 300s;\r\n\tsendfile on;\r\n\tkeepalive_timeout 65;\r\n\ttypes_hash_max_size 2048;\r\n\t# server_tokens off;\r\n\r\n\t# server_names_hash_bucket_size 64;\r\n\t# server_name_in_redirect off;\r\n\r\n\tinclude \/etc\/nginx\/mime.types;\r\n\tdefault_type application\/octet-stream;\r\n\r\n\t##\r\n\t# SSL Settings\r\n\t##\r\n\r\n\tssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE\r\n\tssl_prefer_server_ciphers on;\r\n\r\n\t##\r\n\t# Logging Settings\r\n\t##\r\n\r\n\tlog_format  main  '$remote_addr - $remote_user [$time_local] &quot;$request&quot; '\r\n                    \t  '$status $body_bytes_sent &quot;$http_referer&quot; '\r\n                      \t  '&quot;$http_user_agent&quot; &quot;$http_x_forwarded_for&quot;'\r\n                      \t  '$request_time $upstream_response_time $pipe';\r\n\r\n\r\n\r\n\taccess_log \/var\/log\/nginx\/access.log main;\r\n\terror_log \/var\/log\/nginx\/error.log;\r\n\r\n\t##\r\n\t# Gzip Settings\r\n\t##\r\n\r\n\tgzip on;\r\n\tgzip_disable &quot;msie6&quot;;\r\n\r\n\tgzip_vary on;\r\n\tgzip_proxied any;\r\n\tgzip_comp_level 6;\r\n\tgzip_buffers 16 8k;\r\n\tgzip_http_version 1.0;\r\n\tgzip_types text\/plain text\/css application\/json application\/javascript text\/xml application\/xml application\/xml+rss text\/javascript;\r\n\r\n\tinclude \/etc\/nginx\/conf.d\/*.conf;\r\n\tinclude \/etc\/nginx\/sites-enabled\/*;\r\n}\r\ndaemon off;\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h4>app.conf<\/h4>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nserver {\r\n    listen 80 default_server;\r\n    root \/usr\/src\/app;\r\n    index index.html;\r\n \r\n    location \/ {\r\n        try_files $uri $uri\/ \/index.html;\r\n     }\r\n\r\n    location ~* \\.(mp4|obj|mtl|ttf|woff|pdf|jpg|jpeg|gif|png|ico|css|bmp|swf|js|html|txt|svg)$ {\r\n        expires max;\r\n    }\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u043c\u0435\u0440 MultibranchPipeline \u0441\u0431\u043e\u0440\u043a\u0438 \u0438 \u0434\u0435\u043f\u043b\u043e\u044f NodeJS \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 Jenkins&#39;\u0430, \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 Nginx&#39;\u043e\u043c \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043e\u0431\u0440\u0430\u0437\u0430 \u0432 Kubernetes. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f AWS ECR, \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043e \u0441\u0431\u043e\u0440\u043a\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 SLACK \u043a\u0430\u043d\u0430\u043b. Jenkinsfile:<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[37],"tags":[39,125,10,721,723],"_links":{"self":[{"href":"https:\/\/artem.services\/index.php?rest_route=\/wp\/v2\/posts\/973"}],"collection":[{"href":"https:\/\/artem.services\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/artem.services\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/artem.services\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/artem.services\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=973"}],"version-history":[{"count":7,"href":"https:\/\/artem.services\/index.php?rest_route=\/wp\/v2\/posts\/973\/revisions"}],"predecessor-version":[{"id":980,"href":"https:\/\/artem.services\/index.php?rest_route=\/wp\/v2\/posts\/973\/revisions\/980"}],"wp:attachment":[{"href":"https:\/\/artem.services\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=973"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/artem.services\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=973"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/artem.services\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=973"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}