skip to Main Content

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"
  ]
}

2

Answers


  1. 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".

    Login or Signup to reply.
  2. To ensure that Docker is fully available before running the "dapr init" command, you can add a delay before running the "dapr init" command in your DevContainer definition. The "sleep" command you tried didn’t work because it might not be waiting long enough. You can use a more robust approach by continuously checking if Docker is available and then running "dapr init" once it is. Here’s how you can modify your DevContainer definition to achieve this:

    {
      "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": "waitForDockerAndDaprInit",
      "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"
      ]
    }
    

    Then, create a shell script named waitForDockerAndDaprInit in your DevContainer directory with the following content:

    #!/bin/sh
    
    # Wait for Docker to be available
    while ! docker info >/dev/null 2>&1; do
      sleep 1
    done
    
    # Run dapr init
    dapr init
    

    Make sure to make the shell script executable using chmod +x waitForDockerAndDaprInit.

    This script will continuously check if Docker is available, and once it is, it will run "dapr init." This should ensure that "dapr init" runs when Docker is ready.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search