Windows Docker Desktop Installation and Upgrade
Updated: 2026-09-05
This is the Windows host path for the same Recipe Site Docker application stack used on Linux. It does not create a separate Windows build of PHP, MariaDB, or the application.
Windows status: this path has been reviewed and syntax/static-tested on Windows, and it is expected to work with Docker Desktop using Linux containers. It has not yet completed a real Windows 10/11 + Docker Desktop end-to-end acceptance run, so Windows support should be treated as preview/expected-compatible rather than proven. If you try it, please report both problems and successful installs so the Windows instructions can be improved.
Expected Windows model
Recipe Site is expected to run on Windows through Docker Desktop using Linux containers.
Host-side product operations use PowerShell:
tools/recipe-site-install.ps1
tools/recipe-site-migrate.ps1
tools/recipe-site-health.ps1
tools/recipe-site-upgrade.ps1
The PowerShell scripts implement the same safety model as the accepted Bash product scripts:
- clean fresh-install baseline rather than replaying historical migrations;
- explicit pre-code/post-code migration phases;
- fail-closed migration verification;
- pre-upgrade database backup and code snapshot;
- preservation of
.env, runtime media, local release state, Git metadata, backups, and local dependency state; - MariaDB remains internal-only;
- health checks are required after install and upgrade.
Additional Windows hardening includes:
- Git line-ending rules that keep Linux shell scripts as LF even when checked out on Windows;
- refusal to upgrade when the release source and installation directories are nested inside one another;
- refusal to use a drive root as the upgrade destination;
- a visible
robocopy /MIRdry-run so release-managed file removals/replacements can be reviewed before upgrading; - a health check that verifies the Apache/PHP
www-datauser can actually write the runtime media directories through Docker Desktop's bind mount.
Requirements
- Windows 11 64-bit, or a currently supported Windows 10 64-bit release;
- hardware virtualization enabled;
- Docker Desktop;
- Docker Desktop configured for Linux containers;
- Docker Compose v2 (
docker compose); - Windows PowerShell 5.1 or PowerShell 7+;
robocopy.exeandtar.exefor release upgrades (included with current Windows releases);- Git only when installing from a Git checkout; a release archive can also be used.
Docker Desktop normally uses WSL2 internally on current Windows systems. The Recipe Site operator does not need to work inside an Ubuntu terminal: the Windows commands below are run from normal PowerShell.
Recommended installation location
Use a normal local folder such as:
C:\RecipeSite\recipe-site
Until real Windows acceptance is complete, avoid installing the live site inside:
- OneDrive/Dropbox/other continuously synchronized folders;
- UNC/network shares;
- removable drives;
- unusually deep directory trees.
Those locations add file-sharing, locking, path-length, and performance variables that are unrelated to the Recipe Site itself. Paths containing spaces should work because the PowerShell tooling passes paths as quoted/structured arguments, but a short local path is still easier to troubleshoot.
If Windows Controlled Folder Access, endpoint security, or antivirus software blocks Docker Desktop, PowerShell, robocopy.exe, or file creation in the chosen folder, allow the operation rather than weakening Recipe Site security settings.
Verify Docker Desktop
Start Docker Desktop and wait until the engine reports that it is running. From PowerShell:
docker version
docker compose version
docker version --format '{{.Server.Os}}'
The final command must report:
linux
If it reports windows, switch Docker Desktop to Linux containers before proceeding.
If Docker Desktop cannot start its Linux engine, verify that virtualization/WSL2 requirements are satisfied before troubleshooting the Recipe Site scripts.
Obtain the release
For a Git checkout:
git clone <repository-url> recipe-site
Set-Location recipe-site
For a packaged release, extract it into its own directory and open PowerShell in that directory.
Do not copy a production .env, Docker volume, database, or runtime image tree into a clean installation unless intentionally performing a restore.
Configure .env
The first real installer run creates .env from .env.example if .env is absent, then deliberately stops so deployment values can be edited.
You can also create it yourself:
Copy-Item .env.example .env
notepad .env
At minimum review the same values documented in Installation and Upgrade Guide, including database credentials, APP_BASE_URL, timezone, HTTPS/cookie settings, backup location, and optional SMTP settings.
Never commit the real .env.
Fresh-install preflight
powershell -ExecutionPolicy Bypass -File .\tools\recipe-site-install.ps1 -DryRun
With PowerShell 7 you may use:
pwsh -File .\tools\recipe-site-install.ps1 -DryRun
If .env does not exist, the dry run reports that configuration is required. After .env is configured, run the dry run again.
Fresh install
powershell -ExecutionPolicy Bypass -File .\tools\recipe-site-install.ps1
For a separately controlled noninteractive installation:
powershell -ExecutionPolicy Bypass -File .\tools\recipe-site-install.ps1 -Yes
Successful completion ends with:
INSTALL=PASS
Then open the first-Owner page, normally:
http://127.0.0.1:8080/setup-owner.php
or the configured HTTPS site URL.
Health check
powershell -ExecutionPolicy Bypass -File .\tools\recipe-site-health.ps1
Success ends with:
RECIPE_SITE_HEALTH=PASS
The Windows health check specifically verifies that the web process can write the runtime image/import/avatar directories through the Windows-to-Linux Docker bind mount. If this fails, check Docker Desktop file access and Windows security controls for the installation folder.
Release-to-release upgrade
Do not overwrite the installed site first. Extract or clone the new release into a separate directory.
Use sibling directories, not one directory inside the other. For example:
C:\RecipeSite\recipe-site existing installation
C:\RecipeSite\recipe-site-release-new new release tree
From the new release tree:
powershell -ExecutionPolicy Bypass -File .\tools\recipe-site-upgrade.ps1 `
-InstallDir 'C:\RecipeSite\recipe-site' `
-DryRun
The dry run prints the robocopy /MIR operations that would occur. Review any deleted or replaced release-managed files before continuing. The following installation-specific paths are protected separately and are not mirrored away:
.env
.git\
.recipe-site\
www\assets\images\
backups\
node_modules\
Other files inside the installation tree are considered release-managed and may be replaced or removed. Keep unrelated custom files outside the Recipe Site installation directory.
Then run:
powershell -ExecutionPolicy Bypass -File .\tools\recipe-site-upgrade.ps1 `
-InstallDir 'C:\RecipeSite\recipe-site'
Successful completion ends with:
UPGRADE=PASS
Windows-specific preservation and copy behavior
The Windows upgrader uses native robocopy.exe mirror behavior rather than Linux rsync. It refuses source/destination layouts that are nested because /MIR in that configuration could recurse or remove the wrong files.
Before release files or database schema are changed, it creates and verifies:
- a MariaDB dump;
- a SHA-256 checksum for the dump;
- a compressed pre-upgrade code snapshot;
- a SHA-256 checksum for that snapshot;
- an upgrade transcript under
.recipe-site\upgrade-logs\.
If an upgrade stops after the web service has been taken offline, do not manually delete files or database rows. Preserve the displayed backup/snapshot paths and use them for recovery/troubleshooting.
Security / networking
The Compose file is shared with Linux installations:
- web binds to
127.0.0.1:${WEB_PORT}; - phpMyAdmin binds to
127.0.0.1:${PHPMYADMIN_PORT}; - MariaDB has no published host port.
Because web/phpMyAdmin bind to localhost by default, another PC on the LAN will not automatically be able to browse to the Windows machine's port. For access from other devices, publish the Recipe Site through an HTTPS reverse proxy/tunnel rather than exposing MariaDB or phpMyAdmin to the internet.
Known unproven areas
The code review and Windows runner validation cover PowerShell parsing, host-side safety logic, Compose/static invariants, and first-run .env bootstrap behavior. They do not prove the following on a real Windows desktop yet:
- Docker Desktop Linux-container startup and bind-mount behavior on Windows 10/11;
- full baseline creation inside MariaDB;
- first Owner creation through the browser;
- persistent operation across Docker Desktop/Windows restart;
- a complete release-to-release upgrade with real containers;
- backup and runtime-media preservation under real Windows filesystem semantics.
These are expected to work based on the shared Docker architecture and the safeguards above, but they remain unproven until someone completes the end-to-end Windows acceptance run.
Please send Windows feedback
If you install or upgrade Recipe Site on Windows, feedback is useful even when everything works. Please report through the project's normal support/feedback channel and include:
- Windows edition/version and build;
- Docker Desktop version;
- whether Docker Desktop is using WSL2/Linux containers;
- Windows PowerShell 5.1 or PowerShell 7 version;
- whether this was a fresh install or upgrade;
- the exact Recipe Site command that failed;
- the error text or screenshot;
- whether
recipe-site-health.ps1passes; - anything unusual about the installation folder, virtualization, antivirus, or Windows security configuration.
Do not include .env, database passwords, SMTP passwords, API keys, access tokens, or other secrets in a report.
Successful reports are also valuable: they help turn this Windows path from expected-compatible into formally accepted support.
Validation status
The PowerShell scripts are syntax/static validated on a clean GitHub-hosted Windows Server runner. That confirms the Windows-host code parses and preserves the intended installer/upgrader invariants.
A real Docker Desktop Linux-container acceptance run on a Windows 10/11 machine is still required before Windows support is declared fully accepted for v1. GitHub-hosted Windows runners cannot provide the Linux Docker service-container environment needed to substitute for that acceptance test.
