├── .gitignore ├── CONTRIBUTORS.md ├── LICENSE ├── extra_script_example.sh ├── CONTRIBUTING.md ├── lib └── common.sh ├── CODE_OF_CONDUCT.md ├── README.md └── run_wine_container /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | /extra/ 3 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | # Contributors 2 | 3 | **Tony Walker** https://github.com/tonywalker1 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Tony Walker 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 | -------------------------------------------------------------------------------- /extra_script_example.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # 3 | # MIT License 4 | # 5 | # Copyright (c) 2021 Tony Walker 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # 25 | 26 | # 27 | # The working container is passed as the first argument (i.e., $1) 28 | # 29 | WORKING_NAME="$1" 30 | 31 | 32 | echo "***" 33 | echo "*** Hello $WORKING_NAME!" 34 | echo "***" 35 | 36 | # some example commands... 37 | # buildah info 38 | # buildah run "$WORKING_NAME" -- dnf install -y ... 39 | 40 | echo "***" 41 | echo "*** Custom configuration done." 42 | echo "***" 43 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to wine-container 2 | 3 | Thank you for your interest in contributing to wine-container! This project welcomes contributions from everyone. 4 | 5 | ## How to Contribute 6 | 7 | ### Reporting Issues 8 | 9 | - Search existing issues first to avoid duplicates 10 | - Use a clear, descriptive title 11 | - Include your OS, Podman/Buildah versions, and Wine source used 12 | - Provide steps to reproduce the problem 13 | - Include any relevant error messages or logs 14 | 15 | ### Suggesting Enhancements 16 | 17 | - Check if the enhancement has already been suggested 18 | - Explain why this enhancement would be useful 19 | - Provide specific examples of how it would work 20 | 21 | ### Code Contributions 22 | 23 | 1. **Fork the repository** and create your branch from `main` 24 | 2. **Make your changes** following these guidelines: 25 | - Keep changes focused and atomic 26 | - Follow the existing code style 27 | - Test your changes with different Wine sources (debian, winehq, crossover) 28 | - Update documentation if needed 29 | 3. **Add yourself to CONTRIBUTORS.md** as part of your pull request 30 | 4. **Submit a pull request** with: 31 | - Clear description of what you changed and why 32 | - Reference any related issues 33 | - Test results on your system 34 | 35 | ### Development Setup 36 | 37 | ```bash 38 | git clone https://github.com/tonywalker1/wine-container.git 39 | cd wine-container 40 | 41 | # Test the build process 42 | ./build_wine_container --help 43 | ./run_wine_container --help 44 | 45 | # Make your changes and test 46 | ./build_wine_container -d TestVolume -n TestContainer 47 | ./run_wine_container -d TestVolume -n TestContainer -r "winecfg" 48 | ``` -------------------------------------------------------------------------------- /lib/common.sh: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2021-2025 Tony Walker 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | # 24 | 25 | # Global defaults 26 | BASE_IMAGE="docker.io/library/debian" 27 | DEBIAN_VERSION="latest" 28 | WINE_SOURCE="debian" 29 | IMAGE_NAME="wine_container" 30 | HOME_VOLUME="wine_volume" 31 | COMMAND_LINE="/bin/bash" 32 | 33 | display_help_footer() { 34 | echo "" 35 | echo "For more information, see: https://github.com/user/wine-container" 36 | } 37 | 38 | set_volume_permissions() { 39 | local volume_name="$1" 40 | local volume_path 41 | volume_path=$(podman volume inspect "$volume_name" --format '{{.Mountpoint}}' 2>/dev/null) 42 | if [ -n "$volume_path" ] && [ -d "$volume_path" ]; then 43 | if ! chmod u+rwx "$volume_path" 2>/dev/null; then 44 | echo "Warning: Failed to set permissions on $volume_path (this may be expected on some systems)" >&2 45 | fi 46 | else 47 | echo "Warning: Could not determine or access volume path for $volume_name" >&2 48 | fi 49 | } 50 | 51 | ensure_volume_exists() { 52 | local volume_name="$1" 53 | if ! podman volume exists "$volume_name" 2>/dev/null; then 54 | echo "* Creating volume $volume_name..." 55 | podman volume create "$volume_name" || { 56 | echo "Error: Failed to create volume $volume_name" >&2 57 | return 1 58 | } 59 | set_volume_permissions "$volume_name" 60 | fi 61 | } 62 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We pledge to make our community welcoming, safe, and equitable for all. 6 | 7 | We are committed to fostering an environment where everyone feels valued, respected, and able to participate fully. This 8 | includes, but is not limited to, creating a harassment-free experience for everyone, regardless of age, body size, 9 | visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, 10 | education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and 11 | orientation. 12 | 13 | ## Our Standards 14 | 15 | Examples of behavior that contributes to a positive environment for our 16 | community include: 17 | 18 | * Demonstrating empathy and kindness toward other people 19 | * Being respectful of differing opinions, viewpoints, and experiences 20 | * Giving and gracefully accepting constructive feedback 21 | * Accepting responsibility and apologizing to those affected by our mistakes, 22 | and learning from the experience 23 | * Focusing on what is best not just for us as individuals, but for the 24 | overall community 25 | 26 | Examples of unacceptable behavior include: 27 | 28 | * The use of sexualized language or imagery, and sexual attention or 29 | advances of any kind 30 | * Trolling, insulting, or derogatory comments, and personal or political attacks 31 | * Public or private harassment 32 | * Publishing others' private information, such as a physical or email 33 | address, without their explicit permission 34 | * Other conduct which could reasonably be considered inappropriate in a 35 | professional setting 36 | 37 | ## Enforcement Responsibilities 38 | 39 | Community leaders are responsible for clarifying and enforcing our standards of 40 | acceptable behavior and will take appropriate and fair corrective action in 41 | response to any behavior that they deem inappropriate, threatening, offensive, 42 | or harmful. 43 | 44 | Community leaders have the right and responsibility to remove, edit, or reject 45 | comments, commits, code, wiki edits, issues, and other contributions that are 46 | not aligned to this Code of Conduct, and will communicate reasons for moderation 47 | decisions when appropriate. 48 | 49 | ## Scope 50 | 51 | This Code of Conduct applies within all community spaces, and also applies when 52 | an individual is officially representing the community in public spaces. 53 | Examples of representing our community include using an official e-mail address, 54 | posting via an official social media account, or acting as an appointed 55 | representative at an online or offline event. 56 | 57 | ## Enforcement 58 | 59 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 60 | reported to the community leaders responsible for enforcement at 61 | tony.walker.iu@gmail.com. 62 | All complaints will be reviewed and investigated promptly and fairly. 63 | 64 | All community leaders are obligated to respect the privacy and security of the 65 | reporter of any incident. 66 | 67 | ## Enforcement Guidelines 68 | 69 | Community leaders will follow these Community Impact Guidelines in determining 70 | the consequences for any action they deem in violation of this Code of Conduct: 71 | 72 | ### 1. Correction 73 | 74 | **Community Impact**: Use of inappropriate language or other behavior deemed 75 | unprofessional or unwelcome in the community. 76 | 77 | **Consequence**: A private, written warning from community leaders, providing 78 | clarity around the nature of the violation and an explanation of why the 79 | behavior was inappropriate. A public apology may be requested. 80 | 81 | ### 2. Warning 82 | 83 | **Community Impact**: A violation through a single incident or series 84 | of actions. 85 | 86 | **Consequence**: A warning with consequences for continued behavior. No 87 | interaction with the people involved, including unsolicited interaction with 88 | those enforcing the Code of Conduct, for a specified period of time. This 89 | includes avoiding interactions in community spaces as well as external channels 90 | like social media. Violating these terms may lead to a temporary or 91 | permanent ban. 92 | 93 | ### 3. Temporary Ban 94 | 95 | **Community Impact**: A serious violation of community standards, including 96 | sustained inappropriate behavior. 97 | 98 | **Consequence**: A temporary ban from any sort of interaction or public 99 | communication with the community for a specified period of time. No public or 100 | private interaction with the people involved, including unsolicited interaction 101 | with those enforcing the Code of Conduct, is allowed during this period. 102 | Violating these terms may lead to a permanent ban. 103 | 104 | ### 4. Permanent Ban 105 | 106 | **Community Impact**: Demonstrating a pattern of violation of community 107 | standards, including sustained inappropriate behavior, harassment of an 108 | individual, or aggression toward or disparagement of classes of individuals. 109 | 110 | **Consequence**: A permanent ban from any sort of public interaction within 111 | the community. 112 | 113 | ## Attribution 114 | 115 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 3.0, available 116 | at https://www.contributor-covenant.org/version/3/0/code_of_conduct/. 117 | 118 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 119 | enforcement ladder](https://github.com/mozilla/diversity). 120 | 121 | [homepage]: https://www.contributor-covenant.org 122 | 123 | For answers to common questions about this code of conduct, see the FAQ at 124 | https://www.contributor-covenant.org/faq. Translations are available at 125 | https://www.contributor-covenant.org/translations. 126 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wine-container 2 | 3 | OCI Container for Wine (or Codeweaver's Crossover) using Buildah and Podman. 4 | 5 | Many old but useful Windows apps are probably poorly maintained or patched. 6 | Others that, while newer, are potentially buggy or have security issues. One 7 | solution is to run those apps in a container. That is the point of this project. 8 | 9 | ## 🚨 Breaking Changes in v2.0 10 | 11 | > **Fedora-based images are no longer supported. If you need that, please use 12 | the [v1 branch](https://github.com/tonywalker1/wine-container/tree/v1).** 13 | 14 | This version introduces significant changes to simplify maintenance and reduce complexity: 15 | 16 | ### Key Changes 17 | 18 | - **Debian-only base images** (Fedora support removed) 19 | - **Wine source selection** instead of base OS selection (e.g., Debian vs WineHQ) 20 | - **Smaller container images** (~1.2GB vs ~4.2GB for Fedora) 21 | - **Simplified command-line interface** 22 | 23 | ### Rationale 24 | 25 | - **Image size**: Debian images are ~70% smaller than Fedora equivalents 26 | - **Consistency**: Single base OS reduces complexity and maintenance burden 27 | - **Wine versions**: WineHQ repository provides the latest Wine versions on a stable Debian base 28 | - **Performance**: Smaller images mean faster downloads and less storage usage 29 | 30 | ## Goals 31 | 32 | * Use Podman (rootless) to limit breakout attacks. 33 | * All data is written to a volume and, except the sockets for graphics and 34 | audio, the containers have no access to the underlying filesystem. 35 | * Allow Windows apps to be orchestrated as a part of a collection of containers. 36 | * Support Codeweaver's Crossover in addition to Wine. 37 | 38 | ## Wine Source Options 39 | 40 | Choose your Wine installation source based on your needs: 41 | 42 | | Source | Description | Use Case | 43 | |-------------|------------------------------------|--------------------------------------------------| 44 | | `debian` | Debian's packaged Wine (default) | Stable, well-tested, older versions | 45 | | `winehq` | Latest Wine from WineHQ repository | Newest features, latest compatibility | 46 | | `crossover` | CodeWeavers Crossover (commercial) | Professional support, specific app compatibility | 47 | 48 | ## Documentation and Usage 49 | 50 | Building and running are facilitated by two scripts: *build_wine_container* 51 | and *run_wine_container*. Each script offers help in the usual way, for example: 52 | 53 | ```shell 54 | build_wine_container --help 55 | ``` 56 | 57 | ### Basic Usage 58 | 59 | ```shell 60 | # Default: Debian Wine on latest Debian 61 | build_wine_container -d CrappyHomeVolume -f -n CrappyWindowsApp 62 | 63 | # Latest Wine version 64 | build_wine_container --wine-source winehq -d CrappyHomeVolume -f -n CrappyWindowsApp 65 | 66 | # Specific Debian version with WineHQ 67 | build_wine_container --wine-source winehq --debian-version bookworm -d CrappyHomeVolume -n CrappyWindowsApp 68 | 69 | # Crossover (requires DEB package) 70 | build_wine_container --wine-source crossover --crossover-pkg /path/to/crossover.deb -d CrappyHomeVolume -n CrappyWindowsApp 71 | ``` 72 | 73 | Then run your application: 74 | 75 | ```shell 76 | run_wine_container -d CrappyHomeVolume -n CrappyWindowsApp -r "/path/to/crappy_app.exe" 77 | ``` 78 | 79 | The first line above will create a volume named *CrappyHomeVolume* and an OCI 80 | container named *CrappyWindowsApp*. The second line will run the app in the new 81 | container. 82 | 83 | ### Debian Version Selection 84 | 85 | You can specify which Debian version to use as the base: 86 | 87 | ```shell 88 | # Use latest Debian (default) 89 | build_wine_container --debian-version latest 90 | 91 | # Use specific stable release 92 | build_wine_container --debian-version bookworm # Debian 12 93 | build_wine_container --debian-version bullseye # Debian 11 94 | build_wine_container --debian-version buster # Debian 10 95 | ``` 96 | 97 | ## Migration Guide 98 | 99 | ### From v1.x Fedora Usage 100 | 101 | ```shell 102 | # OLD (v1.x): Fedora with newer Wine 103 | build_wine_container --base fedora 104 | 105 | # NEW (v2.x): Debian with WineHQ (equivalent functionality, smaller image) 106 | build_wine_container --wine-source winehq --debian-version latest 107 | ``` 108 | 109 | ### From v1.x Debian Usage 110 | 111 | ```shell 112 | # OLD (v1.x): Debian base 113 | build_wine_container --base debian 114 | 115 | # NEW (v2.x): Explicit Debian Wine (same functionality) 116 | build_wine_container --wine-source debian --debian-version latest 117 | ``` 118 | 119 | ### From v1.x Crossover Usage 120 | 121 | ```shell 122 | # OLD (v1.x): Crossover 123 | build_wine_container --crossover /path/to/crossover.deb 124 | 125 | # NEW (v2.x): Crossover as wine source 126 | build_wine_container --wine-source crossover --crossover-pkg /path/to/crossover.deb 127 | ``` 128 | 129 | ## Deprecated Options 130 | 131 | The following options are deprecated and have been removed: 132 | 133 | | Deprecated Option | Replacement | Notes | 134 | |-----------------------|------------------------------------------------|--------------------------------------------| 135 | | `--base fedora` | `--wine-source winehq` | Provides same Wine versions, smaller image | 136 | | `--base debian` | `--wine-source debian --debian-version latest` | More explicit | 137 | | `--crossover` | `--wine-source crossover --crossover-pkg` | Unified interface | 138 | | `--base ` | Not supported | Use `--debian-version` for version control | 139 | 140 | **Note**: Only Crossover DEB packages are supported (RPM support removed with Fedora). 141 | 142 | ## Volume Storage 143 | 144 | The volume is stored on the container host 145 | in ```~/.local/share/containers/storage/volumes/$HOME_VOLUME/_data```. The build 146 | script automatically makes this directory writable from the user that launched 147 | Podman, so you can copy/rename/delete files from the host. 148 | 149 | ## Platforms 150 | 151 | This project should work correctly on any recent Linux distribution. I currently 152 | use Fedora (Silverblue and Kinoite), so this is well-tested. 153 | 154 | ## Dependencies 155 | 156 | * [Buildah](https://buildah.io/) 157 | * [Podman](https://podman.io/) 158 | 159 | ## Contributing 160 | 161 | I would love suggestions, fixes, documentation, examples, and other 162 | contributions. See [CONTRIBUTING](CONTRIBUTING.md) 163 | and [CODE_OF_CONDUCT](CODE_OF_CONDUCT.md) 164 | for details. 165 | 166 | See [CONTRIBUTORS](CONTRIBUTORS.md) for a list of contributors. 167 | 168 | ## Legacy Version 169 | 170 | **Need Fedora support?** Use 171 | the [v1 branch](https://github.com/tonywalker1/wine-container/tree/v1) which maintains the original functionality: 172 | 173 | ```shell 174 | git clone -b v1 https://github.com/tonywalker1/wine-container.git 175 | ``` 176 | 177 | The v1 branch will receive critical bug fixes but no new features. 178 | -------------------------------------------------------------------------------- /run_wine_container: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | # 3 | # MIT License 4 | # 5 | # Copyright (c) 2021-2025 Tony Walker 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # 25 | 26 | set -euo pipefail 27 | 28 | # 29 | # Load globals and shared functions 30 | # 31 | LIB_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib/common.sh" 32 | # shellcheck disable=SC1090 33 | source "$LIB_PATH" || { 34 | echo "Error: Failed to load $LIB_PATH" >&2 35 | exit 1 36 | } 37 | BASE_IMAGE="${BASE_IMAGE}:${DEBIAN_VERSION}" 38 | 39 | # 40 | # Helper functions 41 | # 42 | display_help() { 43 | echo "Run a Wine or Codeweaver Crossover OCI container." 44 | echo "" 45 | echo "Usage: run_wine_container [options]" 46 | echo "" 47 | echo "Options:" 48 | echo " -d, --dir Volume to contain the home directory. [default: $HOME_VOLUME]" 49 | echo " -h, --help Display this message." 50 | echo " -n, --name Image name. [default: $IMAGE_NAME]" 51 | echo " -r, --run Command to run. [default: $COMMAND_LINE]" 52 | display_help_footer 53 | } 54 | 55 | check_dependencies() { 56 | local missing_deps=() 57 | command -v podman >/dev/null 2>&1 || missing_deps+=("podman") 58 | command -v id >/dev/null 2>&1 || missing_deps+=("id") 59 | 60 | if [ ${#missing_deps[@]} -gt 0 ]; then 61 | echo "Error: dependencies missing: ${missing_deps[*]}" >&2 62 | exit 1 63 | fi 64 | } 65 | 66 | # 67 | # Check dependencies and handle the command line 68 | # 69 | check_dependencies 70 | while [ $# -gt 0 ]; do 71 | case $1 in 72 | -d | --dir) 73 | if [ -z "${2:-}" ] || [[ "${2:-}" =~ ^- ]]; then 74 | echo "Error: --dir requires a volume name argument" >&2 75 | exit 1 76 | fi 77 | HOME_VOLUME="$2" 78 | shift 2 79 | ;; 80 | -h | --help) 81 | display_help 82 | exit 0 83 | ;; 84 | -n | --name) 85 | if [ -z "${2:-}" ] || [[ "${2:-}" =~ ^- ]]; then 86 | echo "Error: --name requires an image name argument" >&2 87 | exit 1 88 | fi 89 | IMAGE_NAME="$2" 90 | shift 2 91 | ;; 92 | -r | --run) 93 | if [ -z "${2:-}" ] || [[ "${2:-}" =~ ^- ]]; then 94 | echo "Error: --run requires a command argument" >&2 95 | exit 1 96 | fi 97 | COMMAND_LINE="$2" 98 | shift 2 99 | ;; 100 | *) 101 | echo "Warning: Unknown argument '$1' ignored" >&2 102 | shift 103 | ;; 104 | esac 105 | done 106 | 107 | if ! podman image exists "$IMAGE_NAME"; then 108 | echo "Error: Container image '$IMAGE_NAME' not found." >&2 109 | echo "Please build the image first using the build_wine_container script." >&2 110 | exit 1 111 | fi 112 | 113 | # 114 | # Setup the environment 115 | # 116 | ensure_volume_exists "$HOME_VOLUME" 117 | 118 | LOCAL_UID=$(id -u) 119 | DISPLAY_MOUNTS="" 120 | ENV_VARS="" 121 | 122 | # Wayland or X11 123 | if [ -n "${WAYLAND_DISPLAY:-}" ] && [ -S "/run/user/$LOCAL_UID/${WAYLAND_DISPLAY:-}" ]; then 124 | echo "Using Wayland display server" 125 | DISPLAY_MOUNTS="$DISPLAY_MOUNTS --volume /run/user/$LOCAL_UID/$WAYLAND_DISPLAY:/run/user/$LOCAL_UID/$WAYLAND_DISPLAY" 126 | ENV_VARS="$ENV_VARS --env WAYLAND_DISPLAY=$WAYLAND_DISPLAY" 127 | ENV_VARS="$ENV_VARS --env XDG_SESSION_TYPE=wayland" 128 | ENV_VARS="$ENV_VARS --env QT_QPA_PLATFORM=wayland" 129 | ENV_VARS="$ENV_VARS --env GDK_BACKEND=wayland" 130 | # For X11 compatibility 131 | if [ -n "${DISPLAY:-}" ]; then 132 | ENV_VARS="$ENV_VARS --env DISPLAY=$DISPLAY" 133 | DISPLAY_MOUNTS="$DISPLAY_MOUNTS --volume /tmp/.X11-unix:/tmp/.X11-unix" 134 | fi 135 | elif [ -n "${DISPLAY:-}" ] && [ -d "/tmp/.X11-unix" ]; then 136 | echo "Using X11 display server" 137 | DISPLAY_MOUNTS="$DISPLAY_MOUNTS --volume /tmp/.X11-unix:/tmp/.X11-unix" 138 | ENV_VARS="$ENV_VARS --env DISPLAY=$DISPLAY" 139 | ENV_VARS="$ENV_VARS --env XDG_SESSION_TYPE=x11" 140 | else 141 | echo "Warning: No display server detected" 142 | fi 143 | 144 | # Pipewire or PulseAudio 145 | AUDIO_MOUNTS="" 146 | if [ -S "/run/user/$LOCAL_UID/pipewire-0" ]; then 147 | echo "Using PipeWire audio" 148 | AUDIO_MOUNTS="$AUDIO_MOUNTS --volume /run/user/$LOCAL_UID/pipewire-0:/run/user/$LOCAL_UID/pipewire-0" 149 | ENV_VARS="$ENV_VARS --env PIPEWIRE_RUNTIME_DIR=/run/user/$LOCAL_UID" 150 | elif [ -S "/run/user/$LOCAL_UID/pulse/native" ]; then 151 | echo "Using PulseAudio" 152 | AUDIO_MOUNTS="$AUDIO_MOUNTS --volume /run/user/$LOCAL_UID/pulse:/run/user/$LOCAL_UID/pulse" 153 | ENV_VARS="$ENV_VARS --env PULSE_RUNTIME_PATH=/run/user/$LOCAL_UID/pulse" 154 | ENV_VARS="$ENV_VARS --env PULSE_SERVER=unix:/run/user/$LOCAL_UID/pulse/native" 155 | else 156 | echo "Warning: No audio system detected" 157 | fi 158 | 159 | # DBus 160 | DBUS_MOUNTS="" 161 | if [ -S "/run/user/$LOCAL_UID/bus" ]; then 162 | DBUS_MOUNTS="--volume /run/user/$LOCAL_UID/bus:/run/user/$LOCAL_UID/bus" 163 | ENV_VARS="$ENV_VARS --env DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$LOCAL_UID/bus" 164 | fi 165 | 166 | # SELinux 167 | SECURITY_OPTS="" 168 | if command -v getenforce >/dev/null 2>&1 && [ "$(getenforce 2>/dev/null)" = 'Enforcing' ]; then 169 | echo "SELinux enforcing detected" 170 | SECURITY_OPTS="--security-opt label=type:container_runtime_t" 171 | elif command -v getenforce >/dev/null 2>&1 && [ "$(getenforce 2>/dev/null)" = 'Permissive' ]; then 172 | echo "SELinux permissive mode detected" 173 | SECURITY_OPTS="--security-opt label=type:container_runtime_t" 174 | else 175 | echo "SELinux not enforcing or not present" 176 | fi 177 | 178 | # Extra GUI options 179 | GUI_OPTS="" 180 | if [ -n "$DISPLAY_MOUNTS" ] || [ -n "${WAYLAND_DISPLAY:-}" ]; then 181 | echo "GUI mode detected, adding graphics capabilities" 182 | GUI_OPTS="--cap-add SYS_PTRACE" 183 | 184 | if [ -d "/dev/dri" ]; then 185 | GUI_OPTS="$GUI_OPTS --device /dev/dri" 186 | fi 187 | 188 | GUI_OPTS="$GUI_OPTS --shm-size=1g" 189 | fi 190 | 191 | # 192 | # Run the container 193 | # 194 | echo "DEBUG: $DISPLAY_MOUNTS" 195 | echo "Starting container $IMAGE_NAME..." 196 | podman run \ 197 | --mount "type=volume,source=$HOME_VOLUME,target=/root" \ 198 | --volume /etc/localtime:/etc/localtime:ro \ 199 | $DISPLAY_MOUNTS \ 200 | $AUDIO_MOUNTS \ 201 | $DBUS_MOUNTS \ 202 | $ENV_VARS \ 203 | --env XDG_RUNTIME_DIR="/run/user/$LOCAL_UID" \ 204 | --env HOME="/root" \ 205 | $SECURITY_OPTS \ 206 | $GUI_OPTS \ 207 | --rm \ 208 | -ti \ 209 | "$IMAGE_NAME" \ 210 | "$COMMAND_LINE" 211 | 212 | echo "Container $IMAGE_NAME finished successfully." 213 | --------------------------------------------------------------------------------