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