From 469f2cbe1e7099ab57f4f4a980f4b805ec4fd3c5 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 18 Nov 2025 15:57:52 +0000 Subject: [PATCH 01/10] Add multi-architecture Docker build support - Update Dockerfile with optimized build dependencies (gcc, g++, cmake, build-essential) - Add .github/workflows/docker.yml for multi-arch builds (amd64, arm64, armv7) - Create install/install.sh script for easy local Docker image building - Add .venv/ to .gitignore to prevent committing virtual environment - Follow orchestrator-agent pattern for consistent Docker workflow - Enable easy installation via: docker pull ghcr.io/autonomy-logic/openplc-runtime:latest Co-Authored-By: Thiago Alves --- .github/workflows/docker.yml | 41 +++++++++ .gitignore | 1 + Dockerfile | 32 +++++-- install/install.sh | 168 +++++++++++++++++++++++++++++++++++ 4 files changed, 236 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/docker.yml create mode 100755 install/install.sh diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 00000000..b80dd034 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,41 @@ +name: Build and Publish Multi-Arch Docker Image + +on: + push: + branches: ["development"] + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ secrets.GHCR_USERNAME }} + password: ${{ secrets.GHCR_TOKEN }} + + - name: Build and Push Multi-Arch Image + uses: docker/build-push-action@v6 + with: + context: . + push: true + platforms: linux/amd64,linux/arm64,linux/arm/v7 + tags: | + ghcr.io/autonomy-logic/openplc-runtime:latest + ghcr.io/autonomy-logic/openplc-runtime:${{ github.sha }} + ghcr.io/autonomy-logic/openplc-runtime:${{ github.ref_name }} diff --git a/.gitignore b/.gitignore index 1d594b08..663e2838 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ .vscode/ #.*/ /venvs/ +.venv/ __pycache__/ .clinerules diff --git a/Dockerfile b/Dockerfile index 6d6636a1..2f8028ac 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,19 +1,39 @@ -# Dockerfile +# syntax=docker/dockerfile:1 + FROM debian:bookworm-slim -RUN apt-get update && apt-get install -y \ - python3 python3-venv python3-pip bash \ +# Install runtime and build dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + python3 \ + python3-venv \ + python3-pip \ + python3-dev \ + bash \ pkg-config \ + build-essential \ + gcc \ + g++ \ + make \ + cmake \ && rm -rf /var/lib/apt/lists/* WORKDIR /workdir + +# Copy source code COPY . . -RUN mkdir -p /var/run/runtime + +# Setup runtime directory and permissions +RUN mkdir -p /var/run/runtime && \ + chmod +x install.sh scripts/* start_openplc.sh + # Clean any existing build artifacts to ensure clean Docker build -RUN rm -rf build/ venvs/ 2>/dev/null || true -RUN chmod +x install.sh scripts/* start_openplc.sh +RUN rm -rf build/ venvs/ .venv/ 2>/dev/null || true + +# Run installation script RUN ./install.sh +# Expose webserver port EXPOSE 8443 +# Start OpenPLC Runtime CMD ["bash", "./start_openplc.sh"] diff --git a/install/install.sh b/install/install.sh new file mode 100755 index 00000000..c690f2d6 --- /dev/null +++ b/install/install.sh @@ -0,0 +1,168 @@ +#!/usr/bin/env bash +set -euo pipefail + +### --- OS CHECK --- ### +if [[ $OSTYPE != linux-gnu* ]]; then + echo "[ERROR] This script supports Linux only. Aborting." + exit 1 +fi + +# --- Auto-save if running from a pipe --- +if [ -p /dev/stdin ]; then + TMP_SCRIPT="/tmp/install-openplc-runtime.sh" + echo "[INFO] Detected script running from a pipe. Saving to $TMP_SCRIPT..." + cat > "$TMP_SCRIPT" + chmod +x "$TMP_SCRIPT" + + echo "[INFO] Re-running saved script..." + exec "$TMP_SCRIPT" "$@" +fi + +### --- CONFIGURATION --- ### +IMAGE_NAME="ghcr.io/autonomy-logic/openplc-runtime:latest" +CONTAINER_NAME="openplc-runtime" +CONTAINER_PORT="8443" +HOST_PORT="8443" + +# Check for root privileges +check_root() +{ + if [[ $EUID -ne 0 ]]; then + echo "[INFO] Root privileges are required. Trying to elevate with sudo..." + # Re-run the script with sudo, passing all original arguments + exec sudo "$0" "$@" + # exec replaces the current shell with the new command, so the rest of the script continues as root + fi +} + +# Make sure we are root before proceeding +check_root "$@" + +### --- DEPENDENCIES --- ### +echo "Checking and installing required dependencies..." +PKG_MANAGER="" + +# Detect package manager +if command -v apt-get &>/dev/null; then + PKG_MANAGER="apt-get" +elif command -v dnf &>/dev/null; then + PKG_MANAGER="dnf" +elif command -v yum &>/dev/null; then + PKG_MANAGER="yum" +else + echo "[ERROR] No supported package manager found (apt, dnf, or yum). Install dependencies manually." + exit 1 +fi + +# Define package names per package manager +declare -A PKG_MAP +if [[ "$PKG_MANAGER" == "apt-get" ]]; then + PKG_MAP=( + [docker]="docker.io" + ) +elif [[ "$PKG_MANAGER" == "dnf" ]]; then + PKG_MAP=( + [docker]="docker" + ) +elif [[ "$PKG_MANAGER" == "yum" ]]; then + PKG_MAP=( + [docker]="docker" + ) +fi + +# Collect missing packages +MISSING_PKGS=() +for cmd in docker; do + if ! command -v "$cmd" &>/dev/null; then + echo "Missing dependency: $cmd" + MISSING_PKGS+=("${PKG_MAP[$cmd]}") + else + echo "[SUCCESS] $cmd is already installed." + fi +done + +# Install missing packages +if [ ${#MISSING_PKGS[@]} -ne 0 ]; then + echo "Updating package lists and installing missing dependencies: ${MISSING_PKGS[*]}" + case "$PKG_MANAGER" in + apt-get) + sudo apt-get update -y + sudo apt-get install -y "${MISSING_PKGS[@]}" + ;; + dnf) + sudo dnf install -y "${MISSING_PKGS[@]}" + ;; + yum) + sudo yum install -y "${MISSING_PKGS[@]}" + ;; + esac +fi + +echo "Attempting to pull Docker image: $IMAGE_NAME" +if docker pull "$IMAGE_NAME" 2>/dev/null; then + echo "[SUCCESS] Image pulled successfully from registry." +else + echo "[INFO] Image not available in registry. Building locally..." + + if [ ! -f "Dockerfile" ]; then + echo "[ERROR] Dockerfile not found. Please run this script from the openplc-runtime repository root." + echo "Or clone the repository first:" + echo " git clone https://github.com/Autonomy-Logic/openplc-runtime.git" + echo " cd openplc-runtime" + echo " sudo ./install/install.sh" + exit 1 + fi + + echo "Building Docker image locally..." + docker build -t "$IMAGE_NAME" . + echo "[SUCCESS] Image built successfully." +fi + +if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + echo "Existing container detected. Stopping and removing..." + docker stop "$CONTAINER_NAME" 2>/dev/null || true + docker rm "$CONTAINER_NAME" 2>/dev/null || true +fi + +echo "Creating and starting container: $CONTAINER_NAME" +docker run -d \ + --name "$CONTAINER_NAME" \ + --restart unless-stopped \ + -p "${HOST_PORT}:${CONTAINER_PORT}" \ + "$IMAGE_NAME" + +echo "[SUCCESS] Container started successfully." + +# Detect color support +if [ -t 1 ] && command -v tput >/dev/null && [ "$(tput colors 2>/dev/null)" -ge 8 ]; then + GREEN="$(tput setaf 2)" + CYAN="$(tput setaf 6)" + YELLOW="$(tput setaf 3)" + GRAY="$(tput setaf 8)" + BOLD="$(tput bold)" + RESET="$(tput sgr0)" +else + GREEN="" + CYAN="" + YELLOW="" + GRAY="" + BOLD="" + RESET="" +fi + +echo +echo +echo -e "${BOLD}${GREEN}INSTALLATION COMPLETE${RESET}" +echo -e "${GRAY}=====================================================${RESET}" +echo +echo -e "OpenPLC Runtime is now running in a Docker container." +echo -e "Access the web interface at: ${BOLD}${CYAN}https://localhost:${HOST_PORT}${RESET}" +echo +echo -e "Container name: ${YELLOW}${CONTAINER_NAME}${RESET}" +echo +echo "Useful commands:" +echo " View logs: docker logs $CONTAINER_NAME" +echo " Stop: docker stop $CONTAINER_NAME" +echo " Start: docker start $CONTAINER_NAME" +echo " Remove: docker rm -f $CONTAINER_NAME" +echo -e "${GRAY}=====================================================${RESET}" From d9ebd7f132ecc52d3f1ff336bb15363e6306ef6e Mon Sep 17 00:00:00 2001 From: Thiago Alves Date: Tue, 18 Nov 2025 11:19:26 -0500 Subject: [PATCH 02/10] Remove useless install script --- install/install.sh | 168 --------------------------------------------- 1 file changed, 168 deletions(-) delete mode 100755 install/install.sh diff --git a/install/install.sh b/install/install.sh deleted file mode 100755 index c690f2d6..00000000 --- a/install/install.sh +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -### --- OS CHECK --- ### -if [[ $OSTYPE != linux-gnu* ]]; then - echo "[ERROR] This script supports Linux only. Aborting." - exit 1 -fi - -# --- Auto-save if running from a pipe --- -if [ -p /dev/stdin ]; then - TMP_SCRIPT="/tmp/install-openplc-runtime.sh" - echo "[INFO] Detected script running from a pipe. Saving to $TMP_SCRIPT..." - cat > "$TMP_SCRIPT" - chmod +x "$TMP_SCRIPT" - - echo "[INFO] Re-running saved script..." - exec "$TMP_SCRIPT" "$@" -fi - -### --- CONFIGURATION --- ### -IMAGE_NAME="ghcr.io/autonomy-logic/openplc-runtime:latest" -CONTAINER_NAME="openplc-runtime" -CONTAINER_PORT="8443" -HOST_PORT="8443" - -# Check for root privileges -check_root() -{ - if [[ $EUID -ne 0 ]]; then - echo "[INFO] Root privileges are required. Trying to elevate with sudo..." - # Re-run the script with sudo, passing all original arguments - exec sudo "$0" "$@" - # exec replaces the current shell with the new command, so the rest of the script continues as root - fi -} - -# Make sure we are root before proceeding -check_root "$@" - -### --- DEPENDENCIES --- ### -echo "Checking and installing required dependencies..." -PKG_MANAGER="" - -# Detect package manager -if command -v apt-get &>/dev/null; then - PKG_MANAGER="apt-get" -elif command -v dnf &>/dev/null; then - PKG_MANAGER="dnf" -elif command -v yum &>/dev/null; then - PKG_MANAGER="yum" -else - echo "[ERROR] No supported package manager found (apt, dnf, or yum). Install dependencies manually." - exit 1 -fi - -# Define package names per package manager -declare -A PKG_MAP -if [[ "$PKG_MANAGER" == "apt-get" ]]; then - PKG_MAP=( - [docker]="docker.io" - ) -elif [[ "$PKG_MANAGER" == "dnf" ]]; then - PKG_MAP=( - [docker]="docker" - ) -elif [[ "$PKG_MANAGER" == "yum" ]]; then - PKG_MAP=( - [docker]="docker" - ) -fi - -# Collect missing packages -MISSING_PKGS=() -for cmd in docker; do - if ! command -v "$cmd" &>/dev/null; then - echo "Missing dependency: $cmd" - MISSING_PKGS+=("${PKG_MAP[$cmd]}") - else - echo "[SUCCESS] $cmd is already installed." - fi -done - -# Install missing packages -if [ ${#MISSING_PKGS[@]} -ne 0 ]; then - echo "Updating package lists and installing missing dependencies: ${MISSING_PKGS[*]}" - case "$PKG_MANAGER" in - apt-get) - sudo apt-get update -y - sudo apt-get install -y "${MISSING_PKGS[@]}" - ;; - dnf) - sudo dnf install -y "${MISSING_PKGS[@]}" - ;; - yum) - sudo yum install -y "${MISSING_PKGS[@]}" - ;; - esac -fi - -echo "Attempting to pull Docker image: $IMAGE_NAME" -if docker pull "$IMAGE_NAME" 2>/dev/null; then - echo "[SUCCESS] Image pulled successfully from registry." -else - echo "[INFO] Image not available in registry. Building locally..." - - if [ ! -f "Dockerfile" ]; then - echo "[ERROR] Dockerfile not found. Please run this script from the openplc-runtime repository root." - echo "Or clone the repository first:" - echo " git clone https://github.com/Autonomy-Logic/openplc-runtime.git" - echo " cd openplc-runtime" - echo " sudo ./install/install.sh" - exit 1 - fi - - echo "Building Docker image locally..." - docker build -t "$IMAGE_NAME" . - echo "[SUCCESS] Image built successfully." -fi - -if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - echo "Existing container detected. Stopping and removing..." - docker stop "$CONTAINER_NAME" 2>/dev/null || true - docker rm "$CONTAINER_NAME" 2>/dev/null || true -fi - -echo "Creating and starting container: $CONTAINER_NAME" -docker run -d \ - --name "$CONTAINER_NAME" \ - --restart unless-stopped \ - -p "${HOST_PORT}:${CONTAINER_PORT}" \ - "$IMAGE_NAME" - -echo "[SUCCESS] Container started successfully." - -# Detect color support -if [ -t 1 ] && command -v tput >/dev/null && [ "$(tput colors 2>/dev/null)" -ge 8 ]; then - GREEN="$(tput setaf 2)" - CYAN="$(tput setaf 6)" - YELLOW="$(tput setaf 3)" - GRAY="$(tput setaf 8)" - BOLD="$(tput bold)" - RESET="$(tput sgr0)" -else - GREEN="" - CYAN="" - YELLOW="" - GRAY="" - BOLD="" - RESET="" -fi - -echo -echo -echo -e "${BOLD}${GREEN}INSTALLATION COMPLETE${RESET}" -echo -e "${GRAY}=====================================================${RESET}" -echo -echo -e "OpenPLC Runtime is now running in a Docker container." -echo -e "Access the web interface at: ${BOLD}${CYAN}https://localhost:${HOST_PORT}${RESET}" -echo -echo -e "Container name: ${YELLOW}${CONTAINER_NAME}${RESET}" -echo -echo "Useful commands:" -echo " View logs: docker logs $CONTAINER_NAME" -echo " Stop: docker stop $CONTAINER_NAME" -echo " Start: docker start $CONTAINER_NAME" -echo " Remove: docker rm -f $CONTAINER_NAME" -echo -e "${GRAY}=====================================================${RESET}" From bdb5f74a47bc97f11d60b9355a1a69881d8f782c Mon Sep 17 00:00:00 2001 From: Thiago Alves Date: Tue, 18 Nov 2025 09:58:11 -0800 Subject: [PATCH 03/10] Docker adjustments --- .github/workflows/build.yml | 17 ----------------- .github/workflows/docker.yml | 4 +++- Dockerfile | 17 +---------------- 3 files changed, 4 insertions(+), 34 deletions(-) delete mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 11c0e554..00000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Build - -on: - push: - branches: [ main, development ] - pull_request: - branches: [ main, development ] - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Install dependencies and build - run: sudo ./install.sh diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index b80dd034..f1734619 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -2,7 +2,9 @@ name: Build and Publish Multi-Arch Docker Image on: push: - branches: ["development"] + branches: [ main, development ] + pull_request: + branches: [ main, development ] workflow_dispatch: jobs: diff --git a/Dockerfile b/Dockerfile index 2f8028ac..5528a3ff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,21 +2,6 @@ FROM debian:bookworm-slim -# Install runtime and build dependencies -RUN apt-get update && apt-get install -y --no-install-recommends \ - python3 \ - python3-venv \ - python3-pip \ - python3-dev \ - bash \ - pkg-config \ - build-essential \ - gcc \ - g++ \ - make \ - cmake \ - && rm -rf /var/lib/apt/lists/* - WORKDIR /workdir # Copy source code @@ -35,5 +20,5 @@ RUN ./install.sh # Expose webserver port EXPOSE 8443 -# Start OpenPLC Runtime +# Default execution - Start OpenPLC Runtime CMD ["bash", "./start_openplc.sh"] From b03a2a4efe98ee0860cafe69aa681aa63cbe6140 Mon Sep 17 00:00:00 2001 From: Thiago Alves Date: Tue, 18 Nov 2025 13:04:45 -0500 Subject: [PATCH 04/10] Adjust build script --- .github/workflows/docker.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index f1734619..1828c119 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -40,4 +40,3 @@ jobs: tags: | ghcr.io/autonomy-logic/openplc-runtime:latest ghcr.io/autonomy-logic/openplc-runtime:${{ github.sha }} - ghcr.io/autonomy-logic/openplc-runtime:${{ github.ref_name }} From c5714b7ade32293b1ba7dc86473a0c029e4405c1 Mon Sep 17 00:00:00 2001 From: Thiago Alves Date: Tue, 18 Nov 2025 13:11:17 -0500 Subject: [PATCH 05/10] Add pkg-config for Ubuntu targets --- install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 48a22872..c3f0d82a 100755 --- a/install.sh +++ b/install.sh @@ -70,6 +70,7 @@ install_deps_apt() { gcc \ make \ cmake \ + pkg-config \ && rm -rf /var/lib/apt/lists/* } @@ -167,4 +168,4 @@ else echo "ERROR: Build process failed!" >&2 echo "Please check the error messages above for details." >&2 exit 1 -fi \ No newline at end of file +fi From eccbf195914dca526f71c0def099a32e3845a347 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 18 Nov 2025 19:30:06 +0000 Subject: [PATCH 06/10] Fix plugin system compilation error on 32-bit architectures (arm/v7) The plugin system was using Py_SET_REFCNT(args, UINT64_MAX) to prevent garbage collection of the runtime args capsule. This caused an overflow error on 32-bit systems where Py_ssize_t is 32 bits (int), but UINT64_MAX is a 64-bit value. Changes: - Add args_capsule field to python_binds_t structure to store capsule reference - Replace Py_SET_REFCNT hack with proper reference counting pattern - Store capsule reference in plugin->python_plugin->args_capsule for lifetime - Add Py_XDECREF in python_plugin_cleanup to properly release capsule This fix ensures proper cross-architecture compatibility (32-bit and 64-bit) and follows Python C API best practices for reference counting. Co-Authored-By: Thiago Alves --- core/src/drivers/plugin_driver.c | 5 ++++- core/src/drivers/python_plugin_bridge.h | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/core/src/drivers/plugin_driver.c b/core/src/drivers/plugin_driver.c index 26ad4a14..c10a400a 100644 --- a/core/src/drivers/plugin_driver.c +++ b/core/src/drivers/plugin_driver.c @@ -160,7 +160,9 @@ int plugin_driver_init(plugin_driver_t *driver) // Call the Python init function with proper capsule PyObject *result = PyObject_CallFunctionObjArgs(plugin->python_plugin->pFuncInit, args, NULL); - Py_SET_REFCNT(args, UINT64_MAX); + + // Store the capsule reference for the lifetime of the plugin + plugin->python_plugin->args_capsule = args; if (!result) { @@ -639,6 +641,7 @@ static void python_plugin_cleanup(plugin_instance_t *plugin) Py_XDECREF(plugin->python_plugin->pFuncStop); Py_XDECREF(plugin->python_plugin->pFuncCleanup); Py_XDECREF(plugin->python_plugin->pModule); + Py_XDECREF(plugin->python_plugin->args_capsule); free(plugin->python_plugin); plugin->python_plugin = NULL; diff --git a/core/src/drivers/python_plugin_bridge.h b/core/src/drivers/python_plugin_bridge.h index 1c00060d..b0442e0f 100644 --- a/core/src/drivers/python_plugin_bridge.h +++ b/core/src/drivers/python_plugin_bridge.h @@ -15,6 +15,7 @@ typedef struct PyObject *pFuncStart; PyObject *pFuncStop; PyObject *pFuncCleanup; + PyObject *args_capsule; // Capsule containing plugin_runtime_args_t for lifetime management } python_binds_t; -#endif // __PYTHON_PLUGIN_BRIDGE_H \ No newline at end of file +#endif // __PYTHON_PLUGIN_BRIDGE_H From 4a186e4fc1bb97d6adae8021422990960d0cdb91 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 18 Nov 2025 20:21:51 +0000 Subject: [PATCH 07/10] Fix Flask-SocketIO production server error by switching to eventlet The webserver was crashing in Docker with RuntimeError: 'The Werkzeug web server is not designed to run in production.' This occurred because Flask-SocketIO was using Werkzeug's development server by default. Changes: - Add eventlet to requirements.txt for production-ready async server - Update SocketIO initialization to use async_mode='eventlet' instead of 'threading' - Eventlet provides proper WebSocket support with HTTPS/SSL for production use This fix ensures the webserver runs reliably in Docker containers while maintaining WebSocket functionality for debug communication with OpenPLC Editor. The ssl_context parameter should work with eventlet's server. If issues arise, we can switch to ssl_certfile/ssl_keyfile parameters as an alternative. Co-Authored-By: Thiago Alves --- requirements.txt | 1 + webserver/debug_websocket.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 898a574e..5b1c6396 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,7 @@ Flask-Login Flask-JWT-Extended>=4.6.0 flask_sqlalchemy Flask-SocketIO +eventlet PyJWT python-dotenv pytest diff --git a/webserver/debug_websocket.py b/webserver/debug_websocket.py index d85763ed..738e5fbc 100644 --- a/webserver/debug_websocket.py +++ b/webserver/debug_websocket.py @@ -10,6 +10,7 @@ from flask_jwt_extended import decode_token from flask_socketio import SocketIO, emit from jwt.exceptions import ExpiredSignatureError, InvalidTokenError + from webserver.logger import get_logger logger, _ = get_logger("debug_ws", use_buffer=True) @@ -54,7 +55,7 @@ def _filtered_server_log(self, log_type, message, *args): _socketio = SocketIO( app, cors_allowed_origins="*", - async_mode="threading", + async_mode="eventlet", logger=False, engineio_logger=False, ping_timeout=60, From c98bef5c5bb06fd85ca9a12c1cf033127abaa820 Mon Sep 17 00:00:00 2001 From: Thiago Alves Date: Tue, 18 Nov 2025 15:59:01 -0500 Subject: [PATCH 08/10] Revert eventlet addition on requirements --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 5b1c6396..898a574e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,6 @@ Flask-Login Flask-JWT-Extended>=4.6.0 flask_sqlalchemy Flask-SocketIO -eventlet PyJWT python-dotenv pytest From 70dba8303ff3f81e01f358626630ad3e00654de5 Mon Sep 17 00:00:00 2001 From: Thiago Alves Date: Tue, 18 Nov 2025 15:59:42 -0500 Subject: [PATCH 09/10] Revert using eventlet on debug socket --- webserver/debug_websocket.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webserver/debug_websocket.py b/webserver/debug_websocket.py index 738e5fbc..89c2e430 100644 --- a/webserver/debug_websocket.py +++ b/webserver/debug_websocket.py @@ -55,7 +55,7 @@ def _filtered_server_log(self, log_type, message, *args): _socketio = SocketIO( app, cors_allowed_origins="*", - async_mode="eventlet", + async_mode="threading", logger=False, engineio_logger=False, ping_timeout=60, From df89fa6371c98fce2f88fce095212ef859bff93e Mon Sep 17 00:00:00 2001 From: Thiago Alves Date: Tue, 18 Nov 2025 16:00:47 -0500 Subject: [PATCH 10/10] Allow werkzeug on docker --- webserver/app.py | 1 + 1 file changed, 1 insertion(+) diff --git a/webserver/app.py b/webserver/app.py index c5504e22..89555228 100644 --- a/webserver/app.py +++ b/webserver/app.py @@ -240,6 +240,7 @@ def run_https(): ssl_context=context, use_reloader=False, log_output=False, + allow_unsafe_werkzeug=True, ) except FileNotFoundError: