Time in Docker container out of sync with host machine
docker
Solution
Docker containers don't maintain a separate clock, it's identical to the Linux host since time is not a namespaced value. This is also why Docker removes the permission to change the time inside the container, since that would impact the host and other containers, breaking the isolation model.
However, on Docker Desktop, docker runs inside of a VM (allowing you to run Linux containers on non-Linux desktops), and that VM's time can get out of sync when the laptop is suspended. This is currently being tracked in an issue over on github which you can follow to see the progress: https://github.com/docker/for-win/issues/4526
Potential solutions include restarting your computer, restarting docker's VM, running NTP as a privileged container, or resetting the time sync in the windows VM with the following PowerShell:
Get-VMIntegrationService -VMName DockerDesktopVM -Name "Time Synchronization" | Disable-VMIntegrationService
Get-VMIntegrationService -VMName DockerDesktopVM -Name "Time Synchronization" | Enable-VMIntegrationService
With WSL 2, restarting the VM involves:
wsl --shutdown
wsl
Problem
I'm trying to connect to `CosmosDB` through my `SpringBoot` app. I have all of this working if I run the app with `Spring` or via `Intellij`. But, when I run the app in `Docker` I get the following error message: ``` com.azure.data.cosmos.CosmosClientException: The authorization token is not valid at the current time. Please create another token and retry (token start time: Thu, 26 Mar 2020 04:32:10 GMT, token expiry time: Thu, 26 Mar 2020 04:47:10 GMT, current server time: Tue, 31 Mar 2020 20:12:42 GMT). ``` Note that in the above error message the `current server time` is correct but the other times are 5 days behind. What I find interesting is that I only ever receive this in the docker container. ``` FROM {copy of zulu-jdk11} ARG JAR_FILE #.crt file in the same folder as your Dockerfile ARG CERT="cosmos.cer" ARG ALIAS="cosmos2" #import cert into java COPY $CERT / RUN chmod +x /$CERT WORKDIR $JAVA_HOME/lib/security RUN keytool -importcert -file /$CERT -alias $ALIAS -cacerts -storepass changeit -noprompt WORKDIR / COPY /target/${JAR_FILE} app.jar COPY run-java.sh / RUN chmod +x /run-java.sh ENV JAVA_OPTIONS "-Duser.timezone=UTC" ENV JAVA_APP_JAR "/app.jar" # run as non-root to mitigate some security risks RUN addgroup -S pcc && adduser -S nonroot -G nonroot USER nonroot:nonroot ENTRYPOINT ["/run-java.sh"] ``` One thing to note is `ENV JAVA_OPTIONS "-Duser.timezone=UTC"` but removing this didn't help me at all I basically run the same step from IntelliJ and I have no issues with it but in docker the expiry date seems to be 5 days behind. ``` version: "3.7" services: orchestration-agent: image: {image-name} ports: - "8080:8080" network_mode: host environment: - COSMOSDB_URI=https://host.docker.internal:8081/ - COSMOSDB_KEY={key} - COSMOSDB_DATABASE={database} - COSMOSDB_POPULATEQUERYMETRICS=true - COSMOSDB_ITEMLEVELTTL=60 ``` I think it should also be mentioned that I changed the `network_mode` to `host`. And I also changed the CosmosDB URI from `https://localhost:8081` to `https://host.docker.internal:8081/` I would also like to mention that I built my `dockerfile` with the help of: Importing self-signed cert into Docker's JRE cacert is not recognized by the service How to add a SSL self-signed cert to Jenkins for LDAPS within Dockerfile?