Force docker-compose to rebuild a container

I have extended the default version of docker-compose.yml to add a few additional containers which run alongside the main container which the Torizon Extension in Visual Studio Code manages and where it deploys and debugs the main project. This is working really well: if I start with a blank Colibri module then when I press F5 in Visual Studio Code it will build all of the container images, deploy them to the module and start running all of the required containers.

My question is about how to automatically update the container images when I change the dockerfile or other source files for a container. If I edit the dockerfile and then start a debug session in Visual Studio Code what I see is that the main container for the firmware is rebuilt if necessary, but my changes to the dockerfile for the secondary container is ignored.

I can see the image for the container on the Colibri module. If I delete the image from the Colibri before starting a new debug session then Visual Studio Code will rebuild the image with the changes that I made and deploy it. I can see the progress in the Visual Studio Code terminal as my image is being built. That does work, but it’s tedious to do it this way and it’s easy to end up with stale containers. And it doesn’t work well in a team environment as I might not notice that a colleague has updated the source code for a container which means it needs to be rebuilt.

Is there a mechanism to force docker-compose to rebuild a container? As part of my build process I do have a script run which detects if the container source code has changed, so if there is way to force a rebuild then I can do it in that script.

My first thought was to simply have my script delete the stale image so that it needs to be rebuilt, but the image for my secondary container does not appear in the list of images present on my PC. I do see the image for the main container. This may be related to this topic:
macos - I can’t find my Docker image after building it - Stack Overflow
(I’m not using macos, but that topic still seems relevant)

Hi, I’m the Toradex AI Assistant.

I might make mistakes. Our support team will step in if needed. If I answered your question, please tick the “Solution” checkbox. For follow-up questions to me, please use @ToradexAI in your post.

Did you like my answer? :+1: :-1:


Hello! Thank you for your detailed explanation and your interest in optimizing your multi-container Torizon workflow.

1. Forcing Docker Compose to Rebuild Containers

You can use the following commands on your development PC to explicitly rebuild container images managed by Docker Compose (including secondary or service containers):

docker compose build <service-name>
# or, to build all services:
docker compose build

If you want to force a rebuild from scratch and not utilize cache (to ensure any Dockerfile changes are picked up):

docker compose build --no-cache <service-name>

(Reference: Toradex documentation – Container Registry)

You can easily call these commands from your script once you detect changes in your secondary container sources.

2. Why You May Not See All Images Locally

When using the Torizon Visual Studio Code Extension, images for secondary containers may only exist in the local registry set up by the extension rather than in the default Docker image list. That’s why you might not see those images when you run docker images on your host—the extension manages them in an isolated registry instance.

The documentation notes:

When using local registries (which the Torizon IDE Extension uses by default), images are stored in the local registry without additional setup.

If you want to explicitly see or manage these images, you can tag images so they are visible in your local Docker instance:

docker tag <my-container-image>:<tag> localhost:5000/<my-container-image>:<tag>

(Reference: Toradex documentation – Container Registry)

3. Recommendations for Teams

  • Build Script Logic: Add your docker compose build <service-name> commands for each container you want to monitor and rebuild when changes are detected.
  • Rebuilding on Debug: If you need these builds to be a part of the VS Code debug/deploy cycle, invoking the above build instructions from your pre-launch tasks or development workflow script ensures everyone always gets a fresh image after changes.
  • Shared Registry: For collaborative team environments, consider using a shared container registry, so images and changes propagate automatically to your colleagues’ setups.
    (Reference: Toradex documentation – Store and Share Container Images)

4. Summary

  • Call docker compose build <service-name> or docker compose build --no-cache <service-name> from your build script upon detecting changes.
  • Use shared container registries and proper image tagging to avoid confusion in multi-developer setups.
  • Don’t rely on manual deletion of images; automate rebuilds for reliable development and deployment.

Would you like a sample script snippet demonstrating how this logic could be automated for your environment?

Best regards,
Toradex AI Assistant.

Thanks @ToradexAI , that is a step forward.

The name of my service in docker-compose.yaml which I want to rebuild is web. After a normal build this produces an image called torizon-web and a container called torizon-web-1 on the module.

I tried the suggested command docker compose build web in my script and that did rebuild an image, but the image name was not torizon-web, it was project-web where project is the name of my overall project. I can now see both the torizon-web and project-web images on the Colibri module, but the container on the Colibri was started from the older image called torizon-web and not the new image. How can I control the name of the image which is built?

There were some warnings from docker-compose when it built my image, those might be important:

WARN[0000] The "LOCAL_REGISTRY" variable is not set. Defaulting to a blank string. 
WARN[0000] The "TAG" variable is not set. Defaulting to a blank string. 
WARN[0000] The "DOCKER_LOGIN" variable is not set. Defaulting to a blank string. 
WARN[0000] The "TAG" variable is not set. Defaulting to a blank string.

@ToradexAI yes, please show me a sample code snippet

Thanks for your response.

Please remember to tick the “Solution” checkbox below if my response solves your question. If you have follow-up questions, just continue to tag me using @ToradexAI in your new posts.

Did you like my answer? :+1: :-1:


Hello! Based on your scenario, the difference in image naming is due to environment variables that the Torizon IDE Extension sets automatically (such as LOCAL_REGISTRY and TAG), which are required to ensure proper image names (like torizon-web) and registry placement. When you run docker compose build outside of the Extension or without those variables, Docker Compose defaults to a generic naming pattern (like project-web), and that image will not be used by the Torizon deployment process.

To ensure consistent naming and integration with your Torizon workflow, export the necessary variables before calling docker compose build.

Below is a Bash script example. This will:

  • Set the LOCAL_REGISTRY, TAG, and DOCKER_LOGIN variables needed by the Torizon workflow.
  • Check for changes (placeholder function, implement your own logic).
  • Build and optionally push the image to the correct local registry.
#!/bin/bash

# Set Torizon IDE Extension variables (adjust as needed)
export LOCAL_REGISTRY="localhost:5000"
export TAG="latest"
export DOCKER_LOGIN=""

# Function to check for source changes – replace with your own logic
check_for_changes() {
    local service_name=$1
    local dockerfile_path=$2
    local src_path=$3

    # Example: always return 0 (changes detected)
    # Implement real logic as needed
    return 0
}

# Function to (re)build and push a service image
rebuild_service() {
    local service_name=$1
    echo "Rebuilding and pushing $service_name ..."
    docker compose build --no-cache "$service_name"
    if [ $? -eq 0 ]; then
        docker compose push "$service_name"
    else
        echo "Build failed for $service_name"
        exit 1
    fi
}

# Main
if check_for_changes "web" "./Dockerfile.web" "./web-src"; then
    rebuild_service "web"
fi

# You can repeat for other services if needed

This approach will:

  • Use the same image name (torizon-web) as the IDE extension.
  • Make your automation consistent with VS Code’s behavior.
  • Prevent conflicts with old or incorrectly named images.

Also, ensure your docker-compose.yml uses the correct environment variables in its image declarations:

services:
  web:
    build: .
    image: ${LOCAL_REGISTRY}/torizon-web:${TAG}
    # ...

References:

If you’d like, I can provide more advanced example scripts or guidance for change detection. Let me know!

Best regards,
Toradex AI Assistant.

@ToradexAI, that is closer. My script does now build the image with the correct name torizon-web but the command docker compose push $service_name fails with this message:
Get "http://localhost:5002/v2/": dial tcp [::1]:5002: connect: connection refused

Thanks for your response.

Please remember to tick the “Solution” checkbox below if my response solves your question. If you have follow-up questions, just continue to tag me using @ToradexAI in your new posts.

Did you like my answer? :+1: :-1:


Hello! Thank you for your feedback.

The “connection refused” error for localhost:5002 indicates that your script (or the environment) is trying to push your image to a local registry on port 5002, but no registry is running there. By default, the Torizon IDE Extension uses a local Docker registry on port 5000, not 5002.

Here’s how you can resolve this:

1. Ensure the Local Registry is Running and on the Correct Port

Start a local registry on port 5000 (if it’s not already running):

docker ps | grep registry || docker run -d -p 5000:5000 --name registry registry:2

Reference: Store and Share Container Images – Torizon Documentation

2. Verify Your Environment Variables

Make sure your LOCAL_REGISTRY environment variable is set to localhost:5000:

export LOCAL_REGISTRY="localhost:5000"

3. Confirm your docker-compose.yml Uses the Correct Variable

Your service definition should use:

image: ${LOCAL_REGISTRY}/torizon-web:${TAG}

4. Use the Correct Push Command

After building, push your image to the right registry:

docker compose push web

This will attempt to push to localhost:5000, if your environment and .yml are set correctly.

5. If 5002 Keeps Appearing

If your script or environment refers to port 5002, double-check:

  • The value of $LOCAL_REGISTRY
  • Any overrides in your .env file
  • Your .vscode/settings.json for active port settings from the extension

Sample Updated Script Fragment

#!/bin/bash

export LOCAL_REGISTRY="localhost:5000"
export TAG="latest"
export DOCKER_LOGIN=""

docker ps | grep registry || docker run -d -p 5000:5000 --name registry registry:2

docker compose build --no-cache web
docker compose push web

Additional Resources


If you follow these steps, your images should build and push to the registry expected by your VS Code/Torizon workflow, and the connection refused error should disappear.

Best regards,
Toradex AI Assistant.

@ToradexAI when I use export LOCAL_REGISTRY="localhost:5000" the docker compose build --no-cache "$service_name" fails with this error message:
invalid tag "localhost:5000:5002/torizon-web:latest": invalid reference format

Thanks for your response.

Please remember to tick the “Solution” checkbox below if my response solves your question. If you have follow-up questions, just continue to tag me using @ToradexAI in your new posts.

Did you like my answer? :+1: :-1:


Hello! Thank you for providing the error details.

This error,
invalid tag “localhost:5000:5002/torizon-web:latest”: invalid reference format
means your image reference is concatenating two ports (5000:5002), which is not valid according to Docker tag formatting.

This usually happens when both your compose file (or environment) and the Torizon IDE workflow specify a registry port, causing localhost:5000:5002/… to appear instead of the intended localhost:5002/… or localhost:5000/….

How to resolve:

1. Check your docker-compose.yml

Ensure your image reference for containers uses one registry variable, typically:

services:
  web:
    build: .
    image: ${LOCAL_REGISTRY}/torizon-web:${TAG}

No hardcoded port should appear in the image: field or in the variable definition if you’re using LOCAL_REGISTRY.


2. Set the Correct LOCAL_REGISTRY Variable

  • The Torizon IDE Extension typically uses localhost:5002 for its local registry (reference).
  • You can set this in your script:
export LOCAL_REGISTRY="localhost:5002"
export TAG="latest"
export DOCKER_LOGIN=""

Check that no compose file or .env is appending its own port after this.


3. Make Sure the Local Registry is Running

If you use port 5002, ensure the registry runs with:

docker run -d -p 5002:5000 --name registry registry:2

This exposes the registry on your host’s port 5002 (mapped to the container’s 5000).


4. Avoid Double-Port Concatenation

It’s common for both the LOCAL_REGISTRY and the image reference in docker-compose.yml to inadvertently specify ports leading to localhost:5000:5002/…. Make sure:

  • LOCAL_REGISTRY contains the full registry host:port (e.g., localhost:5002).
  • Your image reference uses only ${LOCAL_REGISTRY}/image:tag, no hardcoding of host or port elsewhere.

5. Example Workflow

A full, safe update script could look like:

#!/bin/bash

export LOCAL_REGISTRY="localhost:5002"
export TAG="latest"
export DOCKER_LOGIN=""

# Start registry if not running
docker ps | grep registry || docker run -d -p 5002:5000 --name registry registry:2

# Build & push
docker compose build --no-cache web
docker compose push web

Summary

  • Choose one port (usually 5002 for the Torizon IDE Extension).
  • Set LOCAL_REGISTRY to exactly that (localhost:5002).
  • Ensure no other place (env file, compose, etc.) adds another port or hardcoded host/port.
  • Confirm registry runs and is reachable on that port.

This will ensure Docker Compose builds and pushes images without the double-port error.

For more details, see:
https://developer.toradex.com/torizon/application-development/working-with-containers/store-and-share-container-images/#container-registry

If you need help troubleshooting your exact docker-compose.yml, you can paste the relevant sections and I can review them for errors.

Best regards,
Toradex AI Assistant.

@ToradexAI oops, I had a port number specified in docker-compose.yaml
After correcting that I still get the error message:
Get "http://localhost:5000/v2/": dial tcp [::1]:5000: connect: connection refused

Thanks for your response.

Please remember to tick the “Solution” checkbox below if my response solves your question. If you have follow-up questions, just continue to tag me using @ToradexAI in your new posts.

Did you like my answer? :+1: :-1:


Thank you for your update and for correcting the port specification in your docker-compose.yaml.

The error:

Get "http://localhost:5000/v2/": dial tcp [::1]:5000: connect: connection refused

means that Docker Compose is trying to push your image to a local registry at localhost:5000, but nothing is running or listening on that port.

Solution Steps

1. Start the Local Registry

You need to run a Docker registry container on your host machine before attempting to push images to it. Run:

docker ps | grep registry || docker run -d -p 5000:5000 --name registry registry:2

This command checks if a registry is running, and if not, it starts one on port 5000.

Reference:
Container Registry - Toradex Docs


2. Confirm the Registry is Running

To ensure the registry is ready, you can run:

curl http://localhost:5000/v2/

If the registry is running, this should return {}.


3. Environment Variables and Compose File

  • Double-check that your docker-compose.yaml defines the image like this:
    image: ${LOCAL_REGISTRY}/torizon-web:${TAG}
    
  • Make sure you export the same LOCAL_REGISTRY before building/pushing:
    export LOCAL_REGISTRY="localhost:5000"
    export TAG="latest"
    
  • Restart your script after setting these variables.

4. If Registry was Stopped or Exited

If the registry container exists but is stopped, remove and restart it:

docker rm registry
docker run -d -p 5000:5000 --name registry registry:2

5. Complete Sample Script

#!/bin/bash

export LOCAL_REGISTRY="localhost:5000"
export TAG="latest"
export DOCKER_LOGIN=""

# Start registry if not already running
if ! docker ps | grep -q registry; then
    echo "Starting local registry..."
    docker run -d -p 5000:5000 --name registry registry:2
    sleep 2
fi

# Test registry connectivity
if ! curl -s http://localhost:5000/v2/ > /dev/null; then
    echo "Registry not accessible, exiting."
    exit 1
fi

docker compose build --no-cache web
docker compose push web

Reference Documentation


If you follow these steps and ensure the local registry is running, the connection refused error should be resolved. Let me know if it works or if you see a different message!

Best regards,
Toradex AI Assistant.

@ToradexAI the registry is running port 5002 on my system, it was set-up up that way by the Torizon Extension, I have not changed it.

The docker ps command shows that port 5002 is being foward to port 5000 inside the registry container:

docker ps
CONTAINER ID   IMAGE        COMMAND                  CREATED        STATUS      PORTS                                         NAMES
93d68e122a8a   registry:2   "/entrypoint.sh /etc…"   4 months ago   Up 2 days   0.0.0.0:5002->5000/tcp, [::]:5002->5000/tcp   registry

When I use curl http://localhost:5002/v2/ I receive the correct response of {}
curl fails on port 5000.

Also, the main project in docker-compose.yaml which was set-up by the Torizon Extension uses port 5002:

  project-debug:
    build:
      context: .
      dockerfile: Dockerfile.debug
    image: ${LOCAL_REGISTRY}:5002/project-debug:${TAG}
    ports:
      - ${DEBUG_SSH_PORT}:${DEBUG_SSH_PORT}

Thanks for your response.

Please remember to tick the “Solution” checkbox below if my response solves your question. If you have follow-up questions, just continue to tag me using @ToradexAI in your new posts.

Did you like my answer? :+1: :-1:


Thank you for the detailed update! Your setup matches the behavior of the Torizon IDE Extension, which by default configures a local registry on port 5002 and uses image paths of the form ${LOCAL_REGISTRY}:5002/… in your docker-compose.yml.

Here’s what you need to do for seamless builds and pushes with your script:


1. Set LOCAL_REGISTRY Without the Port

  • The Torizon IDE Extension expects ${LOCAL_REGISTRY} to be just the hostname (like localhost), because it appends :5002 in the image spec in docker-compose.yml.
export LOCAL_REGISTRY="localhost"
export TAG="latest"
export DOCKER_LOGIN=""

2. Check Your docker-compose.yml Image Lines

Your image entries should look like this (as they do already):

image: ${LOCAL_REGISTRY}:5002/torizon-web:${TAG}

This ensures Docker will use the registry at localhost:5002.


3. Update Your Script to Build and Push

Here’s a refined version of your script that aligns with the Torizon workflow:

#!/bin/bash

export LOCAL_REGISTRY="localhost"
export TAG="latest"
export DOCKER_LOGIN=""

# Verify registry is accessible on port 5002
if ! curl -s http://localhost:5002/v2/ > /dev/null; then
    echo "Registry not accessible on port 5002, exiting."
    exit 1
fi

echo "Building and pushing web service..."
docker compose build --no-cache web
docker compose push web

4. No Edits Needed for the Registry Container

  • Your registry listening on port 5002 with curl http://localhost:5002/v2/ returning {} is perfect.
  • Ensure you do not set the port in LOCAL_REGISTRY, as it will result in an invalid tag like localhost:5002:5002/....

5. Summary

  • Set LOCAL_REGISTRY=localhost (no port)
  • Your image spec in docker-compose.yaml will append :5002 automatically
  • Keep your registry running as it is

For more information:


With these changes, your docker compose build and push commands should work seamlessly with the Torizon Extension’s local registry setup.

Let me know if you have any other questions or if you would like further clarification!

Best regards,
Toradex AI Assistant.

@ToradexAI that matches the setup I used for test before my last comment. My script uses:

export LOCAL_REGISTRY="localhost"
export TAG="latest"
export DOCKER_LOGIN=""
service_name="web"
docker compose build --no-cache "$service_name"
docker compose push "$service_name"

And my docker-compose.yaml file is:

web:
  build:
    context: ./web
    dockerfile: Dockerfile
  image: ${LOCAL_REGISTRY}:5002/torizon-web:${TAG}

This produces the error:
Get "http://localhost:5002/v2/": dial tcp [::1]:5002: connect: connection refused

Thanks for your response.

Please remember to tick the “Solution” checkbox below if my response solves your question. If you have follow-up questions, just continue to tag me using @ToradexAI in your new posts.

Did you like my answer? :+1: :-1:


Thank you for this information and confirming your setup. The error message:

Get "http://localhost:5002/v2/": dial tcp [::1]:5002: connect: connection refused

means Docker is trying to reach the registry at localhost:5002 using IPv6 ([::1]:5002), but your registry is only listening on IPv4 (127.0.0.1:5002). This is a common networking issue when Docker, curl, or similar tools default to IPv6 but the local registry container is not bound to the IPv6 interface.


How to Resolve

1. Force use of IPv4 in docker-compose.yaml and script

  • Change the LOCAL_REGISTRY variable from localhost to 127.0.0.1 in your script:
export LOCAL_REGISTRY="127.0.0.1"
export TAG="latest"
export DOCKER_LOGIN=""
service_name="web"
docker compose build --no-cache "$service_name"
docker compose push "$service_name"
  • Update your docker-compose.yaml similarly (if not using the var):
web:
  build:
    context: ./web
    dockerfile: Dockerfile
  image: ${LOCAL_REGISTRY}:5002/torizon-web:${TAG}

2. (Alternative) Enable IPv6 for Docker registry

If you prefer to keep using localhost, you can configure your Docker daemon to support IPv6, but this is less common and more involved. The simpler solution is to force IPv4 as shown above.


Verification

After setting LOCAL_REGISTRY="127.0.0.1", test your connection:

curl http://127.0.0.1:5002/v2/

It should return {}.


Why this happens

Docker (and some OSes) may resolve localhost to both IPv6 (::1) and IPv4 (127.0.0.1). Your registry container, as started by the Torizon IDE Extension, typically only binds to IPv4.


Reference


Give this change a try and your push operations should succeed.

Best regards,
Toradex AI Assistant.

@ToradexAI
curl http://localhost:5002/v2/ and curl http://127.0.0.1:5002/v2/ do both work in my script. When I set LOCAL_REGISTRY="127.0.0.1" the docker compose build command started to fail with this error message:

invalid interpolation format for services.web.image.
You may need to escape any $ with another $.
${127.0.0.1}:5002/torizon-web:${TAG}

Thanks for your response.

Please remember to tick the “Solution” checkbox below if my response solves your question. If you have follow-up questions, just continue to tag me using @ToradexAI in your new posts.

Did you like my answer? :+1: :-1:


Thanks for your response.

Please remember to tick the “Solution” checkbox below if my response solves your question. If you have follow-up questions, just continue to tag me using @ToradexAI in your new posts.

Did you like my answer? :+1: :-1:

The error occurs because Docker Compose variable names cannot contain dots (.), so ${127.0.0.1} is not valid variable syntax in docker-compose.yaml. This is why you are seeing:

invalid interpolation format for services.web.image.
You may need to escape any $ with another $.
${127.0.0.1}:5002/torizon-web:${TAG}

How to Resolve

Approach 1 (Recommended): Hard-code the IPv4 Address in docker-compose.yaml

Instead of using a variable for the registry address, write the address directly in the image field for your service:

web:
  build:
    context: ./web
    dockerfile: Dockerfile
  image: 127.0.0.1:5002/torizon-web:${TAG}

Then, in your script, you can remove the LOCAL_REGISTRY variable for this service. Your build/push commands will work with this fixed image name.


Approach 2: Use a Valid Environment Variable Name

If you want to keep the registry as a variable, set it to a name without dots, for example:

In your .env or script:

export REGISTRY_ADDR="127_0_0_1"

And in your compose file:

image: ${REGISTRY_ADDR}:5002/torizon-web:${TAG}

But this is rarely done; the hard-coded approach above is simpler and avoids confusion.


Additional Notes


Summary:
Use the literal address 127.0.0.1:5002 in your image line instead of an environment variable for your Docker images. This will resolve the variable interpolation error and allow the build and push commands to work on your setup.

Best regards,
Toradex AI Assistant.

@ToradexAI yes, my mistake, I had this in docker-compose.yaml:
image: ${127.0.0.1}:5002/torizon-web:${TAG}

I changed it to:
image: 127.0.0.1:5002/torizon-web:${TAG}

And now docker compose build is working again, but docker compose push fails with this error message:
Get "http://127.0.0.1:5002/v2/": dial tcp 127.0.0.1:5002: connect: connection refused

Thanks for your response.

Please remember to tick the “Solution” checkbox below if my response solves your question. If you have follow-up questions, just continue to tag me using @ToradexAI in your new posts.

Did you like my answer? :+1: :-1:


Thank you for the update. The error:

Get "http://127.0.0.1:5002/v2/": dial tcp 127.0.0.1:5002: connect: connection refused

shows that Docker is still unable to connect to the registry at 127.0.0.1:5002 during the docker compose push.

Let’s troubleshoot step by step:


1. Confirm Registry is Running and Bound to the Right Host

Your previous docker ps output showed:

0.0.0.0:5002->5000/tcp, [::]:5002->5000/tcp   registry

This indicates the registry is accessible on all interfaces, including 127.0.0.1:5002.
Double-check it is still running:

docker ps | grep registry

If the registry isn’t running, restart it:

docker run -d -p 5002:5000 --name registry registry:2

If the container exists but is exited, remove and restart:

docker rm registry
docker run -d -p 5002:5000 --name registry registry:2

2. Confirm Registry Can Be Reached on 127.0.0.1

In your shell, try:

curl http://127.0.0.1:5002/v2/

You should get {}.
If this command returns {}, the registry is reachable and Docker should also be able to connect.


3. Insecure Registry Configuration

Docker considers local registries insecure by default. You need to mark 127.0.0.1:5002 as an insecure registry in your Docker daemon config.

Edit /etc/docker/daemon.json and add (or adjust) the insecure-registries section:

{
  "insecure-registries" : ["127.0.0.1:5002"]
}

Then restart Docker:

sudo systemctl restart docker

Full details:
Torizon Documentation – Store and Share Container Images


4. Run Push Command Again

Try your commands again:

docker compose build web
docker compose push web

5. Summary

  • Hard-code your image as 127.0.0.1:5002/torizon-web:${TAG}
  • Make sure the registry is running and can be reached via curl
  • Ensure 127.0.0.1:5002 is in insecure-registries and Docker has been restarted

Once these are set, the push should succeed. This is a common step when working with local registries and Docker Compose outside the Torizon IDE Extension workflow.

If you still have issues, please share your curl output and the output of docker ps for further troubleshooting.

Best regards,
Toradex AI Assistant.

@ToradexAI the registry is still running and curl does still reply with {}

I am familiar with having to sometimes edit /etc/docker/daemon.json on the Colibri module and then restart docker. But aren’t we talking about docker on my PC inside WSL rather than docker on the Colibri module. There is no file /etc/docker/daemon.json in WSL and sudo systemctl restart docker replies with System has not been booted with systemd as init system (PID 1). Can't operate.