# WAGO 750-362 Modbus TCP simulator — service container # # Build: docker build -t wago-sim . # Run: docker run -d --name wago-sim -p 502:502 \ # -v ./config:/app/config:ro -v ./scenarios:/app/scenarios:ro \ # -e WAGO_SIM_NODE=config/pump_node.yaml \ # -e WAGO_SIM_PORT=502 wago-sim # # Or with compose: docker compose up -d FROM python:3.12-slim AS base # Don't buffer stdout/stderr — service logs must stream immediately # WAGO_SIM_VERBOSE=1 enables plain-text Modbus request tracing. ENV PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 \ WAGO_SIM_NODE=config/pump_node.yaml \ WAGO_SIM_HOST=0.0.0.0 \ WAGO_SIM_PORT=502 WORKDIR /app # Install the package first (layer caching: dependencies rarely change) COPY pyproject.toml README.md ./ COPY src ./src RUN pip install --no-cache-dir . # Node configurations and scenarios are mounted at runtime; # the example files are baked in for out-of-the-box startup. COPY config ./config COPY scenarios ./scenarios COPY plugins ./plugins # Non-root user: the Modbus port (502) is configured via WAGO_SIM_PORT, # so no privileged ports are needed inside the container. RUN useradd --system --no-create-home wago-sim \ && chown -R wago-sim:wago-sim /app USER wago-sim # Built-in health check: attempt a TCP connect to the Modbus port. # A full MBAP request/response would be better, but keep the image slim # (no curl/wget) — the TCP probe is sufficient for compose/Swarm/K8s # restart decisions. HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \ CMD python -c "import socket, os; s=socket.create_connection(('127.0.0.1', int(os.environ['WAGO_SIM_PORT'])), timeout=3); s.close()" # EXPOSE is documentation only; compose maps the actual port. # Use 5020 on the host if 502 requires privileges on your machine. EXPOSE 502 # The console script runs the server until SIGTERM (docker stop). CMD ["wago-sim", "serve"]