Docker-sonarqube: Unable to use custom sonar properties via docker config in 7.0

Created on 27 Feb 2018  Â·  17Comments  Â·  Source: SonarSource/docker-sonarqube

With SonarQube 6.4, I was able to create a docker swarm that mounts in a custom sonar.properties file.

In my sonarstack file:

services:
  sonarqube-server:
    image: my-registry/my-namespace/sonarqube:6.4
    networks:
      - sonarnet
    ports:
      - "9000:9000"
    environment:
      - SONARQUBE_WEB_JVM_OPTS=-Djavax.net.ssl.keyStore=/root/keystore -Djavax.net.ssl.keyStorePassword=changeit
      - SONARQUBE_JDBC_URL=jdbc:postgresql://MYDB_HOST/MYDB_NAME
      - SONARQUBE_JDBC_USERNAME=MYDB_USER
      - SONARQUBE_JDBC_PASSWORD=MYDB_PASS
    configs:
      - source: sonar.conf
        target: /opt/sonarqube/conf/sonar.properties

configs:
  sonar.conf:
    file: ./my-sonar.properties

With SonarQube 7.0 (now with non-root user - yay!), this fails. I see this repeatedly in logs...

sonarstack_sonarqube-server.1.blahblah | chown: changing ownership of '/opt/sonarqube/conf/sonar.properties': Read-only file system

The container crashes and restarts only to fail with this same error.

Tried explicitly setting UID/GID/MODE in the stack definition file...

    configs:
      - source: sonar.conf
        target: /opt/sonarqube/conf/sonar.properties
        uid: '999'
        gid: '999'
        mode: 0440

But, no joy. (I grabbed the UID/GID from /etc/passwd in the container.)

Again, same config works w/6.4 (running as root) but fails now in 7.0 (running as sonarqube).

I'd prefer to use the newer sonarqube. I need to use swarm to take advantage of docker secrets and docker config. Please advise.

help wanted

Most helpful comment

@Godin There are two PRs #161 and #171 which supposedly both fix this issue. The pipelines of both only fail due to some flaky behaviour.

Can you please spare some minutes and evaluate them? Especially #161 seems like an easy thing to review. Thanks a lot!

All 17 comments

Same here, i'm trying to mount a ConfigMap in Kubernetes, and it fails with that error. I'm wondering why it's necessary to chown the properties file, as it should be sufficient to just read it?!

@introllo @jangrewe versions prior to 6.6 were running under root user, while newer ones require and run under dedicated sonarqube user, so chown was explicitly asked by users and added to allow upgrades - see https://github.com/SonarSource/docker-sonarqube/pull/115#issuecomment-338385606

As far as I understand chown fails because file mounted as read-only. Hence logically question arises - can you mount it as writable?

After very short/quick thinking about solution: to preserve upgradability while solving this issue, there probably should be check of owner before attempt to change it.

As you might have noticed - there is only one maintainer and almost no external contributions. And I'm sorry, but right now I don't have capacity / free time slots to look deeper into this. Will do after finishing work on other projects. Feel free to propose patch instead of just complains.

Unfortunately i can't mount it r/w from a ConfigMap, as its... well, let's say "not really a file".
How about doing the chown, but just ignoring it it fails?

I have some cycles next week and will propose a patch.

@Godin There are two PRs #161 and #171 which supposedly both fix this issue. The pipelines of both only fail due to some flaky behaviour.

Can you please spare some minutes and evaluate them? Especially #161 seems like an easy thing to review. Thanks a lot!

Not a solution, but workaround in Kubernetes with configMap and lifecycle.postStart.

As stated here configMaps in Kubernetes are always read only.

apiVersion: v1
data:
  sonar.properties: |
    sonar.web.context=/sonar
kind: ConfigMap
metadata:
  name: sonar-config
  namespace: monitoring
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    run: sonarqube
  name: sonarqube
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      run: sonarqube
  strategy:
    rollingUpdate:
      maxSurge: 50%
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      labels:
        run: sonarqube
    spec:
      terminationGracePeriodSeconds: 120
      containers:
      - image: sonarqube:latest
        imagePullPolicy: IfNotPresent
        name: sonarqube
        ports:
        - name: sonar
          containerPort: 9000
        - name: sonar2
          containerPort: 9092
        readinessProbe:
          tcpSocket:
            port: sonar
          initialDelaySeconds: 70
          timeoutSeconds: 4
          periodSeconds: 2
          failureThreshold: 200
        resources:
          limits:
            cpu: "2"
            memory: "8192Mi"
          requests:
            memory: 256Mi
            cpu: "0.2"
        volumeMounts:
        - name: config-volume
          mountPath: /kubeconf/
        lifecycle:
          postStart:
            exec:
              command: ["cp", "/kubeconf/sonar.properties", "/opt/sonarqube/conf/"]
      volumes:
      - name: config-volume
        configMap:
          name: sonar-config
---
kind: Service
apiVersion: v1
metadata:
  labels:
    run: sonarqube
  name: sonarqube
  namespace: monitoring
spec:
  selector:
    run: sonarqube
  ports:
  - port: 9000
    targetPort: 9000
  type: NodePort
status:
  loadBalancer: {}

The solution for docker-compose was to chown 999:999 the sonar.properties file from the host.

I don't think there's actually a permission 999? You only have the three bits for rwx, and setting each bit to 1 gives you 111, which results in 7 in decimal - so 777 (as inu:111, g:111 and o:111) is the highest, AFAIK.

Edit: Just scrolled up and read the issue again, you probably mean chown 999:999, not chmod 999:999.

@jangrewe my bad, I meant chown, so it has the same userid as the container's user

same issue here. running into this right now:

19:15:12.659 [main] WARN org.sonar.application.config.AppSettingsLoaderImpl - Configuration file not found: /opt/sonarqube/conf/sonar.properties

well, normally the first non-root (non administrator) user start with uid 1000, why sonarqube is 999?

@eonie That applies to regular users, not system users. For system users the UID starts with 999 and decrements, for regular users it starts with 1000 and increments.

@jangrewe If I have none-root user with UID 1000 and also belong to Docker group, how can I run docker sonarqube with custom sonar.properties?

From all the posts above i guess your best bet is mounting it into the container and making sure that it's owned by the proper UID/GID.

@jangrewe It's worked, but the problem is if didn't mount /opt/sonarqube/temp to local FS, sonar will throw the bellow exception.

2018.12.15 19:47:46 INFO  app[][o.s.a.AppFileSystem] Cleaning or creating temp directory /opt/sonarqube/temp
Exception in thread "main" java.nio.file.AccessDeniedException: /opt/sonarqube/temp/README.txt
    at sun.nio.fs.UnixException.translateToIOException(UnixException.java:84)
    at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
    at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
    at sun.nio.fs.UnixFileSystemProvider.implDelete(UnixFileSystemProvider.java:244)
    at sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:103)
    at java.nio.file.Files.delete(Files.java:1126)
    at org.sonar.application.AppFileSystem$CleanTempDirFileVisitor.visitFile(AppFileSystem.java:121)
    at org.sonar.application.AppFileSystem$CleanTempDirFileVisitor.visitFile(AppFileSystem.java:101)
    at java.nio.file.Files.walkFileTree(Files.java:2670)
    at org.sonar.application.AppFileSystem.createOrCleanTempDirectory(AppFileSystem.java:96)
    at org.sonar.application.AppFileSystem.reset(AppFileSystem.java:62)
    at org.sonar.application.App.start(App.java:55)
    at org.sonar.application.App.main(App.java:78)

mount /opt/sonarqube/temp to local FS can resolve this problem , like this:

version: '2'
services:
## master
  sonarqube6.7:
    image: sonarqube:lts
    container_name: sonarqube
    volumes:
      - ./data/sonarqube/conf:/opt/sonarqube/conf
      - ./data/sonarqube/data:/opt/sonarqube/data
      - ./data/sonarqube/logs:/opt/sonarqube/logs
      - ./data/sonarqube/temp:/opt/sonarqube/temp
      - ./data/sonarqube/extensions:/opt/sonarqube/extensions
      - /etc/localtime:/etc/localtime:ro
    user: "1000:1000"
    ports:
      - "7500:9000"
    ulimits:
      nproc: 65535
    restart: always
    environment:
      - TZ=Asia/Shanghai

hope this could help somebody and thanks @jangrewe

Database config dont work from sonar.properties

This docker-compose.yml work (sonar.properties in ./data/sonarqube/conf)

version: '2'
services:
  sonarqube:
    image: sonarqube:7.5-community
    container_name: sonarqube
    environment:
      - SONARQUBE_JDBC_URL=jdbc:postgresql://db:5432/database
      - SONARQUBE_JDBC_USERNAME=user
      - SONARQUBE_JDBC_PASSWORD=password
    volumes:
      - ./data/sonarqube/conf:/opt/sonarqube/conf
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "9000:9000"
    ulimits:
      nproc: 65535

I'm closing this since there has been no update for a while. Please retry with the latest SQ version and create a new issue if needed, with more details and logs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mmaier2 picture mmaier2  Â·  6Comments

alexsuter picture alexsuter  Â·  3Comments

carloscds picture carloscds  Â·  3Comments

valeriimars picture valeriimars  Â·  8Comments

longquan7 picture longquan7  Â·  7Comments