├── Dockerfile ├── README.md ├── root └── usr │ └── bin │ └── fix-permissions ├── run.sh ├── sonarqube-postgresql-template.yaml └── sonarqube-template.yaml /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM jboss/base-jdk:8 2 | 3 | MAINTAINER Erik Jacobs 4 | MAINTAINER Siamak Sadeghianfar 5 | 6 | ENV SONAR_VERSION=6.7 \ 7 | SONARQUBE_HOME=/opt/sonarqube \ 8 | SONARQUBE_JDBC_USERNAME=sonar \ 9 | SONARQUBE_JDBC_PASSWORD=sonar \ 10 | SONARQUBE_JDBC_URL= 11 | 12 | USER root 13 | EXPOSE 9000 14 | ADD root / 15 | 16 | RUN set -x \ 17 | 18 | # pub 2048R/D26468DE 2015-05-25 19 | # Key fingerprint = F118 2E81 C792 9289 21DB CAB4 CFCA 4A29 D264 68DE 20 | # uid sonarsource_deployer (Sonarsource Deployer) 21 | # sub 2048R/06855C1D 2015-05-25 22 | && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys F1182E81C792928921DBCAB4CFCA4A29D26468DE \ 23 | 24 | && cd /opt \ 25 | && curl -o sonarqube.zip -fSL https://sonarsource.bintray.com/Distribution/sonarqube/sonarqube-$SONAR_VERSION.zip \ 26 | && curl -o sonarqube.zip.asc -fSL https://sonarsource.bintray.com/Distribution/sonarqube/sonarqube-$SONAR_VERSION.zip.asc \ 27 | && gpg --batch --verify sonarqube.zip.asc sonarqube.zip \ 28 | && unzip sonarqube.zip \ 29 | && mv sonarqube-$SONAR_VERSION sonarqube \ 30 | && rm sonarqube.zip* \ 31 | && rm -rf $SONARQUBE_HOME/bin/* 32 | 33 | WORKDIR $SONARQUBE_HOME 34 | COPY run.sh $SONARQUBE_HOME/bin/ 35 | 36 | RUN useradd -r sonar 37 | RUN /usr/bin/fix-permissions $SONARQUBE_HOME \ 38 | && chmod 775 $SONARQUBE_HOME/bin/run.sh 39 | 40 | USER sonar 41 | ENTRYPOINT ["./bin/run.sh"] 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SonarQube on OpenShift 2 | This repo contains all of the resources required to build an OpenShift-specific 3 | Docker image of SonarQube. 4 | 5 | It is inspired by the upstream SonarQube Docker image: 6 | https://github.com/SonarSource/docker-sonarqube 7 | 8 | # Docker Hub 9 | 10 | The SonarQube image is available on Docker Hub at: https://hub.docker.com/r/openshiftdemos/sonarqube/ 11 | 12 | # Deploy on OpenShift 13 | You can do use the provided templates with an embedded or postgresql database to deploy SonarQube on 14 | OpenShift: 15 | 16 | SonarQube with Embedded H2 Database: 17 | 18 | oc new-app -f sonarqube-template.yaml --param=SONARQUBE_VERSION=6.7 19 | 20 | SonarQube with PostgreSQL Database: 21 | 22 | oc new-app -f sonarqube-postgresql-template.yaml --param=SONARQUBE_VERSION=6.7 23 | -------------------------------------------------------------------------------- /root/usr/bin/fix-permissions: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Fix permissions on the given directory to allow group read/write of 3 | # regular files and execute of directories. 4 | chown -R sonar "$1" 5 | chgrp -R 0 "$1" 6 | chmod -R g+rw "$1" 7 | find "$1" -type d -exec chmod g+x {} + 8 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | if [ "${1:0:1}" != '-' ]; then 6 | exec "$@" 7 | fi 8 | 9 | exec java -jar lib/sonar-application-$SONAR_VERSION.jar \ 10 | -Dsonar.log.console=true \ 11 | -Dsonar.jdbc.username="$SONARQUBE_JDBC_USERNAME" \ 12 | -Dsonar.jdbc.password="$SONARQUBE_JDBC_PASSWORD" \ 13 | -Dsonar.jdbc.url="$SONARQUBE_JDBC_URL" \ 14 | -Dsonar.web.javaAdditionalOpts="$SONARQUBE_WEB_JVM_OPTS -Djava.security.egd=file:/dev/./urandom" \ 15 | "$@" 16 | -------------------------------------------------------------------------------- /sonarqube-postgresql-template.yaml: -------------------------------------------------------------------------------- 1 | kind: Template 2 | apiVersion: v1 3 | metadata: 4 | annotations: 5 | description: The SonarQube OpenShift template 6 | tags: instant-app,sonarqube 7 | name: sonarqube 8 | message: "Login to SonarQube with the default admin user: admin/admin" 9 | objects: 10 | - apiVersion: v1 11 | kind: Service 12 | metadata: 13 | name: sonarqube 14 | labels: 15 | app: sonarqube 16 | spec: 17 | ports: 18 | - name: sonarqube 19 | port: 9000 20 | protocol: TCP 21 | targetPort: 9000 22 | selector: 23 | app: sonarqube 24 | deploymentconfig: sonarqube 25 | sessionAffinity: None 26 | type: ClusterIP 27 | - apiVersion: v1 28 | kind: Route 29 | metadata: 30 | annotations: 31 | description: Route for SonarQube's http service. 32 | name: sonarqube 33 | labels: 34 | app: sonarqube 35 | spec: 36 | to: 37 | kind: Service 38 | name: sonarqube 39 | - apiVersion: v1 40 | kind: ImageStream 41 | metadata: 42 | labels: 43 | app: sonarqube 44 | name: sonarqube 45 | spec: 46 | tags: 47 | - annotations: 48 | description: The SonarQube Docker image 49 | tags: sonarqube 50 | from: 51 | kind: DockerImage 52 | name: openshiftdemos/sonarqube:${SONARQUBE_VERSION} 53 | importPolicy: {} 54 | name: ${SONARQUBE_VERSION} 55 | - apiVersion: v1 56 | kind: DeploymentConfig 57 | metadata: 58 | labels: 59 | app: sonarqube 60 | deploymentconfig: sonarqube 61 | name: sonarqube 62 | spec: 63 | replicas: 1 64 | selector: 65 | app: sonarqube 66 | deploymentconfig: sonarqube 67 | strategy: 68 | resources: {} 69 | rollingParams: 70 | intervalSeconds: 1 71 | maxSurge: 25% 72 | maxUnavailable: 25% 73 | timeoutSeconds: 600 74 | updatePeriodSeconds: 1 75 | type: Rolling 76 | template: 77 | metadata: 78 | annotations: 79 | openshift.io/container.sonarqube.image.entrypoint: '["./bin/run.sh"]' 80 | creationTimestamp: null 81 | labels: 82 | app: sonarqube 83 | deploymentconfig: sonarqube 84 | spec: 85 | containers: 86 | - env: 87 | - name: SONARQUBE_JDBC_PASSWORD 88 | value: ${POSTGRESQL_PASSWORD} 89 | - name: SONARQUBE_JDBC_URL 90 | value: jdbc:postgresql://postgresql-sonarqube/sonar 91 | - name: SONARQUBE_JDBC_USERNAME 92 | value: sonar 93 | image: ' ' 94 | imagePullPolicy: IfNotPresent 95 | name: sonarqube 96 | ports: 97 | - containerPort: 9000 98 | protocol: TCP 99 | livenessProbe: 100 | failureThreshold: 3 101 | initialDelaySeconds: 60 102 | periodSeconds: 20 103 | successThreshold: 1 104 | httpGet: 105 | port: 9000 106 | path: / 107 | timeoutSeconds: 5 108 | readinessProbe: 109 | failureThreshold: 3 110 | initialDelaySeconds: 60 111 | periodSeconds: 20 112 | successThreshold: 1 113 | httpGet: 114 | port: 9000 115 | path: / 116 | timeoutSeconds: 5 117 | resources: 118 | requests: 119 | cpu: 200m 120 | memory: 1Gi 121 | limits: 122 | cpu: 1 123 | memory: 2Gi 124 | terminationMessagePath: /dev/termination-log 125 | volumeMounts: 126 | - mountPath: /opt/sonarqube/data 127 | name: sonarqube-data 128 | dnsPolicy: ClusterFirst 129 | restartPolicy: Always 130 | securityContext: {} 131 | terminationGracePeriodSeconds: 30 132 | volumes: 133 | - name: sonarqube-data 134 | persistentVolumeClaim: 135 | claimName: sonarqube-data 136 | triggers: 137 | - type: ConfigChange 138 | - imageChangeParams: 139 | automatic: true 140 | containerNames: 141 | - sonarqube 142 | from: 143 | kind: ImageStreamTag 144 | name: sonarqube:${SONARQUBE_VERSION} 145 | type: ImageChange 146 | - apiVersion: v1 147 | kind: Service 148 | metadata: 149 | name: postgresql-sonarqube 150 | labels: 151 | app: sonarqube 152 | spec: 153 | ports: 154 | - name: postgresql 155 | port: 5432 156 | protocol: TCP 157 | targetPort: 5432 158 | selector: 159 | app: sonarqube 160 | deploymentconfig: postgresql-sonarqube 161 | sessionAffinity: None 162 | type: ClusterIP 163 | - apiVersion: v1 164 | kind: DeploymentConfig 165 | metadata: 166 | labels: 167 | app: sonarqube 168 | deploymentconfig: postgresql-sonarqube 169 | name: postgresql-sonarqube 170 | spec: 171 | replicas: 1 172 | selector: 173 | app: sonarqube 174 | deploymentconfig: postgresql-sonarqube 175 | strategy: 176 | recreateParams: 177 | timeoutSeconds: 600 178 | resources: {} 179 | type: Recreate 180 | template: 181 | metadata: 182 | labels: 183 | app: sonarqube 184 | deploymentconfig: postgresql-sonarqube 185 | spec: 186 | containers: 187 | - env: 188 | - name: POSTGRESQL_USER 189 | value: sonar 190 | - name: POSTGRESQL_PASSWORD 191 | value: ${POSTGRESQL_PASSWORD} 192 | - name: POSTGRESQL_DATABASE 193 | value: sonar 194 | image: ' ' 195 | imagePullPolicy: IfNotPresent 196 | livenessProbe: 197 | failureThreshold: 3 198 | initialDelaySeconds: 30 199 | periodSeconds: 10 200 | successThreshold: 1 201 | tcpSocket: 202 | port: 5432 203 | timeoutSeconds: 1 204 | name: postgresql 205 | ports: 206 | - containerPort: 5432 207 | protocol: TCP 208 | readinessProbe: 209 | exec: 210 | command: 211 | - /bin/sh 212 | - -i 213 | - -c 214 | - psql -h 127.0.0.1 -U $POSTGRESQL_USER -q -d $POSTGRESQL_DATABASE -c 'SELECT 1' 215 | failureThreshold: 3 216 | initialDelaySeconds: 5 217 | periodSeconds: 10 218 | successThreshold: 1 219 | timeoutSeconds: 1 220 | resources: 221 | limits: 222 | memory: 256Mi 223 | securityContext: 224 | capabilities: {} 225 | privileged: false 226 | terminationMessagePath: /dev/termination-log 227 | volumeMounts: 228 | - mountPath: /var/lib/pgsql/data 229 | name: postgresql-data 230 | dnsPolicy: ClusterFirst 231 | restartPolicy: Always 232 | securityContext: {} 233 | terminationGracePeriodSeconds: 30 234 | volumes: 235 | - name: postgresql-data 236 | persistentVolumeClaim: 237 | claimName: postgresql-sonarqube-data 238 | test: false 239 | triggers: 240 | - imageChangeParams: 241 | automatic: true 242 | containerNames: 243 | - postgresql 244 | from: 245 | kind: ImageStreamTag 246 | name: postgresql:9.5 247 | namespace: openshift 248 | type: ImageChange 249 | - type: ConfigChange 250 | - apiVersion: v1 251 | kind: PersistentVolumeClaim 252 | metadata: 253 | name: postgresql-sonarqube-data 254 | spec: 255 | accessModes: 256 | - ReadWriteOnce 257 | resources: 258 | requests: 259 | storage: ${POSTGRESQL_VOLUME_CAPACITY} 260 | - apiVersion: v1 261 | kind: PersistentVolumeClaim 262 | metadata: 263 | name: sonarqube-data 264 | spec: 265 | accessModes: 266 | - ReadWriteOnce 267 | resources: 268 | requests: 269 | storage: ${SONAR_VOLUME_CAPACITY} 270 | parameters: 271 | - displayName: SonarQube version 272 | value: "6.7" 273 | name: SONARQUBE_VERSION 274 | required: true 275 | - description: Password for SonarQube Server PostgreSQL backend 276 | displayName: SonarQube's PostgreSQL Password 277 | from: '[a-zA-Z0-9]{16}' 278 | generate: expression 279 | name: POSTGRESQL_PASSWORD 280 | required: true 281 | - description: Volume space available for PostgreSQL 282 | displayName: PostgreSQL Volume Capacity 283 | name: POSTGRESQL_VOLUME_CAPACITY 284 | required: true 285 | value: 1Gi 286 | - description: Volume space available for SonarQube 287 | displayName: SonarQube Volume Capacity 288 | name: SONAR_VOLUME_CAPACITY 289 | required: true 290 | value: 1Gi -------------------------------------------------------------------------------- /sonarqube-template.yaml: -------------------------------------------------------------------------------- 1 | kind: Template 2 | apiVersion: v1 3 | metadata: 4 | annotations: 5 | description: The SonarQube OpenShift template 6 | tags: instant-app,sonarqube 7 | name: sonarqube 8 | message: "Login to SonarQube with the default admin user: admin/admin" 9 | objects: 10 | - apiVersion: v1 11 | kind: Service 12 | metadata: 13 | name: sonarqube 14 | labels: 15 | app: sonarqube 16 | spec: 17 | ports: 18 | - name: sonarqube 19 | port: 9000 20 | protocol: TCP 21 | targetPort: 9000 22 | selector: 23 | app: sonarqube 24 | deploymentconfig: sonarqube 25 | sessionAffinity: None 26 | type: ClusterIP 27 | - apiVersion: v1 28 | kind: Route 29 | metadata: 30 | annotations: 31 | description: Route for SonarQube's http service. 32 | name: sonarqube 33 | labels: 34 | app: sonarqube 35 | spec: 36 | to: 37 | kind: Service 38 | name: sonarqube 39 | - apiVersion: v1 40 | kind: ImageStream 41 | metadata: 42 | labels: 43 | app: sonarqube 44 | name: sonarqube 45 | spec: 46 | tags: 47 | - annotations: 48 | description: The SonarQube Docker image 49 | tags: sonarqube 50 | from: 51 | kind: DockerImage 52 | name: openshiftdemos/sonarqube:${SONARQUBE_VERSION} 53 | importPolicy: {} 54 | name: ${SONARQUBE_VERSION} 55 | - apiVersion: v1 56 | kind: DeploymentConfig 57 | metadata: 58 | labels: 59 | app: sonarqube 60 | deploymentconfig: sonarqube 61 | name: sonarqube 62 | spec: 63 | replicas: 1 64 | selector: 65 | app: sonarqube 66 | deploymentconfig: sonarqube 67 | strategy: 68 | resources: {} 69 | rollingParams: 70 | intervalSeconds: 1 71 | maxSurge: 25% 72 | maxUnavailable: 25% 73 | timeoutSeconds: 600 74 | updatePeriodSeconds: 1 75 | type: Rolling 76 | template: 77 | metadata: 78 | annotations: 79 | openshift.io/container.sonarqube.image.entrypoint: '["./bin/run.sh"]' 80 | creationTimestamp: null 81 | labels: 82 | app: sonarqube 83 | deploymentconfig: sonarqube 84 | spec: 85 | containers: 86 | - image: ' ' 87 | imagePullPolicy: IfNotPresent 88 | name: sonarqube 89 | ports: 90 | - containerPort: 9000 91 | protocol: TCP 92 | livenessProbe: 93 | failureThreshold: 5 94 | initialDelaySeconds: 180 95 | periodSeconds: 20 96 | successThreshold: 1 97 | httpGet: 98 | port: 9000 99 | path: / 100 | timeoutSeconds: 5 101 | readinessProbe: 102 | failureThreshold: 5 103 | initialDelaySeconds: 60 104 | periodSeconds: 20 105 | successThreshold: 1 106 | httpGet: 107 | port: 9000 108 | path: / 109 | timeoutSeconds: 5 110 | resources: 111 | requests: 112 | cpu: 200m 113 | memory: 1Gi 114 | limits: 115 | cpu: 1 116 | memory: ${SONAR_MAX_MEMORY} 117 | terminationMessagePath: /dev/termination-log 118 | volumeMounts: 119 | - mountPath: /opt/sonarqube/data 120 | name: sonarqube-data 121 | dnsPolicy: ClusterFirst 122 | restartPolicy: Always 123 | securityContext: {} 124 | terminationGracePeriodSeconds: 30 125 | volumes: 126 | - name: sonarqube-data 127 | persistentVolumeClaim: 128 | claimName: sonarqube-data 129 | triggers: 130 | - type: ConfigChange 131 | - imageChangeParams: 132 | automatic: true 133 | containerNames: 134 | - sonarqube 135 | from: 136 | kind: ImageStreamTag 137 | name: sonarqube:${SONARQUBE_VERSION} 138 | type: ImageChange 139 | - apiVersion: v1 140 | kind: PersistentVolumeClaim 141 | metadata: 142 | name: sonarqube-data 143 | spec: 144 | accessModes: 145 | - ReadWriteOnce 146 | resources: 147 | requests: 148 | storage: ${SONAR_VOLUME_CAPACITY} 149 | parameters: 150 | - displayName: SonarQube version 151 | value: "6.7" 152 | name: SONARQUBE_VERSION 153 | required: true 154 | - description: Volume space available for SonarQube 155 | displayName: SonarQube Volume Capacity 156 | name: SONAR_VOLUME_CAPACITY 157 | required: true 158 | value: 1Gi 159 | - displayName: SonarQube Max Memory 160 | name: SONAR_MAX_MEMORY 161 | required: true 162 | value: 2Gi --------------------------------------------------------------------------------