WiFi-connect installation in Raspberry Pi Docker container

Hi Alexis,

The web application doesn’t use 80 port. In addition, my Dockerfile contains only the parts related with wifi-connect. I removed all other lines from Dockerfile except for wifi-connect installation steps. Please check the above screenshot.
One thing I want to tell you is that wifi-connect has been installed outside the container. I have previously installed it on my pi4. Is it the reason? However, I just installed it and didn’t execute it.

In this point, I’d like to know the following things.

  1. How can I change the port for wifi-connect? Do I have to change start.sh file as follows to change the port to 3000?

    export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket
    ./wifi-connect -o 3000
    

    Or do I have to add the port option to docker run command as follows?

    docker run --mount type=bind,source=/run/dbus/system_bus_socket,target=/host/run/dbus/system_bus_socket -p 3000:80 -e DBUS_SYSTEM_BUS_ADDRESS="unix:path=/host/run/dbus/system_bus_socket" test:1.0
    
  2. How can I remove wifi-connect installed outside the container? Is there a good way to remove it completely from Raspberry Pi?

Anatoli

Hi Alexis, Amit

I added an option for the port to start.sh file as follows and tested it, but it doesn’t still work.

export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket
./wifi-connect -o 3000

So I don’t think it’s because 80 port or 3000port are used anywhere. Actually, they are not used anywhere. There seems to be another reason.

Hey there Anatoli

There seems to have been a lot of confusion here. Let me try to answer some of the questions

Is it possible to install and run wifi-connect inside the web container?

Yes, and the current approach seems to be the best one.

So far, you seem to have the executable installed in the web-container(django) and have it running. What seems to be the issue might be related to the container not having enough privileges to bind to the ports?

Maybe now you can use docker-compose with the NET_ADMIN permission on your web-container and try again?

Hi Rahul,

As I have already mentioned above, I have includes only the parts related to installation and execution of wifi-connect in my Dockerfile. Here is my Dockerfile and start.sh file.


I built a docker image called test:1.0 using this Dockerfile and run it with the following command.

docker run --mount type=bind,source=/run/dbus/system_bus_socket,target=/host/run/dbus/system_bus_socket -e DBUS_SYSTEM_BUS_ADDRESS="unix:path=/host/run/dbus/system_bus_socket" test:1.0

When I built a docker image using the above Dockerfile and run it, I got the following error.

pi@raspberrypi:~/balena-wifi-connect-example $ docker run --mount type=bind,source=/run/dbus/system_bus_socket,target=/host/run/dbus/system_bus_socket -e DBUS_SYSTEM_BUS_ADDRESS="unix:path=/host/run/dbus/system_bus_socket" balena_test:1.0
Error: Starting the NetworkManager service failed
caused by: Service

I wanted to make sure that wifi-connect works into a docker container first before making it run in my web container.
For three weeks, I’ve been struggling with this problem and connecting with you, Balena members, but no one is telling me the exact solution. Why is it so hard?
Can you tell me in detail what should be added to the current Dockerfile and what should be changed in Dockerfile to run wifi-connect?
Could you make Dockerfile for wifi-connect and send it to me? I’m really going crazy because of this.

Anatoli,

Sorry to hear about your frustration with wifi-connect, I know if I had spent 3 weeks on a problem, I would be frustrated too, and I applaud your tenacity!

I think what my colleague was saying is the docker container does not have the permissions to bind to the address on the host OS, so you need to grant the container the capability to bind to that address.

One way to test this would be to run the docker container in “privileged” mode, which basically grants all available privileges to the docker container. You can do this by adding the --privileged flag to docker run command.

Another way, which would only allow the network administration capabilities (probably a best practice to limit your attack surface) would be to add the flag --cap-add NET_ADMIN.

So, just run your regular commands you were running before, but with those flags:

docker run --mount type=bind,source=/run/dbus/system_bus_socket,target=/host/run/dbus/system_bus_socket -e DBUS_SYSTEM_BUS_ADDRESS="unix:path=/host/run/dbus/system_bus_socket" --privileged test:1.0

I apologize, I wasn’t sure if you needed this, but after checking, you need to run the container on your host’s network, not the virtual host provided by docker. You can do this by adding the flag --network host.

So, the full command would be:

docker run --mount type=bind,source=/run/dbus/system_bus_socket,target=/host/run/dbus/system_bus_socket -e DBUS_SYSTEM_BUS_ADDRESS="unix:path=/host/run/dbus/system_bus_socket" --privileged --network host test:1.0

Hi Zane,

Thanks for your great help. Your guide helped me! I run wifi-connect inside the container using the full command you shared. But I still have the following questions.

  1. Your solution works only if wifi-connect is installed on the host device(raspberry pi4) outside of the docker container. If wifi-connect is not installed outside the container, it doesn’t work and I still get the same error.

    pi@raspberrypi:~/balena-wifi-connect-example $ docker run --mount type=bind,source=/run/dbus/system_bus_socket,target=/host/run/dbus/system_bus_socket -e DBUS_SYSTEM_BUS_ADDRESS="unix:path=/host/run/dbus/system_bus_socket" --privileged --network host test:1.0
    WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm/v7) and no specific platform was requested
    Error: Starting the NetworkManager service failed
    caused by: Service
    

    I think this is because NetworkManager is not installed outside the container. Actually, there is no any part for installing NetworkManager in Dockerfile.
    How can I run wifi-connect in the container without installing it outside the container? Do I just need to install NetworkManager with the following command?

    RUN apt-get install -y -d network-manager
    

    Is it also necessary to disable dhcpcd? Are there any other necessary settings?

  2. The commands for wifi-connect installation will be included in Dockerfile for my web container.
    This Dockerfile will be run by docker-compose file. So I need to know how to set type=bind, privileged and network host like we set in the docker run command. Sounds reasonable?
    Some researching, I made some changes on my docker-compose file as follows.


    Are the above changes correct? You can see my questions in the screenshot above.

Thanks Zane again. Looking forward to your next reply!
Anatoli.

Hi Zane,

How are you?
Did you have a chance to check my docker-compose.yml file?
I’m waiting for your great advice.

Thanks.
Anatoli

Hello Anatoli,
Sounds to good to hear that Zane’s solution worked for you. The thread has become quite long so I will try to summarise and then try to answer your question. You are using Raspbian on raspberrypi4. You want to run wifi-connect inside the Django container that you have and control wifi-connect using that. At this point, you have built a Docker image on your end with Wifi-connect running inside a container. Let me know if this is accurate. Regarding your questions,

Your solution works only if wifi-connect is installed on the host device(raspberry pi4) outside of the docker container.

I am not sure what you mean by Wifi-connect installed on the host device outside the docker container. Looking from the steps above, I am not sure Zane’s steps would lead to Wifi-connect being installed in the HostOS rather would allow you to run wifi-connect in a docker container only. Can you please confirm what you wrote in your previous message to avoid any confusion.

  • The warning you get is quite important WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm/v7) and no specific platform was requested
    Do make sure you are building the image for the right architecture. Raspberrypi4 is of armv7 architecture where it seems like the docker image you built is for amd64. We may have to resolve that first before fixing the Network-manager service error. Regarding the point about if you need any other things in your dockerfile for wifi-connect, you can refer to Wifi-connect’s Dockerfile https://github.com/balena-io/wifi-connect/blob/master/Dockerfile.template

  • Regarding your second question, The docker-compose file does look good. Here’s some more information on bind mounting in a docker-compose version 2 Compose file version 2 reference | Docker Docs

Hope this helps you out!

Hi @vipulgupta2048

Thanks for your help. I think your summary about my work is correct. Here is my answer about your question.

I am not sure what you mean by Wifi-connect installed on the host device outside the docker container.
I meant that I installed wifi-connect not only in Django docker container but also outside the container, i.e. on the hostOS(raspbian). If wifi-connect is not installed on the hostOS, I get such an error(NetworkManager service failed) when I run the container using Zane’s command.
If wifi-connnect is installed on the hostOS, then wifi-connect works when I run the container.
Does it make sense?

I think I need to share my whole Dockerfile for Django container.

 FROM python:3.7.3
 ENV PYTHONUNBUFFERED=0
 ENV INITSYSTEM on

 RUN apt-get -y update && apt-get -y upgrade
 RUN pip3 install --upgrade pip
 RUN apt-get -y  install libopenblas-dev
 RUN pip3 install pybind11
 RUN apt install python3-netifaces

 WORKDIR /app

 ADD requirements.txt /app/
 RUN pip3 install -r requirements.txt
 COPY . /app

 RUN apt-get install -y supervisor
 RUN service supervisor restart
 ADD uart.conf /etc/supervisor/conf.d
 
 # Install balena wifi-connect
 RUN apt-get update && apt-get install -yq --no-install-recommends \
 dnsmasq && \
 apt-get clean && rm -rf /var/lib/apt/lists/*

 RUN curl https://api.github.com/repos/balena-io/wifi-connect/releases/latest -s \
 | grep -hoP 'browser_download_url": "\K.*armv7hf\.tar\.gz' \
 | xargs -n1 curl -Ls \
 | tar -xvz -C /app/

 RUN chmod 774 docker-entrypoint.sh
 ENTRYPOINT ["bash", "docker-entrypoint.sh"]

I have already built a Django container with this Dockerfile using docker build command and ran the container using Zane’s command. Then I accessed the container and executed wifi-connect by running a bash file I made. Wifi-connect worked properly inside the container.

Next I needed to run the Django container and other containers using docker-compose. So I ran all containers using the docker-compose.yml I have already shared with Zane. I think you already checked it. You can see it in above screenshot.
The problem is from now on.
When I accessed the Django container, I can’t see wifi-connect installed. Therefore, when I run the bash file(I mentioned in above) in the container, it causes the following error.

wifi-connect.sh: line 5: ./wifi-connect: No such file or directory

The Dockerfile for django service in docker-compose.yml file is the same as Dockerfile that I have already tested using Zane’s command. They’re exactly the same. And I definitely saw wifi-connect being installed while building the image using docker-compose.yml file.
Please check the below screenshot.


In the above screenshot, wifi-connect.sh is my custom bash file to execute wifi-connect.

In other words, I couldn’t see wifi-connect installed in Django container when using docker-compose.
Again, the same Dockerfile was used for both cases.
I think there is any problem in docker-compose.yml file. I don’t think the options used in Zane’s docker run command were exactly applied to docker-compose.yml file. I made several changes on docker-compose.yml file, they didn’t work. I also tried docker-compose.yml with “2”, “2.1” and “3” of Dockerfile version. Unfortunately, they also didn’t work.
How can I solve this?

Sorry for my long explanation, but I tried to explain my situation clearly.
Looking forward to your solution.
Thanks.

Anatoli

Yes, I see that wifi-connect and its associated ui folder are missing. Those should be generated as a result of this in your Dockerfile:

RUN curl https://api.github.com/repos/balena-io/wifi-connect/releases/latest -s \
 | grep -hoP 'browser_download_url": "\K.*armv7hf\.tar\.gz' \
 | xargs -n1 curl -Ls \
 | tar -xvz -C /app/

I am not 100% certain why they are not showing up in the container, as it definitely seems they should be written out to the /app directory, which is where you are working in the container.

Simply for testing purposes, I have to wonder what would happen if you moved that snippet into the top of your wifi-connect.sh script instead. Essentially, trying to perform that installation after the container has already been built, deployed, and is running.

Hi @dtischler

I am not 100% certain why they are not showing up in the container, as it definitely seems they should be written out to the /app directory, which is where you are working in the container.

That’s exactly what I want to know. I have wifi-connect working inside the container when I used docker build and docker run command to build the image and run the container. But the wifi-connect and ui folder don’t appear in the container when I use docker-compose.yml file.
I have already mentioned this with the screenshot above.

Simply for testing purposes, I have to wonder what would happen if you moved that snippet into the top of your wifi-connect.sh script instead.

This is not reasonable way. It means that every time we execute wifi-connect.sh, the installation step is repeated. The Dockerfile I shared above has been confirmed.
If I add the above command to wifi-connect.sh file, can I use it as it is? Does the bash file recognize Dockerfile command?

I think @vipulgupta2048 and Zane can give me a good solution. They already understand my hardship and know what I want. How can I connect them?

Hi there, I’ve tested your command separately on macOS (substituting jq for grep), it unpacks wifi-connect into /app as expected:

curl https://api.github.com/repos/balena-io/wifi-connect/releases/latest -s \
 | jq -r '.assets[] | select(.browser_download_url | contains("armv7hf")).browser_download_url' \
 | xargs -n1 curl -Ls \
 | tar -xvz -C /app/

x ./
x ./wifi-connect
x ./ui/
x ./ui/index.html
x ./ui/service-worker.js
...

$ ls /app
ui              wifi-connect

The error you are getting is likely due to path context being different, please try changing the command to the full path (i.e.) /app/wifi-connect.

Perhaps you could share your bash script used to call wifi-connect next if my suggestion doesn’t work and we can go from there…

Hi Anton,

I’m not sure this.

The error you are getting is likely due to path context being different, please try changing the command to the full path (i.e.) /app/wifi-connect .

Do you mean to change the path for wifi-connect installation to /app/wifi-connect/ in Dockerfile?
Or do you mean to change the path for executing wifi-connect in wifi-connect.sh file?
Anyway, I tried both cases.
I changed the work directory to /app/wifi-connect in Dockerfile and installed wifi-connect in it.

WORKDIR /app/wifi-connect
#Install balena wifi-connect
RUN apt-get update && apt-get install -yq --no-install-recommends
dnsmasq &&
apt-get clean && rm -rf /var/lib/apt/lists/*
RUN curl https://api.github.com/repos/balena-io/wifi-connect/releases/latest -s
| grep -hoP ‘browser_download_url": "\K.*armv7hf.tar.gz’
| xargs -n1 curl -Ls
| tar -xvz -C /app/wifi-connect/

While building the docker image using docker-compose, I actually see wifi-connect is installed.

But as you can see in the above screenshot, I can’t still see wifi-connect and ui folder inside the container. Very weird. As I said before, I think there is some problem with docker-compose.yml file.
Even though the same Dockerfile was used, wif-connect and ui folder don’t seem to be installed inside the container when using docker-compose.
Could you check it in detail? I shared it before.

Here is the bash file used to execute wifi-connect you asked.

#!/bin/bash
#Start balena-wifi-connect
export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket
./wifi-connect
#At this point the WiFi connection has been configured and the device has
#internet unless the configured WiFi connection is no longer available.

Looking forward to your good solution.
Anatoli

Hi @vipulgupta2048 @zwhitchcox
I’m still waiting for your reply on my issue.
Did you check my work progress above?
I’m very struggling why I can’t see wifi-connect installed and ui folder in the container when building Django docker image using my docker-compose.yml file. I see wifi-connect installed and ui folder when building the docker image with the same Dockerfile uisng docker build command.
As I said again, I definitely see wifi-connect being installed in the terminal while building the image using docker-compose.yml. But when I connected to the container after build is finished, I can’t see wifi-connect installed and its related files(ui folder)
I hope you will give me a clear solution to this problem.


Here is my update.
I accessed to Django container and installed wifi-connect manually inside container.
And then I executed wifi-connect using my custom bash file in the container. In that case, I got the same error(192.168.42.1:80 address is not available)
I think this is because the options added to the docker-compose.yml file were not applied correctly at the start of the container.
Could you please check docker-compose.yml file in detail?

Hi Zane,

Your docker run command with some options helped me to run wifi-connect in Django container.
Now I need to use docker-compose to build the images and run the containers.
That means it’s necessary to add all options that are applied with docker run command to docker-compose.yml file.
So I updated the docker-compose.yml file with the options we added to docker run command.


I built and started the containers with docker-compose up -d --build
After that, I connected to Django container and run wifi-connect. But I got the same error like before.
I think there are some problems on docker-compose.yml file
Could you check my docker-compose,yml file?
Dockerfile version is “2”

Thanks.
Anatoli

Hi Zane,

I solved the issue that wifi-connect was not installed when building image using docker-compose.
Now I see wifi-connect and ui folder installed in the container.
However, I still have an error when I executed wifi-connect inside my Django container.

Starting access point…
Access point ‘WiFi Connect’ created
Starting HTTP server on 192.168.42.1:80
Error: Cannot start HTTP server on ‘192.168.42.1:80’: address not available
root@e01f4423ceb4:/app#
dnsmasq: unknown interface wlan0

We’ve previously met the same error when running the container by docker run command. In that time, I solved it by the following docker run options you gave me.

docker run --mount type=bind,source=/run/dbus/system_bus_socket,target=/host/run/dbus/system_bus_socket -e DBUS_SYSTEM_BUS_ADDRESS="unix:path=/host/run/dbus/system_bus_socket" --privileged --network host test:1.0

I think there is some mistakes on the container option settings in docker-comopse.yml file.

I really want you to help me with this as soon as possible.
Thanks in advance.
Anatolim

Hello Anatoli,
I see you have been working towards a solution and are very close. David, Anton, Zane, and a lot of good folks have gone out of their way to help you with your issue. I have read the thread and followed along with the solutions provided. What was the error regarding not able to see Wifi-connect and UI folder inside your container when building using docker-compose?

In your most recent screenshot of the docker-compose, there are some minor inconsistencies. Since you are doing a deploying a Multi-container app, these are the options you should be having in your docker-compose as mentioned here https://github.com/balena-io/wifi-connect#balenaos-multicontainer-app. These are for if you are using balenaOS but should be true for any Raspian nonetheless.

Another question, is there any reason you are not using balenaOS or not know about it? I do see you commented labels in your docker-compose meant for balenaOS. Your process would been quite painless if you are using balenaOS. You can get started here https://www.balena.io/docs/learn/getting-started/raspberrypi4-64/python/ if you haven’t yet. Hope this helps.

Hi @vipulgupta2048

Thanks for you reply. Your(You and Zane) understanding of my work process and your guide to solutions are always the most specific! So I’m always very grateful for you guys!

I’ll answer your questions.

What was the error regarding not able to see Wifi-connect and UI folder inside your container when building using docker-compose?


I just changed this and that in docker-compose.yml to fix the above issue. And at some point it worked. In order to find the exact cause, I revived the changes that had already made from the beginning one by one. A surprising thing happened. When I built the image again by using the original docker-compose.yml, I could see wifi-connect and ui folder installed. It certainly wasn’t working before. Very strange! Anyway, it works now.

In your most recent screenshot of the docker-compose, there are some minor inconsistencies. Since you are doing a deploying a Multi-container app, these are the options you should be having in your docker-compose as mentioned here GitHub - balena-os/wifi-connect: Easy WiFi setup for Linux devices from your mobile phone or laptop.


I have already tried those options in my docker-compose.yml file. I just added those options to only Django service. I haven’t made any changes on the other services because they were working well and I just needed to install and execute wifi-connect only inside Django container.
However, to make everything clear, I’ll try the options above again.

Is there any reason you are not using balenaOS or not know about it? I do see you commented labels in your docker-compose meant for balenaOS. Your process would been quite painless if you are using balenaOS.


Do you mean the OS installed as hostOS? I know balenaOS, but I have never used balena OS.
I burnt Raspberry Lite OS(32 bit with no desktop version) on my Pi4 using Raspberry Pi Imager tool.
I already have the containers that are built and running by my docker-compose.yml. The Dockerfile used to build Django container is based on python3.7.3 image.(You can also see my Dockerfile in above). So I don’t want to change the environments as much as possible.

Sir, I’ll try with the options you suggested above. I’ll let you know when I got any results on it.

Thank you very much.
Anatoli

Thanks for reaching out with the answers, Anatoli. Docker requires patience to figure small things out, I am glad you are seeing that with what works and what doesn’t. There is a strong reason behind everything we are doing so do be careful making any changes. Always try to make sure the change you are making has worked successfully and why it did work. That’s the only path to learn.

Yes, all changes suggested were for the Django service only. Send us the updated docker-compose.yml file if things doesn’t work out.
Maybe you can use balenaOS for your next project, I wholeheartedly recommend that (Follow the Getting Started guide linked). But, don’t change environments now as it would lead to further confusion. Also, no “sir” in open-source. Firstname is good enough. Let us know how it goes.