Jenkins — NodeJS + Nginx

Пример MultibranchPipeline сборки и деплоя NodeJS при помощи Jenkins'а, упаковывание собранного в контейнер с Nginx'ом и обновлением образа в Kubernetes. В качестве хранилища образов используется AWS ECR, уведомления о сборке отправляются в SLACK канал.

Jenkinsfile:

pipeline{
    parameters {
        booleanParam(name: 'del_cache', defaultValue: false, description: 'Toggle this value to build with cache clearing.')
    }
    agent any
    environment {
        SLACK_CHANNEL = '#maintenance-test'
        IMAGE_REPO = 'XXXXXXXXXXXX.dkr.ecr.eu-west-1.amazonaws.com/artem'
        KUBECTL = 'kubectl --kubeconfig=/var/lib/jenkins/.kube/k8s-artem.yml'
        PROJECT_NAME = 'test-web'
        REPO = 'https://git.artem.services/scm/dev/test-web.git'
        REPO_CRED = 'svc-bitbucket'
    }
    options {
        ansiColor('xterm')
        timeout(time: 30, unit:'MINUTES')
        timestamps()
    }
    stages {
        stage ('Authorization in repo') {
            steps {
                script {
                    sh 'eval "$(aws ecr get-login --profile artem --region eu-west-1 --no-include-email)" &> /dev/null'
                }
            }
        }
        stage ('Delete Work Dir') {
            when { expression { return params.del_cache } }
            steps {
                deleteDir()
                git branch: "${BRANCH_NAME}", credentialsId: "${REPO_CRED}", url: "${REPO}"
            }
        }
        stage ('Build app') {
            agent {
                docker {
                    image 'node:latest'
                    args "--name ${BUILD_TAG}-app \
                    -v /etc/passwd:/etc/passwd:ro"
                    reuseNode true                
                }
            }
            environment {
                HOME = "${WORKSPACE}"
            }
            steps {
                sh "npm install"
                sh "npm run build"
            }
        }
        stage ('Build app image') {
            steps {
                script {
                    withDockerServer([uri:'tcp://127.0.0.1:4243']) {
                        sh 'eval "$(aws ecr get-login --profile artem --region eu-west-1 --no-include-email)" &> /dev/null'
                        echo "Debug: Building  with docker.build(${IMAGE_REPO}:${PROJECT_NAME}-${JOB_BASE_NAME}-${BUILD_NUMBER})"
                        sh "cp ./.jenkins/Dockerfile ./Dockerfile"
                        def image = docker.build ("${IMAGE_REPO}:${PROJECT_NAME}-${JOB_BASE_NAME}-${BUILD_NUMBER}")
                        echo "Debug: Before push to registry"
                        image.push ()
                        echo "Debug: After push to registry"
                    }
                }
            }
        }
        stage ('Deploy on staging.') {
            when { branch 'staging' }
            steps {
                sh "${KUBECTL} -n staging set image deployment.v1.apps/${PROJECT_NAME}-app ${PROJECT_NAME}=${IMAGE_REPO}:${PROJECT_NAME}-${JOB_BASE_NAME}-${BUILD_NUMBER} --record"
            }
        }
    }
    post {
        success {
            slackSend channel: "${SLACK_CHANNEL}", color: 'good', message: "Job: ${JOB_NAME}${BUILD_NUMBER} build was successful."
        }
        failure {
            slackSend channel: "${SLACK_CHANNEL}", color: 'danger', message: "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"
        }
        unstable {
            slackSend channel: "${SLACK_CHANNEL}", color: 'warning', message: "Job: ${JOB_NAME}${BUILD_NUMBER} was finished with some error. Please watch the Jenkins Console Output: ${JOB_URL}${BUILD_ID}/console."
        }
    }
}

Dockerfile:

FROM nginx:latest

RUN rm -f /etc/nginx/nginx.conf /etc/nginx/sites-enabled/default

COPY ./.jenkins/nginx.conf /etc/nginx
COPY ./.jenkins/app.conf /etc/nginx/conf.d/default.conf
COPY ./build/ /usr/src/app

CMD /usr/sbin/nginx -c /etc/nginx/nginx.conf

WORKDIR /usr/src/app

EXPOSE 80

 

nginx.conf

user root;
worker_processes auto;
pid /run/nginx.pid;

events {
	worker_connections 2048;
	# multi_accept on;
}

http {

	##
	# Basic Settings
	##
	client_body_buffer_size 256K;
	client_max_body_size 0;

	
	send_timeout 300s;
	sendfile on;
	keepalive_timeout 65;
	types_hash_max_size 2048;
	# server_tokens off;

	# server_names_hash_bucket_size 64;
	# server_name_in_redirect off;

	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	##
	# SSL Settings
	##

	ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
	ssl_prefer_server_ciphers on;

	##
	# Logging Settings
	##

	log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    	  '$status $body_bytes_sent "$http_referer" '
                      	  '"$http_user_agent" "$http_x_forwarded_for"'
                      	  '$request_time $upstream_response_time $pipe';



	access_log /var/log/nginx/access.log main;
	error_log /var/log/nginx/error.log;

	##
	# Gzip Settings
	##

	gzip on;
	gzip_disable "msie6";

	gzip_vary on;
	gzip_proxied any;
	gzip_comp_level 6;
	gzip_buffers 16 8k;
	gzip_http_version 1.0;
	gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;
}
daemon off;

 

app.conf

server {
    listen 80 default_server;
    root /usr/src/app;
    index index.html;
 
    location / {
        try_files $uri $uri/ /index.html;
     }

    location ~* \.(mp4|obj|mtl|ttf|woff|pdf|jpg|jpeg|gif|png|ico|css|bmp|swf|js|html|txt|svg)$ {
        expires max;
    }
}
0 0 vote
Рейтинг статьи

Метки: Метки

Подписаться
Уведомление о
guest
0 комментариев
Inline Feedbacks
View all comments