diff --git a/Dockerfile b/Dockerfile index 358defb..93fe9f5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,31 +1,60 @@ -FROM python:3.12-alpine3.22 as builder - -RUN apk add --no-cache \ - freetype-dev \ - libjpeg-turbo-dev \ - gcc \ - musl-dev \ - linux-headers - -WORKDIR /usr/src/app +FROM python:3.13-slim-bookworm as builder + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + curl + +WORKDIR /opt/build +WORKDIR /opt/build/ui + +# Download WiFi Connect +# Use latest version. If specific version is required, it should be provided as vX.Y.Z, e.g v4.11.37 +ARG VERSION="latest" + +RUN \ + export BASE_URL="https://github.com/balena-os/wifi-connect/releases" &&\ + DETECTED_ARCH=$(uname -m) &&\ + case $DETECTED_ARCH in \ + "aarch64") \ + BINARY_ARCH_NAME="aarch64-unknown-linux-gnu" ;; \ + "x86_64") \ + BINARY_ARCH_NAME="x86_64-unknown-linux-gnu" ;;\ + "armv7l") \ + BINARY_ARCH_NAME="armv7-unknown-linux-gnueabihf" ;;\ + *) \ + echo >&2 "error: unsupported architecture ($DETECTED_ARCH)"; exit 1 ;; \ + esac;\ + if [ ${VERSION} = "latest" ]; then \ + export URL_PARTIAL="latest/download" ; \ + else \ + export URL_PARTIAL="download/${VERSION}" ; \ + fi; \ + curl -Ls "$BASE_URL/$URL_PARTIAL/wifi-connect-$BINARY_ARCH_NAME.tar.gz" \ + | tar -xvz -C /opt/build && \ + curl -Ls "$BASE_URL/$URL_PARTIAL/wifi-connect-ui.tar.gz" \ + | tar -xvz -C /opt/build/ui # Install the required python packages, and save the compiled result to an output folder # This requires gcc/etc which is why we do it in the build image and save the result for the run image COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -FROM python:3.12-alpine3.22 +# Build final stage +FROM python:3.13-slim-bookworm -RUN apk add --no-cache \ - freetype-dev \ - libjpeg-turbo-dev \ - tzdata +RUN apt-get update && apt-get install -y --no-install-recommends \ + wireless-tools \ + dnsmasq # Copy in the compiled packages -COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages +COPY --from=builder /usr/local/lib/python3.13/site-packages /usr/local/lib/python3.13/site-packages +COPY --from=builder /opt/build /usr/src/app WORKDIR /usr/src/app COPY src ./src COPY VERSION . -CMD ["python3", "src/main.py"] \ No newline at end of file +# For WiFi Connect +ENV DBUS_SYSTEM_BUS_ADDRESS unix:path=/host/run/dbus/system_bus_socket + +CMD ["sh", "src/start.sh"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..6d5fead --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,13 @@ +version: "2" + +services: + train-departure-display: + network_mode: "host" + privileged: true + build: . + ports: + - "80:80" + volumes: + - /run/dbus:/host/run/dbus:ro + labels: + io.balena.features.dbus: "1" diff --git a/src/start.sh b/src/start.sh new file mode 100644 index 0000000..6f63461 --- /dev/null +++ b/src/start.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +sleep 5 # give Supervisor time to attach log stream +set -x + +# Optional step - it takes couple of seconds (or longer) to establish a WiFi connection +# sometimes. In this case, following checks will fail and wifi-connect +# will be launched even if the device will be able to connect to a WiFi network. +# If this is your case, you can wait for a while and then check for the connection. +# sleep 15 + +# Choose a condition for running WiFi Connect according to your use case: + +# 1. Is there a default gateway? +# ip route | grep default + +# 2. Is there Internet connectivity? +# nmcli -t g | grep full + +# 3. Is there Internet connectivity via a google ping? +# wget --spider http://google.com 2>&1 + +# 4. Is there an active WiFi connection? +iwgetid -r + +if [ $? -eq 0 ]; then + printf 'Skipping WiFi Connect\n' +else + printf 'Starting WiFi Connect\n' + ./wifi-connect + printf 'Finished WiFi Connect\n' +fi + +python -u src/main.py \ No newline at end of file