├── .env.template ├── .gitignore ├── README.md ├── docker-compose-sonar.yml ├── docker-compose.yml ├── docker-local-build.jpg ├── gitlabrunner ├── Dockerfile └── entrypointAutoregister ├── helloworld ├── HelloWorld │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ ├── MavenWrapperDownloader.java │ │ │ ├── maven-wrapper.jar │ │ │ └── maven-wrapper.properties │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── hello │ │ │ │ └── world │ │ │ │ └── HelloWorld │ │ │ │ ├── HelloWorldApplication.java │ │ │ │ └── String.java │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── hello │ │ └── world │ │ └── HelloWorld │ │ └── HelloWorldApplicationTests.java └── README.md ├── jenkins-fat ├── .gitignore ├── Dockerfile ├── buildDockerImages.sh ├── docker-compose.yml ├── install-plugins.sh ├── jenkins-support ├── jenkins.sh ├── plugins.txt ├── preDownload.sh ├── publish.sh ├── readme.md └── update-official-library.sh ├── nginx-reverse ├── Dockerfile ├── nginx-micro.conf ├── nginx.conf ├── proxy-settings.conf └── reverse-proxy.conf ├── postgres ├── Dockerfile └── createSonar.sql ├── preconfig ├── docker-registry │ └── config.yml ├── jenkins │ ├── config.xml │ ├── secrets │ │ ├── filepath-filters.d │ │ │ └── 30-default.conf │ │ ├── hudson.util.Secret │ │ ├── jenkins.model.Jenkins.crumbSalt │ │ ├── jenkins.security.ApiTokenProperty.seed │ │ ├── master.key │ │ ├── org.jenkinsci.main.modules.instance_identity.InstanceIdentity.KEY │ │ ├── slave-to-master-security-kill-switch │ │ └── whitelisted-callables.d │ │ │ └── default.conf │ └── users │ │ └── admin │ │ └── config.xml └── sonar │ └── sonar.properties ├── security-paranoia ├── ReadMe.md └── secureExternalPorts.sh └── setupEnvironment.sh /.env.template: -------------------------------------------------------------------------------- 1 | # This is the environment-file for the docker-compose.yaml 2 | # autogenerated ... via setupEnvironmen.sh 3 | # if you edit this file your changes are lost after next setupEnvironmen.sh run 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.jpi 2 | *.war 3 | .env-* 4 | .env 5 | .project 6 | 7 | .dbeaver* 8 | 9 | target/ 10 | !.mvn/wrapper/maven-wrapper.jar 11 | 12 | ### STS ### 13 | .apt_generated 14 | .classpath 15 | .factorypath 16 | .project 17 | .settings 18 | .springBeans 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | 26 | ### NetBeans ### 27 | nbproject/private/ 28 | build/ 29 | nbbuild/ 30 | dist/ 31 | nbdist/ 32 | .nb-gradle/ 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## docker-local-build-environment 2 | 3 | ##### Tired of endless installation and configuration .... ?! 4 | 5 | 6 | ## NOte 7 | - good stuff 8 | 9 | My personal solution is a local, docker-based CI/CD Build Environment ready in a few minutes to offer you a reade-to-use convenience playground with 10 | * Jenkins 11 | * open-jdk 12 | * maven 13 | * ansible 14 | * docker 15 | * Gitlab 16 | * and a docker based gitlab-runner registrated 17 | * secured docker-registry ready (openssh certificate) 18 | * push with ssh available at port 2222 19 | * Nexus 3 20 | * Sonar 21 | * Postgres (used by Sonar and YOUR applications) 22 | * Standard Docker-Registry V2 with a simple UI 23 | * Portainer to check your setup 24 | 25 | so you can be your own local "DevOp"; nearly every category of [periodic table of devoptools][4] has one tool in your local setup. 26 | 27 | #### just a "docker-compose up.." gives you this ! 28 | 29 | ![Screenshot](docker-local-build.jpg) 30 | 31 | ## This is NOT for any cluster (Swarm/Kubernetes) 32 | 33 | ### System requirements 34 | * At least 8GB Memory with 3GB Swap and 10GB Disk-Space, 16GB ist recommended 35 | * docker version >= 17.06.0 36 | * docker-compose version >= 1.15.0 37 | 38 | #### Listenports to be claimed on your host 39 | 40 | |Port | Why | 41 | |---|---| 42 | |80 |NGINX, forwards requests to internal docker-containers | 43 | |5432 |postgres standard connection port | 44 | |2222 |ssh port of gitlab, used to push via ssh connection ssh://git@myHOST:2222/scott/foo.git | 45 | |5555 |Gitlab docker-registry secured with GitLab credentials | 46 | |5000 |Standard Docker-Registry v2 not secured| 47 | 48 | If your change the ports in the docker-compose.yml change them also in nginx-reverse/nginx.conf (stream {...} ) 49 | ## Installation 50 | 51 | ### Important: First use ./setupEnvironment.sh 52 | 53 | The ./setupEnvironment.sh 54 | * configures your settings and generates a .env File used by docker-compose 55 | * copies some configuration File to your local directory 56 | * Donloads all the Jenkins-Plugins to jenkins-fat/Plugins directory to save time. 57 | * generates ssl-keys and certificates to use with git clone and the docker registry 58 | 59 | 60 | Bring up your own DevOp Playground ... just do a 61 | 62 | ### setup without sonar, takes 7GiB 63 | ``` 64 | git clone https://github.com/Springjunky/docker-local-build-environment.git 65 | cd docker-local-build-environment 66 | sudo ./setupEnvironment.sh 67 | docker-compose up --build 68 | ``` 69 | starts 9 container 70 | 71 | ### setup with sonar, takes 10GiB 72 | ``` 73 | git clone https://github.com/Springjunky/docker-local-build-environment.git 74 | cd docker-local-build-environment 75 | sudo ./setupEnvironment.sh 76 | docker-compose -f docker-compose.yml -f docker-compose-sonar.yml up --build 77 | ``` 78 | starts 10 container 79 | 80 | ### The first startup takes a long time (especially gitlab), so be patient 81 | open your favorite browser (_not_ at localhost, use the $(hostname)/jenkins ) 82 | to prevent jenkins spit out "your reverse proxy is wrong") 83 | 84 | ### Ready ! 85 | 86 | Now you are ready to go with a little CI/CD Environment: 87 | ``` 88 | Jenkins http:///jenkins 89 | Nexus http:///nexus 90 | Gitlab http:///gitlab 91 | Sonar http:///sonar 92 | Portainer http:///portainer 93 | Docker-Registry-Ui: http:///regweb 94 | Postgres: At standard listenport 5432 for your jdbc-connection-string 95 | stream-passthrough to postgres-container. 96 | ``` 97 | #### Security 98 | ... not really, its all http .. don't worry about it! It's only local communication 99 | 100 | ##### security paranoia 101 | See Readme in folder security-paranoia if you want to have some hints how to configure your firewall. 102 | 103 | ### Logins and Passwords 104 | |Image | User | Password | 105 | |---|---|---| 106 | |Jenkins| admin| admin | 107 | |Nexus | admin | admin123 | 108 | |Gitlab | root | gitlab4me | 109 | |Sonar | admin | admin | 110 | |Postgres|postgres|admin| 111 | 112 | ## The Tools 113 | There are some configurations you have to do after setup. 114 | *Remember:* At every time use your real hostname and NOT localhost (locahost inside a container is the container itself). 115 | 116 | For example: If you configure a GitLab-Connection in Jenkins, you will reach Gitlab at http://<your host>/gitlab and not http://localhost/gitlab 117 | ### Jenkins 118 | * MAVEN_HOME is /opt/maven 119 | * JAVA_HOME is /usr/lib/jvm/java-8-openjdk-amd64 120 | 121 | ### GitLab 122 | * the docker-registry from GitLab is at port 5555 (and secured with an openssl certificate ..thats part of 123 | setupEnvironment.sh), just create a project in gitlab and click at the registry tab to show 124 | how to login to the project registry and how to tag your images and upload them. 125 | * ssh cloning and pushing is at port 2222 (ssh://git@myHOST:2222/scott/foo.git remeber to upload your public key before, should be ~/.ssh/id_rsa.pub ) 126 | * http cloning and pushing is only http NOT https 127 | 128 | #### gitlab-runner 129 | The runner is a gitlab-multirunner image with a docker-runner (concurrent=1) , based on [gitlab/gitlab-runner][2] at every startup any runner is removed 130 | and only ONE new runner is registrated to avoid multiple runners (the pipeline-history maybe lost.) 131 | setups with a shell-runner works, docker-in-docker (docker:dind) or docker based builds should cause trouble because the 132 | default DNS-Server of a docker-container ist 8.8.8.8 (google) see this link [extra_host for servce][5] for a possible workaround 133 | 134 | It takes a long time until gitlab is ready to accept a runner registration, if it fails, increase the REGISTER_TRYS in docker-compse.yml 135 | 136 | #### Jenkins and Gitlab 137 | 138 | Gitlab is very very fast with new releases and sometimes the api has breaking changes. If something does not work take a look at the Jenkins Bugtracker. 139 | 140 | ### Sonar 141 | You need to install some rules (Administration - System - Update Center - Available - Search: Java) 142 | 143 | ### Postgres 144 | You can use any tool to connect to the database at localhost:5432 this is a pass through to the container so any 145 | JDBC-Connection should work 146 | 147 | ### The Docker-Registries 148 | * NEXUS-Docker-Registry ist NOT configured .. needs a pass trough and some more configs, see [Unsecure docker-registry in Nexus][1] feel free to provide a push-request 149 | * GitLab docker-registry is at port 5555 you have to use your GitLab Credentials from the corresponding git-respository 150 | * standard Docker-Registry v2 ist at standard port 5000 with no credentials, so eays-to-use 151 | 152 | 153 | ## Troubleshooting 154 | ##### check Hostname and IP 155 | In most cases a wrong HOSTNAME:HOSTIP causes trouble, to check this try the following. 156 | * log into the jenkins-fat container (with id) 157 | ``` 158 | docker container ls 159 | docker container exec -it jenkins-fat bash 160 | chmod a+rw /tmp 161 | apt-get update 162 | apt-get install -y --allow-unauthenticated iputils-ping 163 | ping jenkins 164 | ping gitlab 165 | ping 166 | ``` 167 | every ping must work, if not, check the .env file, is there the correct DC_HOSTNAME / DC_HOSTIP ? 168 | 169 | ##### changed interface ip ? 170 | If you change your network (switching between home/office/lan/wifi) your ip-address 171 | could be change and the container is not able to resolve your host any more 172 | Check the .env file or just run the setup-Script again. 173 | 174 | ##### consider low memory: 175 | with an amount lower than 8GB sonar and embedded eleastic search did not startup and no message is displayed 176 | 177 | 178 | ## Starting from scratch 179 | To delete everything an start from scratch (own risk, you will lost all your setting projects and data) 180 | ```diff 181 | - WARNING: this will delete EVERY docker-Images and container and ALL your docker-data !!! 182 | ``` 183 | 184 | ``` 185 | # switch to your home directory 186 | cd 187 | # delete ALL YOUR Settings and data !!!!! 188 | sudo rm -rf devstack-data/ 189 | 190 | # delete all downloaded images 191 | docker rmi -f $(docker images -aq) 192 | 193 | # delete all startet container 194 | docker container stop $(docker container ls -aq) 195 | docker container prune 196 | 197 | # delete docker-container volumes 198 | docker volume prune 199 | 200 | # delete docker-networks 201 | docker network rm dockerlocalbuildenvironment_default dockerlocalbuildenvironment_devstacknetwork 202 | 203 | ``` 204 | 205 | ### My next steps 206 | 207 | * give you some more preconfiguration 208 | * ~~install docker~~ 209 | * ~~install docker-compose~~ 210 | * ~~install ansible~~ 211 | * ~~apply a gitlab runner~~ 212 | * ~~apply git-lfs~~ 213 | * ~~apply sonar~~ 214 | * ~~apply keycloak~~ 215 | * ~~apply a better registry~~ 216 | 217 | 218 | 219 | [1]: https://support.sonatype.com/hc/en-us/articles/217542177-Using-Self-Signed-Certificates-with-Nexus-Repository-Manager-and-Docker-Daemon 220 | [2]: https://hub.docker.com/r/gitlab/gitlab-runner/ 221 | [3]: https://developers.redhat.com/blog/2017/05/25/easily-secure-your-spring-boot-applications-with-keycloak/ 222 | [4]: https://xebialabs.com/periodic-table-of-devops-tools/ 223 | [5]: https://gitlab.com/gitlab-org/gitlab-runner/issues/2302 224 | -------------------------------------------------------------------------------- /docker-compose-sonar.yml: -------------------------------------------------------------------------------- 1 | 2 | # docker-sonar configuration, 3 | # add this to your docker-compose up if you want to have sonarqube 4 | # docker-compose -f docker-compose.yml -f docker-compose-sonar.yml up 5 | version: "3" 6 | 7 | services: 8 | sonar: 9 | image: sonarqube:7.1 # Sonar > 7.1 needs es config on host, see 10 | # https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#docker-cli-run-dev-mode 11 | container_name: sonarcube 12 | depends_on: # start proxy after all the others 13 | - postgres 14 | extra_hosts: 15 | - ${DC_HOSTNAME}:${DC_HOSTIP} 16 | networks: 17 | - devstacknetwork 18 | environment: 19 | # the Default User and Passwort for Postgress is sonar/sonar 20 | - SONARQUBE_JDBC_URL=jdbc:postgresql://postgres:5432/sonar 21 | volumes: 22 | - ${DC_BASE_DATA_DIR}/sonar/sonarqube_conf:/opt/sonarqube/conf 23 | - ${DC_BASE_DATA_DIR}/sonar/sonarqube_data:/opt/sonarqube/data 24 | - ${DC_BASE_DATA_DIR}/sonar/sonarqube_extensions:/opt/sonarqube/extensions 25 | - ${DC_BASE_DATA_DIR}/sonar/sonarqube_bundled-plugins:/opt/sonarqube/lib/bundled-plugins 26 | - ${DC_BASE_DATA_DIR}/sonar/sonarqube_logs:/opt/sonarqube/logs 27 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | ##################################### 2 | # Don't touch this file is generated 3 | # expecilly for: ${DC_HOSTNAME} 4 | ################################### 5 | # 6 | # Consider to Backup ${DC_BASE_DATA_DIR} 7 | # 8 | version: "3" 9 | 10 | ####test 11 | 12 | networks: 13 | devstacknetwork: 14 | driver: bridge 15 | 16 | services: 17 | # ------------------------------------------------------------------------------ 18 | ngnix: 19 | container_name: nginx-reverse 20 | build: nginx-reverse 21 | ports: 22 | - 80:80 # http:// 23 | - 5432:5432 # Default-Port of the Postges DB passing jdbc-Connections to the postgres-Container 24 | - 2222:2222 # ssh port of gitlab (ssh://git@myHOST:2222/scott/foo.git) 25 | - 5555:5555 # Gitlab Docker Registry do NOT use 5000, this is an internal PORT of the gitlab-ce Image 26 | #command: ["nginx-debug", "-g", "daemon off;"] # Start nginx in debug to see whats going on 27 | depends_on: # start proxy after all the others 28 | - gitlab 29 | - jenkins 30 | - nexus 31 | - portainer 32 | networks: 33 | - devstacknetwork 34 | # ------------------------------------------------------------------------------ 35 | regweb: 36 | container_name: docker-registry-web 37 | image: hyper/docker-registry-web:v0.1.2 38 | networks: 39 | - devstacknetwork 40 | extra_hosts: 41 | - ${DC_HOSTNAME}:${DC_HOSTIP} 42 | environment: 43 | - REGISTRY_URL=http://${DC_HOSTNAME}:5000/v2 44 | - REGISTRY_NAME=Your docker-local-build-registry@${DC_HOSTNAME}:5000 45 | - REGISTRY_READONLY=false 46 | - REGISTRY_CONTEXT_PATH=/regweb 47 | # ------------------------------------------------------------------------------ 48 | portainer: 49 | image: portainer/portainer:linux-amd64-1.21.0 50 | container_name: portainer 51 | command: --no-auth 52 | networks: 53 | - devstacknetwork 54 | extra_hosts: 55 | - ${DC_HOSTNAME}:${DC_HOSTIP} 56 | volumes: 57 | - /var/run/docker.sock:/var/run/docker.sock 58 | # ------------------------------------------------------------------------------ 59 | registry: 60 | container_name: registry 61 | image: registry:2.7.1 62 | network_mode: "host" 63 | ports: 64 | - 5000:5000 65 | volumes: 66 | - ${DC_BASE_DATA_DIR}/docker-registry/config.yml:/etc/docker/registry/config.yml 67 | - ${DC_BASE_DATA_DIR}/docker-registry/images:/var/lib/registry 68 | # ------------------------------------------------------------------------------ 69 | postgres: 70 | container_name: postgres 71 | build: postgres 72 | extra_hosts: 73 | - ${DC_HOSTNAME}:${DC_HOSTIP} 74 | environment: 75 | - POSTGRES_PASSWORD=admin 76 | - POSTGRES_USER=postgres 77 | networks: 78 | - devstacknetwork 79 | volumes: 80 | - ${DC_BASE_DATA_DIR}/postgres-db/postgresql:/var/lib/postgresql 81 | # This needs explicit mapping due to 82 | # https://github.com/docker-library/postgres/blob/4e48e3228a30763913ece952c611e5e9b95c8759/Dockerfile.template#L52 83 | # there is ENV PGDATA /var/lib/postgresql/data 84 | - ${DC_BASE_DATA_DIR}/postgres-db/postgresql_data:/var/lib/postgresql/data 85 | # ------------------------------------------------------------------------------ 86 | jenkins: 87 | build: 88 | context: jenkins-fat 89 | args: 90 | JENKINS_LTS_VERSION: ${JENKINS_LTS} 91 | container_name: jenkins-fat 92 | extra_hosts: 93 | - ${DC_HOSTNAME}:${DC_HOSTIP} 94 | networks: 95 | - devstacknetwork 96 | volumes: 97 | - ${DC_BASE_DATA_DIR}/jenkins:/var/jenkins_home 98 | - /var/run/docker.sock:/var/run/docker.sock 99 | # ------------------------------------------------------------------------------ 100 | gitlab: 101 | image: 'gitlab/gitlab-ce:12.0.2-ce.0' 102 | container_name: gitlab-ce 103 | extra_hosts: 104 | - ${DC_HOSTNAME}:${DC_HOSTIP} 105 | networks: 106 | - devstacknetwork 107 | environment: 108 | GITLAB_OMNIBUS_CONFIG: | 109 | external_url 'http://${DC_HOSTNAME}/gitlab' 110 | gitlab_rails['initial_root_password'] = "gitlab4me" 111 | gitlab_rails['initial_shared_runners_registration_token'] = "s3cretToken4Runner" 112 | gitlab_rails['gitlab_shell_ssh_port'] = 2222 113 | # docker-registry config 114 | registry_external_url 'https://${DC_HOSTNAME}:5555' 115 | registry_nginx['listen_port'] = 5555 116 | registry_nginx['listen_https'] = true 117 | # SSL config just for the docker-registry need 118 | nginx['ssl_certificate'] = "/etc/gitlab/ssl/${DC_HOSTNAME}.crt" 119 | nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/${DC_HOSTNAME}.key" 120 | registry_nginx['proxy_set_headers'] = { 121 | "X-Forwarded-Proto" => "https", 122 | "X-Forwarded-Ssl" => "on" 123 | } 124 | volumes: 125 | - ${DC_BASE_DATA_DIR}/gitlab/config:/etc/gitlab 126 | - ${DC_BASE_DATA_DIR}/gitlab/logs:/var/log/gitlab 127 | - ${DC_BASE_DATA_DIR}/gitlab/data:/var/opt/gitlab 128 | ## ------------------------------------------------------------------------------ 129 | nexus: 130 | image: sonatype/nexus3:3.17.0 131 | container_name: sonatype-nexus3 132 | extra_hosts: 133 | - ${DC_HOSTNAME}:${DC_HOSTIP} 134 | networks: 135 | - devstacknetwork 136 | environment: 137 | - NEXUS_CONTEXT=nexus 138 | volumes: 139 | - ${DC_BASE_DATA_DIR}/nexus:/nexus-data 140 | 141 | # ------------------------------------------------------------------------------ 142 | gitlabrunner: 143 | build: gitlabrunner 144 | container_name: gitlabrunner 145 | network_mode: "host" 146 | privileged: true 147 | extra_hosts: 148 | - ${DC_HOSTNAME}:${DC_HOSTIP} 149 | environment: 150 | - GITLAB_URL=http://${DC_HOSTNAME}/gitlab 151 | - HOSTNAME=${DC_HOSTNAME} 152 | - HOSTIP=${DC_HOSTIP} 153 | - REGISTER_TOKEN=s3cretToken4Runner 154 | - REGISTER_TRYS=60 # every 10 seconds a try to register the runner..gitlab takes a long time to startup 155 | volumes: 156 | - ${DC_BASE_DATA_DIR}/gitlab-runner/config:/etc/gitlab-runner 157 | - /var/run/docker.sock:/var/run/docker.sock 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /docker-local-build.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Springjunky/docker-local-build-environment/dd06f5a403df6bfeb3255b2f01ab64b69c044f2c/docker-local-build.jpg -------------------------------------------------------------------------------- /gitlabrunner/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gitlab/gitlab-runner:v12.0.1 2 | 3 | # The giltab multirunner ist an officila Image by gitlab 4 | 5 | ADD entrypointAutoregister / 6 | RUN chmod +x /entrypointAutoregister 7 | 8 | ENTRYPOINT ["/usr/bin/dumb-init", "/entrypointAutoregister"] 9 | 10 | CMD ["run", "--user=gitlab-runner", "--working-directory=/home/gitlab-runner"] 11 | 12 | 13 | -------------------------------------------------------------------------------- /gitlabrunner/entrypointAutoregister: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # gitlab-ci-multi-runner data directory 4 | DATA_DIR="/etc/gitlab-runner" 5 | CONFIG_FILE=${CONFIG_FILE:-$DATA_DIR/config.toml} 6 | # custom certificate authority path 7 | CA_CERTIFICATES_PATH=${CA_CERTIFICATES_PATH:-$DATA_DIR/certs/ca.crt} 8 | LOCAL_CA_PATH="/usr/local/share/ca-certificates/ca.crt" 9 | 10 | update_ca() { 11 | echo "Updating CA certificates..." 12 | cp "${CA_CERTIFICATES_PATH}" "${LOCAL_CA_PATH}" 13 | update-ca-certificates --fresh >/dev/null 14 | } 15 | 16 | if [ -f "${CA_CERTIFICATES_PATH}" ]; then 17 | # update the ca if the custom ca is different than the current 18 | cmp --silent "${CA_CERTIFICATES_PATH}" "${LOCAL_CA_PATH}" || update_ca 19 | fi 20 | 21 | 22 | ########################################################################################################### 23 | echo "Try to autoregister runner at ${GITLAB_URL} with host ${HOSTNAME}:${HOSTIP} and token ${REGISTER_TOKEN} for $REGISTER_TRYS trys" 24 | 25 | grep docker-runner /etc/gitlab-runner/config.toml 2>/dev/null 1>/dev/null 26 | RUNNER_IS_PRESENT=$? 27 | 28 | TRYS=$REGISTER_TRYS 29 | REGISTERED=1 30 | 31 | while test $TRYS -gt 0 -a $REGISTERED -gt 0 ; do 32 | TRYS=$(expr $TRYS - 1) 33 | gitlab-runner register -n --url=${GITLAB_URL} --registration-token=${REGISTER_TOKEN} \ 34 | --executor=docker --name=docker-multi-runner \ 35 | --run-untagged=true --locked=false --docker-image=docker:latest \ 36 | --docker-privileged \ 37 | --docker-extra-hosts="${HOSTNAME}:${HOSTIP}" 38 | REGISTERED=$? 39 | if [ $REGISTERED -ne 0 ] ; then 40 | echo "${GITLAB_URL} not ready $TRYS trys left, next try in 10 second for ${GITLAB_URL}" 41 | sleep 10 42 | else 43 | # Gitlab is ready, so remove ALL runner and re-registrer only one runner 44 | # so we have a clean state 45 | sleep 1 46 | gitlab-runner unregister --all-runners 47 | sleep 1 48 | gitlab-runner verify --delete 49 | sleep 1 50 | gitlab-runner register -n --url=${GITLAB_URL} --registration-token=${REGISTER_TOKEN} \ 51 | --executor=docker --name=docker-multi-runner \ 52 | --run-untagged=true --locked=false --docker-image=docker:latest \ 53 | --docker-privileged \ 54 | --docker-extra-hosts="${HOSTNAME}:${HOSTIP}" 55 | fi 56 | done 57 | 58 | # launch gitlab-ci-multi-runner passing all arguments 59 | exec gitlab-ci-multi-runner "$@" 60 | -------------------------------------------------------------------------------- /helloworld/HelloWorld/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /helloworld/HelloWorld/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import java.net.*; 17 | import java.io.*; 18 | import java.nio.channels.*; 19 | import java.util.Properties; 20 | 21 | public class MavenWrapperDownloader { 22 | 23 | private static final String WRAPPER_VERSION = "0.5.6"; 24 | /** 25 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 26 | */ 27 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 28 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 29 | 30 | /** 31 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 32 | * use instead of the default one. 33 | */ 34 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 35 | ".mvn/wrapper/maven-wrapper.properties"; 36 | 37 | /** 38 | * Path where the maven-wrapper.jar will be saved to. 39 | */ 40 | private static final String MAVEN_WRAPPER_JAR_PATH = 41 | ".mvn/wrapper/maven-wrapper.jar"; 42 | 43 | /** 44 | * Name of the property which should be used to override the default download url for the wrapper. 45 | */ 46 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 47 | 48 | public static void main(String args[]) { 49 | System.out.println("- Downloader started"); 50 | File baseDirectory = new File(args[0]); 51 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 52 | 53 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 54 | // wrapperUrl parameter. 55 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 56 | String url = DEFAULT_DOWNLOAD_URL; 57 | if(mavenWrapperPropertyFile.exists()) { 58 | FileInputStream mavenWrapperPropertyFileInputStream = null; 59 | try { 60 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 61 | Properties mavenWrapperProperties = new Properties(); 62 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 63 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 64 | } catch (IOException e) { 65 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 66 | } finally { 67 | try { 68 | if(mavenWrapperPropertyFileInputStream != null) { 69 | mavenWrapperPropertyFileInputStream.close(); 70 | } 71 | } catch (IOException e) { 72 | // Ignore ... 73 | } 74 | } 75 | } 76 | System.out.println("- Downloading from: " + url); 77 | 78 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 79 | if(!outputFile.getParentFile().exists()) { 80 | if(!outputFile.getParentFile().mkdirs()) { 81 | System.out.println( 82 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 83 | } 84 | } 85 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 86 | try { 87 | downloadFileFromURL(url, outputFile); 88 | System.out.println("Done"); 89 | System.exit(0); 90 | } catch (Throwable e) { 91 | System.out.println("- Error downloading"); 92 | e.printStackTrace(); 93 | System.exit(1); 94 | } 95 | } 96 | 97 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 98 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 99 | String username = System.getenv("MVNW_USERNAME"); 100 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 101 | Authenticator.setDefault(new Authenticator() { 102 | @Override 103 | protected PasswordAuthentication getPasswordAuthentication() { 104 | return new PasswordAuthentication(username, password); 105 | } 106 | }); 107 | } 108 | URL website = new URL(urlString); 109 | ReadableByteChannel rbc; 110 | rbc = Channels.newChannel(website.openStream()); 111 | FileOutputStream fos = new FileOutputStream(destination); 112 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 113 | fos.close(); 114 | rbc.close(); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /helloworld/HelloWorld/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Springjunky/docker-local-build-environment/dd06f5a403df6bfeb3255b2f01ab64b69c044f2c/helloworld/HelloWorld/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /helloworld/HelloWorld/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.2/apache-maven-3.8.2-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /helloworld/HelloWorld/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | fi 118 | 119 | if [ -z "$JAVA_HOME" ]; then 120 | javaExecutable="`which javac`" 121 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 122 | # readlink(1) is not available as standard on Solaris 10. 123 | readLink=`which readlink` 124 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 125 | if $darwin ; then 126 | javaHome="`dirname \"$javaExecutable\"`" 127 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 128 | else 129 | javaExecutable="`readlink -f \"$javaExecutable\"`" 130 | fi 131 | javaHome="`dirname \"$javaExecutable\"`" 132 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 133 | JAVA_HOME="$javaHome" 134 | export JAVA_HOME 135 | fi 136 | fi 137 | fi 138 | 139 | if [ -z "$JAVACMD" ] ; then 140 | if [ -n "$JAVA_HOME" ] ; then 141 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 142 | # IBM's JDK on AIX uses strange locations for the executables 143 | JAVACMD="$JAVA_HOME/jre/sh/java" 144 | else 145 | JAVACMD="$JAVA_HOME/bin/java" 146 | fi 147 | else 148 | JAVACMD="`which java`" 149 | fi 150 | fi 151 | 152 | if [ ! -x "$JAVACMD" ] ; then 153 | echo "Error: JAVA_HOME is not defined correctly." >&2 154 | echo " We cannot execute $JAVACMD" >&2 155 | exit 1 156 | fi 157 | 158 | if [ -z "$JAVA_HOME" ] ; then 159 | echo "Warning: JAVA_HOME environment variable is not set." 160 | fi 161 | 162 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 163 | 164 | # traverses directory structure from process work directory to filesystem root 165 | # first directory with .mvn subdirectory is considered project base directory 166 | find_maven_basedir() { 167 | 168 | if [ -z "$1" ] 169 | then 170 | echo "Path not specified to find_maven_basedir" 171 | return 1 172 | fi 173 | 174 | basedir="$1" 175 | wdir="$1" 176 | while [ "$wdir" != '/' ] ; do 177 | if [ -d "$wdir"/.mvn ] ; then 178 | basedir=$wdir 179 | break 180 | fi 181 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 182 | if [ -d "${wdir}" ]; then 183 | wdir=`cd "$wdir/.."; pwd` 184 | fi 185 | # end of workaround 186 | done 187 | echo "${basedir}" 188 | } 189 | 190 | # concatenates all lines of a file 191 | concat_lines() { 192 | if [ -f "$1" ]; then 193 | echo "$(tr -s '\n' ' ' < "$1")" 194 | fi 195 | } 196 | 197 | BASE_DIR=`find_maven_basedir "$(pwd)"` 198 | if [ -z "$BASE_DIR" ]; then 199 | exit 1; 200 | fi 201 | 202 | ########################################################################################## 203 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 204 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 205 | ########################################################################################## 206 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 207 | if [ "$MVNW_VERBOSE" = true ]; then 208 | echo "Found .mvn/wrapper/maven-wrapper.jar" 209 | fi 210 | else 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 213 | fi 214 | if [ -n "$MVNW_REPOURL" ]; then 215 | jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 216 | else 217 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 218 | fi 219 | while IFS="=" read key value; do 220 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 221 | esac 222 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 223 | if [ "$MVNW_VERBOSE" = true ]; then 224 | echo "Downloading from: $jarUrl" 225 | fi 226 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 227 | if $cygwin; then 228 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 229 | fi 230 | 231 | if command -v wget > /dev/null; then 232 | if [ "$MVNW_VERBOSE" = true ]; then 233 | echo "Found wget ... using wget" 234 | fi 235 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 236 | wget "$jarUrl" -O "$wrapperJarPath" 237 | else 238 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" 239 | fi 240 | elif command -v curl > /dev/null; then 241 | if [ "$MVNW_VERBOSE" = true ]; then 242 | echo "Found curl ... using curl" 243 | fi 244 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 245 | curl -o "$wrapperJarPath" "$jarUrl" -f 246 | else 247 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 248 | fi 249 | 250 | else 251 | if [ "$MVNW_VERBOSE" = true ]; then 252 | echo "Falling back to using Java to download" 253 | fi 254 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 255 | # For Cygwin, switch paths to Windows format before running javac 256 | if $cygwin; then 257 | javaClass=`cygpath --path --windows "$javaClass"` 258 | fi 259 | if [ -e "$javaClass" ]; then 260 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 261 | if [ "$MVNW_VERBOSE" = true ]; then 262 | echo " - Compiling MavenWrapperDownloader.java ..." 263 | fi 264 | # Compiling the Java class 265 | ("$JAVA_HOME/bin/javac" "$javaClass") 266 | fi 267 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 268 | # Running the downloader 269 | if [ "$MVNW_VERBOSE" = true ]; then 270 | echo " - Running MavenWrapperDownloader.java ..." 271 | fi 272 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 273 | fi 274 | fi 275 | fi 276 | fi 277 | ########################################################################################## 278 | # End of extension 279 | ########################################################################################## 280 | 281 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 282 | if [ "$MVNW_VERBOSE" = true ]; then 283 | echo $MAVEN_PROJECTBASEDIR 284 | fi 285 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 286 | 287 | # For Cygwin, switch paths to Windows format before running java 288 | if $cygwin; then 289 | [ -n "$M2_HOME" ] && 290 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 291 | [ -n "$JAVA_HOME" ] && 292 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 293 | [ -n "$CLASSPATH" ] && 294 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 295 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 296 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 297 | fi 298 | 299 | # Provide a "standardized" way to retrieve the CLI args that will 300 | # work with both Windows and non-Windows executions. 301 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 302 | export MAVEN_CMD_LINE_ARGS 303 | 304 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 305 | 306 | exec "$JAVACMD" \ 307 | $MAVEN_OPTS \ 308 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 309 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 310 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 311 | -------------------------------------------------------------------------------- /helloworld/HelloWorld/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 124 | 125 | FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 162 | if ERRORLEVEL 1 goto error 163 | goto end 164 | 165 | :error 166 | set ERROR_CODE=1 167 | 168 | :end 169 | @endlocal & set ERROR_CODE=%ERROR_CODE% 170 | 171 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 172 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 173 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 174 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 175 | :skipRcPost 176 | 177 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 178 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 179 | 180 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 181 | 182 | exit /B %ERROR_CODE% 183 | -------------------------------------------------------------------------------- /helloworld/HelloWorld/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.5.4 9 | 10 | 11 | com.hello.world 12 | HelloWorld 13 | 0.0.1-SNAPSHOT 14 | HelloWorld 15 | Hello World project for Spring Boot 16 | 17 | 16 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-web 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-test 28 | test 29 | 30 | 31 | 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-maven-plugin 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /helloworld/HelloWorld/src/main/java/com/hello/world/HelloWorld/HelloWorldApplication.java: -------------------------------------------------------------------------------- 1 | package com.hello.world; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | @RestController 9 | @SpringBootApplication 10 | public class HelloWorldApplication { 11 | 12 | @RequestMapping("/") 13 | public String home() { 14 | return "Hello World"; 15 | } 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(HelloWorldApplication.class, args); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /helloworld/HelloWorld/src/main/java/com/hello/world/HelloWorld/String.java: -------------------------------------------------------------------------------- 1 | package com.hello.world.HelloWorld; 2 | 3 | public class String { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /helloworld/HelloWorld/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /helloworld/HelloWorld/src/test/java/com/hello/world/HelloWorld/HelloWorldApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.hello.world.HelloWorld; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class HelloWorldApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /helloworld/README.md: -------------------------------------------------------------------------------- 1 | # helloworld -------------------------------------------------------------------------------- /jenkins-fat/.gitignore: -------------------------------------------------------------------------------- 1 | /active-plugins.txt_SAVE 2 | Plugins 3 | -------------------------------------------------------------------------------- /jenkins-fat/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:19.04 2 | ENV DEBIAN_FRONTEND noninteractive 3 | ENV JAVA_VERSION=8 \ 4 | JAVA_UPDATE=131 \ 5 | JAVA_BUILD=11 \ 6 | JAVA_HOME="/usr/lib/jvm/default-jvm" 7 | 8 | # update dpkg repositories and install tools 9 | RUN apt-get update 10 | #-------------------------------------------- 11 | #------------ Open JDK 12 | RUN apt-get install -y openjdk-8-jdk 13 | #-------------------------------------------- 14 | #------------ Tools for Jenkins and apt-get to use SSL Repositorys 15 | RUN apt-get install -y --no-install-recommends apt-utils git wget curl graphviz \ 16 | apt-transport-https ca-certificates software-properties-common gpg-agent zip unzip 17 | #----------------------------------------------- 18 | #--------------- Ansible 19 | #----------------------------------------------- 20 | RUN apt-add-repository ppa:ansible/ansible 2>/dev/null 21 | RUN apt-get update && apt-get -y install ansible 22 | #-------------------------------------------- 23 | #------------ Docker 24 | #-------------------------------------------- 25 | RUN echo 26 | RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg > docker-public-key && \ 27 | apt-key add docker-public-key && \ 28 | rm docker-public-key 29 | RUN add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) edge test" && \ 30 | apt-get update && apt-get install -y docker-ce 31 | #-------------------------------------------- 32 | #------------ Docker Compose 33 | #-------------------------------------------- 34 | RUN curl -o /usr/bin/docker-compose -L \ 35 | "https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m)" \ 36 | && chmod +x /usr/bin/docker-compose 37 | 38 | #-------------------------------------------- 39 | #------------ Jenkins with jdk-8 40 | #-------------------------------------------- 41 | 42 | ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64 43 | 44 | # This is the line for the Jenkins prefix to set to get access with nginx and a 45 | # comfortable path like http:///jenins... remember 46 | # to set the location in the reverse-proxy.conf if you change this 47 | 48 | ENV JENKINS_OPTS="--webroot=/var/cache/jenkins/war --prefix=/jenkins" 49 | ENV GIT_SSL_NO_VERIFY=1 50 | #---------------------------------------- 51 | # Maven 52 | #---------------------------------------- 53 | RUN wget --no-verbose -O /tmp/apache-maven-3.5.3.tar.gz \ 54 | http://archive.apache.org/dist/maven/maven-3/3.5.3/binaries/apache-maven-3.5.3-bin.tar.gz 55 | # verify checksum and install maven 56 | RUN echo "51025855d5a7456fc1a67666fbef29de /tmp/apache-maven-3.5.3.tar.gz" | md5sum -c && \ 57 | tar xzf /tmp/apache-maven-3.5.3.tar.gz -C /opt/ && ln -s /opt/apache-maven-3.5.3 /opt/maven 58 | 59 | ENV MAVEN_HOME /opt/maven 60 | ENV PATH $MAVEN_HOME/bin:$JAVA_HOME/bin:$PATH 61 | 62 | RUN rm -rf /opt/java/src.zip && \ 63 | rm -rf /tmp/$filename && \ 64 | rm -f /tmp/apache-maven-3.5.3.tar.gz 65 | 66 | 67 | #------------------------------ 68 | # install Jenkins 69 | #------------------------------ 70 | ENV JENKINS_HOME /var/jenkins_home 71 | ENV JENKINS_SLAVE_AGENT_PORT 50000 72 | ARG user=jenkins 73 | ARG group=jenkins 74 | ARG uid=1000 75 | ARG gid=1000 76 | # Jenkins is run with user `jenkins`, uid = 1000 If you bind mount a volume from the host or a data container, ensure you use the same uid 77 | RUN groupadd -g ${gid} ${group} && useradd -d "$JENKINS_HOME" -u ${uid} -g ${gid} -m -s /bin/bash ${user} 78 | # Jenkins home directory is a volume, so configuration and build history 79 | # can be persisted and survive image upgrades 80 | 81 | RUN mkdir -p /usr/share/jenkins/ref/init.groovy.d && mkdir /tmp 82 | 83 | VOLUME /var/jenkins_home 84 | 85 | ENV TINI_VERSION 0.18.0 86 | ENV TINI_SHA eadb9d6e2dc960655481d78a92d2c8bc021861045987ccd3e27c7eae5af0cf33 87 | # Use tini as subreaper in Docker container to adopt zombie processes 88 | RUN curl -fsSL https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini-static-amd64 -o /bin/tini && chmod +x /bin/tini \ 89 | && echo "$TINI_SHA /bin/tini" | sha256sum -c - 90 | 91 | # jenkins version being bundled in this docker image 92 | # This is the latest stable version define in file ../.env 93 | ARG JENKINS_LTS_VERSION 94 | RUN echo JENKINS_LTS_VERSION=${JENKINS_LTS_VERSION} 95 | 96 | #### jenkins.war checksum, download will be validated using it 97 | ARG JENKINS_URL=http://updates.jenkins-ci.org/download/war/${JENKINS_LTS_VERSION}/jenkins.war 98 | # could use ADD but this one does not check Last-Modified header neither does it allow to control checksum see https://github.com/docker/docker/issues/8331 99 | RUN echo Download from ${JENKINS_URL} && curl -fL ${JENKINS_URL} -o /usr/share/jenkins/jenkins.war 100 | 101 | ###### # Copy all Cached plugins ... 102 | COPY Plugins/${JENKINS_LTS_VERSION}/* /usr/share/jenkins/ref/plugins/ 103 | 104 | ENV JENKINS_UC https://updates.jenkins.io 105 | ENV JENKINS_UC_EXPERIMENTAL=https://updates.jenkins.io/experimental 106 | RUN chown -R ${user} "$JENKINS_HOME" /usr/share/jenkins/ref 107 | 108 | # for main web interface, reversed-proxied by nginx 109 | EXPOSE 8080 110 | ENV COPY_REFERENCE_FILE_LOG $JENKINS_HOME/copy_reference_file.log 111 | USER ${user} 112 | COPY jenkins-support /usr/local/bin/jenkins-support 113 | COPY jenkins.sh /usr/local/bin/jenkins.sh 114 | ENV JAVA_OPTIONS="-Djava.awt.headless=true -Dhudson.security.csrf.requestfield=crumb -Djenkins.install.runSetupWizard=false" 115 | 116 | ENTRYPOINT ["/bin/tini", "--", "/usr/local/bin/jenkins.sh"] 117 | #------------------------------------------------------------------------- 118 | # if you need a list of all your actual plugins use this to 119 | # get all Plugins from an existing Jenins without Version (latest is used) 120 | #-------------------------------------------------------------------------- 121 | # JENKINS_HOST=username:password@myhost.com:port 122 | # curl -sSL "http://$JENKINS_HOST/pluginManager/api/xml?depth=1&xpath=/*/*/shortName|/*/*/version&wrapper=plugins" | \ 123 | # perl -pe 's/.*?([\w-]+).*?([^<]+)()(<\/\w+>)+/\1 \2\n/g'|sed 's/ /:/ ' | awk -F: '{ print $1 }' | sort' 124 | # ---------------------------------------------------- 125 | # Prevent Setup Wizard .. all Plugins copied before 126 | RUN echo ${JENKINS_LTS_VERSION} > /usr/share/jenkins/ref/jenkins.install.UpgradeWizard.state 127 | RUN echo ${JENKINS_LTS_VERSION} > /usr/share/jenkins/ref/jenkins.install.InstallUtil.lastExecVersion 128 | 129 | USER root 130 | 131 | RUN apt-get clean autoremove && rm -rf /var/lib/apt/lists/* 132 | -------------------------------------------------------------------------------- /jenkins-fat/buildDockerImages.sh: -------------------------------------------------------------------------------- 1 | . ../.env 2 | docker build --build-arg JENKINS_LTS_VERSION=$JENKINS_LTS --tag jenkins-fat --file Dockerfile . 3 | -------------------------------------------------------------------------------- /jenkins-fat/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | networks: 4 | devstacknetwork: 5 | driver: bridge 6 | 7 | services: 8 | jenkins: 9 | ports: 10 | - 8080:8080 # http:// 11 | build: 12 | context: . 13 | args: 14 | JENKINS_LTS_VERSION: 2.176 15 | container_name: jenkins-fat 16 | networks: 17 | - devstacknetwork 18 | volumes: 19 | - /home/tom/devstack-data/jenkins:/var/jenkins_home 20 | - /var/run/docker.sock:/var/run/docker.sock 21 | 22 | -------------------------------------------------------------------------------- /jenkins-fat/install-plugins.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eu 2 | 3 | # Resolve dependencies and download plugins given on the command line 4 | # 5 | # FROM jenkins 6 | # RUN install-plugins.sh docker-slaves github-branch-source 7 | 8 | set -o pipefail 9 | 10 | REF_DIR=${REF:-/usr/share/jenkins/ref/plugins} 11 | FAILED="$REF_DIR/failed-plugins.txt" 12 | 13 | . /usr/local/bin/jenkins-support 14 | 15 | getLockFile() { 16 | printf '%s' "$REF_DIR/${1}.lock" 17 | } 18 | 19 | getArchiveFilename() { 20 | printf '%s' "$REF_DIR/${1}.jpi" 21 | } 22 | 23 | download() { 24 | local plugin originalPlugin version lock ignoreLockFile 25 | plugin="$1" 26 | version="${2:-latest}" 27 | ignoreLockFile="${3:-}" 28 | lock="$(getLockFile "$plugin")" 29 | 30 | if [[ $ignoreLockFile ]] || mkdir "$lock" &>/dev/null; then 31 | if ! doDownload "$plugin" "$version"; then 32 | # some plugin don't follow the rules about artifact ID 33 | # typically: docker-plugin 34 | originalPlugin="$plugin" 35 | plugin="${plugin}-plugin" 36 | if ! doDownload "$plugin" "$version"; then 37 | echo "Failed to download plugin: $originalPlugin or $plugin" >&2 38 | echo "Not downloaded: ${originalPlugin}" >> "$FAILED" 39 | return 1 40 | fi 41 | fi 42 | 43 | if ! checkIntegrity "$plugin"; then 44 | echo "Downloaded file is not a valid ZIP: $(getArchiveFilename "$plugin")" >&2 45 | echo "Download integrity: ${plugin}" >> "$FAILED" 46 | return 1 47 | fi 48 | 49 | resolveDependencies "$plugin" 50 | fi 51 | } 52 | 53 | doDownload() { 54 | local plugin version url jpi 55 | plugin="$1" 56 | version="$2" 57 | jpi="$(getArchiveFilename "$plugin")" 58 | 59 | # If plugin already exists and is the same version do not download 60 | if test -f "$jpi" && unzip -p "$jpi" META-INF/MANIFEST.MF | tr -d '\r' | grep "^Plugin-Version: ${version}$" > /dev/null; then 61 | echo "Using provided plugin: $plugin" 62 | return 0 63 | fi 64 | 65 | if [[ "$version" == "latest" && -n "$JENKINS_UC_LATEST" ]]; then 66 | # If version-specific Update Center is available, which is the case for LTS versions, 67 | # use it to resolve latest versions. 68 | url="$JENKINS_UC_LATEST/latest/${plugin}.hpi" 69 | elif [[ "$version" == "experimental" && -n "$JENKINS_UC_EXPERIMENTAL" ]]; then 70 | # Download from the experimental update center 71 | url="$JENKINS_UC_EXPERIMENTAL/latest/${plugin}.hpi" 72 | else 73 | JENKINS_UC_DOWNLOAD=${JENKINS_UC_DOWNLOAD:-"$JENKINS_UC/download"} 74 | url="$JENKINS_UC_DOWNLOAD/plugins/$plugin/$version/${plugin}.hpi" 75 | fi 76 | 77 | echo "Downloading plugin: $plugin from $url" 78 | 79 | 80 | if test -e "$jpi" 81 | then 82 | echo "Plugin $jpi already downloaded " 83 | else 84 | curl --connect-timeout "${CURL_CONNECTION_TIMEOUT:-20}" --retry "${CURL_RETRY:-5}" --retry-delay "${CURL_RETRY_DELAY:-1}" --retry-max-time "${CURL_RETRY_MAX_TIME:-60}" -s -f -L "$url" -o "$jpi" 85 | fi 86 | return $? 87 | } 88 | 89 | checkIntegrity() { 90 | local plugin jpi 91 | plugin="$1" 92 | jpi="$(getArchiveFilename "$plugin")" 93 | 94 | unzip -t -qq "$jpi" >/dev/null 95 | return $? 96 | } 97 | 98 | resolveDependencies() { 99 | local plugin jpi dependencies 100 | plugin="$1" 101 | jpi="$(getArchiveFilename "$plugin")" 102 | 103 | dependencies="$(unzip -p "$jpi" META-INF/MANIFEST.MF | tr -d '\r' | tr '\n' '|' | sed -e 's#| ##g' | tr '|' '\n' | grep "^Plugin-Dependencies: " | sed -e 's#^Plugin-Dependencies: ##')" 104 | 105 | if [[ ! $dependencies ]]; then 106 | echo " > $plugin has no dependencies" 107 | return 108 | fi 109 | 110 | echo " > $plugin depends on $dependencies" 111 | 112 | IFS=',' read -r -a array <<< "$dependencies" 113 | 114 | for d in "${array[@]}" 115 | do 116 | plugin="$(cut -d':' -f1 - <<< "$d")" 117 | if [[ $d == *"resolution:=optional"* ]]; then 118 | echo "Skipping optional dependency $plugin" 119 | else 120 | local pluginInstalled 121 | if pluginInstalled="$(echo -e "${bundledPlugins}\n${installedPlugins}" | grep "^${plugin}:")"; then 122 | pluginInstalled="${pluginInstalled//[$'\r']}" 123 | local versionInstalled; versionInstalled=$(versionFromPlugin "${pluginInstalled}") 124 | local minVersion; minVersion=$(versionFromPlugin "${d}") 125 | if versionLT "${versionInstalled}" "${minVersion}"; then 126 | echo "Upgrading bundled dependency $d ($minVersion > $versionInstalled)" 127 | download "$plugin" & 128 | else 129 | echo "Skipping already installed dependency $d ($minVersion <= $versionInstalled)" 130 | fi 131 | else 132 | download "$plugin" & 133 | fi 134 | fi 135 | done 136 | wait 137 | } 138 | 139 | bundledPlugins() { 140 | local JENKINS_WAR=/usr/share/jenkins/jenkins.war 141 | if [ -f $JENKINS_WAR ] 142 | then 143 | TEMP_PLUGIN_DIR=/tmp/plugintemp.$$ 144 | for i in $(jar tf $JENKINS_WAR | grep -E '[^detached-]plugins.*\..pi' | sort) 145 | do 146 | rm -fr $TEMP_PLUGIN_DIR 147 | mkdir -p $TEMP_PLUGIN_DIR 148 | PLUGIN=$(basename "$i"|cut -f1 -d'.') 149 | (cd $TEMP_PLUGIN_DIR;jar xf "$JENKINS_WAR" "$i";jar xvf "$TEMP_PLUGIN_DIR/$i" META-INF/MANIFEST.MF >/dev/null 2>&1) 150 | VER=$(grep -E -i Plugin-Version "$TEMP_PLUGIN_DIR/META-INF/MANIFEST.MF"|cut -d: -f2|sed 's/ //') 151 | echo "$PLUGIN:$VER" 152 | done 153 | rm -fr $TEMP_PLUGIN_DIR 154 | else 155 | rm -f "$TEMP_ALREADY_INSTALLED" 156 | echo "ERROR file not found: $JENKINS_WAR" 157 | exit 1 158 | fi 159 | } 160 | 161 | versionFromPlugin() { 162 | local plugin=$1 163 | if [[ $plugin =~ .*:.* ]]; then 164 | echo "${plugin##*:}" 165 | else 166 | echo "latest" 167 | fi 168 | 169 | } 170 | 171 | installedPlugins() { 172 | for f in "$REF_DIR"/*.jpi; do 173 | echo "$(basename "$f" | sed -e 's/\.jpi//'):$(get_plugin_version "$f")" 174 | done 175 | } 176 | 177 | jenkinsMajorMinorVersion() { 178 | local JENKINS_WAR 179 | JENKINS_WAR=/usr/share/jenkins/jenkins.war 180 | if [[ -f "$JENKINS_WAR" ]]; then 181 | local version major minor 182 | version="$(java -jar /usr/share/jenkins/jenkins.war --version)" 183 | major="$(echo "$version" | cut -d '.' -f 1)" 184 | minor="$(echo "$version" | cut -d '.' -f 2)" 185 | echo "$major.$minor" 186 | else 187 | echo "ERROR file not found: $JENKINS_WAR" 188 | return 1 189 | fi 190 | } 191 | 192 | main() { 193 | local plugin pluginVersion jenkinsVersion 194 | local plugins=() 195 | 196 | mkdir -p "$REF_DIR" || exit 1 197 | 198 | # Read plugins from stdin or from the command line arguments 199 | if [[ ($# -eq 0) ]]; then 200 | while read -r line || [ "$line" != "" ]; do 201 | plugins+=("${line}") 202 | done 203 | else 204 | plugins=("$@") 205 | fi 206 | 207 | # Create lockfile manually before first run to make sure any explicit version set is used. 208 | echo "Creating initial locks..." 209 | for plugin in "${plugins[@]}"; do 210 | mkdir "$(getLockFile "${plugin%%:*}")" 211 | done 212 | 213 | echo "Analyzing war..." 214 | bundledPlugins="$(bundledPlugins)" 215 | 216 | echo "Registering preinstalled plugins..." 217 | installedPlugins="$(installedPlugins)" 218 | 219 | # Check if there's a version-specific update center, which is the case for LTS versions 220 | jenkinsVersion="$(jenkinsMajorMinorVersion)" 221 | if curl -fsL -o /dev/null "$JENKINS_UC/$jenkinsVersion"; then 222 | JENKINS_UC_LATEST="$JENKINS_UC/$jenkinsVersion" 223 | echo "Using version-specific update center: $JENKINS_UC_LATEST..." 224 | else 225 | JENKINS_UC_LATEST= 226 | fi 227 | 228 | echo "Downloading plugins..." 229 | for plugin in "${plugins[@]}"; do 230 | pluginVersion="" 231 | 232 | if [[ $plugin =~ .*:.* ]]; then 233 | pluginVersion=$(versionFromPlugin "${plugin}") 234 | plugin="${plugin%%:*}" 235 | fi 236 | 237 | download "$plugin" "$pluginVersion" "true" & 238 | done 239 | wait 240 | 241 | echo 242 | echo "WAR bundled plugins:" 243 | echo "${bundledPlugins}" 244 | echo 245 | echo "Installed plugins:" 246 | installedPlugins 247 | 248 | if [[ -f $FAILED ]]; then 249 | echo "Some plugins failed to download!" "$(<"$FAILED")" >&2 250 | exit 1 251 | fi 252 | 253 | echo "Cleaning up locks" 254 | rm -r "$REF_DIR"/*.lock 255 | } 256 | 257 | main "$@" 258 | -------------------------------------------------------------------------------- /jenkins-fat/jenkins-support: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eu 2 | 3 | # compare if version1 < version2 4 | versionLT() { 5 | local v1; v1=$(echo "$1" | cut -d '-' -f 1 ) 6 | local q1; q1=$(echo "$1" | cut -s -d '-' -f 2- ) 7 | local v2; v2=$(echo "$2" | cut -d '-' -f 1 ) 8 | local q2; q2=$(echo "$2" | cut -s -d '-' -f 2- ) 9 | if [ "$v1" = "$v2" ]; then 10 | if [ "$q1" = "$q2" ]; then 11 | return 1 12 | else 13 | if [ -z "$q1" ]; then 14 | return 1 15 | else 16 | if [ -z "$q2" ]; then 17 | return 0 18 | else 19 | [ "$q1" = "$(echo -e "$q1\n$q2" | sort -V | head -n1)" ] 20 | fi 21 | fi 22 | fi 23 | else 24 | [ "$v1" = "$(echo -e "$v1\n$v2" | sort -V | head -n1)" ] 25 | fi 26 | } 27 | 28 | # returns a plugin version from a plugin archive 29 | get_plugin_version() { 30 | local archive; archive=$1 31 | local version; version=$(unzip -p "$archive" META-INF/MANIFEST.MF | grep "^Plugin-Version: " | sed -e 's#^Plugin-Version: ##') 32 | version=${version%%[[:space:]]} 33 | echo "$version" 34 | } 35 | 36 | # Copy files from /usr/share/jenkins/ref into $JENKINS_HOME 37 | # So the initial JENKINS-HOME is set with expected content. 38 | # Don't override, as this is just a reference setup, and use from UI 39 | # can then change this, upgrade plugins, etc. 40 | copy_reference_file() { 41 | f="${1%/}" 42 | b="${f%.override}" 43 | rel="${b:23}" 44 | version_marker="${rel}.version_from_image" 45 | dir=$(dirname "${b}") 46 | local action; 47 | local reason; 48 | local container_version; 49 | local image_version; 50 | local marker_version; 51 | local log; log=false 52 | if [[ ${rel} == plugins/*.jpi ]]; then 53 | container_version=$(get_plugin_version "$JENKINS_HOME/${rel}") 54 | image_version=$(get_plugin_version "${f}") 55 | if [[ -e $JENKINS_HOME/${version_marker} ]]; then 56 | marker_version=$(cat "$JENKINS_HOME/${version_marker}") 57 | if versionLT "$marker_version" "$container_version"; then 58 | action="SKIPPED" 59 | reason="Installed version ($container_version) has been manually upgraded from initial version ($marker_version)" 60 | log=true 61 | else 62 | if [[ "$image_version" == "$container_version" ]]; then 63 | action="SKIPPED" 64 | reason="Version from image is the same as the installed version $image_version" 65 | else 66 | if versionLT "$image_version" "$container_version"; then 67 | action="SKIPPED" 68 | log=true 69 | reason="Image version ($image_version) is older than installed version ($container_version)" 70 | else 71 | action="UPGRADED" 72 | log=true 73 | reason="Image version ($image_version) is newer than installed version ($container_version)" 74 | fi 75 | fi 76 | fi 77 | else 78 | if [[ -n "$TRY_UPGRADE_IF_NO_MARKER" ]]; then 79 | if [[ "$image_version" == "$container_version" ]]; then 80 | action="SKIPPED" 81 | reason="Version from image is the same as the installed version $image_version (no marker found)" 82 | # Add marker for next time 83 | echo "$image_version" > "$JENKINS_HOME/${version_marker}" 84 | else 85 | if versionLT "$image_version" "$container_version"; then 86 | action="SKIPPED" 87 | log=true 88 | reason="Image version ($image_version) is older than installed version ($container_version) (no marker found)" 89 | else 90 | action="UPGRADED" 91 | log=true 92 | reason="Image version ($image_version) is newer than installed version ($container_version) (no marker found)" 93 | fi 94 | fi 95 | fi 96 | fi 97 | if [[ ! -e $JENKINS_HOME/${rel} || "$action" == "UPGRADED" || $f = *.override ]]; then 98 | action=${action:-"INSTALLED"} 99 | log=true 100 | mkdir -p "$JENKINS_HOME/${dir:23}" 101 | cp -r "${f}" "$JENKINS_HOME/${rel}"; 102 | # pin plugins on initial copy 103 | touch "$JENKINS_HOME/${rel}.pinned" 104 | echo "$image_version" > "$JENKINS_HOME/${version_marker}" 105 | reason=${reason:-$image_version} 106 | else 107 | action=${action:-"SKIPPED"} 108 | fi 109 | else 110 | if [[ ! -e $JENKINS_HOME/${rel} || $f = *.override ]] 111 | then 112 | action="INSTALLED" 113 | log=true 114 | mkdir -p "$JENKINS_HOME/${dir:23}" 115 | cp -r "${f}" "$JENKINS_HOME/${rel}"; 116 | else 117 | action="SKIPPED" 118 | fi 119 | fi 120 | if [[ -n "$VERBOSE" || "$log" == "true" ]]; then 121 | if [ -z "$reason" ]; then 122 | echo "$action $rel" >> "$COPY_REFERENCE_FILE_LOG" 123 | else 124 | echo "$action $rel : $reason" >> "$COPY_REFERENCE_FILE_LOG" 125 | fi 126 | fi 127 | } -------------------------------------------------------------------------------- /jenkins-fat/jenkins.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash -e 2 | 3 | : "${JENKINS_HOME:="/var/jenkins_home"}" 4 | touch "${COPY_REFERENCE_FILE_LOG}" || { echo "Can not write to ${COPY_REFERENCE_FILE_LOG}. Wrong volume permissions?"; exit 1; } 5 | echo "--- Copying files at $(date)" >> "$COPY_REFERENCE_FILE_LOG" 6 | find /usr/share/jenkins/ref/ \( -type f -o -type l \) -exec bash -c '. /usr/local/bin/jenkins-support; for arg; do copy_reference_file "$arg"; done' _ {} + 7 | 8 | # if `docker run` first argument start with `--` the user is passing jenkins launcher arguments 9 | if [[ $# -lt 1 ]] || [[ "$1" == "--"* ]]; then 10 | 11 | # read JAVA_OPTS and JENKINS_OPTS into arrays to avoid need for eval (and associated vulnerabilities) 12 | java_opts_array=() 13 | while IFS= read -r -d '' item; do 14 | java_opts_array+=( "$item" ) 15 | done < <([[ $JAVA_OPTS ]] && xargs printf '%s\0' <<<"$JAVA_OPTS") 16 | 17 | jenkins_opts_array=( ) 18 | while IFS= read -r -d '' item; do 19 | jenkins_opts_array+=( "$item" ) 20 | done < <([[ $JENKINS_OPTS ]] && xargs printf '%s\0' <<<"$JENKINS_OPTS") 21 | 22 | exec java -Duser.home="$JENKINS_HOME" "${java_opts_array[@]}" -jar /usr/share/jenkins/jenkins.war "${jenkins_opts_array[@]}" "$@" 23 | fi 24 | 25 | # As argument is not jenkins, assume user want to run his own process, for example a `bash` shell to explore this image 26 | exec "$@" 27 | -------------------------------------------------------------------------------- /jenkins-fat/plugins.txt: -------------------------------------------------------------------------------- 1 | ace-editor 2 | analysis-collector 3 | analysis-core 4 | ansible 5 | ansicolor 6 | ant 7 | antisamy-markup-formatter 8 | apache-httpcomponents-client-4-api 9 | authentication-tokens 10 | bouncycastle-api 11 | branch-api 12 | buildgraph-view 13 | build-monitor-plugin 14 | build-name-setter 15 | build-timeout 16 | buildtriggerbadge 17 | build-view-column 18 | build-with-parameters 19 | checkstyle 20 | cloudbees-folder 21 | compact-columns 22 | conditional-buildstep 23 | config-file-provider 24 | configuration-as-code 25 | console-badge 26 | console-column-plugin 27 | console-tail 28 | copyartifact 29 | credentials 30 | credentials-binding 31 | cucumber-reports 32 | cvs 33 | delivery-pipeline-plugin 34 | dependencyanalyzer 35 | depgraph-view 36 | display-url-api 37 | docker-commons 38 | docker-java-api 39 | docker-plugin 40 | docker-workflow 41 | durable-task 42 | email-ext 43 | envfile 44 | envinject 45 | envinject-api 46 | extensible-choice-parameter 47 | external-monitor-job 48 | favorite 49 | file-operations 50 | findbugs 51 | git 52 | git-changelog 53 | git-client 54 | github 55 | github-api 56 | github-branch-source 57 | gitlab-hook 58 | gitlab-logo 59 | gitlab-merge-request-jenkins 60 | gitlab-oauth 61 | gitlab-plugin 62 | git-parameter 63 | git-server 64 | git-tag-message 65 | gradle 66 | greenballs 67 | handlebars 68 | htmlpublisher 69 | jackson2-api 70 | javadoc 71 | jdepend 72 | jira 73 | jobConfigHistory 74 | job-dsl 75 | jobtype-column 76 | jquery 77 | jquery-detached 78 | jquery-ui 79 | jsch 80 | junit 81 | lastfailureversioncolumn 82 | lastsuccessversioncolumn 83 | ldap 84 | lockable-resources 85 | m2release 86 | mailer 87 | mapdb-api 88 | matrix-auth 89 | matrix-project 90 | maven-artifact-choicelistprovider 91 | maven-plugin 92 | modernstatus 93 | momentjs 94 | nested-view 95 | nexus-artifact-uploader 96 | nexus-jenkins-plugin 97 | notification 98 | pam-auth 99 | parameterized-trigger 100 | pipeline-build-step 101 | pipeline-github-lib 102 | pipeline-graph-analysis 103 | pipeline-input-step 104 | pipeline-milestone-step 105 | pipeline-model-api 106 | pipeline-model-declarative-agent 107 | pipeline-model-definition 108 | pipeline-model-extensions 109 | pipeline-rest-api 110 | pipeline-stage-step 111 | pipeline-stage-tags-metadata 112 | pipeline-stage-view 113 | plain-credentials 114 | post-completed-build-result 115 | promoted-builds 116 | promoted-builds-simple 117 | pubsub-light 118 | repository-connector 119 | resource-disposer 120 | ruby-runtime 121 | run-condition 122 | saferestart 123 | scm-api 124 | script-security 125 | sonar 126 | sonar-quality-gates 127 | sse-gateway 128 | ssh-credentials 129 | ssh-slaves 130 | structs 131 | subversion 132 | timestamper 133 | token-macro 134 | variant 135 | violation-comments-to-github 136 | workflow-aggregator 137 | workflow-api 138 | workflow-basic-steps 139 | workflow-cps 140 | workflow-cps-global-lib 141 | workflow-durable-task-step 142 | workflow-job 143 | workflow-multibranch 144 | workflow-scm-step 145 | workflow-step-api 146 | workflow-support 147 | ws-cleanup 148 | -------------------------------------------------------------------------------- /jenkins-fat/preDownload.sh: -------------------------------------------------------------------------------- 1 | 2 | . ../.env 3 | 4 | mkdir -p Plugins/${JENKINS_LTS} 5 | chmod -R a+rwx Plugins/${JENKINS_LTS} 6 | 7 | #TODO: Download Jenkins.war 8 | 9 | 10 | for datei in $(cat plugins.txt) 11 | do 12 | if test -e Plugins/${JENKINS_LTS}/${datei}.hpi 13 | then 14 | echo "Already downloaded ${datei} " 15 | else 16 | echo -n "Download ${datei}.hpi" 17 | wget -q -P Plugins/${JENKINS_LTS} https://updates.jenkins.io/${JENKINS_LTS}/latest/${datei}.hpi 18 | chmod a+rw Plugins/${JENKINS_LTS}/${datei}.hpi 19 | if [ $? -eq 0 ] ; then 20 | echo " OK" 21 | else 22 | # Without quiet to show what happened 23 | wget -P Plugins/${JENKINS_LTS} https://updates.jenkins.io/${JENKINS_LTS}/latest/${datei}.hpi 24 | fi 25 | fi 26 | done 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /jenkins-fat/publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eu 2 | 3 | # Publish any versions of the docker image not yet pushed to jenkins/jenkins 4 | # Arguments: 5 | # -n dry run, do not build or publish images 6 | # -d debug 7 | 8 | set -o pipefail 9 | 10 | sort-versions() { 11 | if [ "$(uname)" == 'Darwin' ]; then 12 | gsort --version-sort 13 | else 14 | sort --version-sort 15 | fi 16 | } 17 | 18 | # Try tagging with and without -f to support all versions of docker 19 | docker-tag() { 20 | local from="jenkins/jenkins:$1" 21 | local to="$2/jenkins:$3" 22 | local out 23 | 24 | docker pull "$from" 25 | if out=$(docker tag -f "$from" "$to" 2>&1); then 26 | echo "$out" 27 | else 28 | docker tag "$from" "$to" 29 | fi 30 | } 31 | 32 | login-token() { 33 | # could use jq .token 34 | curl -q -sSL "https://auth.docker.io/token?service=registry.docker.io&scope=repository:jenkins/jenkins:pull" | grep -o '"token":"[^"]*"' | cut -d':' -f 2 | xargs echo 35 | } 36 | 37 | is-published() { 38 | local tag=$1 39 | local opts="" 40 | if [ "$debug" = true ]; then 41 | opts="-v" 42 | fi 43 | local http_code; 44 | http_code=$(curl $opts -q -fsSL -o /dev/null -w "%{http_code}" -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -H "Authorization: Bearer $TOKEN" "https://index.docker.io/v2/jenkins/jenkins/manifests/$tag") 45 | if [ "$http_code" -eq "404" ]; then 46 | false 47 | elif [ "$http_code" -eq "200" ]; then 48 | true 49 | else 50 | echo "Received unexpected http code from Docker hub: $http_code" 51 | fi 52 | } 53 | 54 | get-manifest() { 55 | local tag=$1 56 | local opts="" 57 | if [ "$debug" = true ]; then 58 | opts="-v" 59 | fi 60 | curl $opts -q -fsSL -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -H "Authorization: Bearer $TOKEN" "https://index.docker.io/v2/jenkins/jenkins/manifests/$tag" 61 | } 62 | 63 | get-digest() { 64 | local manifest 65 | manifest=$(get-manifest "$1") 66 | #get-manifest "$1" | jq .config.digest 67 | if [ "$debug" = true ]; then 68 | >&2 echo "DEBUG: Manifest for $1: $manifest" 69 | fi 70 | echo "$manifest" | grep -A 10 -o '"config".*' | grep digest | head -1 | cut -d':' -f 2,3 | xargs echo 71 | } 72 | 73 | get-latest-versions() { 74 | curl -q -fsSL https://repo.jenkins-ci.org/releases/org/jenkins-ci/main/jenkins-war/maven-metadata.xml | grep '.*' | grep -E -o '[0-9]+(\.[0-9]+)+' | sort-versions | uniq | tail -n 20 75 | } 76 | 77 | publish() { 78 | local version=$1 79 | local variant=$2 80 | local tag="${version}${variant}" 81 | local sha 82 | local build_opts=(--no-cache --pull) 83 | 84 | if [ "$dry_run" = true ]; then 85 | build_opts=() 86 | fi 87 | 88 | sha=$(curl -q -fsSL "https://repo.jenkins-ci.org/releases/org/jenkins-ci/main/jenkins-war/${version}/jenkins-war-${version}.war.sha256" ) 89 | 90 | docker build --file "Dockerfile$variant" \ 91 | --build-arg "JENKINS_VERSION=$version" \ 92 | --build-arg "JENKINS_SHA=$sha" \ 93 | --tag "jenkins/jenkins:${tag}" \ 94 | --tag "jenkinsci/jenkins:${tag}" \ 95 | "${build_opts[@]+"${build_opts[@]}"}" . 96 | 97 | # " line to fix syntax highlightning 98 | if [ ! "$dry_run" = true ]; then 99 | docker push "jenkins/jenkins:${tag}" 100 | docker push "jenkinsci/jenkins:${tag}" 101 | fi 102 | } 103 | 104 | tag-and-push() { 105 | local source=$1 106 | local target=$2 107 | local digest_source 108 | local digest_target 109 | 110 | if [ "$debug" = true ]; then 111 | >&2 echo "DEBUG: Getting digest for ${source}" 112 | fi 113 | # if tag doesn't exist yet, ie. dry run 114 | if ! digest_source=$(get-digest "${source}"); then 115 | echo "Unable to get digest for ${source} ${digest_source}" 116 | digest_source="" 117 | fi 118 | 119 | if [ "$debug" = true ]; then 120 | >&2 echo "DEBUG: Getting digest for ${target}" 121 | fi 122 | if ! digest_target=$(get-digest "${target}"); then 123 | echo "Unable to get digest for ${target} ${digest_target}" 124 | digest_target="" 125 | fi 126 | 127 | if [ "$digest_source" == "$digest_target" ] && [ -n "${digest_target}" ]; then 128 | echo "Images ${source} [$digest_source] and ${target} [$digest_target] are already the same, not updating tags" 129 | else 130 | echo "Creating tag ${target} pointing to ${source}" 131 | docker-tag "${source}" "jenkins" "${target}" 132 | docker-tag "${source}" "jenkinsci" "${target}" 133 | if [ ! "$dry_run" = true ]; then 134 | echo "Pushing jenkins/jenkins:${target}" 135 | docker push "jenkins/jenkins:${target}" 136 | docker push "jenkinsci/jenkins:${target}" 137 | else 138 | echo "Would push jenkins/jenkins:${target}" 139 | fi 140 | fi 141 | } 142 | 143 | publish-latest() { 144 | local version=$1 145 | local variant=$2 146 | 147 | # push latest (for master) or the name of the branch (for other branches) 148 | if [ -z "${variant}" ]; then 149 | tag-and-push "${version}${variant}" "latest" 150 | else 151 | tag-and-push "${version}${variant}" "${variant#-}" 152 | fi 153 | } 154 | 155 | publish-lts() { 156 | local version=$1 157 | local variant=$2 158 | tag-and-push "${version}${variant}" "lts${variant}" 159 | } 160 | 161 | # Process arguments 162 | 163 | dry_run=false 164 | debug=false 165 | variant="" 166 | 167 | while [[ $# -gt 0 ]]; do 168 | key="$1" 169 | case $key in 170 | -n) 171 | dry_run=true 172 | ;; 173 | -d) 174 | debug=true 175 | ;; 176 | -v|--variant) 177 | variant="-"$2 178 | shift 179 | ;; 180 | *) 181 | echo "Unknown option: $key" 182 | return 1 183 | ;; 184 | esac 185 | shift 186 | done 187 | 188 | 189 | if [ "$dry_run" = true ]; then 190 | echo "Dry run, will not publish images" 191 | fi 192 | 193 | TOKEN=$(login-token) 194 | 195 | lts_version="" 196 | version="" 197 | for version in $(get-latest-versions); do 198 | if is-published "$version$variant"; then 199 | echo "Tag is already published: $version$variant" 200 | else 201 | echo "Publishing version: $version$variant" 202 | publish "$version" "$variant" 203 | fi 204 | 205 | # Update lts tag 206 | if [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then 207 | lts_version="${version}" 208 | fi 209 | done 210 | 211 | publish-latest "${version}" "${variant}" 212 | if [ -n "${lts_version}" ]; then 213 | publish-lts "${lts_version}" "${variant}" 214 | fi 215 | -------------------------------------------------------------------------------- /jenkins-fat/readme.md: -------------------------------------------------------------------------------- 1 | ### Steps to predownload plugins. 2 | 3 | * Just a little wget Script to download all plugins 4 | ``` 5 | ./preDownload.sh $(cat active-plugins.txt) 6 | ``` 7 | * Download jenkins-war-2.73.2.war to the actual directory 8 | 9 | * Edit Dockerfile to copy all the Plugins into Jenkins 10 | ``` 11 | Line: 107 - 115 before edit 12 | 107 #------------------ Optional lokal caching of files 13 | 108 # Download jenkins with yout favorite browser and put the war in the current dir. 14 | 109 #COPY jenkins-war-2.73.2.war /usr/share/jenkins/jenkins.war 15 | 110 ###### # Copy all Cached plugins ... 16 | 111 # to preLoad all Plugins listed in active-plugins.txt use the command 17 | 112 # ./preDownload.sh $(cat active-plugins.txt) 18 | 113 # this will download all the plugins in th Folder Plugins 19 | 114 # COPY Plugins/* /usr/share/jenkins/ref/plugins/ 20 | 115 #------------------ Optional lokal caching of files end block 21 | 22 | Line: 107 - 115 after edit (edit only line 109 and 114) 23 | 107 #------------------ Optional lokal caching of files 24 | 108 # Download jenkins with yout favorite browser and put the war in the current dir. 25 | 26 | 109 COPY jenkins-war-2.73.2.war /usr/share/jenkins/jenkins.war 27 | 28 | 110 ###### # Copy all Cached plugins ... 29 | 111 # to preLoad all Plugins listed in active-plugins.txt use the command 30 | 112 # ./preDownload.sh $(cat active-plugins.txt) 31 | 113 # this will download all the plugins in th Folder Plugins 32 | 33 | 114 COPY Plugins/* /usr/share/jenkins/ref/plugins/ 34 | 35 | 115 #------------------ Optional lokal caching of files end block 36 | 37 | ``` 38 | 39 | 40 | -------------------------------------------------------------------------------- /jenkins-fat/update-official-library.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eu 2 | 3 | # Generate the Docker official-images file 4 | 5 | sha() { 6 | local branch=$1 7 | git rev-parse "$branch" 8 | } 9 | 10 | version_from_dockerfile() { 11 | local branch=$1 12 | git show "$branch:Dockerfile" | grep JENKINS_VERSION: | sed -e 's/.*:-\(.*\)}/\1/' 13 | } 14 | 15 | master_sha=$(sha master) 16 | alpine_sha=$(sha alpine) 17 | 18 | master_version=$(version_from_dockerfile master) 19 | alpine_version=$(version_from_dockerfile alpine) 20 | 21 | if ! [ "$master_version" == "$alpine_version" ]; then 22 | echo "Master version '$master_version' does not match alpine version '$alpine_version'" 23 | exit 1 24 | fi 25 | 26 | cat << EOF > ../official-images/library/jenkins 27 | # maintainer: Nicolas De Loof (@ndeloof) 28 | # maintainer: Michael Neale (@michaelneale) 29 | # maintainer: Carlos Sanchez (@carlossg) 30 | 31 | latest: git://github.com/jenkinsci/jenkins-ci.org-docker@$master_sha 32 | $master_version: git://github.com/jenkinsci/jenkins-ci.org-docker@$master_sha 33 | 34 | alpine: git://github.com/jenkinsci/jenkins-ci.org-docker@$alpine_sha 35 | $alpine_version-alpine: git://github.com/jenkinsci/jenkins-ci.org-docker@$alpine_sha 36 | EOF 37 | -------------------------------------------------------------------------------- /nginx-reverse/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:1.10 2 | 3 | RUN rm /etc/nginx/conf.d/default.conf 4 | RUN rm /etc/nginx/nginx.conf 5 | 6 | COPY reverse-proxy.conf /etc/nginx/conf.d/reverse-proxy.conf 7 | COPY nginx.* /etc/nginx/ssl/ 8 | COPY nginx.conf /etc/nginx/nginx.conf 9 | COPY proxy-settings.conf /etc/nginx/conf.d/proxy-settings.conf 10 | 11 | -------------------------------------------------------------------------------- /nginx-reverse/nginx-micro.conf: -------------------------------------------------------------------------------- 1 | # Docker doco says turn daemon off - but it produces errors if you do;the 2 | # NGINX Docker container now wires this in for you 3 | # daemon off; 4 | user nginx; 5 | worker_processes 1; 6 | 7 | error_log /var/log/nginx/error.log debug; 8 | pid /var/run/nginx.pid; 9 | 10 | events { 11 | worker_connections 1024; 12 | } 13 | 14 | http { 15 | include /etc/nginx/mime.types; 16 | 17 | # Need to set proxy headers so that the Jenkins Tomcat instance works properly 18 | proxy_set_header X-Real-IP $remote_addr; 19 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 20 | 21 | proxy_headers_hash_max_size 1024; 22 | proxy_headers_hash_bucket_size 512; 23 | 24 | default_type application/octet-stream; 25 | 26 | log_format main '$remote_addr - $remote_user [$time_local] "["servername:"$server_name"uri:"$request_uri] $request" ' 27 | '$status $body_bytes_sent "$http_referer" ' 28 | '"$http_user_agent" "$http_x_forwarded_for"'; 29 | 30 | access_log /var/log/nginx/access.log main; 31 | 32 | sendfile on; 33 | #tcp_nopush on; 34 | 35 | keepalive_timeout 65; 36 | 37 | 38 | # Cope with large file uploads; needed to publish plugins, amongst other things. 39 | client_max_body_size 300m; 40 | client_body_buffer_size 128k; 41 | 42 | # Turn on GZip compression 43 | gzip on; 44 | gzip_http_version 1.0; 45 | gzip_comp_level 6; 46 | gzip_min_length 0; 47 | gzip_buffers 16 8k; 48 | gzip_proxied any; 49 | gzip_types text/plain text/css text/xml text/javascript application/xml application/xml+rss application/javascript application/json; 50 | gzip_disable "MSIE [1-6]\."; 51 | gzip_vary on; 52 | 53 | # include sub-config files, especially the jenkins server 54 | include /etc/nginx/conf.d/*.conf; 55 | } 56 | 57 | # Stream pass through for SSL and JDBC Connections 58 | stream { 59 | server { 60 | listen 5555; 61 | proxy_pass gitlab:5555; 62 | } 63 | server { 64 | listen 2222; 65 | proxy_pass gitlab:22; 66 | 67 | } 68 | } 69 | 70 | 71 | -------------------------------------------------------------------------------- /nginx-reverse/nginx.conf: -------------------------------------------------------------------------------- 1 | # Docker doco says turn daemon off - but it produces errors if you do;the 2 | # NGINX Docker container now wires this in for you 3 | # daemon off; 4 | user nginx; 5 | worker_processes 1; 6 | 7 | error_log /var/log/nginx/error.log debug; 8 | pid /var/run/nginx.pid; 9 | 10 | events { 11 | worker_connections 1024; 12 | } 13 | 14 | http { 15 | include /etc/nginx/mime.types; 16 | 17 | # Need to set proxy headers so that the Jenkins Tomcat instance works properly 18 | proxy_set_header X-Real-IP $remote_addr; 19 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 20 | 21 | proxy_headers_hash_max_size 1024; 22 | proxy_headers_hash_bucket_size 512; 23 | 24 | default_type application/octet-stream; 25 | 26 | log_format main '$remote_addr - $remote_user [$time_local] "["servername:"$server_name"uri:"$request_uri] $request" ' 27 | '$status $body_bytes_sent "$http_referer" ' 28 | '"$http_user_agent" "$http_x_forwarded_for"'; 29 | 30 | access_log /var/log/nginx/access.log main; 31 | 32 | sendfile on; 33 | #tcp_nopush on; 34 | 35 | keepalive_timeout 65; 36 | 37 | 38 | # Cope with large file uploads; needed to publish plugins, amongst other things. 39 | client_max_body_size 300m; 40 | client_body_buffer_size 128k; 41 | 42 | # Turn on GZip compression 43 | gzip on; 44 | gzip_http_version 1.0; 45 | gzip_comp_level 6; 46 | gzip_min_length 0; 47 | gzip_buffers 16 8k; 48 | gzip_proxied any; 49 | gzip_types text/plain text/css text/xml text/javascript application/xml application/xml+rss application/javascript application/json; 50 | gzip_disable "MSIE [1-6]\."; 51 | gzip_vary on; 52 | 53 | # include sub-config files, especially the jenkins server 54 | include /etc/nginx/conf.d/*.conf; 55 | } 56 | 57 | # Stream pass through for SSL and JDBC Connections 58 | stream { 59 | server { 60 | listen 5555; 61 | proxy_pass gitlab:5555; 62 | } 63 | server { 64 | listen 2222; 65 | proxy_pass gitlab:22; 66 | 67 | } 68 | server { 69 | listen 5432; 70 | proxy_pass postgres:5432; 71 | } 72 | } 73 | 74 | 75 | -------------------------------------------------------------------------------- /nginx-reverse/proxy-settings.conf: -------------------------------------------------------------------------------- 1 | 2 | proxy_set_header Host $host; 3 | proxy_set_header X-Real-IP $remote_addr; 4 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 5 | proxy_set_header X-Forwarded-Proto http; 6 | proxy_max_temp_file_size 0; 7 | 8 | proxy_connect_timeout 150; 9 | proxy_send_timeout 100; 10 | proxy_read_timeout 100; 11 | 12 | proxy_buffer_size 8k; 13 | proxy_buffers 4 32k; 14 | proxy_busy_buffers_size 64k; 15 | proxy_temp_file_write_size 64k; 16 | 17 | 18 | -------------------------------------------------------------------------------- /nginx-reverse/reverse-proxy.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # Setting all the prefixes is a crazy .. 5 | 6 | server { 7 | listen 80; 8 | server_name "" ; 9 | access_log on; 10 | 11 | # Same like external_url 'http://HOSTNAME/gitlab' in docker-compose 12 | location ^~/gitlab { 13 | proxy_pass http://gitlab:80; 14 | include /etc/nginx/conf.d/proxy-settings.conf; 15 | } 16 | 17 | # Same like ENV JENKINS_OPTS=.....--prefix=/jenkins in jenkins-fat/Jenkins-Dockerfile 18 | location ^~/jenkins { 19 | proxy_pass http://jenkins:8080; 20 | include /etc/nginx/conf.d/proxy-settings.conf; 21 | } 22 | 23 | # Same like NEXUS_CONTEXT=nexus in docker-compose 24 | location ^~/nexus { 25 | proxy_pass http://nexus:8081; 26 | include /etc/nginx/conf.d/proxy-settings.conf; 27 | } 28 | 29 | 30 | location ^~/regweb/ { 31 | proxy_pass http://regweb:8080/regweb/; 32 | include /etc/nginx/conf.d/proxy-settings.conf; 33 | } 34 | 35 | # see https://portainer.readthedocs.io/en/stable/faq.html#how-can-i-configure-my-reverse-proxy-to-serve-portainer 36 | location ^~/portainer/ { 37 | proxy_http_version 1.1; 38 | proxy_set_header Connection ""; 39 | proxy_pass http://portainer:9000/; 40 | include /etc/nginx/conf.d/proxy-settings.conf; 41 | } 42 | 43 | # this is for docker exec with portainer and reverse-proxy 44 | location ^~/portainer/api/websocket/ { 45 | proxy_set_header Upgrade $http_upgrade; 46 | proxy_set_header Connection "upgrade"; 47 | proxy_http_version 1.1; 48 | proxy_pass http://portainer:9000/api/websocket/; 49 | 50 | 51 | include /etc/nginx/conf.d/proxy-settings.conf; 52 | } 53 | 54 | 55 | 56 | # Same like sonar.web.context=/sonar in preconfig/sonar/sonar.properties 57 | location ^~/sonar { 58 | # prevent nginx to throw errors if sonar 59 | # is not available 60 | # 127.0.0.11 is the Docker DNS 61 | resolver 127.0.0.11 valid=05s; 62 | set $sonarvm sonar; 63 | proxy_pass http://$sonarvm:9000; 64 | include /etc/nginx/conf.d/proxy-settings.conf; 65 | } 66 | 67 | 68 | } 69 | -------------------------------------------------------------------------------- /postgres/Dockerfile: -------------------------------------------------------------------------------- 1 | # vim:set ft=dockerfile: 2 | FROM postgres:11.4-alpine 3 | 4 | COPY createSonar.sql /docker-entrypoint-initdb.d/ 5 | 6 | -------------------------------------------------------------------------------- /postgres/createSonar.sql: -------------------------------------------------------------------------------- 1 | create user sonar with password 'sonar'; 2 | create database sonar with owner sonar encoding 'UTF8'; 3 | 4 | 5 | -------------------------------------------------------------------------------- /preconfig/docker-registry/config.yml: -------------------------------------------------------------------------------- 1 | version: 0.1 2 | log: 3 | fields: 4 | service: registry 5 | storage: 6 | delete: 7 | enabled: true 8 | cache: 9 | blobdescriptor: inmemory 10 | filesystem: 11 | rootdirectory: /var/lib/registry 12 | http: 13 | addr: :5000 14 | headers: 15 | X-Content-Type-Options: [nosniff] 16 | Access-Control-Allow-Origin: ['*'] 17 | Access-Control-Allow-Methods: ['HEAD', 'GET', 'OPTIONS', 'DELETE'] 18 | Access-Control-Allow-Headers: ['Authorization'] 19 | Access-Control-Max-Age: [1728000] 20 | Access-Control-Expose-Headers: ['Docker-Content-Digest'] 21 | -------------------------------------------------------------------------------- /preconfig/jenkins/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1.0 5 | 2 6 | NORMAL 7 | true 8 | 9 | true 10 | 11 | 12 | true 13 | false 14 | 15 | false 16 | 17 | ${JENKINS_HOME}/workspace/${ITEM_FULLNAME} 18 | ${ITEM_ROOTDIR}/builds 19 | 20 | 21 | 22 | 23 | 24 | 0 25 | 26 | 27 | 28 | all 29 | false 30 | false 31 | 32 | 33 | 34 | all 35 | 50000 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /preconfig/jenkins/secrets/filepath-filters.d/30-default.conf: -------------------------------------------------------------------------------- 1 | # GENERATED FILE. DO NOT MODIFY. 2 | # 3 | # This file is for Jenkins core developers to list what we think are the best filtering rules 4 | # for apparently harmless accesses to files on the Jenkins master from slaves. 5 | # 6 | # To override these rules, place *.conf files by other names into this folder. Files are sorted 7 | # before parsed, so using a lower number allows you to override what we have here. This file 8 | # gets overwritten every time Jenkins starts. 9 | # 10 | # See https://jenkins.io/redirect/security-144 for more details. 11 | 12 | # This directory contains credentials, master encryption keys, and other sensitive information 13 | # that slaves have absolutely no business with. 14 | # Unless there are rules in other files allowing access to other portions of $JENKINS_HOME, 15 | # this rule as it stands here has no effect, because anything left unspecified is rejected. 16 | deny all /secrets($|/.*) 17 | 18 | # User content is publicly readable, so quite safe for slaves to read, too. 19 | # (The xunit plugin is known to read from here.) 20 | # https://jenkins.io/redirect/user-content-directory 21 | allow read,stat /userContent($|/.*) 22 | 23 | # In the next rule we grant general access under build directories, so first we protect 24 | # the actual build record that Jenkins core reads, which nothing should be touching. 25 | deny all /build.xml 26 | # Similarly for Pipeline build (WorkflowRun) metadata: 27 | deny all /program.dat 28 | deny all /workflow($|/.*) 29 | 30 | # Various plugins read/write files under build directories, so allow them all. 31 | # - git 1.x writes changelog.xml from the slave (2.x writes from the master so need not be listed) 32 | # - analysis-core and plugins based on it write reports to workspace-files/ 33 | # - cobertura writes coverage.xml 34 | # - violations writes violations.xml and other content under violations/ 35 | # - dependency-check writes archive/artifacts.txt 36 | # But not allowing deletion to prevent data loss and symlink to prevent jailbreaking. 37 | allow create,mkdirs,read,stat,write /.+ 38 | 39 | # cobertura also writes out annotated sources to a dir under the job: 40 | allow create,mkdirs,read,stat,write /jobs/.+/cobertura.* 41 | 42 | # all the other accesses that aren't specified here will be left up to other rules in this directory. 43 | # if no rules in those other files matches, then the access will be rejected. 44 | -------------------------------------------------------------------------------- /preconfig/jenkins/secrets/hudson.util.Secret: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Springjunky/docker-local-build-environment/dd06f5a403df6bfeb3255b2f01ab64b69c044f2c/preconfig/jenkins/secrets/hudson.util.Secret -------------------------------------------------------------------------------- /preconfig/jenkins/secrets/jenkins.model.Jenkins.crumbSalt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Springjunky/docker-local-build-environment/dd06f5a403df6bfeb3255b2f01ab64b69c044f2c/preconfig/jenkins/secrets/jenkins.model.Jenkins.crumbSalt -------------------------------------------------------------------------------- /preconfig/jenkins/secrets/jenkins.security.ApiTokenProperty.seed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Springjunky/docker-local-build-environment/dd06f5a403df6bfeb3255b2f01ab64b69c044f2c/preconfig/jenkins/secrets/jenkins.security.ApiTokenProperty.seed -------------------------------------------------------------------------------- /preconfig/jenkins/secrets/master.key: -------------------------------------------------------------------------------- 1 | 19da5e497f843744fad7ccb80efa458e0920557484cd9c3d0d839cbfd59a84a97da57ed2b97124b88efe75d16ebdb1c1bc58fb9d808c2f8a3dccc2137057f6fb7353c35a05192c3f8c1934c2945e7b45499edace95fea577d00395e7dea65080b963d1f2957871006d1825ec8718500396a0c0b70af30610cce00e342f035406 -------------------------------------------------------------------------------- /preconfig/jenkins/secrets/org.jenkinsci.main.modules.instance_identity.InstanceIdentity.KEY: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Springjunky/docker-local-build-environment/dd06f5a403df6bfeb3255b2f01ab64b69c044f2c/preconfig/jenkins/secrets/org.jenkinsci.main.modules.instance_identity.InstanceIdentity.KEY -------------------------------------------------------------------------------- /preconfig/jenkins/secrets/slave-to-master-security-kill-switch: -------------------------------------------------------------------------------- 1 | false -------------------------------------------------------------------------------- /preconfig/jenkins/secrets/whitelisted-callables.d/default.conf: -------------------------------------------------------------------------------- 1 | # GENERATED FILE. DO NOT MODIFY. 2 | # 3 | # This file is for Jenkins core developers to list plugin callables which we believe are safe. 4 | # 5 | # To whitelist other names, place *.conf files by other names into this folder. 6 | # This file gets overwritten every time Jenkins starts. 7 | # 8 | # See https://jenkins.io/redirect/security-144 for more details. 9 | 10 | # maven plugin 11 | hudson.maven.MavenBuildProxy$Filter$AsyncInvoker 12 | 13 | # cloudbees-deployer plugin 14 | com.cloudbees.plugins.deployer.engines.Engine$FingerprintDecorator 15 | 16 | # subversion plugin 17 | hudson.scm.SubversionWorkspaceSelector$1 18 | 19 | # git-client plugin (prior to #147) 20 | org.jenkinsci.plugins.gitclient.CliGitAPIImpl$GetPrivateKeys 21 | 22 | # ssh-credentials plugin 23 | com.cloudbees.jenkins.plugins.sshcredentials.SSHAuthenticator$1 24 | 25 | # cygwin-process-killer plugin 26 | com.synopsys.arc.jenkinsci.plugins.cygwinprocesskiller.CygwinProcessKiller$KillerRemoteCall 27 | 28 | # selenium-plugin 29 | hudson.plugins.selenium.JenkinsCapabilityMatcher$LabelMatcherCallable 30 | -------------------------------------------------------------------------------- /preconfig/jenkins/users/admin/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Jenkins Admin 4 | 5 | 6 | {AQAAABAAAAAwKDjmjYtWHvzktNslPRHlgM3B33sXQRLTh3kRPAdRijm1YVRrsw0/KaHp319ZxfVAD6WupQJ1eh/zo4sxIrFSDw==} 7 | 8 | 9 | 10 | 11 | 12 | all 13 | false 14 | false 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | true 24 | 25 | 26 | #jbcrypt:$2a$10$/qqbaRyyt5Fu5cEyFMrT4O2B0oRTDVgO5k81F9.iG8HS.PE63Lei2 27 | 28 | 29 | 30 | authenticated 31 | 32 | 1505332796878 33 | 34 | 35 | -------------------------------------------------------------------------------- /preconfig/sonar/sonar.properties: -------------------------------------------------------------------------------- 1 | # Only one Property is need (because sonar ist behind nginx) 2 | sonar.web.context=/sonar 3 | -------------------------------------------------------------------------------- /security-paranoia/ReadMe.md: -------------------------------------------------------------------------------- 1 | All the exposed ports are reachable from outer world because docker creates and deletes dynamically iptables FORWARD rules with default policy ACCEPT on startup/shutdown containers wich have exported ports. 2 | 3 | To deny acccess from outer world the DOCKER-USER Chain (since docker 17.06) ist the medium of choice for your own rules (this is the first target in the FORWARD-Chain and never touched by docker). 4 | 5 | A little Script to deny all access from outer world to your local build environment could be the following (exposed port from nginx are 80,5555,2222) 6 | ``` 7 | #!/bin/bash 8 | if [ $# -lt 1 ] ; then 9 | echo "Need your external interface as one parameter" 10 | echo "Common names are eth0, enp...," 11 | echo "List of your names" 12 | ifconfig -a | sed 's/[ \t].*//;/^\(lo\|\)$/d' 13 | exit 14 | fi 15 | 16 | PORTS_TO_BLOCK="80,5555,2222" 17 | EXTERNAL_INTERFACE=$1 18 | 19 | # Flush and delete custom Chains 20 | iptables -F DOCKER-USER 21 | iptables -F EXTERNAL-ACCESS-DENY 22 | iptables -X EXTERNAL-ACCESS-DENY 23 | 24 | # Create a log-and-drop Chain 25 | iptables -N EXTERNAL-ACCESS-DENY 26 | iptables -A EXTERNAL-ACCESS-DENY -j LOG --log-prefix "DCKR-EXT-ACCESS-DENY:" --log-level 6 27 | iptables -A EXTERNAL-ACCESS-DENY -j DROP 28 | 29 | # Block all incomming traffic for docker 30 | iptables -A DOCKER-USER -i $EXTERNAL_INTERFACE \ 31 | -p tcp --match multiport \ 32 | --dports $PORTS_TO_BLOCK \ 33 | -j EXTERNAL-ACCESS-DENY 34 | 35 | # Restore default rule to return all the rest back to the FORWARD-Chain 36 | iptables -A DOCKER-USER -j RETURN 37 | 38 | echo "Rules created " 39 | iptables -v -L DOCKER-USER 40 | iptables -v -L EXTERNAL-ACCESS-DENY 41 | echo "See logs with prefix DCKR-EXT-ACCESS-DENY:" 42 | ``` 43 | -------------------------------------------------------------------------------- /security-paranoia/secureExternalPorts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ $# -lt 1 ] ; then 3 | echo "Need your external interface as one parameter" 4 | echo "Common names are eth0, enp...," 5 | echo "List of your names" 6 | ifconfig -a | sed 's/[ \t].*//;/^\(lo\|\)$/d' 7 | exit 8 | fi 9 | 10 | PORTS_TO_BLOCK="80,5555,2222" 11 | EXTERNAL_INTERFACE=$1 12 | 13 | # Flush and delete custom Chains 14 | iptables -F DOCKER-USER 15 | iptables -F EXTERNAL-ACCESS-DENY 16 | iptables -X EXTERNAL-ACCESS-DENY 17 | 18 | # Create a log-and-drop Chain 19 | iptables -N EXTERNAL-ACCESS-DENY 20 | iptables -A EXTERNAL-ACCESS-DENY -j LOG --log-prefix "DCKR-EXT-ACCESS-DENY:" --log-level 6 21 | iptables -A EXTERNAL-ACCESS-DENY -j DROP 22 | 23 | # Block all incomming traffic for docker 24 | iptables -A DOCKER-USER -i $EXTERNAL_INTERFACE \ 25 | -p tcp --match multiport \ 26 | --dports $PORTS_TO_BLOCK \ 27 | -j EXTERNAL-ACCESS-DENY 28 | 29 | # Restore default rule to return all the rest back to the FORWARD-Chain 30 | iptables -A DOCKER-USER -j RETURN 31 | 32 | echo "Rules created " 33 | iptables -v -L DOCKER-USER 34 | iptables -v -L EXTERNAL-ACCESS-DENY 35 | echo "See logs with prefix DCKR-EXT-ACCESS-DENY:" -------------------------------------------------------------------------------- /setupEnvironment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function pause(){ 4 | read -p "Press [Enter] key to continue..." 5 | } 6 | 7 | if [ $(id -u) -gt 0 ] ;then 8 | echo "Use sudo $0 " 9 | exit 1 10 | fi 11 | 12 | echo "Prepare .env for compose file and directorys" 13 | 14 | #------------------- Defaults 15 | JENKINS_LTS=2.176.1 16 | USER_DATA_DIR=$HOME/devstack-data 17 | HOSTNAME=$(hostname) 18 | HOSTIP=$(hostname -I | awk '{print $1}' ) 19 | 20 | 21 | echo "########################################################################" 22 | echo "Verify your hostname and the ip is correct, if this is wrong the " 23 | echo "container network ist not able to lookup the host \"$(hostname) \" by name " 24 | echo "it's a docker-Feature !!" 25 | echo "the \"routing \" ist out of container an back into the nginx and forward to container:-) " 26 | echo " and 8.8.8.8 (Google Nameserver) does not known your internal hostname " 27 | echo "########################################################################" 28 | 29 | pause 30 | 31 | echo "--------------------------------------------------------------" 32 | echo "------------------ Host-Settings -----------------------------" 33 | echo "--------------------------------------------------------------" 34 | 35 | read -e -p "Your hostname (hit return if $HOSTNAME is correct) : " -i $HOSTNAME GIVEN_HOSTNAME 36 | echo "Setting HOSTNAME to $GIVEN_HOSTNAME" 37 | HOSTNAME=$GIVEN_HOSTNAME 38 | echo "Type your hostIP, I guess it is one of $(hostname -I) " 39 | echo "Remember, 127.0.0.1 is NOT the correct IP and the docker-Network starts with 172.x.y.z and is also not correct" 40 | read -e -p "Your hostIP : " -i $HOSTIP GIVEN_HOSTIP 41 | HOSTIP=$GIVEN_HOSTIP 42 | echo "Setting HOSTIP to $GIVEN_HOSTIP" 43 | echo " " 44 | 45 | echo "--------------------------------------------------------------" 46 | echo "------------------ Jenkins ----- -----------------------------" 47 | echo "--------------------------------------------------------------" 48 | read -e -p "Please enter your Jenkins-Version (2.176.1) : " -i $JENKINS_LTS GIVEN_JENKINS_VERSION 49 | echo "Number of plugins to download for Jenkins ${JENKINS_LTS_MAJOR}.${JENKINS_LTS_MINOR}.${JENKINS_LTS_BUILD} " 50 | echo " (L)et _ME_ choose (0 Plugins)" 51 | echo " (P)redonwload Plugins (defined in ./jenkins-fat/plugins.txt) " 52 | PLUGINS=P 53 | read -e -p "Choose L or P : " -i $PLUGINS GIVEN_PLUGINS 54 | 55 | 56 | # Set the right volume-names, hostname and host_ip in .env for docker-compose.yml 57 | echo "---------- generating .env file for docker-compose.yml " 58 | 59 | # this enivonment file is sourced by the preDownload.sh script in jenkins-fat 60 | cat .env.template > .env 61 | echo "DC_HOSTNAME=${HOSTNAME}" >> .env 62 | echo "DC_HOSTIP=${HOSTIP}" >> .env 63 | echo "DC_BASE_DATA_DIR=${USER_DATA_DIR}" >> .env 64 | echo "JENKINS_LTS_MAJOR=$(echo $GIVEN_JENKINS_VERSION | cut -d. -f1)" >> .env 65 | echo "JENKINS_LTS_MINOR=$(echo $GIVEN_JENKINS_VERSION | cut -d. -f2)" >> .env 66 | echo "JENKINS_LTS_BUILD=$(echo $GIVEN_JENKINS_VERSION | cut -d. -f3)" >> .env 67 | echo "JENKINS_LTS=$(echo $GIVEN_JENKINS_VERSION | cut -d. -f1).$(echo $GIVEN_JENKINS_VERSION | cut -d. -f2)" >> .env 68 | case $GIVEN_PLUGINS in 69 | "L"|"l" ) 70 | echo "Pluigns for Jenkins ${JENKINS_LTS_MAJOR}.${JENKINS_LTS_MINOR}.${JENKINS_LTS_BUILD} is your choice" 71 | ;; 72 | "P"|"p") 73 | echo "..start Donloading and cache Plugins to ./jenkins-fat/Plugins/${JENKINS_LTS_MAJOR}.${JENKINS_LTS_MINOR}" 74 | pause 75 | cd jenkins-fat 76 | . preDownload.sh 77 | cd - 78 | ;; 79 | esac 80 | 81 | echo "--------------------------------------------------------------" 82 | echo "------------------ ssl ---------------------------------------" 83 | echo "--------------------------------------------------------------" 84 | 85 | type openssl 2>/dev/null 86 | if [ $? -eq 0 ] ; then 87 | echo "openssl installed :-)" 88 | else 89 | echo "please install openssl first" 90 | exit 1 91 | fi 92 | 93 | #---------------------------------- 94 | echo "create need host-volumes" 95 | mkdir -p $USER_DATA_DIR/sonar/sonarqube_conf 96 | mkdir -p $USER_DATA_DIR/jenkins 97 | mkdir -p $USER_DATA_DIR/gitlab/config/ssl 98 | mkdir -p $USER_DATA_DIR/gitlab-runner 99 | mkdir -p $USER_DATA_DIR/nexus 100 | mkdir -p $USER_DATA_DIR/docker-registry/images 101 | chown -R 200 $USER_DATA_DIR/nexus 102 | chmod -R a+rw $USER_DATA_DIR 103 | 104 | 105 | #---------------------------------- 106 | 107 | echo "Create a self-signed certificate for your host: $HOSTNAME to prevent docker complaining unsecure (gitlab) registry " 108 | pause 109 | 110 | if [ -f $USER_DATA_DIR/gitlab/config/ssl/$(hostname).key ]; then 111 | FILE_NAME=$USER_DATA_DIR/gitlab/config/ssl/$(hostname).key-$(date +"%F-%H-%M-%S-%N") 112 | cp $USER_DATA_DIR/gitlab/config/ssl/$(hostname).key $USER_DATA_DIR/gitlab/config/ssl/$(hostname).key-$(date +"%F-%H-%M-%S-%N") 113 | echo "previous key saved as $FILE_NAME" 114 | fi 115 | if [ -f $USER_DATA_DIR/gitlab/config/ssl/$(hostname).crt ]; then 116 | FILE_NAME=$USER_DATA_DIR/gitlab/config/ssl/$(hostname).crt-$(date +"%F-%H-%M-%S-%N") 117 | cp $USER_DATA_DIR/gitlab/config/ssl/$(hostname).crt $USER_DATA_DIR/gitlab/config/ssl/$(hostname).crt-$(date +"%F-%H-%M-%S-%N") 118 | echo "previous crt saved as $FILE_NAME" 119 | fi 120 | 121 | # Key and Cert only need for the docker-registry to "save" push your images to gitlab 122 | openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \ 123 | -keyout $USER_DATA_DIR/gitlab/config/ssl/$(hostname).key \ 124 | -out $USER_DATA_DIR/gitlab/config/ssl/$(hostname).crt \ 125 | -subj "/C=DE/ST=Home/L=Home/O=Local/OU=CI\/CD-Build-Stack/CN=$(hostname)" 126 | 127 | if [ $? -eq 0 ] ;then 128 | echo "----------- Your certificate used by Gitlab docker-registry@${HOSTNAME} -------------------" 129 | openssl x509 -in $USER_DATA_DIR/gitlab/config/ssl/$(hostname).crt -text | head -15 130 | echo "-------------------------------------------------------------------------------------------" 131 | pause 132 | else 133 | echo "NO CERT GENERATED " 134 | exit 1 135 | fi 136 | 137 | if [ -f .env ]; then 138 | FILE_NAME=.env-$(date +"%F-%H-%M-%S-%N") 139 | cp .env $FILE_NAME 140 | echo "previous .env saved as $FILE_NAME" 141 | fi 142 | # Copy preconfigs to host-volumes 143 | # sonar.properties 144 | if [ -f $USER_DATA_DIR/sonar/sonarqube_conf/sonar.properties ] ; then 145 | echo "WARNING: $USER_DATA_DIR/sonar/sonarqube_conf/sonar.properties exists" 146 | echo "make sure it has a sonar.web.context=/sonar entry" 147 | else 148 | cp preconfig/sonar/sonar.properties $USER_DATA_DIR/sonar/sonarqube_conf 149 | fi 150 | 151 | #Copy and modify predefined Jobs and Configs 152 | cp -r preconfig/jenkins/* $USER_DATA_DIR/jenkins/ 153 | 154 | # Copy Registry Config 155 | cp preconfig/docker-registry/config.yml $USER_DATA_DIR/docker-registry/config.yml 156 | 157 | chmod a+rw .env 158 | echo "---------------------------------------------------------------" 159 | echo "------------------ generated Environment for Docker-Compose ---" 160 | echo "---------------------------------------------------------------" 161 | 162 | echo "---------- generated file ---------------------------- " 163 | 164 | cat .env 165 | echo "-------------------------------------------------------------------------------------------" 166 | echo "If something changed (your IP / hostname ... ) just edit the .env or rerun the script." 167 | 168 | echo "-------------------------------------------------------------------------------------------" 169 | echo "-------------------------------------------------------------------------------------------" 170 | echo "Environment for docker-compose.yml created" 171 | echo " " 172 | echo "use the following URL" 173 | BASE_URL="http://"$(hostname)"/" 174 | echo "Jenkins: ${BASE_URL}jenkins" 175 | echo "Nexus : ${BASE_URL}nexus" 176 | echo "Gitlab : ${BASE_URL}gitlab" 177 | echo "Docker-Registry-Ui: ${BASE_URL}regweb" 178 | echo "Sonar: ${BASE_URL}sonar (optional)" 179 | echo "Keycloak: ${BASE_URL}auth (optional)" 180 | echo "Feel free to provide push-requests :-)" 181 | pause 182 | echo " " 183 | 184 | echo "Setup finished, just type the following commands to start and see the logs of your environment" 185 | echo " " 186 | echo "Without Sonar: docker-compose up --build " 187 | echo "Full Toolset : docker-compose -f docker-compose.yml -f docker-compose-sonar.yml up --build " 188 | echo " " 189 | echo "be patient ...10 docker-containers needs time to start up " 190 | 191 | 192 | 193 | 194 | 195 | 196 | --------------------------------------------------------------------------------