This project sets up a multi-user, "Retro Unix" appliance on Ubuntu Server 24.04. It provides a classic Motif Window Manager (MWM) environment that is accessible via any modern web browser.
Key Features:
mwm (Motif Window Manager), classic X11 apps, and period-correct configuration.| Component | Technology | Role |
|---|---|---|
| OS | Ubuntu Server 24.04 | Base operating system (Headless). |
| Display Server | Xorg / X11 | The underlying graphical protocol (Wayland is not supported for MWM). |
| Window Manager | MWM (Motif) | Provides the window borders and "chiseled" look. |
| Session Manager | XDM | Handles graphical login and authentication. |
| Remote Display | TigerVNC + Xinetd | Spawns a virtual display for each incoming connection. |
| Web Gateway | noVNC | Bridges the VNC TCP traffic to WebSockets for browser access. |
This playbook automates the entire stack. It installs packages, configures the network sockets, and sets up the "Skeleton" directory so new users get a pre-configured Motif environment (custom menus, colors, and startup scripts).
Save as: setup_motif_novnc.yml
---
- name: Setup Multi-User Motif with noVNC on Ubuntu 24.04
hosts: all
become: yes
vars:
# Standard ports
vnc_port: 5900
novnc_port: 6080
# Paths (standard for Ubuntu 24.04)
novnc_web_dir: "/usr/share/novnc"
xvnc_binary: "/usr/bin/Xvnc"
tasks:
# =======================================================
# 1. INSTALLATION
# =======================================================
- name: Update apt cache
apt:
update_cache: yes
- name: Install Xorg, Motif, XDM, TigerVNC, and Fonts
apt:
name:
- xorg
- mwm
- xterm
- xdm
- tigervnc-standalone-server
- xfonts-base
- xfonts-100dpi
- xfonts-75dpi
- x11-apps # xclock, xeyes, xcalc
state: present
- name: Install noVNC and Websockify
apt:
name:
- novnc
- python3-websockify
- python3-numpy
state: present
# =======================================================
# 2. XDM CONFIGURATION (Enable Network Logins)
# =======================================================
- name: Enable XDMCP in xdm-config
lineinfile:
path: /etc/X11/xdm/xdm-config
regexp: 'DisplayManager.requestPort:\\s*0'
line: '! DisplayManager.requestPort: 0'
backrefs: yes
- name: Allow any host to connect in Xaccess
lineinfile:
path: /etc/X11/xdm/Xaccess
regexp: '^#\\*\\s+#any host'
line: '* #any host can get a login window'
- name: Ensure XDM service is restarted
systemd:
name: xdm
state: restarted
enabled: yes
# =======================================================
# 3. SYSTEMD SOCKETS (Dynamic VNC Generation)
# =======================================================
- name: Create XVNC systemd socket
copy:
dest: /etc/systemd/system/xvnc.socket
content: |
[Unit]
Description=XVNC Server Socket
[Socket]
ListenStream={{ vnc_port }}
Accept=yes
[Install]
WantedBy=sockets.target
- name: Create XVNC systemd service template
copy:
dest: /etc/systemd/system/[email protected]
content: |
[Unit]
Description=XVNC Per-Connection Daemon
Requires=xdm.service
After=syslog.target network.target xdm.service
[Service]
# -inetd: Talk over network; -query localhost: Ask XDM for login
ExecStart=-{{ xvnc_binary }} -inetd -query localhost -geometry 1280x960 -depth 24 -once -SecurityTypes=None
User=nobody
StandardInput=socket
StandardError=syslog
[Install]
WantedBy=multi-user.target
# =======================================================
# 4. NOVNC WEB BRIDGE
# =======================================================
- name: Create noVNC systemd service
copy:
dest: /etc/systemd/system/novnc.service
content: |
[Unit]
Description=noVNC Web Bridge
After=network.target
[Service]
Type=simple
User=nobody
ExecStart=/usr/bin/websockify --web={{ novnc_web_dir }} {{ novnc_port }} localhost:{{ vnc_port }}
Restart=on-failure
[Install]
WantedBy=multi-user.target
# =======================================================
# 5. USER SKELETON (Default Configs for New Users)
# =======================================================
- name: Create default .xsession script
copy:
dest: /etc/skel/.xsession
mode: '0755'
content: |
#!/bin/sh
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid "dark slate gray"
xterm -geometry 80x24+10+10 -ls -title "Welcome" &
exec mwm
- name: Link .xinitrc to .xsession
file:
src: .xsession
dest: /etc/skel/.xinitrc
state: link
force: yes
- name: Create Motif Styling (.Xresources)
copy:
dest: /etc/skel/.Xresources
content: |
Mwm*activeBackground: #5D7990
Mwm*activeForeground: white
Mwm*background: #C0C0C0
Mwm*foreground: black
xterm*background: black
xterm*foreground: white
xterm*faceName: Monospace
xterm*faceSize: 10
- name: Create Custom Root Menu (.mwmrc)
copy:
dest: /etc/skel/.mwmrc
content: |
Menu DefaultRootMenu
{
"Root Menu" f.title
"New Terminal" f.exec "xterm &"
"Applications" f.menu AppsMenu
"Shuffle Windows" f.circle_down
"Refresh Screen" f.refresh
no-label f.separator
"Restart MWM" f.restart
"Log Out" f.quit_mwm
}
Menu AppsMenu
{
"Applications" f.title
"Calculator" f.exec "xcalc &"
"Clock" f.exec "xclock &"
"Eyes" f.exec "xeyes &"
no-label f.separator
"Top (Process)" f.exec "xterm -T 'Top' -e top &"
"Text Editor" f.exec "xterm -T 'Nano' -e nano &"
}
Buttons DefaultButtonBindings
{
<Btn3Down> root f.menu DefaultRootMenu
}
Mwm*buttonBindings: DefaultButtonBindings
# =======================================================
# 6. START SERVICES
# =======================================================
- name: Reload Systemd and Start
systemd:
daemon_reload: yes
- name: Enable/Start XVNC Socket
systemd:
name: xvnc.socket
state: started
enabled: yes
- name: Enable/Start noVNC
systemd:
name: novnc
state: started
enabled: yes
On the server (requires Ansible):
sudo apt install ansible
ansible-playbook -i "localhost," -c local setup_motif_novnc.yml