Last active
May 5, 2025 00:22
-
-
Save jamietre/d463f0f9132f564bf1d7727257eabf13 to your computer and use it in GitHub Desktop.
Script to start WSL and bind localhost to WSL IP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Example docker-compose.yml for plex. | |
version: "2" | |
services: | |
plex: | |
image: plexinc/pms-docker:plexpass | |
runtime: nvidia | |
container_name: "plex" | |
restart: always | |
hostname: "MY-PLEX" | |
volumes: | |
- plex-transcode:/transcode | |
- /plex:/config | |
- plex-video:/data/video | |
- plex-music:/data/music | |
ports: | |
- "0.0.0.0:32400:32400" | |
- "0.0.0.0:33400:33400" | |
- "0.0.0.0:65001:65001" | |
environment: | |
TZ: America/New_York | |
PLEX_CLAIM: <your-claim> | |
ADVERTISE_IP: https://your.plex.server | |
PLEX_UID: 1001 | |
PLEX_GID: 1001 | |
NVIDIA_VISIBLE_DEVICES: all | |
NVIDIA_DRIVER_CAPABILITIES: compute,video,utility | |
volumes: | |
# Examples only | |
plex-music: | |
driver: local | |
driver_opts: | |
type: cifs | |
device: //192.168.1.2/media/MusicLibrary | |
o: "username=plex,password=xxxx" | |
plex-video: | |
driver: local | |
driver_opts: | |
type: cifs | |
device: //192.168.1.2/media/VideoLibrary | |
o: "username=plex,password=xxxx" | |
plex-transcode: | |
external: false | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
service docker start |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"C:\Program Files\nodejs\node.exe" "c:\scripts\configure-wsl-plex.js" >> "c:\scripts\configure-wsl-plex.log" 2>&1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { exec } = require("child_process"); | |
const distro = "Ubuntu-20.04"; | |
const ipPattern = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/; | |
async function main() { | |
log("info", "Starting WSL initialization"); | |
const isRunning = await isWslDistroRunning(); | |
if (!isRunning) { | |
log("info", "Distro stopped, starting..."); | |
await runCommand(`wsl -d ${distro} -u root /etc/init-wsl`); | |
} | |
const data = await runCommand("C:\\Windows\\System32\\wsl.exe hostname -I"); | |
const parts = data.split(" "); | |
const ip = parts[0]; | |
if (!ipPattern.test(ip)) { | |
throw new Error(`Received '${data}'; could not extract an IP`); | |
} | |
log("info", `Configuring netsh to route to ${ip}`); | |
try { | |
await runCommand( | |
'netsh interface portproxy delete v4tov4 listenaddress="0.0.0.0" listenport=32400' | |
); | |
} catch (e) { | |
log("warn", e.message) | |
} | |
await runCommand( | |
`netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=32400 connectaddress=${ip} connectport=32400` | |
); | |
log("info", "Done"); | |
} | |
async function isWslDistroRunning() { | |
const distroText = distro.replace(/\./g, "\\."); | |
const wslStatePattern = new RegExp( | |
`\\*?\\s*${distroText}\\s*(Running|Stopped)\\s*(1|2)` | |
); | |
const wslState = await runCommand("wsl --list --verbose"); | |
const lines = splitLines(wslState); | |
const distroMatches = lines.filter((line) => wslStatePattern.test(line)); | |
if (distroMatches.length > 1) { | |
throw new Error( | |
`More than one match for distro name "${distro}" was found, can't continue.` | |
); | |
} | |
if (distroMatches.length === 0) { | |
throw new Error(`No matches for distro name "${distro}".`); | |
} | |
const matches = distroMatches[0].match(wslStatePattern); | |
const state = matches[1]; | |
log("info",`Machine state: ${state}`) | |
switch (state) { | |
case "Running": | |
return true; | |
case "Stopped": | |
return false; | |
default: | |
throw new Error(`Unknown wsl state "${state}"`); | |
} | |
} | |
async function runCommand(command) { | |
const deferred = createDeferred(); | |
log("info", `> ${command}`); | |
exec(command, function (err, stdout, stderr) { | |
if (err) { | |
deferred.reject(err); | |
return; | |
} | |
if (stderr) { | |
log("error", stderr); | |
} | |
deferred.resolve(stdout); | |
return; | |
}); | |
return deferred.promise(); | |
} | |
/** | |
* make a promise, and provide the resolve/reject functions | |
*/ | |
function createDeferred() { | |
let resolve; | |
let reject; | |
const promise = new Promise((_resolve, _reject) => { | |
resolve = _resolve; | |
reject = _reject; | |
}); | |
return { | |
promise: async () => promise, | |
resolve: resolve, | |
reject: reject, | |
}; | |
} | |
function splitLines(lines) { | |
let cleanLines = lines.replace(/\r/g, "").replace(/\0/g, ""); | |
while (cleanLines.endsWith("\n")) { | |
cleanLines = cleanLines.slice(0, cleanLines.length - 1); | |
} | |
return cleanLines.split("\n"); | |
} | |
function log(level, message) { | |
const now = new Date().toISOString(); | |
console.log(`${now} [${level}] ${message}`); | |
} | |
main() | |
.then(() => { | |
process.exit(0); | |
}) | |
.catch((e) => { | |
log("error", e.message); | |
process.exit(1); | |
}); |
Docker Desktop now supports remote WSL2 containers - I think you now only need the compose file and the rest can be achieved natively there.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You are a genius!