Skip to content

Instantly share code, notes, and snippets.

@renepardon
Created December 20, 2018 09:15
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save renepardon/3f45d1bcb95caf7e6839dd91e6f2c85e to your computer and use it in GitHub Desktop.
Save renepardon/3f45d1bcb95caf7e6839dd91e6f2c85e to your computer and use it in GitHub Desktop.
Create CI/CD setup with Jenkins and worker nodes
version: '3.2'
services:
jenkins:
build: ./jenkins
container_name: jenkins
ports:
- "50000:50000"
expose:
- 8080
restart: always
environment:
- VIRTUAL_HOST=${JENKINS_HOST}
- VIRTUAL_PORT=8080
- LETSENCRYPT_HOST=${JENKINS_HOST}
- LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}
- "constraint:NODE==cl-leader"
volumes:
- '/srv/jenkins:/var/jenkins_home'
- '/var/run/docker.sock:/var/run/docker.sock'
depends_on:
- sonarqube
logging:
driver: gelf
options:
gelf-address: ${GELF_HOST}
sonarqube:
build: ./sonarqube
container_name: sonarqube
depends_on:
- db
links:
- db
environment:
- SONARQUBE_JDBC_USERNAME=${SONARQUBE_JDBC_USERNAME}
- SONARQUBE_JDBC_PASSWORD=${SONARQUBE_JDBC_PASSWORD}
- SONARQUBE_JDBC_URL=jdbc:postgresql://db:5432/sonar
- sonar.jdbc.url=jdbc:postgresql://db:5432/sonar
- VIRTUAL_HOST=${SONARQUBE_HOST}
- VIRTUAL_PORT=9000
- LETSENCRYPT_HOST=${SONARQUBE_HOST}
- LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}
ports:
- 9000:9000
- 9092:9092
restart: always
logging:
driver: gelf
options:
gelf-address: ${GELF_HOST}
db:
image: postgres
environment:
- POSTGRES_DB=sonar
- POSTGRES_USER=${SONARQUBE_JDBC_USERNAME}
- POSTGRES_PASSWORD=${SONARQUBE_JDBC_PASSWORD}
expose:
- 5432
restart: always
volumes:
- '/srv/sonarqube/db:/var/lib/postgresql'
# This needs explicit mapping due to https://github.com/docker-library/postgres/blob/4e48e3228a30763913ece952c611e5e9b95c8759/Dockerfile.template#L52
- '/srv/sonarqube/db_data:/var/lib/postgresql/data'
jenkins_slave_nodejs:
build: ./jenkins_slave_nodejs
container_name: jenkins_slave_nodejs_1
command: -url https://${JENKINS_HOST}/ ${JENKINS_SLAVE_NODEJS_SECRET} jenkins-slave-nodejs
restart: always
environment:
- 'JAVA_OPTS=-Dhudson.footerURL=https://jenkinsdomain.internal'
volumes:
- '/srv/jenkins_slave_nodejs:/var/jenkins_home'
- '/var/run/docker.sock:/var/run/docker.sock'
logging:
driver: gelf
options:
gelf-address: ${GELF_HOST}
jenkins_slave_php:
build: ./jenkins_slave_php
container_name: jenkins_slave_php_1
command: -url https://jenkinsdomain.internal/ ${JENKINS_SLAVE_PHP_SECRET} jenkins-slave-php
restart: always
environment:
- 'JAVA_OPTS=-Dhudson.footerURL=https://jenkinsdomain.internal'
volumes:
- '/srv/jenkins_slave_php:/var/jenkins_home'
- '/var/run/docker.sock:/var/run/docker.sock'
logging:
driver: gelf
options:
gelf-address: ${GELF_HOST}
jenkins_slave_php_js:
build: ./jenkins_slave_php_js
container_name: jenkins_slave_php_js_1
command: -url https://jenkinsdomain.internal/ ${JENKINS_SLAVE_PHP_JS_SECRET} jenkins-slave-php-js
restart: always
environment:
- 'JAVA_OPTS=-Dhudson.footerURL=https://jenkinsdomain.internal'
volumes:
- '/srv/jenkins_slave_php_js:/var/jenkins_home'
- '/var/run/docker.sock:/var/run/docker.sock'
logging:
driver: gelf
options:
gelf-address: ${GELF_HOST}
worker:
image: jenkins/jnlp-slave:3.27-1
command: -url https://jenkinsdomain.internal/ -workDir=/home/jenkins/agent ${WORKER_SECRET} worker
logging:
driver: gelf
options:
gelf-address: ${GELF_HOST}
networks:
default:
external:
name: nginx-proxy
FROM jenkins/jnlp-slave:3.27-1
LABEL Description="This is a base image, which allows connecting Jenkins agents via JNLP protocols" Vendor="Jenkins project" Version="3.23"
# See https://github.com/jenkinsci/docker-jnlp-slave for more information
# Customization of jnlp slave to install required packages for building/testing
USER root
# JS/NPM RELATED STUFF
COPY jenkins-slave.sh /usr/local/bin/jenkins-slave
RUN chmod +x /usr/local/bin/jenkins-slave
RUN apt-get update && \
apt-get install -y curl build-essential libssl-dev software-properties-common zip apt-transport-https ca-certificates curl gnupg2 && \
apt-get -y autoclean
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
RUN apt-get install nodejs
RUN node -v && npm -v
# Install required global packages for build/test
RUN npm install -g grunt
RUN chown -R jenkins /usr/lib/node_modules
RUN chown -R jenkins /home/jenkins/.npm
# NOW THE PHP STUFF
COPY jenkins-slave.sh /usr/local/bin/jenkins-slave
RUN chmod +x /usr/local/bin/jenkins-slave
RUN apt-get update && \
apt-get install -y --no-install-recommends lsb-release git zip
RUN wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
RUN sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
RUN apt-get update && \
apt-get install -y php7.2-cli php7.2-xdebug php7.2-sqlite3 php7.2-mysql php7.2-mbstring php7.2-dom php7.2-curl php7.2-gd php7.2-ldap php7.2-opcache php7.2-calendar php7.2-ctype php7.2-exif php7.2-fileinfo php7.2-ftp php7.2-gettext php7.2-iconv php7.2-json php7.2-phar php7.2-posix php7.2-readline php7.2-shmop php7.2-sockets php7.2-sysvmsg php7.2-sysvsem php7.2-sysvshm php7.2-tokenizer && \
apt-get autoclean -y
RUN curl --silent --show-error https://getcomposer.org/installer | php && \
mv composer.phar /usr/local/bin/composer && \
chown jenkins /usr/local/bin/composer && \
chown -R jenkins /home/jenkins/.composer
# FINALLY WE NEED DOCKER TO BE ABLE TO BUILD IMAGES WITHIN THIS CONTAINER
# IMPORTANT NOTE: docker daemon running on host must be the same version as the client libraries installing now!
RUN curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && \
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") $(lsb_release -cs) stable" && \
apt-get update && \
apt-get -y install docker-ce
RUN usermod -a -G docker jenkins
USER jenkins
ENV PATH=/home/jenkins/.composer/vendor/bin:$PATH
RUN composer global require phing/phing
RUN composer global require phpunit/phpunit
RUN composer global require phpunit/php-code-coverage
RUN composer global require phpunit/dbunit
RUN composer global require phing/phing
RUN composer global require sebastian/phpcpd
RUN composer global require phploc/phploc
RUN composer global require phpmd/phpmd
RUN composer global require phpab/phpab
RUN composer global require pdepend/pdepend
RUN composer global require squizlabs/php_codesniffer
RUN composer global require pear/archive_tar
# RUN composer global require theseer/phpdox
ENTRYPOINT ["/usr/local/bin/jenkins-slave"]
#!/usr/bin/env sh
# The MIT License
#
# Copyright (c) 2015, CloudBees, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# Usage jenkins-slave.sh [options] -url http://jenkins [SECRET] [AGENT_NAME]
# Optional environment variables :
# * JENKINS_TUNNEL : HOST:PORT for a tunnel to route TCP traffic to jenkins host, when jenkins can't be directly accessed over network
# * JENKINS_URL : alternate jenkins URL
# * JENKINS_SECRET : agent secret, if not set as an argument
# * JENKINS_AGENT_NAME : agent name, if not set as an argument
# * JENKINS_AGENT_WORKDIR : agent work directory, if not set by optional parameter -workDir
if [ $# -eq 1 ]; then
# if `docker run` only has one arguments, we assume user is running alternate command like `bash` to inspect the image
exec "$@"
else
# if -tunnel is not provided, try env vars
case "$@" in
*"-tunnel "*) ;;
*)
if [ ! -z "$JENKINS_TUNNEL" ]; then
TUNNEL="-tunnel $JENKINS_TUNNEL"
fi ;;
esac
# if -workDir is not provided, try env vars
if [ ! -z "$JENKINS_AGENT_WORKDIR" ]; then
case "$@" in
*"-workDir"*) echo "Warning: Work directory is defined twice in command-line arguments and the environment variable" ;;
*)
WORKDIR="-workDir $JENKINS_AGENT_WORKDIR" ;;
esac
fi
if [ -n "$JENKINS_URL" ]; then
URL="-url $JENKINS_URL"
fi
if [ -n "$JENKINS_NAME" ]; then
JENKINS_AGENT_NAME="$JENKINS_NAME"
fi
if [ -z "$JNLP_PROTOCOL_OPTS" ]; then
echo "Warning: JnlpProtocol3 is disabled by default, use JNLP_PROTOCOL_OPTS to alter the behavior"
JNLP_PROTOCOL_OPTS="-Dorg.jenkinsci.remoting.engine.JnlpProtocol3.disabled=true"
fi
# if java home is defined, use it
JAVA_BIN="java"
if [ "$JAVA_HOME" ]; then
JAVA_BIN="$JAVA_HOME/bin/java"
fi
# if both required options are defined, do not pass the parameters
OPT_JENKINS_SECRET=""
if [ -n "$JENKINS_SECRET" ]; then
case "$@" in
*"${JENKINS_SECRET}"*) echo "Warning: SECRET is defined twice in command-line arguments and the environment variable" ;;
*)
OPT_JENKINS_SECRET="${JENKINS_SECRET}" ;;
esac
fi
OPT_JENKINS_AGENT_NAME=""
if [ -n "$JENKINS_AGENT_NAME" ]; then
case "$@" in
*"${JENKINS_AGENT_NAME}"*) echo "Warning: AGENT_NAME is defined twice in command-line arguments and the environment variable" ;;
*)
OPT_JENKINS_AGENT_NAME="${JENKINS_AGENT_NAME}" ;;
esac
fi
#TODO: Handle the case when the command-line and Environment variable contain different values.
#It is fine it blows up for now since it should lead to an error anyway.
exec $JAVA_BIN $JAVA_OPTS $JNLP_PROTOCOL_OPTS -cp /usr/share/jenkins/slave.jar hudson.remoting.jnlp.Main -headless $TUNNEL $URL $WORKDIR $OPT_JENKINS_SECRET $OPT_JENKINS_AGENT_NAME "$@"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment