multiplatform build
This commit is contained in:
parent
345666cb2e
commit
5029e46359
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,3 +2,5 @@ __pycache__
|
|||||||
devices.yml
|
devices.yml
|
||||||
history.*
|
history.*
|
||||||
data/
|
data/
|
||||||
|
*.iso
|
||||||
|
*.cow
|
||||||
36
Dockerfile
36
Dockerfile
@ -1,4 +1,7 @@
|
|||||||
FROM python:3.12-alpine3.20 AS build_bluepy
|
# This is the build stage for getting all python libs. Mainly it's for reducing the final image size because for building and installing the pips, many tools are needed which are just bloat to the final image.
|
||||||
|
FROM python:3.12-alpine3.20 AS pip_build_stage
|
||||||
|
|
||||||
|
COPY ./python/requierements.txt /
|
||||||
|
|
||||||
RUN apk add \
|
RUN apk add \
|
||||||
make \
|
make \
|
||||||
@ -8,17 +11,32 @@ RUN apk add \
|
|||||||
build-base \
|
build-base \
|
||||||
freetype-dev \
|
freetype-dev \
|
||||||
libpng-dev \
|
libpng-dev \
|
||||||
openblas-dev
|
openblas-dev \
|
||||||
|
libxml2-dev \
|
||||||
|
libxslt-dev
|
||||||
|
|
||||||
|
# BluePy needs to be build here... idk why but pip install fails on alpine somehow
|
||||||
RUN git clone https://github.com/IanHarvey/bluepy.git && \
|
RUN git clone https://github.com/IanHarvey/bluepy.git && \
|
||||||
cd bluepy && \
|
cd bluepy && \
|
||||||
python3.12 setup.py build && \
|
python3.12 setup.py build && \
|
||||||
python3.12 setup.py install
|
python3.12 setup.py install && \
|
||||||
|
cd /
|
||||||
|
|
||||||
|
# Normal pip install for pyyaml failed on RPI4, so I build it here
|
||||||
|
RUN git clone https://github.com/yaml/pyyaml.git && \
|
||||||
|
cd pyyaml && \
|
||||||
|
python3.12 setup.py build && \
|
||||||
|
python3.12 setup.py install && \
|
||||||
|
cd /
|
||||||
|
|
||||||
|
RUN pip3.12 install -r requierements.txt
|
||||||
|
|
||||||
|
|
||||||
|
# This is the stage for the final image
|
||||||
FROM python:3.12-alpine3.20
|
FROM python:3.12-alpine3.20
|
||||||
|
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY ./python/src/ .
|
COPY ./python/src/ .
|
||||||
COPY ./python/requierements.txt .
|
|
||||||
COPY ./python/docker_entrypoint.sh /
|
COPY ./python/docker_entrypoint.sh /
|
||||||
RUN mkdir data
|
RUN mkdir data
|
||||||
RUN touch DOCKER
|
RUN touch DOCKER
|
||||||
@ -26,12 +44,10 @@ VOLUME /src/data
|
|||||||
|
|
||||||
RUN apk add --no-cache sudo bluez tzdata
|
RUN apk add --no-cache sudo bluez tzdata
|
||||||
ENV TZ=Europe/Berlin
|
ENV TZ=Europe/Berlin
|
||||||
|
ENV DOCKER=TRUE
|
||||||
|
|
||||||
# Copy bluepy from the bluepy build stage
|
# Copy pips from the pip build stage
|
||||||
COPY --from=build_bluepy /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
|
COPY --from=pip_build_stage /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
|
||||||
COPY --from=build_bluepy /usr/local/bin /usr/local/bin
|
COPY --from=pip_build_stage /usr/local/bin /usr/local/bin
|
||||||
|
|
||||||
RUN pip3.12 install -r requierements.txt && rm requierements.txt
|
|
||||||
# RUN echo '@reboot root python3.12 /src/serve_json.py' >> /etc/crontab
|
|
||||||
|
|
||||||
ENTRYPOINT sh /docker_entrypoint.sh
|
ENTRYPOINT sh /docker_entrypoint.sh
|
||||||
35
build_docker.sh
Normal file
35
build_docker.sh
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
ARCH=linux/arm/v6
|
||||||
|
#ARCH=linux/amd64
|
||||||
|
TAG=develop
|
||||||
|
HELP="USAGE: sh build_docker.sh \n
|
||||||
|
[ -a | --architecture ] Select a architecture. Default is auto\n
|
||||||
|
[ -t | --tag ] Set a docker tag. Default is develop \n
|
||||||
|
[ -h | --help ] Get this dialog"
|
||||||
|
|
||||||
|
docker_build(){
|
||||||
|
docker build --build-arg TARGETPLATFORM=$ARCH --platform $ARCH --tag dasmoorhuhn/atc-mithermometer-gateway:$TAG .
|
||||||
|
}
|
||||||
|
|
||||||
|
while [ "$1" != "" ]; do
|
||||||
|
case $1 in
|
||||||
|
-a | --architecture )
|
||||||
|
shift
|
||||||
|
ARCH=$1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-t | --tag )
|
||||||
|
shift
|
||||||
|
TAG=$1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h | --help )
|
||||||
|
echo $HELP
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
echo $HELP
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
docker_build
|
||||||
10
build_docker_multi_platforn.sh
Normal file
10
build_docker_multi_platforn.sh
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
TAG=develop
|
||||||
|
|
||||||
|
set e
|
||||||
|
docker buildx version
|
||||||
|
unset e
|
||||||
|
|
||||||
|
docker buildx create --name builder
|
||||||
|
docker buildx use builder
|
||||||
|
|
||||||
|
docker buildx build --tag dasmoorhuhn/atc-mithermometer-gateway:$TAG --platform=linux/amd64,linux/arm64,linux/arm --push .
|
||||||
@ -1,4 +1,10 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
python3.12 api_endpoints.py &
|
env > .env
|
||||||
|
|
||||||
|
if [ "$API" = true ]; then
|
||||||
|
python3.12 api_endpoints.py &
|
||||||
|
sleep 1
|
||||||
|
fi
|
||||||
|
|
||||||
sudo python3.12 main.py
|
sudo python3.12 main.py
|
||||||
@ -1,6 +1,5 @@
|
|||||||
pyyaml
|
pyyaml
|
||||||
bs4
|
bs4
|
||||||
lxml
|
|
||||||
requests
|
requests
|
||||||
flask
|
flask
|
||||||
flask_cors
|
flask_cors
|
||||||
@ -49,7 +49,7 @@ def cleanup():
|
|||||||
devices = []
|
devices = []
|
||||||
|
|
||||||
|
|
||||||
def start_discovery(timeout=20.0):
|
def start_discovery(timeout=20):
|
||||||
cleanup()
|
cleanup()
|
||||||
global devices
|
global devices
|
||||||
print(f'Start discovery with timout {timeout}s...')
|
print(f'Start discovery with timout {timeout}s...')
|
||||||
|
|||||||
16
python/src/load_env.py
Normal file
16
python/src/load_env.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# This is a quick and dirty hack since the ENVs from the docker run command won't show up in the main.py
|
||||||
|
# I echo the output from the env command of a .env file, read and load it here into the os.environ.
|
||||||
|
# https://stackoverflow.com/questions/78684481/python-wont-find-the-env-in-my-docker-container
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def load_env():
|
||||||
|
if 'DOCKER' not in os.listdir('.'): return False
|
||||||
|
with open(file='.env', mode='r') as file: ENV = file.readlines()
|
||||||
|
for env in ENV:
|
||||||
|
env = env.strip()
|
||||||
|
key, value = env.split('=')
|
||||||
|
os.environ[key] = value
|
||||||
|
return True
|
||||||
@ -3,8 +3,9 @@ from log_data import log_to_json
|
|||||||
from discovery import start_discovery
|
from discovery import start_discovery
|
||||||
|
|
||||||
|
|
||||||
def start_loop(interval=60):
|
def start_loop(interval=40, timeout=20):
|
||||||
|
print(f"Starting loop with interval {interval}s")
|
||||||
while True:
|
while True:
|
||||||
devices = start_discovery()
|
devices = start_discovery(timeout=timeout)
|
||||||
log_to_json(devices)
|
log_to_json(devices)
|
||||||
sleep(interval)
|
sleep(interval)
|
||||||
|
|||||||
@ -1,9 +1,25 @@
|
|||||||
|
import os
|
||||||
from discovery import start_discovery
|
from discovery import start_discovery
|
||||||
from log_data import log_to_json
|
from log_data import log_to_json
|
||||||
from loop import start_loop
|
from loop import start_loop
|
||||||
|
from load_env import load_env
|
||||||
|
|
||||||
|
DOCKER = load_env()
|
||||||
|
INTERVAL = 40
|
||||||
|
TIMEOUT = 20
|
||||||
|
|
||||||
# devices = start_discovery()
|
if DOCKER:
|
||||||
# log_to_json(devices)
|
print("Running in docker")
|
||||||
|
interval = os.getenv('LOOP')
|
||||||
|
timeout = os.getenv('TIMEOUT')
|
||||||
|
|
||||||
start_loop()
|
try:INTERVAL = int(interval)
|
||||||
|
except:pass
|
||||||
|
|
||||||
|
try:TIMEOUT = int(timeout)
|
||||||
|
except:pass
|
||||||
|
|
||||||
|
start_loop(INTERVAL, TIMEOUT)
|
||||||
|
|
||||||
|
else:
|
||||||
|
start_loop(interval=40)
|
||||||
|
|||||||
132
run_docker.sh
132
run_docker.sh
@ -1,21 +1,117 @@
|
|||||||
TAG=develop-alpine
|
TAG=develop
|
||||||
CONTAINER=dasmoorhuhn/atc-mithermometer-gateway:$TAG
|
CONTAINER=dasmoorhuhn/atc-mithermometer-gateway:$TAG
|
||||||
|
CONTAINER_NAME=ATC_MiThermometer_Gateway
|
||||||
|
VOLUME=YOUR_VOLUME
|
||||||
|
|
||||||
sudo killall -9 bluetoothd > /dev/null 2>&1
|
D=""
|
||||||
# docker stop $CONTAINER > /dev/null 2>&1
|
TIME_ZONE="Europe/Berlin"
|
||||||
sh stop_docker.sh
|
INTERACTIVE=false
|
||||||
docker container rm ATC_MiThermometer_Gateway > /dev/null 2>&1
|
BUILD=false
|
||||||
echo Start container...
|
API=false
|
||||||
docker run \
|
LOOP="0"
|
||||||
--cap-add=SYS_ADMIN \
|
TIMEOUT="0"
|
||||||
--cap-add=NET_ADMIN \
|
|
||||||
--net=host \
|
HELP="USAGE: sh run_docker.sh [OPTIONS] \n
|
||||||
--name=ATC_MiThermometer_Gateway \
|
[ -d ] Run in Backgrund \n
|
||||||
--restart unless-stopped \
|
[ -t | --tag ] Set a docker tag \n
|
||||||
--tty \
|
[ -b | --build ] Build the image before running the container \n
|
||||||
-ti \
|
[ -l | --loop ] Start the gateway in looping mode. e.g.: --loop 40 will set the interval of the loop to 40s. Default is single run mode \n
|
||||||
-v /var/run/dbus/:/var/run/dbus/ \
|
[ -a | --api ] Start with the API \n
|
||||||
-v ./data:/src/data \
|
[ -tz | --timezone ] Set the timezone. Default is Europe/Berlin \n
|
||||||
$CONTAINER \
|
[ -to | --timeout ] Set the timeout for the bluetooth scan. default is 20s \n
|
||||||
|
[ -h | --help ] Get this dialog"
|
||||||
|
|
||||||
|
docker_run() {
|
||||||
|
sudo killall -9 bluetoothd > /dev/null 2>&1
|
||||||
|
echo Killing old container...
|
||||||
|
docker stop $CONTAINER_NAME
|
||||||
|
docker container rm $CONTAINER_NAME > /dev/null 2>&1
|
||||||
|
|
||||||
|
COMMAND="docker run $D"
|
||||||
|
COMMAND="$COMMAND --cap-add=SYS_ADMIN"
|
||||||
|
COMMAND="$COMMAND --cap-add=NET_ADMIN"
|
||||||
|
COMMAND="$COMMAND --net=host"
|
||||||
|
COMMAND="$COMMAND --env TZ=$TIME_ZONE"
|
||||||
|
COMMAND="$COMMAND --env API=$API"
|
||||||
|
COMMAND="$COMMAND --name=$CONTAINER_NAME"
|
||||||
|
COMMAND="$COMMAND --restart=on-failure"
|
||||||
|
COMMAND="$COMMAND --volume=/var/run/dbus/:/var/run/dbus/"
|
||||||
|
COMMAND="$COMMAND --volume=$VOLUME:/src/data"
|
||||||
|
|
||||||
|
if [ "$INTERACTIVE" = true ]; then
|
||||||
|
COMMAND="$COMMAND --interactive"
|
||||||
|
COMMAND="$COMMAND --tty"
|
||||||
|
COMMAND="$COMMAND --attach=stdout"
|
||||||
|
COMMAND="$COMMAND --attach=stdin"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$LOOP" != "0" ]; then
|
||||||
|
COMMAND="$COMMAND --env LOOP=$LOOP"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$TIMEOUT" != "0" ]; then
|
||||||
|
COMMAND="$COMMAND --env TIMEOUT=$TIMEOUT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$BUILD" = true ]; then
|
||||||
|
sh build_docker.sh --tag $TAG
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo $COMMAND
|
||||||
|
echo Start container...
|
||||||
|
echo
|
||||||
|
$COMMAND $CONTAINER
|
||||||
|
|
||||||
|
docker container rm $CONTAINER_NAME > /dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
while [ "$1" != "" ]; do
|
||||||
|
case $1 in
|
||||||
|
-d )
|
||||||
|
D="-d"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-a | --api)
|
||||||
|
API=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-b | --build )
|
||||||
|
BUILD=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-tz | --timezone )
|
||||||
|
shift
|
||||||
|
TIME_ZONE=$1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-to | --timeout )
|
||||||
|
shift
|
||||||
|
TIMEOUT=$1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-t | --tag )
|
||||||
|
shift
|
||||||
|
TAG=$1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-l | --loop )
|
||||||
|
shift
|
||||||
|
LOOP=$1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-i | --interactive )
|
||||||
|
INTERACTIVE=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h | --help )
|
||||||
|
echo $HELP
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
echo $HELP
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
docker_run
|
||||||
|
|
||||||
docker container rm ATC_MiThermometer_Gateway > /dev/null 2>&1
|
|
||||||
Loading…
x
Reference in New Issue
Block a user