How to Pass Environment Variables to start-stop-daemon for Wine Applications on Linux


2 views

When trying to daemonize a Windows application running under Wine on Linux, you might encounter issues with environment variables - particularly $DISPLAY for X11 applications. The standard approach of prefixing the command with variables (VAR=value start-stop-daemon) fails when using the -c user option because the environment gets reset.

The -c user switch in start-stop-daemon creates a clean environment for security reasons. This means:

  • Variables set before the command are ignored
  • User's .bashrc or .profile aren't sourced
  • System-wide environment files aren't read

Here are several approaches that actually work:

1. Using envfile with start-stop-daemon

Some versions support the --env-file option:

start-stop-daemon --start \
  --pidfile /var/run/wine-app.pid \
  -m -c myuser -g mygroup \
  --env-file /path/to/envfile \
  --exec /home/myuser/.wine/drive_c/Program\ Files/wine-app.exe

Create the envfile with your variables:

DISPLAY=:0
WINEPREFIX=/home/myuser/.wine

2. Wrapper Script Approach

Create a wrapper script that sets the environment:

#!/bin/bash
export DISPLAY=:0
export WINEPREFIX=/home/myuser/.wine
exec /home/myuser/.wine/drive_c/Program\ Files/wine-app.exe "$@"

Then point start-stop-daemon to the wrapper:

start-stop-daemon --start \
  --pidfile /var/run/wine-app.pid \
  -m -c myuser -g mygroup \
  --exec /path/to/wrapper-script.sh

3. Systemd Alternative (for modern systems)

If you're on a system with systemd, create a service file:

[Unit]
Description=Wine Application
After=network.target

[Service]
User=myuser
Group=mygroup
Environment="DISPLAY=:0"
Environment="WINEPREFIX=/home/myuser/.wine"
ExecStart=/home/myuser/.wine/drive_c/Program\ Files/wine-app.exe
Restart=on-failure

[Install]
WantedBy=multi-user.target
  • Ensure the X11 server is running before starting your Wine app
  • Check permissions on /var/run for PID file creation
  • Consider using xvfb-run for headless environments
  • Test environment variables with env in your wrapper script

If you're still having issues:

# Check what environment the process actually sees:
start-stop-daemon --start \
  --pidfile /tmp/debug.pid \
  -m -c myuser \
  --exec /usr/bin/env > /tmp/wine-env.log

# Check X11 access:
sudo -u myuser xhost

Remember that Wine applications often need additional environment variables like WINEDEBUG, WINEPREFIX, or WINEARCH set properly.


When trying to daemonize Windows applications running under Wine that require X11 display access, we often hit a wall with environment variable inheritance. The traditional approach of prefixing commands with variables like DISPLAY=:0 fails when combined with start-stop-daemon's user switching (-c option).

Many users first attempt to set DISPLAY in the target user's shell configuration files, but this fails because:

  • start-stop-daemon doesn't spawn a login shell
  • The daemon environment is sanitized for security
  • X11 session variables exist in a specific session context

Method 1: Using envfile (Recommended)

Create an environment file and source it before execution:

# /etc/default/wine-app
DISPLAY=:0
XAUTHORITY=/home/myuser/.Xauthority

# In init script
start-stop-daemon --start \
    --pidfile /var/run/wine-app.pid \
    -m -c myuser -g mygroup \
    --env-file /etc/default/wine-app \
    --exec /usr/bin/env -- \
    /home/myuser/.wine/drive_c/Program\ Files/wine-app.exe

Method 2: Wrapper Script Approach

Create a wrapper that sets the environment:

#!/bin/bash
# /usr/local/bin/wine-app-wrapper
export DISPLAY=:0
export XAUTHORITY=/home/myuser/.Xauthority
exec /home/myuser/.wine/drive_c/Program\ Files/wine-app.exe "$@"

# Then call the wrapper
start-stop-daemon --start \
    --pidfile /var/run/wine-app.pid \
    -m -c myuser -g mygroup \
    --exec /usr/local/bin/wine-app-wrapper

Method 3: Direct env Injection (For Modern Systems)

Newer start-stop-daemon versions support direct env setting:

start-stop-daemon --start \
    --pidfile /var/run/wine-app.pid \
    -m -c myuser -g mygroup \
    --env DISPLAY=:0 \
    --env XAUTHORITY=/home/myuser/.Xauthority \
    --exec /home/myuser/.wine/drive_c/Program\ Files/wine-app.exe
  • Always validate the Xauthority file permissions
  • Consider using xhost restrictions instead of :0
  • The wrapper script should be root-owned with 755 permissions

If you still experience issues:

  1. Verify the X11 socket exists: ls -l /tmp/.X11-unix/
  2. Check process environment: cat /proc/$(pidof wine-app.exe)/environ | tr '\\0' '\\n'
  3. Test without daemonization first: sudo -u myuser env DISPLAY=:0 wine-app.exe