How to set SonarQube TimeZone in a Docker container setup

I’m trying to update the Time that SonarQube uses inside of a Docker container. It is 2 hours ahead of where I need it to be:

  • SQ version 9.5.0.56709 with a Postgres back end
  • I need to set the Timezone to be Central US time
  • Inside of the container I have tried setting the date manually, but that is not allowed. All other solutions I have used in the past are not available in this container without major updates to install other features.
  • The host machine’s time is set to Central time as desired. It’s just inside the SonarQube Docker container where the system time is 2 hours ahead of the desired time
  • I have also searched through the docs and yet to find anything that specifies where I can set the time inside of the app

Any other suggestions?

Hey there.

Not currently being able to run SonarQube on Docker (because I’m using an M1 mac), I would anticipate that you could just do something like docker run -e TZ="CET" sonarqube.

Although as far as I’m aware – users don’t typically need to do this. What are the symptoms of your SonarQube server’s time not aligning with your local time? What do you see in the UI – what features are behaving oddly?

My apologies for delayed response. The issue is that everything is being saved as GMT, and I need it to be saved as Central US time.

When I look at the Administration > System > “Web JVM Properties” I see that user.timezone is set to GMT.

Would it be possible to somehow update that value to be set to US Central Timezone?

For the record, I have tried setting ‘user.timezone’ inside of the existing Docker container in the sonar.properties, but it does not seem to be enforced in the app.

container:/opt/sonarqube/conf $ cat sonar.properties
sonar.web.javaAdditionalOptsi=-Duser.timezone=CET
sonar.ce.javaAdditionalOpts=-Duser.timezone=CET
sonar.search.javaAdditionalOpts=-Duser.timezone=CET

Then in the sonar.log file I see that the user.timezone parm is sent to the JVM:

container:/opt/sonarqube/logs $ cat sonar.log | grep timezone
2022.09.23 01:48:36 INFO app[o.s.a.ProcessLauncherImpl] Launch process[COMPUTE_ENGINE] from [/opt/sonarqube]: /usr/lib/jvm/java-11-openjdk/bin/java -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djava.io.tmpdir=/opt/sonarqube/temp -XX:-OmitStackTraceInFastThrow --add-opens=java.base/java.util=ALL-UNNAMED --add-exports=java.base/jdk.internal.ref=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.management/sun.management=ALL-UNNAMED --add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED -Dcom.redhat.fips=false -Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError -Duser.timezone=America/Chicago -Dhttp.nonProxyHosts=localhost|127.|[::1] -cp ./lib/sonar-application-9.5.0.56709.jar:/opt/sonarqube/lib/jdbc/postgresql/postgresql-42.3.3.jar org.sonar.ce.app.CeServer /opt/sonarqube/temp/sq-process7023462536063294818properties
2022.09.23 20:41:37 INFO app[][o.s.a.ProcessLauncherImpl] Launch process[COMPUTE_ENGINE] from [/opt/sonarqube]: /usr/lib/jvm/java-11-openjdk/bin/java -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djava.io.tmpdir=/opt/sonarqube/temp -XX:-OmitStackTraceInFastThrow --add-opens=java.base/java.util=ALL-UNNAMED --add-exports=java.base/jdk.internal.ref=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.management/sun.management=ALL-UNNAMED --add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED -Dcom.redhat.fips=false -Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError -Duser.timezone=CET -Dhttp.nonProxyHosts=localhost|127.
|[::1] -cp ./lib/sonar-application-9.5.0.56709.jar:/opt/sonarqube/lib/jdbc/postgresql/postgresql-42.3.3.jar org.sonar.ce.app.CeServer /opt/sonarqube/temp/sq-process1794718339891702569properties

I have this container setup the way I want it for our POC, and I do not have external volumes (unfortunately), and at this point I’d rather not have to start from scratch.

For starters, CET is Central European Time. You would need to set it for your timezone, CST.

And, I still think this is an important question:

Where exactly do you see the timezone having an impact?

Ok, I got everything back to default settings in the app, and everything looks good in the browser console. What led me down this road was issues in the API timestamps (to answer your question from above, kind of) when trying to retrieve some basic data about a scan. At some point I must have gotten things all messed up, which resulted in the GUI looking off as well, but it is working as expected now.

The timezone was having an impact when I try to retrieve data via the API, it does not appear to grab data between the “to” and “from” timeframe I’m passing in as parameters in the URL. This is not really a “timezone” issue any more, it is more of a “I’m probably messing things up when trying to retrieve data between a given time in the API” issue.

When I retrieve the entire day, the values are pulled back as expected:

URL to pull back the entire day’s worth of data:

https://sonarqube.mycompany.com/api/measures/search_history?component=EComm-Admin&from=2022-09-27&to=2022-09-27&metrics=bugs,code_smells,vulnerabilities,reliability_rating,security_rating,sqale_rating,coverage,duplicated_blocks&ps=1000

Data retrieved for the entire day query above:

2022-09-27T19:38:38+0000 coverage=0.0 project-key=EComm-Admin duplicated_blocks=299 code_smells=2448 bugs=55 vulnerabilities=28 sqale_rating=1.0 reliability_rating=5.0 security_rating=2.0

When I try to retrieve the last hour’s worth of data, the above activity should also be returned in the response, but it is not.

URL to pull back the last hour’s worth of data (I’m using GMT time in my script):

https://sonarqube.mycompany.com/api/measures/search_history?component=EComm-Admin&from=2022-09-27T19:09&to=2022-09-27T20:09&metrics=bugs,code_smells,vulnerabilities,reliability_rating,security_rating,sqale_rating,coverage,duplicated_blocks&ps=1000

No results were returned.

Given the documentation, I also tried appending several TimeZone options to the end of the “to” and “from” parameters, but nothing there seemed to work either: 2022-09-27T19:09+0000, 2022-09-27T19:09-0500, etc.

Am I using the API query in the wrong way?

Hey there.

In the API doc it reads:

Example value: 2017-10-19 or 2017-10-19T13:00:00+0200

Which means there are two problems with the query parameters you’re trying:

  1. You need to include seconds (19:09:00)
  2. A + sign has a semantic meaning in a query string. It is used to represent a space. You need to specify %2B instead, which will be URL-decoded to a + sign.

Which makes a “correct” query something like::

https://next.sonarqube.com/sonarqube/api/measures/search_history?component=rspec-frontend&metrics=ncloc&from=2022-09-26T19:09:00%2B0500

Somebody internally stumbled on this second point recently, and I’ll flag this for our documentation team to see if we can improve something. Let me know if this helps.

Thanks for all the help Colin. That got me over this hurdle. The seconds not being attached was an oversight on my part.

Might be worth adding an example to the documentation to avoid confusion with the “+” and “%2B” in the future.

This ticket can be closed.

Hi @SeanCharles, thanks for spelling out this issue. It’s a great topic to add to the SonarQube docs!

We created a ticket for it and added it to our backlog.