Skip to content

Commit 953d255

Browse files
committed
develop: added windows-oci nixos module
1 parent 172e344 commit 953d255

File tree

3 files changed

+194
-0
lines changed

3 files changed

+194
-0
lines changed

docs/modules/nixos/windows-oci.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Windows OCI
2+
3+
Windows inside a Docker container.
4+
5+
View the [*nix-core* NixOS module on GitHub](https://github.com/sid115/nix-core/tree/master/modules/nixos/windows-oci).
6+
7+
## References
8+
9+
- [dockur on GitHub](https://github.com/dockur/windows)
10+
11+
## Config
12+
13+
```nix
14+
imports = [ inputs.core.nixosModule.windows-oci ];
15+
16+
services.windows-oci.enable = true;
17+
```
18+
19+
## Usage
20+
21+
Access the VNC web interface at `http://127.0.0.1:8006`. Or connect via RDP at `127.0.0.1`.
22+
23+
TODO: Setup Windows RemoteApp

modules/nixos/default.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,6 @@
4545
webPage = import ./webPage;
4646
wg-client = import ./wg-client;
4747
wg-server = import ./wg-server;
48+
windows-oci = import ./windows-oci;
4849
xrdp = import ./xrdp;
4950
}
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
{
2+
config,
3+
lib,
4+
pkgs,
5+
...
6+
}:
7+
8+
let
9+
cfg = config.services.windows-oci;
10+
11+
inherit (lib)
12+
mkEnableOption
13+
mkIf
14+
mkOption
15+
mkOverride
16+
optional
17+
types
18+
;
19+
in
20+
{
21+
options.services.windows-oci = {
22+
enable = mkEnableOption "Run Windows in an OCI container using Podman";
23+
volume = mkOption {
24+
type = types.str;
25+
default = "/opt/windows";
26+
description = "Path to the volume for Windows data.";
27+
};
28+
sharedVolume = mkOption {
29+
type = types.nullOr types.str;
30+
default = null;
31+
description = "Path to a shared volume to mount inside the Windows container. You have to create this directory manually.";
32+
};
33+
settings = {
34+
version = mkOption {
35+
type = types.str;
36+
default = "11";
37+
example = "2025";
38+
description = "Windows version to use.";
39+
};
40+
ramSize = mkOption {
41+
type = types.str;
42+
default = "8G";
43+
description = "Amount of RAM to allocate to the Windows container.";
44+
};
45+
cpuCores = mkOption {
46+
type = types.str;
47+
default = "4";
48+
description = "Number of CPU cores to allocate to the Windows container.";
49+
};
50+
diskSize = mkOption {
51+
type = types.str;
52+
default = "64G";
53+
description = "Size of the virtual disk for the Windows container.";
54+
};
55+
username = mkOption {
56+
type = types.str;
57+
default = "admin";
58+
description = "Username for the Windows installation.";
59+
};
60+
password = mkOption {
61+
type = types.str;
62+
default = "admin";
63+
description = "Password for the Windows installation.";
64+
};
65+
language = mkOption {
66+
type = types.str;
67+
default = "English";
68+
description = "Language for the Windows installation.";
69+
};
70+
region = mkOption {
71+
type = types.str;
72+
default = "en-DE";
73+
description = "Region for the Windows installation.";
74+
};
75+
keyboard = mkOption {
76+
type = types.str;
77+
default = "de-DE";
78+
description = "Keyboard layout for the Windows installation.";
79+
};
80+
};
81+
};
82+
83+
config = mkIf cfg.enable {
84+
systemd.tmpfiles.rules = [ "d ${cfg.volume} 0755 root podman -" ];
85+
86+
virtualisation.podman = {
87+
enable = true;
88+
autoPrune.enable = true;
89+
dockerCompat = true;
90+
defaultNetwork.settings = {
91+
dns_enabled = true;
92+
};
93+
};
94+
95+
# https://github.com/NixOS/nixpkgs/issues/226365
96+
networking.firewall.interfaces."podman+".allowedUDPPorts = [ 53 ];
97+
98+
virtualisation.oci-containers.backend = "podman";
99+
100+
virtualisation.oci-containers.containers."windows" = {
101+
image = "dockurr/windows";
102+
environment = with cfg.settings; {
103+
"VERSION" = version;
104+
"RAM_SIZE" = ramSize;
105+
"CPU_CORES" = cpuCores;
106+
"DISK_SIZE" = diskSize;
107+
"USERNAME" = username;
108+
"PASSWORD" = password;
109+
"LANGUAGE" = language;
110+
"REGION" = region;
111+
"KEYBOARD" = keyboard;
112+
};
113+
volumes = [
114+
"${cfg.volume}:/storage:rw"
115+
]
116+
++ optional (cfg.sharedVolume != null) "${cfg.sharedVolume}:/shared:rw";
117+
ports = [
118+
"8006:8006/tcp"
119+
"3389:3389/tcp"
120+
"3389:3389/udp"
121+
];
122+
log-driver = "journald";
123+
extraOptions = [
124+
"--cap-add=NET_ADMIN"
125+
"--device=/dev/kvm:/dev/kvm:rwm"
126+
"--device=/dev/net/tun:/dev/net/tun:rwm"
127+
"--network-alias=windows"
128+
"--network=windows_default"
129+
];
130+
};
131+
systemd.services."podman-windows" = {
132+
serviceConfig = {
133+
Restart = mkOverride 90 "always";
134+
};
135+
after = [
136+
"podman-network-windows_default.service"
137+
];
138+
requires = [
139+
"podman-network-windows_default.service"
140+
];
141+
partOf = [
142+
"podman-compose-windows-root.target"
143+
];
144+
wantedBy = [
145+
"podman-compose-windows-root.target"
146+
];
147+
};
148+
149+
systemd.services."podman-network-windows_default" = {
150+
path = [ pkgs.podman ];
151+
serviceConfig = {
152+
Type = "oneshot";
153+
RemainAfterExit = true;
154+
ExecStop = "podman network rm -f windows_default";
155+
};
156+
script = ''
157+
podman network inspect windows_default || podman network create windows_default
158+
'';
159+
partOf = [ "podman-compose-windows-root.target" ];
160+
wantedBy = [ "podman-compose-windows-root.target" ];
161+
};
162+
163+
systemd.targets."podman-compose-windows-root" = {
164+
unitConfig = {
165+
Description = "Root target generated by compose2nix.";
166+
};
167+
wantedBy = [ "multi-user.target" ];
168+
};
169+
};
170+
}

0 commit comments

Comments
 (0)