diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1120be9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +docker-compose.yml diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..482f492 --- /dev/null +++ b/Makefile @@ -0,0 +1,92 @@ +############################################################################## +# Environment variables +# Set locales +# +CITY=$(shell timedatectl | awk '/Time zone/ {print $$3}' | awk -F/ '{print $$2}') +COUNTRY=$(shell echo $$LANG | awk -F. '{print $$1}' | awk -F_ '{print $$2}') +LANGUAGE=$(shell echo $$LANG | awk -F. '{print $$1}' | awk -F_ '{print $$2}') +TIMEZONE=$(shell timedatectl | awk '/Time zone/ {print $$3}') + +############################################################################## + +.PHONY: help # This help message +help: + @grep '^.PHONY: .* #' Makefile \ + | sed 's/\.PHONY: \(.*\) # \(.*\)/\1\t\2/' \ + | expand -t20 \ + | sort + +############################################################################## + +.PHONY: prepare # Generate Dockerfiles from templates +prepare: + # Sonar: Set locales and proxy + @sed "s!%%COUNTRY%%!${COUNTRY}! ; \ + s!%%LANGUAGE%%!${LANGUAGE}! ; \ + s!%%TIMEZONE%%!${TIMEZONE}! ; \ + s!%%HTTP_PROXY%%!${HTTP_PROXY}!" \ + sonar/Dockerfile.tmpl > sonar/Dockerfile + + # Jenkins: Set locales and proxy + @sed "s!%%HTTP_PROXY%%!${HTTP_PROXY}!" \ + jenkins/Dockerfile.tmpl > jenkins/Dockerfile + + @test -z ${HTTP_PROXY} \ + && sed '/HTTP_PROXY/d' \ + jenkins/Dockerfile.tmpl > jenkins/Dockerfile \ + || true + + # Nexus: Set proxy + @sed "s!%%HTTP_PROXY%%!${HTTP_PROXY}!" \ + nexus/Dockerfile.tmpl > nexus/Dockerfile + + @test -z ${HTTP_PROXY} \ + && sed '/^HTTP_OPTIONS/d' \ + nexus/Dockerfile.tmpl > nexus/Dockerfile \ + || true + + # docker-compose: Set traefik virtualhost + @test -z ${TRAEFIK_VIRTUALHOST} \ + && sed "s/%%TRAEFIK_VIRTUALHOST%%/localhost/" \ + docker-compose.yml.tmpl > docker-compose.yml \ + || sed "s/%%TRAEFIK_VIRTUALHOST%%/${TRAEFIK_VIRTUALHOST}/" \ + docker-compose.yml.tmpl > docker-compose.yml + +.PHONY: clean # Stop and remove temporary files +clean: down + @docker-compose rm + + @rm -f \ + jenkins/Dockerfile \ + nexus/Dockerfile \ + sonar/Dockerfile \ + docker-compose.yml + +############################################################################## + +.PHONY: status # Get stack status "docker-compose ps" +status: + @docker-compose ps + +.PHONY: up # Start "docker-compose up" +up: prepare + @docker-compose up + +.PHONY: daemon # Start "docker-compose up -d" +daemon: prepare + @docker-compose up -d + +.PHONY: down # Stop the stack "docker-compose down" +down: + @docker-compose down + +.PHONY: rebuild # Rebuild the containers and run +rebuild: prepare + @docker-compose down --rmi all + @docker-compose up --build + +.PHONY: daemon-rebuild # Rebuild the containers and run +daemon-rebuild: prepare + @docker-compose down --rmi all + @docker-compose up --build -d + diff --git a/docker-compose.yml b/docker-compose.yml index bd01c5c..471fc8a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,20 +9,33 @@ volumes: jenkins-data: services: - nexus: - build: ./docker-nexus3 + traefik: + image: traefik:montdor restart: always + command: --accesslog --api --api.insecure=true --log --providers.docker=true --providers.docker.exposedbydefault=false ports: - - "18081:8081" + - "80:80" + - "443:443" + - "8080:8080" + networks: + - prodnetwork + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + nexus: + # Nexus3 uses chef-solo. HTTP_PROXY env is not used. + # TODO: deal with Nexus3 and proxies. + build: ./nexus + restart: always networks: - prodnetwork volumes: - nexus-data:/nexus-data + labels: + - "traefik.enable=true" + - "traefik.http.routers.nexus.rule=Host(`localhost`) && PathPrefix(`/nexus/`)" jenkins: build: ./jenkins restart: always - ports: - - "18080:8080" networks: - prodnetwork volumes: @@ -36,22 +49,21 @@ services: - NEXUS_PORT=8081 - SONAR_PORT=9000 - SONAR_DB_PORT=5432 + - JENKINS_OPTS=--prefix=/jenkins/ + labels: + - "traefik.enable=true" + - "traefik.http.routers.jenkins.rule=Host(`localhost`) && PathPrefix(`/jenkins`)" sonardb: networks: - prodnetwork restart: always image: postgres:9.6 - ports: - - "5432:5432" environment: - POSTGRES_USER=sonar - POSTGRES_PASSWORD=sonar sonar: image: sonarqube restart: always - ports: - - "19000:9000" - - "19092:9092" networks: - prodnetwork depends_on: @@ -60,6 +72,10 @@ services: - SONARQUBE_JDBC_URL=jdbc:postgresql://sonardb:5432/sonar - SONARQUBE_JDBC_USERNAME=sonar - SONARQUBE_JDBC_PASSWORD=sonar + - sonar.web.context=/sonar + labels: + - "traefik.enable=true" + - "traefik.http.routers.sonar.rule=Host(`localhost`) && PathPrefix(`/sonar/`)" ########################################################################################## # DISABLED: GitLab takes too much memory and CPU. Demo uses GitHub repositories instead. diff --git a/docker-compose.yml.tmpl b/docker-compose.yml.tmpl new file mode 100644 index 0000000..112ab10 --- /dev/null +++ b/docker-compose.yml.tmpl @@ -0,0 +1,99 @@ +version: '3' + +networks: + prodnetwork: + driver: bridge + +volumes: + nexus-data: + jenkins-data: + +services: + traefik: + image: traefik:montdor + restart: always + command: --accesslog --api --api.insecure=true --log --providers.docker=true --providers.docker.exposedbydefault=false + ports: + - "80:80" + - "443:443" + - "8080:8080" + networks: + - prodnetwork + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + nexus: + # Nexus3 uses chef-solo. HTTP_PROXY env is not used. + # TODO: deal with Nexus3 and proxies. + build: ./nexus + restart: always + networks: + - prodnetwork + volumes: + - nexus-data:/nexus-data + labels: + - "traefik.enable=true" + - "traefik.http.routers.nexus.rule=Host(`%%TRAEFIK_VIRTUALHOST%%`) && PathPrefix(`/nexus/`)" + jenkins: + build: ./jenkins + restart: always + networks: + - prodnetwork + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /usr/bin/docker:/usr/bin/docker + - jenkins-data:/var/lib/jenkins/ + depends_on: + - nexus + - sonar + environment: + - NEXUS_PORT=8081 + - SONAR_PORT=9000 + - SONAR_DB_PORT=5432 + - JENKINS_OPTS=--prefix=/jenkins/ + labels: + - "traefik.enable=true" + - "traefik.http.routers.jenkins.rule=Host(`%%TRAEFIK_VIRTUALHOST%%`) && PathPrefix(`/jenkins`)" + sonardb: + networks: + - prodnetwork + restart: always + image: postgres:9.6 + environment: + - POSTGRES_USER=sonar + - POSTGRES_PASSWORD=sonar + sonar: + image: sonarqube + restart: always + networks: + - prodnetwork + depends_on: + - sonardb + environment: + - SONARQUBE_JDBC_URL=jdbc:postgresql://sonardb:5432/sonar + - SONARQUBE_JDBC_USERNAME=sonar + - SONARQUBE_JDBC_PASSWORD=sonar + - sonar.web.context=/sonar + labels: + - "traefik.enable=true" + - "traefik.http.routers.sonar.rule=Host(`%%TRAEFIK_VIRTUALHOST%%`) && PathPrefix(`/sonar/`)" + +########################################################################################## +# DISABLED: GitLab takes too much memory and CPU. Demo uses GitHub repositories instead. +# +# gitlab: +# image: gitlab/gitlab-ce:latest +# restart: always +# networks: +# - prodnetwork +# environment: +# GITLAB_OMNIBUS_CONFIG: | +# # external_url 'https://gitlab.example.com' +# # Add any other gitlab.rb configuration here, each on its own line +# ports: +# - "10080:80" +# - "10443:443" +# - "10022:22" +# volumes: +# - /opt/gitlab/config:/etc/gitlab +# - /opt/gitlab/logs:/var/log/gitlab +# - /opt/gitlab/data:/var/opt/gitlab diff --git a/jenkins/Dockerfile b/jenkins/Dockerfile.tmpl similarity index 80% rename from jenkins/Dockerfile rename to jenkins/Dockerfile.tmpl index 7e73e25..00a479b 100644 --- a/jenkins/Dockerfile +++ b/jenkins/Dockerfile.tmpl @@ -1,10 +1,16 @@ -FROM jenkins/jenkins:lts +FROM jenkins/jenkins:lts-alpine + +# Authors +LABEL maintainer="Marcel Birkner " +LABEL maintainer="Mathieu Grzybek USER root -RUN apt-get update \ - && apt-get install -y sudo curl\ - && apt-get install -y libltdl7\ - && rm -rf /var/lib/apt/lists/* + +ENV HTTP_PROXY="%%HTTP_PROXY%%" +ENV HTTP_OPTIONS="-x ${HTTP_PROXY}" +ENV CURL_OPTIONS="${HTTP_OPTIONS} -sSL" + +RUN apk add --no-cache sudo curl RUN echo "jenkins ALL=NOPASSWD: ALL" >> /etc/sudoers # getting the docker-cli @@ -12,7 +18,7 @@ RUN echo "jenkins ALL=NOPASSWD: ALL" >> /etc/sudoers # see: https://issues.jenkins-ci.org/browse/JENKINS-35025 # see: https://get.docker.com/builds/ # see: https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+Docker+Custom+Build+Environment+Plugin#CloudBeesDockerCustomBuildEnvironmentPlugin-DockerinDocker -RUN curl -sSL -o /bin/docker https://get.docker.io/builds/Linux/x86_64/docker-latest +RUN curl $CURL_OPTIONS -o /bin/docker https://get.docker.io/builds/Linux/x86_64/docker-latest RUN chmod +x /bin/docker USER jenkins diff --git a/nexus/Dockerfile b/nexus/Dockerfile deleted file mode 100644 index 8faf139..0000000 --- a/nexus/Dockerfile +++ /dev/null @@ -1,56 +0,0 @@ -# -# Creates a docker container with Nexus Artifact Repository -# - -FROM centos:7 - -MAINTAINER Marcel Birkner - -ENV SONATYPE_WORK /sonatype-work -ENV NEXUS_VERSION 2.14.1-01 -ENV NEXUS_HOME /opt/sonatype/nexus/ - -RUN INSTALL_PKGS="java-1.8.0-openjdk.x86_64" && \ - yum -y --setopt=tsflags=nodocs install $INSTALL_PKGS && \ - rpm -V $INSTALL_PKGS && \ - yum clean all && \ - localedef -f UTF-8 -i en_US en_US.UTF-8 - -# Install packages necessary -RUN yum -y install unzip && yum clean all - -ADD https://download.sonatype.com/nexus/oss/nexus-${NEXUS_VERSION}-bundle.zip nexus-${NEXUS_VERSION}-bundle.zip - -# Extract Nexus -RUN set -x \ - && unzip nexus-${NEXUS_VERSION}-bundle.zip \ - && mkdir -p ${NEXUS_HOME} \ - && cp -r nexus-${NEXUS_VERSION}/* ${NEXUS_HOME} \ - && rm -rf nexus-${NEXUS_VERSION}-bundle.tar.gz \ - && rm -rf nexus-${NEXUS_VERSION} - -RUN groupadd -r nexus -g 3001 && \ - useradd -u 3001 -r -g nexus -m -d ${SONATYPE_WORK} -s /bin/bash -c "Nexus Run User" nexus - -VOLUME ${SONATYPE_WORK} - -EXPOSE 8081 - -WORKDIR /opt/sonatype/nexus - -RUN INSTALL_PKGS="createrepo" && \ - yum -y --setopt=tsflags=nodocs install $INSTALL_PKGS && \ - rpm -V $INSTALL_PKGS && \ - yum clean all - -ENV CONTEXT_PATH / -ENV MAX_HEAP 768m -ENV MIN_HEAP 256m -ENV JAVA_OPTS -server -XX:MaxPermSize=192m -Djava.net.preferIPv4Stack=true -ENV LAUNCHER_CONF ./conf/jetty.xml ./conf/jetty-requestlog.xml -CMD java \ - -Dnexus-work=${SONATYPE_WORK} -Dnexus-webapp-context-path=${CONTEXT_PATH} \ - -Xms${MIN_HEAP} -Xmx${MAX_HEAP} \ - -cp 'conf/:lib/*' \ - ${JAVA_OPTS} \ - org.sonatype.nexus.bootstrap.Launcher ${LAUNCHER_CONF} diff --git a/nexus/Dockerfile.tmpl b/nexus/Dockerfile.tmpl new file mode 100644 index 0000000..08b8d17 --- /dev/null +++ b/nexus/Dockerfile.tmpl @@ -0,0 +1,57 @@ +# +# Creates a docker container with Nexus Artifact Repository +# + +FROM openjdk:8-alpine + +LABEL maintainer="Marcel Birkner " +LABEL maintainer="Mathieu Grzybek + +ENV SONATYPE_WORK /sonatype-work +ENV NEXUS_VERSION 2.14.1-01 +ENV NEXUS_HOME /opt/sonatype/nexus/ +ENV HTTP_PROXY=%%HTTP_PROXY%% + +# Install packages necessary +RUN apk add --no-cache unzip shadow + +ADD https://download.sonatype.com/nexus/oss/nexus-${NEXUS_VERSION}-bundle.zip nexus-${NEXUS_VERSION}-bundle.zip + +# Extract Nexus +RUN set -x \ + && unzip nexus-${NEXUS_VERSION}-bundle.zip \ + && mkdir -p ${NEXUS_HOME} \ + && cp -r nexus-${NEXUS_VERSION}/* ${NEXUS_HOME} \ + && rm -rf nexus-${NEXUS_VERSION}-bundle.tar.gz \ + && rm -rf nexus-${NEXUS_VERSION} + + +RUN groupadd -r nexus -g 3001 \ + && useradd \ + -u 3001 \ + -g nexus \ + -d ${SONATYPE_WORK} \ + -s /bin/bash \ + -c "Nexus Run User" \ + -r \ + -m \ + nexus + +VOLUME ${SONATYPE_WORK} + +EXPOSE 8081 + +WORKDIR /opt/sonatype/nexus + +ENV CONTEXT_PATH /nexus +ENV MAX_HEAP 768m +ENV MIN_HEAP 256m +ENV JAVA_OPTS -server -XX:MaxPermSize=192m -Djava.net.preferIPv4Stack=true +ENV LAUNCHER_CONF ./conf/jetty.xml ./conf/jetty-requestlog.xml + +CMD java \ + -Dnexus-work=${SONATYPE_WORK} -Dnexus-webapp-context-path=${CONTEXT_PATH} \ + -Xms${MIN_HEAP} -Xmx${MAX_HEAP} \ + -cp 'conf/:lib/*' \ + ${JAVA_OPTS} \ + org.sonatype.nexus.bootstrap.Launcher ${LAUNCHER_CONF} diff --git a/sonar/Dockerfile b/sonar/Dockerfile.tmpl similarity index 78% rename from sonar/Dockerfile rename to sonar/Dockerfile.tmpl index 084e112..bec7f79 100644 --- a/sonar/Dockerfile +++ b/sonar/Dockerfile.tmpl @@ -4,9 +4,13 @@ FROM centos:7 -MAINTAINER Marcel Birkner +LABEL maintainer="Marcel Birkner " +LABEL maintainer="Mathieu Grzybek -ENV JAVA_OPTS "$JAVA_OPTS -Duser.country=DE -Duser.language=de -Duser.timezone=Europe/Berlin" +ENV JAVA_OPTS "$JAVA_OPTS -Duser.country=%%COUNTRY%% -Duser.language=%%LANGUAGE%% -Duser.timezone=%%TIMEZONE%%" + +# Proxy variable if needed +ENV HTTP_PROXY=%%HTTP_PROXY%% # Set the JAVA_HOME variable to make it clear where Java is located ENV JAVA_HOME /usr/lib/jvm/java-1.8.0 @@ -20,10 +24,11 @@ ENV SONAR_WEB_PLUGIN 2.4 ENV SONAR_SCM_GIT_PLUGIN 1.0 RUN INSTALL_PKGS="java-1.8.0-openjdk.x86_64" && \ - yum -y --setopt=tsflags=nodocs install $INSTALL_PKGS && \ - rpm -V $INSTALL_PKGS && \ - yum clean all && \ - localedef -f UTF-8 -i en_US en_US.UTF-8 + echo "proxy=$HTTP_PROXY" >> /etc/yum.conf && \ + yum -y --setopt=tsflags=nodocs install $INSTALL_PKGS && \ + rpm -V $INSTALL_PKGS && \ + yum clean all && \ + localedef -f UTF-8 -i en_US en_US.UTF-8 # Http port EXPOSE 9000