diff --git a/Dockerfile b/Dockerfile index 2c36463..cfc2067 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,15 +19,15 @@ COPY ./src /run/ COPY ./assets /run/assets ADD https://raw.githubusercontent.com/ElliotKillick/Mido/main/Mido.sh /run/mido.sh -ADD https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso /run/drivers.iso +ADD https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/virtio-win.iso /run/drivers.iso RUN chmod +x /run/*.sh -EXPOSE 8006 +EXPOSE 3389 8006 VOLUME /storage -ENV CPU_CORES "2" ENV RAM_SIZE "4G" +ENV CPU_CORES "2" ENV DISK_SIZE "64G" ARG VERSION_ARG "0.0" diff --git a/assets/win7x64-ultimate.xml b/assets/win7x64-ultimate.xml deleted file mode 100644 index 322450a..0000000 --- a/assets/win7x64-ultimate.xml +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - - en-US - - 0409:00000409 - en-US - en-US - en-US - - - - - 0 - true - - - - 1 - Primary - 300 - - - - 2 - EFI - 100 - - - - 3 - MSR - 128 - - - - 4 - Primary - true - - - - - - 1 - 1 - - NTFS - DE94BBA4-06D1-4D40-A16A-BFD50179D6AC - - - - 2 - 2 - - FAT32 - - - - 3 - 3 - - - - 4 - 4 - - C - NTFS - - - - - - - - 0 - 4 - - false - - - - - FJ82H-XT6CR-J8D7P-XQJJ2-GPDD4 - Never - - true - Docker - - - false - - - - - D:\viostor\w7\amd64 - - - D:\NetKVM\w7\amd64 - - - D:\Balloon\w7\amd64 - - - D:\pvpanic\w7\amd64 - - - D:\qemupciserial\w7\amd64 - - - D:\qxldod\w7\amd64 - - - D:\vioinput\w7\amd64 - - - D:\viorng\w7\amd64 - - - D:\vioscsi\w7\amd64 - - - D:\vioserial\w7\amd64 - - - - - - - 0409:00000409 - en-US - en-US - en-US - - - true - - - 0 - - - - - - - - Docker - Administrators - - - true</PlainText> - </Password> - </LocalAccount> - </LocalAccounts> - <AdministratorPassword> - <Value>password</Value> - <PlainText>true</PlainText> - </AdministratorPassword> - </UserAccounts> - <AutoLogon> - <Username>Docker</Username> - <Enabled>true</Enabled> - <LogonCount>1</LogonCount> - <Password> - <Value/> - <PlainText>true</PlainText> - </Password> - </AutoLogon> - <OOBE> - <HideEULAPage>true</HideEULAPage> - <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen> - <HideOnlineAccountScreens>true</HideOnlineAccountScreens> - <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE> - <NetworkLocation>Home</NetworkLocation> - <ProtectYourPC>1</ProtectYourPC> - <SkipUserOOBE>true</SkipUserOOBE> - <SkipMachineOOBE>true</SkipMachineOOBE> - </OOBE> - <FirstLogonCommands> - <SynchronousCommand wcm:action="add"> - <Order>1</Order> - <CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoLogonCount /t REG_DWORD /d 0 /f</CommandLine> - </SynchronousCommand> - <SynchronousCommand wcm:action="add"> - <Order>2</Order> - <RequiresUserInput>false</RequiresUserInput> - <CommandLine>cmd /C wmic useraccount where name="Docker" set PasswordExpires=false</CommandLine> - <Description>Password Never Expires</Description> - </SynchronousCommand> - <SynchronousCommand wcm:action="add"> - <Order>3</Order> - <CommandLine>msiexec /i E:\virtio-win-gt-x64.msi /qb!</CommandLine> - <Description>Install VirtIO drivers</Description> - </SynchronousCommand> - </FirstLogonCommands> - </component> - </settings> -</unattend> diff --git a/assets/win81x64.xml b/assets/win81x64.xml index 7e4fe1d..e0f8857 100644 --- a/assets/win81x64.xml +++ b/assets/win81x64.xml @@ -1,6 +1,5 @@ <?xml version="1.0"?> <unattend xmlns="urn:schemas-microsoft-com:unattend" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"> - <settings pass="offlineServicing"/> <settings pass="windowsPE"> <component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> <SetupUILanguage> @@ -76,6 +75,12 @@ </DiskConfiguration> <ImageInstall> <OSImage> + <InstallFrom> + <MetaData wcm:action="add"> + <Value>Windows 8.1 Pro</Value> + <Key>/IMAGE/NAME</Key> + </MetaData> + </InstallFrom> <InstallTo> <DiskID>0</DiskID> <PartitionID>4</PartitionID> @@ -86,18 +91,18 @@ <UserData> <ProductKey> <Key>GCRJD-8NW9H-F2CDX-CCM8D-9D6T9</Key> - <WillShowUI>Never</WillShowUI> + <WillShowUI>OnError</WillShowUI> </ProductKey> <AcceptEula>true</AcceptEula> <FullName>Docker</FullName> - <Organization/> + <Organization>Docker</Organization> </UserData> <EnableFirewall>false</EnableFirewall> </component> <component name="Microsoft-Windows-PnpCustomizationsWinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> <DriverPaths> <PathAndCredentials wcm:action="add" wcm:keyValue="1"> - <Path>D:\viostor\w8.1\amd64</Path> + <Path>D:\viostor\w10\amd64</Path> </PathAndCredentials> <PathAndCredentials wcm:action="add" wcm:keyValue="2"> <Path>D:\NetKVM\w8.1\amd64</Path> @@ -121,7 +126,7 @@ <Path>D:\viorng\w8.1\amd64</Path> </PathAndCredentials> <PathAndCredentials wcm:action="add" wcm:keyValue="9"> - <Path>D:\vioscsi\w8.1\amd64</Path> + <Path>D:\vioscsi\w10\amd64</Path> </PathAndCredentials> <PathAndCredentials wcm:action="add" wcm:keyValue="10"> <Path>D:\vioserial\w8.1\amd64</Path> @@ -129,6 +134,11 @@ </DriverPaths> </component> </settings> + <settings pass="offlineServicing"> + <component name="Microsoft-Windows-LUA-Settings" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> + <EnableLUA>false</EnableLUA> + </component> + </settings> <settings pass="specialize"> <component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> <InputLocale>0409:00000409</InputLocale> @@ -187,12 +197,6 @@ </SynchronousCommand> <SynchronousCommand wcm:action="add"> <Order>2</Order> - <RequiresUserInput>false</RequiresUserInput> - <CommandLine>cmd /C wmic useraccount where name="Docker" set PasswordExpires=false</CommandLine> - <Description>Password Never Expires</Description> - </SynchronousCommand> - <SynchronousCommand wcm:action="add"> - <Order>3</Order> <CommandLine>msiexec /i E:\virtio-win-gt-x64.msi /qb!</CommandLine> <Description>Install VirtIO drivers</Description> </SynchronousCommand> diff --git a/docker-compose.yml b/docker-compose.yml index fde81c1..9315465 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,13 +3,13 @@ services: windows: image: dockurr/windows container_name: windows - environment: - VERSION: "win11x64" devices: - /dev/kvm cap_add: - NET_ADMIN ports: - 8006:8006 + - 3389:3389/tcp + - 3389:3389/udp stop_grace_period: 2m restart: unless-stopped diff --git a/readme.md b/readme.md index 503456a..b241b38 100644 --- a/readme.md +++ b/readme.md @@ -36,6 +36,8 @@ services: - NET_ADMIN ports: - 8006:8006 + - 3389:3389/tcp + - 3389:3389/udp stop_grace_period: 2m restart: unless-stopped ``` @@ -52,37 +54,31 @@ docker run -it --rm -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN dockurr/w Very simple! These are the steps: - - Start the container and get some coffee, it will begin downloading the ISO file. + - Start the container and get some coffee. - - Connect to port 8006 of the container in your web browser and wait until you see the screen. + - Connect to port 8006 of the container in 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 it, and don't forget to star this repo! - * ### How do I specify another Windows version? + * ### How do I select the Windows version? By default, Windows 11 will be installed. But you can add the `VERSION` environment variable to your compose file, in order to specify an alternative Windows version to download: ```yaml environment: - VERSION: "win11x64" + VERSION: "win11" ``` Select from the values below: - - ```win11x64``` (Windows 11) - - ```win10x64``` (Windows 10) - - ```win81x64``` (Windows 8.1) - - ```win2022-eval``` (Windows Server 2022) - - ```win2019-eval``` (Windows Server 2019) - - ```win2016-eval``` (Windows Server 2016) - - * ### How do I install a custom ISO file? - - You can supply your own ISO file by naming it ```custom.iso``` and placing it in the ```/storage``` folder. - - Make sure to delete any other files in this folder, so that there are no leftovers from previous installations. Then follow the same steps as for [manual installation](https://github.com/dockur/windows/tree/master?tab=readme-ov-file#how-do-i-perform-a-manual-installation). + - ```win11``` (Windows 11) + - ```win10``` (Windows 10) + - ```win81``` (Windows 8.1) + - ```win22``` (Windows Server 2022) + - ```win19``` (Windows Server 2019) + - ```win16``` (Windows Server 2016) * ### How do I increase the amount of CPU or RAM? @@ -96,20 +92,20 @@ docker run -it --rm -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN dockurr/w CPU_CORES: "4" ``` - * ### How do I change the size of the data disk? + * ### How do I change the size of the disk? To expand the default size of 64 GB, add the `DISK_SIZE` setting to your compose file and set it to your preferred capacity: ```yaml environment: - DISK_SIZE: "128G" + DISK_SIZE: "256G" ``` This can also be used to resize the existing disk to a larger capacity without any data loss. - * ### How do I change the location of the data disk? + * ### How do I change the storage location? - To change the location of the data disk, include the following bind mount in your compose file: + To change the storage location, include the following bind mount in your compose file: ```yaml volumes: @@ -131,24 +127,22 @@ docker run -it --rm -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN dockurr/w * ### How do I view the screen? - The container includes a web-based viewer, so you can visit [http://localhost:8006/](http://localhost:8006/) using any web browser to view the screen and interact with Windows via the keyboard or mouse. + The container includes a web-based viewer, so you can visit [http://localhost:8006/](http://localhost:8006/) using any web browser to view the screen and interact with Windows via the keyboard and mouse. This is mainly for use during installation, as afterwards you can use Remote Desktop, TeamViewer or any other software you prefer. * ### How do I perform a manual installation? - If you prefer to perform the installation manually in order to customize some options, add the following environment variable: + If you prefer to perform the installation manually in order to customize some options, such as selecting another edition, add the following environment variable: ```yaml environment: - ATTENDED: "Y" + MANUAL: "Y" ``` Then follow these steps: - - Start the container and wait until the ISO download is finished. If needed, you can view the progress in the Docker log. - - - Connect to port 8006 of the container in your web browser, you will see the Windows installation screen. + - Start the container and connect to port 8006 of the container in your web browser. After the download is finished, you will see the Windows installation screen. - Start the installation by clicking ```Install now```. On the next screen, press 'OK' when prompted to ```Load driver``` and select the ```VirtIO SCSI``` driver from the list that matches your Windows version. So for Windows 11, select ```D:\amd64\w11\vioscsi.inf``` and click 'Next'. @@ -164,6 +158,17 @@ docker run -it --rm -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN dockurr/w - Now your Windows installation is ready for use. Enjoy it, and don't forget to star this repo! + * ### How do I install an unsupported version? + + You can specify an URL in the `VERSION` environment variable, in order to download a custom ISO file: + + ```yaml + environment: + VERSION: "https://example.com/win.iso" + ``` + + During the installation you will need to add some drivers as described in [manual installation](https://github.com/dockur/windows/tree/master?tab=readme-ov-file#how-do-i-perform-a-manual-installation) above. + * ### Is this project legal? Yes, this project contains only open-source code and does not distribute any copyrighted material. Neither does it try to circumvent any copyright protection measures. So under all applicable laws, this project would be considered legal. diff --git a/src/install.sh b/src/install.sh index 4ab4d2b..7761289 100644 --- a/src/install.sh +++ b/src/install.sh @@ -1,64 +1,152 @@ #!/usr/bin/env bash set -Eeuo pipefail -: "${ATTENDED:="N"}" +: "${MANUAL:="N"}" +: "${EXTERNAL:="N"}" : "${VERSION:="win11x64"}" -# Display wait message -MSG="Please wait while Windows is being downloaded..." -/run/server.sh "Windows" "$MSG" & - ARGUMENTS="-chardev socket,id=chrtpm,path=/dev/shm/emulated_tpm/swtpm-sock $ARGUMENTS" ARGUMENTS="-tpmdev emulator,id=tpm0,chardev=chrtpm -device tpm-tis,tpmdev=tpm0 $ARGUMENTS" -BASE="$VERSION.iso" +[[ "${VERSION,,}" == "http"* ]] && EXTERNAL="Y" + +[[ "${VERSION,,}" == "11" ]] && VERSION="win11x64" +[[ "${VERSION,,}" == "win11" ]] && VERSION="win11x64" + +[[ "${VERSION,,}" == "10" ]] && VERSION="win10x64" +[[ "${VERSION,,}" == "win10" ]] && VERSION="win10x64" + +[[ "${VERSION,,}" == "8" ]] && VERSION="win81x64" +[[ "${VERSION,,}" == "81" ]] && VERSION="win81x64" +[[ "${VERSION,,}" == "8.1" ]] && VERSION="win81x64" +[[ "${VERSION,,}" == "win81" ]] && VERSION="win81x64" +[[ "${VERSION,,}" == "win8" ]] && VERSION="win81x64" + +[[ "${VERSION,,}" == "22" ]] && VERSION="win2022-eval" +[[ "${VERSION,,}" == "2022" ]] && VERSION="win2022-eval" +[[ "${VERSION,,}" == "win22" ]] && VERSION="win2022-eval" +[[ "${VERSION,,}" == "win2022" ]] && VERSION="win2022-eval" + +[[ "${VERSION,,}" == "19" ]] && VERSION="win2019-eval" +[[ "${VERSION,,}" == "2019" ]] && VERSION="win2019-eval" +[[ "${VERSION,,}" == "win19" ]] && VERSION="win2019-eval" +[[ "${VERSION,,}" == "win2019" ]] && VERSION="win2019-eval" + +[[ "${VERSION,,}" == "16" ]] && VERSION="win2016-eval" +[[ "${VERSION,,}" == "2016" ]] && VERSION="win2016-eval" +[[ "${VERSION,,}" == "win16" ]] && VERSION="win2016-eval" +[[ "${VERSION,,}" == "win2016" ]] && VERSION="win2016-eval" + +MSG="Please wait while Windows is being started..." + +if [ ! -f "$STORAGE/custom.iso" ]; then + if [[ "$EXTERNAL" != [Yy1]* ]]; then + + if [ ! -f "$STORAGE/$VERSION.iso" ]; then + MSG="Please wait while Windows is being downloaded..." + fi + + else + + BASE=$(basename "$VERSION") + if [ ! -f "$STORAGE/$BASE" ]; then + MSG="Please wait while '$BASE' is being downloaded..." + fi + + fi +fi + +# Display wait message +/run/server.sh "Windows" "$MSG" & + +BASE="custom.iso" +[ -f "$STORAGE/$BASE" ] && return 0 + +if [[ "$EXTERNAL" != [Yy1]* ]]; then + + BASE="$VERSION.iso" + +else + + BASE=$(basename "$VERSION") + +fi + [ -f "$STORAGE/$BASE" ] && return 0 TMP="$STORAGE/tmp" -rm -rf "$TMP" -mkdir -p "$TMP" +rm -rf "$TMP" && mkdir -p "$TMP" -if [ -f "$STORAGE/custom.iso" ]; then - ATTENDED="Y" - LABEL="Custom" - cp "$STORAGE/custom.iso" "$TMP/$BASE" -fi +ISO="$TMP/$BASE" +rm -f "$ISO" -if [ ! -f "$TMP/$BASE" ]; then +if [[ "$EXTERNAL" != [Yy1]* ]]; then - LABEL="$VERSION" SCRIPT="$TMP/mido.sh" + rm -f "$SCRIPT" cp /run/mido.sh "$SCRIPT" chmod +x "$SCRIPT" cd "$TMP" bash "$SCRIPT" "$VERSION" - cd /run rm -f "$SCRIPT" + cd /run - [ ! -f "$TMP/$BASE" ] && error "Failed to download $VERSION.iso from the Microsoft servers!" && exit 66 +else + info "Downloading $BASE as boot image..." + + # Check if running with interactive TTY or redirected to docker log + if [ -t 1 ]; then + PROGRESS="--progress=bar:noscroll" + else + PROGRESS="--progress=dot:giga" + fi + + { wget "$VERSION" -O "$ISO" -q --no-check-certificate --show-progress "$PROGRESS"; rc=$?; } || : + + (( rc != 0 )) && error "Failed to download $VERSION, reason: $rc" && exit 60 + +fi + +[ ! -f "$ISO" ] && error "Failed to download $VERSION" && exit 61 + +SIZE=$(stat -c%s "$ISO") + +if ((SIZE<10000000)); then + error "Invalid ISO file: Size is smaller than 10 MB" && exit 62 fi info "Preparing ISO image for installation..." DIR="$TMP/unpack" -7z x "$TMP/$BASE" -o"$DIR" +rm -rf "$DIR" -if [[ "$ATTENDED" != [Yy1]* ]]; then - if [ -f "/run/assets/$VERSION.xml" ]; then +7z x "$ISO" -o"$DIR" - wimlib-imagex update "$DIR/sources/boot.wim" 2 \ - --command "add /run/assets/$VERSION.xml /autounattend.xml" +if [[ "$MANUAL" != [Yy1]* ]]; then + if [[ "$EXTERNAL" != [Yy1]* ]]; then + if [ -f "/run/assets/$VERSION.xml" ]; then + wimlib-imagex update "$DIR/sources/boot.wim" 2 \ + --command "add /run/assets/$VERSION.xml /autounattend.xml" + + fi fi fi +LABEL="${BASE%.*}" +LABEL="${LABEL::32}" + +ISO="$TMP/$LABEL.tmp" +rm -f "$ISO" + genisoimage -b boot/etfsboot.com -no-emul-boot -c BOOT.CAT -iso-level 4 -J -l -D -N -joliet-long -relaxed-filenames \ -v -V "$LABEL" -udf -boot-info-table -eltorito-alt-boot -eltorito-boot efi/microsoft/boot/efisys_noprompt.bin \ - -no-emul-boot -o "$TMP/$BASE.tmp" -allow-limited-size "$DIR" + -no-emul-boot -o "$ISO" -allow-limited-size "$DIR" + +mv "$ISO" "$STORAGE/$BASE" -mv "$TMP/$BASE.tmp" "$STORAGE/$BASE" rm -rf "$TMP" return 0