devcontainers / features

A collection of Dev Container Features managed by Dev Container spec maintainers. See https://github.com/devcontainers/feature-starter to publish your own
https://containers.dev/features
MIT License
948 stars 387 forks source link

Docker not available in postCreateCommand (universal image) #780

Closed mandrasch closed 11 months ago

mandrasch commented 12 months ago

Hi,

we recently updated the docs for DDEV usage with Codespaces, https://ddev.readthedocs.io/en/latest/users/install/ddev-installation/#github-codespaces.

Users now reported, that they run into this, when they try to use ddev (which relies on Docker) on postCreateCommand:

Could not connect to a Docker provider. Please start or install a Docker provider.

I tried it multiple times in the last week and this week - same error when I try to launch https://github.com/mandrasch/ddev-craftcms-vite.

This error results from here:

    // Determine if Docker is running by getting the version.
    // This helps to prevent a user from seeing the Cobra error: "Error: unknown command "<custom command>" for ddev"
    _, err := dockerutil.GetDockerVersion()
    // ddev --version may be called without Docker available.
    if err != nil && len(os.Args) > 1 && os.Args[1] != "--version" && os.Args[1] != "hostname" {
        util.Failed("Could not connect to a Docker provider. Please start or install a Docker provider.\nFor install help go to: https://ddev.readthedocs.io/en/latest/users/install/")
    }

More detailed log:

2023-12-03 15:19:38.906Z: Running the postCreateCommand from devcontainer.json...

2023-12-03 15:19:38.915Z: chmod +x ./.devcontainer/postCreateCommand.sh && ./.devcontainer/postCreateCommand.sh
2023-12-03 15:19:39.083Z: + ddev config global --omit-containers=ddev-router
2023-12-03 15:19:50.015Z: ERRO[0010] app.FindContainerByType(web) failed 
ERRO[0010] app.FindContainerByType(db) failed  
Could not connect to a Docker provider. Please start or install a Docker provider.
For install help go to: https://ddev.readthedocs.io/en/latest/users/install/
2023-12-03 15:19:50.060Z: {"outcome":"error","message":"Command failed: /bin/sh -c chmod +x ./.devcontainer/postCreateCommand.sh && ./.devcontainer/postCreateCommand.sh","description":"The postCreateCommand in the devcontainer.json failed.","containerId":"f60437911600ca72d26ac8d58c7b4f846bf51b3e7a6fca6b3533082cc957148e"}
2023-12-03 15:19:50.070Z: postCreateCommand failed with exit code 1. Skipping any further user-provided commands.

The full creation.log: https://gist.github.com/mandrasch/001d52c50eb367dba466869f3439e0b3

{
  // https://hub.docker.com/_/microsoft-devcontainers-universal
  // this will also install docker-in-docker
  "image": "mcr.microsoft.com/devcontainers/universal:2",
  "features": {
    "ghcr.io/ddev/ddev/install-ddev:latest": {}
  },
  // TODO: is this still necessary?
  // https://code.visualstudio.com/docs/devcontainers/containers#_always-forwarding-a-port
  "forwardPorts": [5174],
  // these are just labels for codespaces ports tab, these will not create ports by default
  "portsAttributes": {
    "3306": {
      "label": "database"
    },
    "8027": {
      "label": "mailhog"
    },
    "8036": {
      "label": "phpmyadmin"
    },
    "8080": {
      "label": "web http"
    },
    "8443": {
      "label": "web https"
    },
    // our custom vite port for ddev + codespaces
    "5174":{
      "label": "vite"
    }
  },

  "postCreateCommand": "chmod +x ./.devcontainer/postCreateCommand.sh && ./.devcontainer/postCreateCommand.sh"
}

I already left a comment here.

One user reported he used postAttachCommand as workaround, which worked fine. But in my understanding this would run every time the codespace is really opened in the browser IDE (source) - so not a real alternative for initial installation scripts.

Thanks very much in advance for investigation!

Please let me know if I could assist in any way to help debug this.

Best regards, Matthias

eljog commented 11 months ago

Hi @mandrasch thank you for opening this issue and sharing the details. As indicated in the comments on the other issues this is caused since docker may be not yet ready by the time the postcreate command runs.

Have you considered adding a check inside your postCreateCommand script that waits for docker to be running before it tries to use docker? Probably something like this

wait_for_docker() {
  while true; do
    docker ps > /dev/null 2>&1
    if [ $? -eq 0 ]; then
      break
    fi
    sleep 1
  done
  echo "Docker is ready."
}

You may also attach this script to the onCreateCommand hook, so everything is ready before it proceeds to run postCreateCommand

postAttachCommand may not be a suitable alternative since it runs everytime you connect to the codespace.

mandrasch commented 11 months ago

Hi @eljog,

thanks very much for reply! I'll check this out as soon as I have resources for it. πŸ‘

eiriksm commented 11 months ago

Went with this slightly altered version which seems to work:

#!/bin/bash
set -ex

wait_for_docker() {
  while true; do
    docker ps > /dev/null 2>&1 && break
    sleep 1
  done
  echo "Docker is ready."
}

wait_for_docker

# proceed with commands requiring docker
mandrasch commented 11 months ago

Went with this slightly altered version which seems to work:

#!/bin/bash
set -ex

wait_for_docker() {
  while true; do
    docker ps > /dev/null 2>&1 && break
    sleep 1
  done
  echo "Docker is ready."
}

wait_for_docker

# proceed with commands requiring docker

Nice, thanks very much! πŸŽ‰πŸ‘

mandrasch commented 11 months ago

@eljog thanks very much for advice on this, works fine with script of @eiriksm πŸ‘