I am trying to setup a DevContainer for Dapr to make dev environment setup easy. I would like to run Dapr Init automatically so that there are no manual steps needed to run services.

I put "dapr init" in the postStartCommand, but when it runs it says there is no Docker Runtime available.

❌  could not connect to docker. docker may not be installed or running

Immediately after that fails, I can manually run "dapr init" in a terminal and it works appropriately.

I have tried giving it more time by adding a "sleep 30", but that doesn't seem to help.

Is there anything I can do to ensure the docker runtime is up and running so I can automatically initialize dapr?

Here is my devcontainer definition

{
  "name": "Dapr Quickstarts Codespace",
  "dockerFile": "Dockerfile",
  "customizations": {
    "vscode": {
      "extensions": [
        "golang.go",
        "ms-azuretools.vscode-dapr",
        "ms-azuretools.vscode-docker",
        "ms-kubernetes-tools.vscode-kubernetes-tools",
        "ms-dotnettools.csdevkit"
      ]
    }
  },
  "features": {
    "ghcr.io/dapr/cli/dapr-cli:0": {},
    "ghcr.io/devcontainers/features/docker-in-docker:2": {}
    },
  "mounts": [
    // Mount docker-in-docker library volume
    "source=codespaces-linux-var-lib-docker,target=/var/lib/docker,type=volume"
  ],
  "postStartCommand": "dapr init",
  // Always run image-defined docker-init.sh to enable docker-in-docker
  "overrideCommand": false,
  "remoteUser": "codespace",
  "runArgs": [
    // Enable ptrace-based debugging for Go in container
    "--cap-add=SYS_PTRACE",
    "--security-opt",
    "seccomp=unconfined",

    // Enable docker-in-docker configuration
    "--init",
    "--privileged"
  ]
}
1

There are 1 answers

4
VonC On BEST ANSWER

Since the dapr init command does rely on Docker, which apparently has not fully initialized when postStartCommand is executed, you might consider, as a workaround, a script that checks for Docker availability before running the dapr init command

Create a file named check-docker.sh:

#!/bin/bash

# Wait for Docker
until docker info >/dev/null 2>&1; do
    echo "Waiting for Docker..."
    sleep 1
done

# Now run dapr init
dapr init

And update your devcontainer.json file to point to the check-docker.sh script in the postStartCommand field:

"postStartCommand": "/path/to/check-docker.sh",

Does this actually work, though? I've added a 3-minute sleep and after the sleep docker is still not initialized. I suspect it simply will not initialize until the postStartCommand is finished executing.

That would mean the postStartCommand execution may be blocking the Docker initialization process.
That makes sense, especially if the Docker service is being initialized in the same context or process tree as the postStartCommand. In that case, the postStartCommand would block Docker from fully initializing until it completes.

A possible solution could be to offload the dapr init command to a background process, which would allow postStartCommand to complete, and Docker to continue its initialization. That could be achieved by updating the script to run dapr init in the background or after a delay, allowing the postStartCommand to complete, and potentially allowing Docker to finish initializing.

The check-docker.sh script, which now offloads dapr init to a background process, would be (using "nohup"):

#!/bin/bash

# Function to check docker and run dapr init
run_dapr_init() {
  # Wait for Docker
  until docker info >/dev/null 2>&1; do
    echo "Waiting for Docker..."
    sleep 1
  done

  # Now run dapr init
  dapr init
}

# Export the function and run it in the background
export -f run_dapr_init
nohup bash -c run_dapr_init &

# Exit immediately so postStartCommand completes
exit 0

And the updated postStartCommand in your devcontainer.json would remain the same:

"postStartCommand": "/path/to/check-docker.sh",

The postStartCommand should complete immediately, potentially allowing Docker to finish initializing, while the dapr init command will be attempted in a separate background process.

If you place check-docker.sh at the root of your project, the path would just be "/check-docker.sh".