From 1552e0c7574b82ecf519b10a79461da3121505db Mon Sep 17 00:00:00 2001 From: Stavros Date: Wed, 6 Mar 2024 18:29:51 +0200 Subject: [PATCH] feat: add windows app (#2710) --- apps/windows/config.json | 54 ++++++++++++++++++ apps/windows/docker-compose.yml | 49 ++++++++++++++++ apps/windows/metadata/description.md | 82 +++++++++++++++++++++++++++ apps/windows/metadata/logo.jpg | Bin 0 -> 17464 bytes 4 files changed, 185 insertions(+) create mode 100644 apps/windows/config.json create mode 100644 apps/windows/docker-compose.yml create mode 100644 apps/windows/metadata/description.md create mode 100644 apps/windows/metadata/logo.jpg diff --git a/apps/windows/config.json b/apps/windows/config.json new file mode 100644 index 00000000..7559d9c7 --- /dev/null +++ b/apps/windows/config.json @@ -0,0 +1,54 @@ +{ + "name": "Windows", + "available": true, + "port": 8006, + "exposable": true, + "id": "windows", + "description": "Run windows in docker...because why not?", + "tipi_version": 1, + "version": "2.04", + "categories": ["utilities"], + "short_desc": "Full windows vm in your browser", + "author": "dockurr", + "source": "https://github.com/dockur/windows/", + "form_fields": [ + { + "type": "number", + "label": "RAM", + "hint": "RAM to asign in the VM (in gigabytes)", + "default": 4, + "required": false, + "env_variable": "WINDOWS_RAM_GB" + + }, + { + "type": "number", + "label": "CPU Cores", + "hint": "CPU cores to asign in the VM", + "default": 4, + "required": false, + "env_variable": "WINDOWS_CPU_CORES" + + }, + { + "type": "number", + "label": "Disk Size", + "hint": "Disk size for the VM, it will be used dynamically (in gigabytes)", + "default": 16, + "required": false, + "env_variable": "WINDOWS_DISK_SIZE_GB" + + }, + { + "type": "text", + "label": "Windows Version", + "hint": "The windows version to use, see the description for available versions", + "default": "win11", + "required": false, + "env_variable": "WINDOWS_VERSION" + + } + ], + "supported_architectures": ["arm64", "amd64"] + } + \ No newline at end of file diff --git a/apps/windows/docker-compose.yml b/apps/windows/docker-compose.yml new file mode 100644 index 00000000..361077c4 --- /dev/null +++ b/apps/windows/docker-compose.yml @@ -0,0 +1,49 @@ +version: "3.9" +services: + windows: + container_name: windows + image: dockurr/windows:2.04 + restart: unless-stopped + devices: + - /dev/kvm + cap_add: + - NET_ADMIN + ports: + - ${APP_PORT}:8006 + - 3389:3389/tcp + - 3389:3389/udp + stop_grace_period: 2m + environment: + - RAM_SIZE=${WINDOWS_RAM_GB}G + - CPU_CORE=${WINDOWS_CPU_CORES} + - DISK_SIZE=${WINDOWS_DISK_SIZE_GB}G + - VERSION=${WINDOWS_VERSION} + volumes: + - ${APP_DATA_DIR}/data:/storage + networks: + - tipi_main_network + labels: + # Main + traefik.enable: true + traefik.http.middlewares.windows-web-redirect.redirectscheme.scheme: https + traefik.http.services.windows.loadbalancer.server.port: 8006 + # Web + traefik.http.routers.windows-insecure.rule: Host(`${APP_DOMAIN}`) + traefik.http.routers.windows-insecure.entrypoints: web + traefik.http.routers.windows-insecure.service: windows + traefik.http.routers.windows-insecure.middlewares: windows-web-redirect + # Websecure + traefik.http.routers.windows.rule: Host(`${APP_DOMAIN}`) + traefik.http.routers.windows.entrypoints: websecure + traefik.http.routers.windows.service: windows + traefik.http.routers.windows.tls.certresolver: myresolver + # Local domain + traefik.http.routers.windows-local-insecure.rule: Host(`windows.${LOCAL_DOMAIN}`) + traefik.http.routers.windows-local-insecure.entrypoints: web + traefik.http.routers.windows-local-insecure.service: windows + traefik.http.routers.windows-local-insecure.middlewares: windows-web-redirect + # Local domain secure + traefik.http.routers.windows-local.rule: Host(`windows.${LOCAL_DOMAIN}`) + traefik.http.routers.windows-local.entrypoints: websecure + traefik.http.routers.windows-local.service: windows + traefik.http.routers.windows-local.tls: true \ No newline at end of file diff --git a/apps/windows/metadata/description.md b/apps/windows/metadata/description.md new file mode 100644 index 00000000..149ac535 --- /dev/null +++ b/apps/windows/metadata/description.md @@ -0,0 +1,82 @@ +

Windows
+
+ +
+
+ +

+ +Windows in a Docker container. + +## Features + + - ISO downloader + - KVM acceleration + - Web-based viewer + +## FAQ + +* ### How do I use it? + + Very simple! These are the steps: + + - Start the container and connect to [port 8006](http://localhost:8006) using your web browser. + + - Sit back and relax while the magic happens, the whole installation will be performed fully automatic. + + - Once you see the desktop, your Windows installation is ready for use. + + Enjoy your brand new machine, and don't forget to star this repo! + +* ### How do I select the Windows version? + + By default, Windows 11 will be installed. But you can change that in settings, in order to specify an alternative Windows version to be downloaded: + + Select from the values below: + + | **Value** | **Description** | **Source** | **Transfer** | **Size** | + |---|---|---|---|---| + | `win11` | Windows 11 Pro | Microsoft | Fast | 6.4 GB | + | `win10` | Windows 10 Pro | Microsoft | Fast | 5.8 GB | + | `ltsc10` | Windows 10 LTSC | Microsoft | Fast | 4.6 GB | + | `win81` | Windows 8.1 Pro | Microsoft | Fast | 4.2 GB | + | `win7` | Windows 7 SP1 | Bob Pony | Medium | 3.0 GB | + | `vista` | Windows Vista SP2 | Bob Pony | Medium | 3.6 GB | + | `winxp` | Windows XP SP3 | Bob Pony | Medium | 0.6 GB | + |||||| + | `2022` | Windows Server 2022 | Microsoft | Fast | 4.7 GB | + | `2019` | Windows Server 2019 | Microsoft | Fast | 5.3 GB | + | `2016` | Windows Server 2016 | Microsoft | Fast | 6.5 GB | + | `2012` | Windows Server 2012 R2 | Microsoft | Fast | 4.3 GB | + | `2008` | Windows Server 2008 R2 | Microsoft | Fast | 3.0 GB | + |||||| + | `core11` | Tiny 11 Core | Archive.org | Slow | 2.1 GB | + | `tiny11` | Tiny 11 | Archive.org | Slow | 3.8 GB | + | `tiny10` | Tiny 10 | Archive.org | Slow | 3.6 GB | + +* ### How do I connect using RDP? + + The web-viewer is mainly meant to be used during installation, as its picture quality is low, and it has no audio or clipboard for example. + + So for a better experience you can connect using any Microsoft Remote Desktop client to the IP of the container, using the username `docker` and by leaving the password empty. + + There is a good RDP client for [Android](https://play.google.com/store/apps/details?id=com.microsoft.rdc.androidx) available from the Play Store. One for [iOS](https://apps.apple.com/nl/app/microsoft-remote-desktop/id714464092?l=en-GB) is in the Apple Store. For Linux you can use [rdesktop](http://www.rdesktop.org/) and for Windows you don't need to install anything as it is already ships as part of the operating system. + +* ### How do I verify if my system supports KVM? + + To verify if your system supports KVM, run the following commands: + + ```bash + sudo apt install cpu-checker + sudo kvm-ok + ``` + + If you receive an error from `kvm-ok` indicating that KVM acceleration can't be used, check the virtualization settings in the BIOS. + +* ### Is this project legal? + + Yes, this project contains only open-source code and does not distribute any copyrighted material. Any product keys found in the code are just generic placeholders provided by Microsoft for trial purposes. So under all applicable laws, this project would be considered legal. + +## Disclaimer + +The product names, logos, brands, and other trademarks referred to within this project are the property of their respective trademark holders. This project is not affiliated, sponsored, or endorsed by Microsoft Corporation. \ No newline at end of file diff --git a/apps/windows/metadata/logo.jpg b/apps/windows/metadata/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..79a0cc3efbfff6c8250cf0e33ce149fae60831c2 GIT binary patch literal 17464 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 aSsoklH6@S#{|*dNe?@8NKl~1he*RyWXQ4R& literal 0 HcmV?d00001