├── .pics └── vnc_container_view.jpg ├── LICENSE ├── .github └── workflows │ └── docker-publish.yml ├── startup.sh ├── Dockerfile └── README.md /.pics/vnc_container_view.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LabEG/centos-lxqt-vnc/HEAD/.pics/vnc_container_view.jpg -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Evgeniy Labutin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/docker-publish.yml: -------------------------------------------------------------------------------- 1 | name: Docker 2 | 3 | # This workflow uses actions that are not certified by GitHub. 4 | # They are provided by a third-party and are governed by 5 | # separate terms of service, privacy policy, and support 6 | # documentation. 7 | 8 | on: 9 | schedule: 10 | - cron: '19 17 * * *' 11 | push: 12 | branches: [ master ] 13 | workflow_dispatch: 14 | 15 | jobs: 16 | build: 17 | 18 | runs-on: ubuntu-latest 19 | permissions: 20 | contents: read 21 | packages: write 22 | 23 | steps: 24 | - name: Checkout repository 25 | uses: actions/checkout@v4 26 | 27 | - name: Set up QEMU 28 | uses: docker/setup-qemu-action@v3 29 | 30 | - name: Set up Docker Buildx 31 | uses: docker/setup-buildx-action@v3 32 | 33 | - name: Log into registry docker.io 34 | uses: docker/login-action@v3 35 | with: 36 | registry: docker.io 37 | username: ${{ secrets.DOCKERHUB_USER }} 38 | password: ${{ secrets.DOCKERHUB_PASSWORD }} 39 | 40 | - name: Build and push Docker image 41 | uses: docker/build-push-action@v6 42 | with: 43 | push: true 44 | tags: labeg/centos-lxqt-vnc:latest, labeg/centos-lxqt-vnc:43, labeg/centos-lxqt-vnc:43.0 45 | platforms: linux/amd64, linux/arm64/v8 46 | cache-from: type=registry,ref=labeg/centos-lxqt-vnc:latest 47 | cache-to: type=inline 48 | -------------------------------------------------------------------------------- /startup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/expec 2 | 3 | # set screen resolution from environment variable 'resolution' or default 1820x960 4 | set SCREEN_RESOLUTION 1920x1080 5 | catch {set SCREEN_RESOLUTION $env(resolution)} 6 | 7 | set PASSWORD $env(password) 8 | 9 | set USER_PASSWORD $PASSWORD 10 | catch {set USER_PASSWORD $env(user_password)} 11 | 12 | set ROOT_PASSWORD $USER_PASSWORD 13 | catch {set ROOT_PASSWORD $env(root_password)} 14 | 15 | set HOME $env(HOME) 16 | 17 | # unsets by security reason, user can write env in demonstration time 18 | system "unset password" 19 | system "unset user_password" 20 | system "unset root_password" 21 | 22 | system "rm -fr /tmp/.X11-unix/*; rm -fr /tmp/.X1-lock; rm -fr /home/headless/.Xauthority; rm -fr /home/headless/.vnc/*.log; rm -fr /home/headless/.vnc/*.pid" 23 | 24 | if { ! [file exists $HOME/.issetpassword] } { 25 | # change root user password 26 | spawn sudo passwd root 27 | expect "\\\[sudo\\\] password for headless:" 28 | send "centos\r" 29 | expect "New password:" 30 | send "$ROOT_PASSWORD\r" 31 | expect "Retype new password:" 32 | send "$ROOT_PASSWORD\r" 33 | expect eof 34 | 35 | # change headless user password 36 | spawn passwd 37 | expect "Current password:" 38 | send "centos\r" 39 | expect "New password:" 40 | send "$USER_PASSWORD\r" 41 | expect "Retype new password:" 42 | send "$USER_PASSWORD\r" 43 | expect eof 44 | 45 | system "echo 'true' > $HOME/.issetpassword" 46 | 47 | # launch vnc 48 | spawn /usr/bin/vncserver :1 -fg -geometry $SCREEN_RESOLUTION 49 | expect "Password:" 50 | send "$PASSWORD\r" 51 | expect "Verify:" 52 | send "$PASSWORD\r" 53 | expect "Would you like to enter a view-only password (y/n)?" 54 | send "n\r" 55 | } else { 56 | spawn /usr/bin/vncserver :1 -fg -geometry $SCREEN_RESOLUTION 57 | } 58 | 59 | set timeout -1 60 | expect eof 61 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | 2 | FROM fedora:43 3 | 4 | 5 | LABEL maintainer="labeg@mail.ru" \ 6 | io.k8s.description="Headless VNC Container with LXQt Desktop manager" \ 7 | io.k8s.display-name="Headless VNC Container based on Centos" \ 8 | io.openshift.expose-services="5901:xvnc" \ 9 | io.openshift.tags="vnc, centos, lxqt" \ 10 | io.openshift.non-scalable=true 11 | 12 | 13 | ENV HOME=/home/headless 14 | 15 | 16 | RUN dnf install -y \ 17 | tigervnc-server \ 18 | openbox obconf-qt \ 19 | lxqt-about lxqt-config lxqt-globalkeys lxqt-notificationd \ 20 | lxqt-openssh-askpass lxqt-panel lxqt-policykit lxqt-qtplugin lxqt-runner \ 21 | lxqt-session pcmanfm-qt lxqt-archiver lxqt-themes lxqt-themes-fedora \ 22 | dejavu-sans-mono-fonts \ 23 | xterm nano htop expect sudo \ 24 | passwd cracklib-dicts binutils wget \ 25 | && \ 26 | dnf clean all \ 27 | && \ 28 | rm -rf /var/cache/dnf/* 29 | # 202MB -> 648MB 30 | 31 | 32 | RUN /bin/dbus-uuidgen --ensure && \ 33 | useradd headless && \ 34 | echo "centos" | passwd --stdin root && \ 35 | echo "centos" | passwd --stdin headless && \ 36 | usermod -aG wheel headless 37 | 38 | 39 | COPY ./startup.sh ${HOME} 40 | RUN mkdir -p ${HOME}/.vnc \ 41 | && \ 42 | echo '#!/bin/sh' > ${HOME}/.vnc/xstartup && \ 43 | echo 'exec startlxqt' >> ${HOME}/.vnc/xstartup && \ 44 | chmod 775 ${HOME}/.vnc/xstartup \ 45 | && \ 46 | chown headless:headless -R ${HOME} 47 | 48 | 49 | WORKDIR ${HOME} 50 | USER headless 51 | 52 | 53 | # apply plazma theme, wallpaper, qterimal and pcman to quicklaunch 54 | RUN mkdir -p ${HOME}/.config/lxqt && \ 55 | echo '[General]' >> ${HOME}/.config/lxqt/lxqt.conf && \ 56 | echo 'theme=KDE-Plasma' >> ${HOME}/.config/lxqt/lxqt.conf \ 57 | && \ 58 | echo 'Xcursor.theme: breeze_cursors' >> ${HOME}/.Xdefaults \ 59 | && \ 60 | mkdir -p ${HOME}/.config/pcmanfm-qt/lxqt && \ 61 | echo '[Desktop]' >> ${HOME}/.config/pcmanfm-qt/lxqt/settings.conf && \ 62 | echo 'Wallpaper=/usr/share/lxqt/wallpapers/kde-plasma.png' >> ${HOME}/.config/pcmanfm-qt/lxqt/settings.conf && \ 63 | echo 'WallpaperMode=stretch' >> ${HOME}/.config/pcmanfm-qt/lxqt/settings.conf \ 64 | && \ 65 | mkdir -p ${HOME}/.config/lxqt/ && \ 66 | echo '[quicklaunch]' >> ${HOME}/.config/lxqt/panel.conf && \ 67 | echo 'apps\1\desktop=/usr/share/applications/qterminal.desktop' >> ${HOME}/.config/lxqt/panel.conf && \ 68 | echo 'apps\2\desktop=/usr/share/applications/pcmanfm-qt.desktop' >> ${HOME}/.config/lxqt/panel.conf && \ 69 | echo 'apps\size=3' >> ${HOME}/.config/lxqt/panel.conf 70 | 71 | 72 | ENTRYPOINT ["expect", "./startup.sh"] 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LXQt Desktop Environment with VNC Access 2 | 3 | [![Docker Image](https://img.shields.io/badge/docker-labeg%2Fcentos--lxqt--vnc-blue)](https://hub.docker.com/r/labeg/centos-lxqt-vnc) 4 | 5 | ## Overview 6 | 7 | > **Note:** This project has transitioned from CentOS to Fedora following the [CentOS Stream announcement](https://blog.centos.org/2020/12/future-is-centos-stream/). 8 | 9 | A lightweight Docker image providing a complete desktop environment accessible via VNC. Built on Fedora minimal with LXQt desktop environment, OpenBox window manager, and TigerVNC Server. 10 | 11 | **Key Features:** 12 | 13 | - Minimal footprint with essential desktop components 14 | - Multi-architecture support (amd64, arm64) 15 | - Automated daily builds for latest security updates 16 | - Customizable display resolution 17 | - Easy VNC access configuration 18 | 19 | ![LXQt Desktop via VNC](https://raw.githubusercontent.com/LabEG/centos-lxqt-vnc/master/.pics/vnc_container_view.jpg) 20 | 21 | ## Quick Start 22 | 23 | ### Prerequisites 24 | 25 | - Docker installed on your system 26 | - VNC client (TigerVNC, TightVNC, RealVNC, or any compatible viewer) 27 | 28 | ### Try It Out 29 | 30 | For a quick test run: 31 | 32 | ```bash 33 | docker run -it --rm -e password='YOUR_VNC_PASSWORD' -p 5901:5901 labeg/centos-lxqt-vnc 34 | ``` 35 | 36 | Connect to `localhost:5901` using your VNC client with the password you specified. 37 | 38 | ### Production Deployment 39 | 40 | For persistent use with automatic restart: 41 | 42 | ```bash 43 | docker run -d \ 44 | --name lxqt-vnc \ 45 | --restart always \ 46 | -e password='YOUR_VNC_PASSWORD' \ 47 | -p 5901:5901 \ 48 | labeg/centos-lxqt-vnc 49 | ``` 50 | 51 | ## Configuration 52 | 53 | ### Environment Variables 54 | 55 | | Variable | Required | Default | Description | 56 | |----------|----------|---------|-------------| 57 | | `password` | **Yes** | - | VNC connection password | 58 | | `user_password` | No | `password` value | Password for the `headless` user | 59 | | `root_password` | No | `user_password` value | Password for the `root` user | 60 | | `resolution` | No | `1920x1080` | Virtual screen resolution | 61 | 62 | ### Docker Options 63 | 64 | | Option | Description | 65 | |--------|-------------| 66 | | `--shm-size='64m'` | Increase shared memory size if Firefox or other browsers crash | 67 | | `-p 5901:5901` | Map VNC port (change host port as needed) | 68 | | `--restart always` | Automatically restart container on system reboot | 69 | 70 | ### Example with Custom Configuration 71 | 72 | ```bash 73 | docker run -d \ 74 | --name lxqt-vnc \ 75 | --restart always \ 76 | --shm-size='128m' \ 77 | -e password='SecureVNCPassword' \ 78 | -e user_password='UserPassword123' \ 79 | -e resolution='2560x1440' \ 80 | -p 5901:5901 \ 81 | labeg/centos-lxqt-vnc 82 | ``` 83 | 84 | ## Customization 85 | 86 | ### Changing LXQt Theme 87 | 88 | 1. Open the application menu 89 | 2. Navigate to **Preferences** → **Appearance** → **LXQt Theme** 90 | 3. Select your preferred theme (e.g., Kde-Plasma) 91 | 92 | ### Changing OpenBox Window Manager Theme 93 | 94 | 1. Open the application menu 95 | 2. Navigate to **Preferences** → **LXQt Settings** → **OpenBox Settings** 96 | 3. Select your preferred theme (e.g., Clearlooks) 97 | 98 | ## Supported Architectures 99 | 100 | This image supports multiple platforms: 101 | 102 | - `linux/amd64` - x86-64 architecture 103 | - `linux/arm64/v8` - ARM 64-bit architecture 104 | 105 | ## Building from Source 106 | 107 | Clone the repository and build the image locally: 108 | 109 | ```bash 110 | git clone https://github.com/LabEG/centos-lxqt-vnc.git 111 | cd centos-lxqt-vnc 112 | docker build -t labeg/centos-lxqt-vnc . 113 | ``` 114 | 115 | ## Security Considerations 116 | 117 | - Always use strong passwords for VNC and user accounts 118 | - Consider using SSH tunneling for VNC connections over untrusted networks 119 | - Limit port exposure using firewall rules when deploying in production 120 | - Keep the image updated by pulling the latest version regularly 121 | 122 | ## Contributing 123 | 124 | Contributions are welcome! Please feel free to submit issues or pull requests on [GitHub](https://github.com/LabEG/centos-lxqt-vnc). 125 | 126 | ## License 127 | 128 | See the [LICENSE](LICENSE) file for details. 129 | --------------------------------------------------------------------------------