GraphWeather is a Windows application. That is a fact, not a limitation β€” provided you are willing to meet it halfway. I have been running GraphWeather on Linux servers for the better part of four years, across three different approaches, and each one solves a slightly different problem. Wine gives you the full desktop experience. Mono handles the .NET helper tools. Docker wraps everything in an isolated, reproducible container. This guide walks through all three so you can pick the one that fits your infrastructure.

If you have not yet decided whether GraphWeather is the right tool for your setup, the three-way comparison with Weewx and CumulusMX will help you weigh the options before investing time in a Linux deployment. And if you just want the GraphWeather overview, start there.

Quick-Answer Summary

Approach Best for Complexity Serial/USB support
Wine Full desktop app on a Linux workstation Medium Yes, with configuration
Mono Running .NET helper tools only (not the main app) Low N/A (tools only)
Docker Headless server, CI/CD, reproducible deployments Medium-high Possible but fiddly

If you want the fastest path to a working setup and your station connects via USB: Wine on a dedicated Linux box. If you want maximum isolation and your data arrives via network (IP logger, MQTT, or CSV import): Docker.

Prerequisites

Regardless of which approach you choose, you will need:

  • A Linux distribution from the past three years. Debian 12, Ubuntu 22.04+, Fedora 38+, and Raspberry Pi OS (64-bit) are all tested.
  • Root or sudo access for package installation.
  • The GraphWeather installer (.exe) downloaded from the GraphWeather page.
  • At least 2 GB of free disk space (Wine alone pulls in several hundred megabytes of dependencies).
  • For USB station connections: the station physically attached to the Linux machine, with the appropriate kernel driver loaded (most Davis and Fine Offset stations use cp210x or ch341).

Approach 1 β€” Wine

Wine translates Windows API calls into POSIX calls at runtime. It is not an emulator β€” it is a compatibility layer, and for a well-behaved C++ desktop application like GraphWeather, it works remarkably well.

Step 1: Install Wine

On Debian/Ubuntu:

sudo dpkg --add-architecture i386
sudo apt update
sudo apt install wine64 wine32 winetricks

On Fedora:

sudo dnf install wine winetricks

Confirm the version:

wine --version

You want Wine 8.0 or later. Earlier versions have known issues with the GDI rendering that GraphWeather uses for its real-time gauge display.

Step 2: Configure the Wine Prefix

Create a dedicated prefix for GraphWeather to keep it isolated from any other Wine applications:

export WINEPREFIX="$HOME/.wine-graphweather"
export WINEARCH=win64
wineboot --init

Install the Visual C++ runtime (GraphWeather links against it):

winetricks vcrun2019

If GraphWeather's installer also requires .NET components for helper tools, add:

winetricks dotnet48

This step can take ten to fifteen minutes. Winetricks downloads and installs the actual Microsoft runtimes inside the Wine prefix.

Step 3: Install GraphWeather

wine GraphWeather_Setup_2.0.308b.exe

Follow the installer prompts. The default installation path maps to $WINEPREFIX/drive_c/Program Files/GraphWeather/. After installation, launch it:

wine "$WINEPREFIX/drive_c/Program Files/GraphWeather/GraphWeather.exe"

The main window should appear. If it does not, check $WINEPREFIX/drive_c/users/$USER/Temp/ for log files, or run with WINEDEBUG=+relay for verbose output (warning: this produces enormous logs).

Step 4: Serial/USB Passthrough

This is where most people get stuck. Wine maps Linux serial devices to COM ports, but you have to tell it which device maps to which port.

Create a symbolic link inside the Wine prefix:

ln -s /dev/ttyUSB0 "$WINEPREFIX/dosdevices/com1"

Replace /dev/ttyUSB0 with your station's actual device node. Find it with:

dmesg | grep tty

Ensure your user is in the dialout group:

sudo usermod -aG dialout $USER

Log out and back in (or newgrp dialout). In GraphWeather's station configuration, select COM1 as the port.

Step 5: Run as a Service

For unattended operation, create a systemd service:

# /etc/systemd/system/graphweather.service
[Unit]
Description=GraphWeather via Wine
After=network.target

[Service]
User=weather
Environment=WINEPREFIX=/home/weather/.wine-graphweather
Environment=DISPLAY=:0
ExecStart=/usr/bin/wine "/home/weather/.wine-graphweather/drive_c/Program Files/GraphWeather/GraphWeather.exe"
Restart=on-failure
RestartSec=30

[Install]
WantedBy=multi-user.target

The DISPLAY=:0 environment variable is necessary because GraphWeather is a GUI application. On a headless server, use Xvfb (a virtual framebuffer) instead:

sudo apt install xvfb

Change the ExecStart line to:

ExecStart=/usr/bin/xvfb-run -a /usr/bin/wine "/home/weather/.wine-graphweather/drive_c/Program Files/GraphWeather/GraphWeather.exe"

Enable and start the service:

sudo systemctl enable graphweather
sudo systemctl start graphweather

Known Wine Quirks

  • Font rendering: Some dialog labels may appear truncated. Install winetricks corefonts to fix most cases.
  • High-DPI displays: The gauge rendering can scale incorrectly. Set the Wine DPI override: wine reg add "HKCU\\Control Panel\\Desktop" /v LogPixels /t REG_DWORD /d 96 /f.
  • Audio warnings: GraphWeather can play audio alerts for extreme conditions. Wine's audio subsystem requires PulseAudio or ALSA configuration. If you do not need audio alerts, disable them in GraphWeather's settings to avoid error messages in the Wine log.

Approach 2 β€” Mono for .NET Helper Tools

GraphWeather's core is C++, but some helper tools (data migration utilities, configuration editors) are .NET assemblies. If you only need these tools β€” not the full desktop application β€” Mono runs them natively on Linux without Wine.

Install Mono

sudo apt install mono-complete

Run a .NET tool:

mono GraphWeatherDataTool.exe --import data.csv

Mono does not support Windows Forms rendering as well as Wine does, so GUI-based tools may have visual glitches. For command-line utilities, though, it works flawlessly.

This approach is most useful when your main GraphWeather instance runs on a Windows machine and you want to run data processing or migration scripts on a Linux server. For the template and plugin side of things, the custom templates and plugin development guide explains what you can build on the Windows side; the Mono approach lets you run the data pipeline components on Linux.

Approach 3 β€” Docker

Docker gives you the strongest isolation and the most reproducible deployments. The trade-off is complexity β€” especially around USB device access.

Dockerfile

FROM scottyhardy/docker-wine:stable

# Install GraphWeather
COPY GraphWeather_Setup_2.0.308b.exe /tmp/
RUN xvfb-run wine /tmp/GraphWeather_Setup_2.0.308b.exe /S && \
    rm /tmp/GraphWeather_Setup_2.0.308b.exe

# Create data directories
RUN mkdir -p /data/export /data/config

# Copy default configuration
COPY graphweather.ini /root/.wine/drive_c/Program\ Files/GraphWeather/

VOLUME ["/data/export", "/data/config"]

CMD ["xvfb-run", "wine", "/root/.wine/drive_c/Program Files/GraphWeather/GraphWeather.exe"]

The scottyhardy/docker-wine base image bundles Wine with Xvfb and the necessary 32-bit libraries. The /S flag runs the GraphWeather installer in silent mode.

Docker Compose

version: "3.9"
services:
  graphweather:
    build: .
    volumes:
      - ./export:/data/export
      - ./config:/data/config
    devices:
      - /dev/ttyUSB0:/dev/ttyUSB0
    restart: unless-stopped

The devices key passes the USB serial device into the container. This requires the container to run with sufficient privileges β€” --privileged in the worst case, or more targeted capability grants:

    cap_add:
      - SYS_RAWIO
    security_opt:
      - apparmor:unconfined

USB Device Access from Containers

This is the hardest part of the Docker approach. The device node must exist when the container starts, which means:

  1. The station must be plugged in before you run docker compose up.
  2. If the station disconnects and reconnects, the device node may change (e.g., /dev/ttyUSB0 becomes /dev/ttyUSB1). Use a udev rule to create a stable symlink:
# /etc/udev/rules.d/99-weather-station.rules
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="weatherstation"

Replace the vendor and product IDs with your station's values (find them with lsusb). Then mount /dev/weatherstation in the Compose file.

Scheduling with Cron Inside the Container

GraphWeather has its own internal scheduler, so you typically do not need cron for data collection. However, if you want to trigger periodic maintenance tasks (log rotation, backup exports), add a cron job to the Docker image:

RUN apt-get update && apt-get install -y cron
COPY crontab /etc/cron.d/graphweather-cron
RUN chmod 0644 /etc/cron.d/graphweather-cron && crontab /etc/cron.d/graphweather-cron

A simpler alternative: keep maintenance tasks outside the container and operate on the mounted volumes from the host.

Performance Comparison

Approach CPU overhead Memory Startup time
Wine (bare metal) ~5% above native Windows ~150 MB 3-5 seconds
Mono (tools only) Negligible ~50 MB 1-2 seconds
Docker + Wine ~8% above native Windows ~300 MB (container + Wine) 10-15 seconds

For a dedicated weather-station server, all three approaches are well within the capabilities of a Raspberry Pi 4 (4 GB model). On a Pi 3, the Docker approach is tight on memory β€” stick with bare-metal Wine.

If you are already running a Grafana stack for visualisation β€” as described in the Grafana dashboard guide β€” Docker Compose lets you manage GraphWeather, Telegraf, InfluxDB, and Grafana as a single stack. That operational simplicity can outweigh the USB complexity.

Common Mistakes

  1. Wine version too old. Distributions sometimes ship ancient Wine packages. GraphWeather needs Wine 8.0+ for reliable GDI rendering. Use the WineHQ repository for up-to-date packages if your distro's version is behind.
  2. Missing 32-bit libraries. Even on a 64-bit system, Wine needs 32-bit libraries (lib32- packages or i386 architecture). The symptom is a cryptic "Bad EXE format" error. Run dpkg --add-architecture i386 && apt update && apt install wine32 to fix it.
  3. Docker volume permission issues. Files written by Wine inside the container are owned by the Wine user (usually root). If you mount a host directory, set permissions with chown or run the container with --user $(id -u):$(id -g).
  4. Forgetting Xvfb on headless systems. GraphWeather will not start without a display. xvfb-run creates a virtual framebuffer that satisfies the requirement without a physical monitor.
  5. USB device disappearing after reboot. If you hard-code /dev/ttyUSB0 in your config and the device enumerates differently after a reboot, GraphWeather will not find the station. Always use a udev symlink for stable device naming.

Related Reading

FAQ

Does GraphWeather run on ARM Linux (Raspberry Pi)? Yes, via the wine-arm package or the box86/box64 translation layer. Performance is acceptable on a Pi 4. On a Pi 3, expect slow startup and occasional GUI lag β€” but the data collection and publishing pipeline runs fine once it stabilises.

Can I run GraphWeather in WSL2 instead of full Linux? WSL2 is technically Linux, but it adds its own layer of complexity for USB passthrough (you need usbipd-win). If your host is Windows, just run GraphWeather natively β€” WSL2 adds overhead without benefit in this scenario.

Which approach is most reliable for 24/7 unattended operation? Wine as a systemd service with Xvfb. It has the fewest moving parts and recovers cleanly from crashes via systemd's Restart=on-failure directive. Docker is a close second if you already operate a container infrastructure.

Can I access GraphWeather's GUI remotely when running under Xvfb? Yes. Install a VNC server (e.g., x11vnc) and point it at the Xvfb display. You will be able to interact with GraphWeather's full interface from any VNC client. Alternatively, use xpra for a more responsive experience over high-latency connections.

Will future versions of GraphWeather support Linux natively? That is a question for the developer. The PHP web components already run natively on Linux. The C++ desktop application is the Windows-dependent piece. Based on the current architecture, a native Linux port would require significant effort, so Wine and Docker remain the practical path for the foreseeable future.