Farid Ahmadian / DevOps

Jenkins and NodeJS


Jenkins pipelineScript.groovy


/**
 * Represents a stage with a stage label,
 * the label where the stage should be executed,
 * an action to execute and the respective arguments.
 */
class Stage implements Serializable {

    def stageLabel // label of the stage represented by this object
    def action // action to perform in the stage
    def parameters // required arguments

    Stage(stageLabel, action, parameters) {
        this.stageLabel = stageLabel
        this.action = action
        this.parameters = parameters
    }

    /**
     * Helper function which transforms a list of
     * arguments to var args before passing them
     * to the action.
     */
    private def execute(environment, enabled, Object... args) {
            if (this.stageLabel) {
                environment.stage(this.stageLabel)
            }

            if (!enabled) {
                return
            }

            if (this.stageLabel != null) {
                environment.gitlabCommitStatus(this.stageLabel) {
                    this.action.call(args)
                }
            } else {
                this.action.call(args)
            }
    }

    /**
     * Runs the stage
     */
    def run(environment, enabled) {
        execute(environment, enabled, this.parameters)
    }
}

def cleanUpWorkspace(workspace) {
    // delete all files in the workspace
    if (fileExists("${workspace}")) {
        sh "rm -rf ${workspace}"
    }
}

def checkoutSourceCode(repoUrl) {
    /// Checkouts the source branch from the specified
    /// repository into 'src' directory and merges to target branch
    checkout([
        $class: 'GitSCM',
        branches: [[name: "origin/${sourceBranch}"]],
        browser: [$class: 'GitLab', repoUrl: 'https://gitlab.pathseeker.ir', version: '8.9'],
        doGenerateSubmoduleConfigurations: false,
        extensions: [
        [$class: 'RelativeTargetDirectory', relativeTargetDir: 'src'],
        [$class: 'PreBuildMerge',
            options: [
            fastForwardMode: 'FF',
            mergeRemote: 'origin',
            mergeStrategy: 'default',
            mergeTarget: "${targetBranch}"]
            ],
        [$class: 'SubmoduleOption',
            disableSubmodules: false,
            recursiveSubmodules: true,
            reference: '',
            trackingSubmodules: false]
        ],
        submoduleCfg: [],
        userRemoteConfigs: [
            [credentialsId: 'New Jenkins Password',
            name: 'origin',
            url: "${repoUrl}"]
        ]
    ])
}

def cleanUp(targetDir) {
    if (fileExists("${targetDir}")) {
        echo "Cleaning directory ${targetDir}"
        dir("${targetDir}") {
            deleteDir()
        }
    }
}

def buildStage(workspace) {
    if (isUnix()) {
            setup_and_run_cmd = "cd ${workspace}/src;date +'%d-%m-%Y-%H:%M:%S' > BuildDate.txt; bash install_node_modules.sh; npm run build:productionPortal;cp -r . /home/jenkins/build/"
            sh(setup_and_run_cmd)

    }
}



node('nodeJS') {

    // create all stages
    def repo_url = "[email protected]:linuxCamp/nodeJS-app.git"
    def allStages = []
    allStages.add(new Stage(null, {cleanUpWorkspace it}, [workspace] as Object[])) /* Windows clean up */
    allStages.add(new Stage("Checkout", {checkoutSourceCode it}, [repo_url] as Object[])) /* Windows checkout */
    allStages.add(new Stage("Build", {buildStage it}, [workspace] as Object[])) /* perform unit tests */


    // enable / disable stages
    def enabledStages = [
        cleanBeforeBuild.toBoolean(),                        // clean up
        true,                                                // checkout
        RunBuild.toBoolean(),                                // run tests
    ]

    for (int i=0; i < allStages.size(); i++) {
        def enabled = enabledStages[i]
        allStages[i].run(this, enabled)
    }
}

docker-compose.yml


version: '2'
services:
  nodejs:
    build: ./build
    image: pathseeker/nodejs:1.0
    tty: true
    ports:
    - "22022:22"
    volumes:
    - ./data:/home/jenkins/build 
    depends_on:
      - "local-npm"   
  #https://hub.docker.com/r/orlandohohmeier/local-npm/~/dockerfile/   
  local-npm:
    image: pathseeker/local-npm:latest
    tty: true    
    build: ./build/local-npm
    ports:
    - "5080:5080"
    volumes:
    - ./npm-local:/data

local-npm Dockerfile


FROM node:6.9

MAINTAINER Orlando Hohmeier <[email protected]>

WORKDIR /local-npm
ADD . /local-npm/

RUN groupadd -r local-npm --gid=999 \
    && useradd -r -g local-npm --uid=999 local-npm

RUN npm set progress=false && npm install --no-color && npm dedupe

EXPOSE 5080
EXPOSE 16984

VOLUME /data

ENV BASE_URL='http://local-npm:5080'
ENV DATA_DIRECTORY='/data'
ENV REMOTE_REGISTRY='https://registry.npmjs.org'
ENV REMOTE_REGISTRY_SKIMDB='https://skimdb.npmjs.com/registry'

CMD mkdir -p "$DATA_DIRECTORY" chmod 700 "$DATA_DIRECTORY" \
    && chown -R local-npm "$DATA_DIRECTORY" \
    && npm start -- --remote $REMOTE_REGISTRY \
        --remote-skim $REMOTE_REGISTRY_SKIMDB --directory $DATA_DIRECTORY \
        --url-base $BASE_URL

node Dockerfile


FROM node:6.9-slim

MAINTAINER Farid Ahmadian <[email protected]>

RUN useradd -m jenkins

# Copy .ssh/known_hosts including the gitlab server's key
# ATTENTION: Make sure the public key of the gitlab server
# is contained in the provided `known_hosts` file
COPY ssh /home/jenkins/.ssh
# change ownership of the .ssh directory content
RUN chown -hR jenkins:jenkins /home/jenkins/.ssh
RUN chmod go-rwx /home/jenkins/.ssh
RUN chmod 400 /home/jenkins/.ssh/id_rsa

RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends apt-utils
RUN apt-get update && apt-get install -y openssh-server

# Global install yarn package manager
RUN apt-get update && apt-get install -y curl apt-transport-https && \
    curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
    echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
    apt-get update && apt-get install -y yarn


WORKDIR /workspace

# Copy the script to desire location
ADD docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh

ENTRYPOINT [ "sh", "/docker-entrypoint.sh" ]

RUN echo "jenkins:jenkins" | chpasswd jenkins

RUN set -ex && \
    echo 'deb http://deb.debian.org/debian jessie-backports main' \
      > /etc/apt/sources.list.d/jessie-backports.list && \

    apt update -y && \
    apt install -t \
      jessie-backports \
      openjdk-8-jre-headless \
ca-certificates-java -y

RUN apt-get install -y git
RUN npm set registry http://local-npm:5080

docker-entrypoint.sh


#!/bin/bash
/etc/init.d/ssh start
bash

jenkins_home/jobs/Builder/config.xml


<?xml version='1.1' encoding='UTF-8'?>
<flow-definition plugin="[email protected]">
  <actions/>
  <description></description>
  <keepDependencies>false</keepDependencies>
  <properties>
    <com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty plugin="[email protected]">
      <gitLabConnection>GitLab Server Connection</gitLabConnection>
    </com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty>
    <hudson.model.ParametersDefinitionProperty>
      <parameterDefinitions>
        <hudson.model.BooleanParameterDefinition>
          <name>cleanBeforeBuild</name>
          <description></description>
          <defaultValue>false</defaultValue>
        </hudson.model.BooleanParameterDefinition>
        <hudson.model.BooleanParameterDefinition>
          <name>RunBuild</name>
          <description></description>
          <defaultValue>true</defaultValue>
        </hudson.model.BooleanParameterDefinition>
        <hudson.model.StringParameterDefinition>
          <name>sourceBranch</name>
          <description></description>
          <defaultValue>master</defaultValue>
          <trim>false</trim>
        </hudson.model.StringParameterDefinition>
        <hudson.model.StringParameterDefinition>
          <name>targetBranch</name>
          <description></description>
          <defaultValue>master</defaultValue>
          <trim>false</trim>
        </hudson.model.StringParameterDefinition>
      </parameterDefinitions>
    </hudson.model.ParametersDefinitionProperty>
    <org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty>
      <triggers>
        <com.dabsquared.gitlabjenkins.GitLabPushTrigger plugin="[email protected]">
          <spec></spec>
          <triggerOnPush>true</triggerOnPush>
          <triggerOnMergeRequest>true</triggerOnMergeRequest>
          <triggerOnPipelineEvent>false</triggerOnPipelineEvent>
          <triggerOnAcceptedMergeRequest>false</triggerOnAcceptedMergeRequest>
          <triggerOnClosedMergeRequest>false</triggerOnClosedMergeRequest>
          <triggerOpenMergeRequestOnPush>never</triggerOpenMergeRequestOnPush>
          <triggerOnNoteRequest>true</triggerOnNoteRequest>
          <noteRegex>@jenkins rebuild</noteRegex>
          <ciSkip>true</ciSkip>
          <skipWorkInProgressMergeRequest>true</skipWorkInProgressMergeRequest>
          <setBuildDescription>true</setBuildDescription>
          <branchFilterType>All</branchFilterType>
          <includeBranchesSpec></includeBranchesSpec>
          <excludeBranchesSpec></excludeBranchesSpec>
          <targetBranchRegex></targetBranchRegex>
          <secretToken>{AQAAABAAAAAQ3ZQX7gSjEN5TSx6Qi77xM8AU5at4slVt+odvdtBKFVY=}</secretToken>
        </com.dabsquared.gitlabjenkins.GitLabPushTrigger>
      </triggers>
    </org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty>
  </properties>
  <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="[email protected]">
    <script>
    </script>
    <sandbox>true</sandbox>
  </definition>
  <triggers/>
  <disabled>false</disabled>
</flow-definition>

BY: Farid Ahmadian
TAG: Jenkins, NodeJS, Dockerfile, docker
DATE: 2018-06-13 10:36:53


Farid Ahmadian / DevOps [ TXT ]

With many thanks and best wishes for dear Pejman Moghadam, someone who taught me alot in linux and life :)