mirror of
https://github.com/jo-inc/camofox-browser.git
synced 2026-10-02 04:14:41 +08:00
feat: Windows support — build.ps1, .gitattributes, and Dockerfile fixes
Add three changes to make camofox-browser buildable on Windows: - build.ps1: PowerShell script mirroring the Makefile targets (build, up, down, reset, clean, fetch) for Windows users without make. - .gitattributes: enforce LF line endings for .sh files so shell scripts don't break when run inside Linux containers after a Windows clone. - Dockerfile + Dockerfile.ci: run plugin installer via 'sh' explicitly instead of relying on +x permissions, since Docker COPY on Windows does not preserve executable bits.
This commit is contained in:
committed by
Pradeep Elankumaran
parent
6d0e5ae869
commit
c2555d071c
@@ -0,0 +1,12 @@
|
||||
# Shell scripts must always use LF line endings
|
||||
# CRLF breaks shebang lines in Linux containers (e.g. Docker builds)
|
||||
*.sh text eol=lf
|
||||
|
||||
# JS/TS and other text files use native line endings
|
||||
*.js text
|
||||
*.ts text
|
||||
*.json text
|
||||
*.yml text
|
||||
*.yaml text
|
||||
*.md text
|
||||
*.toml text
|
||||
+1
-1
@@ -68,7 +68,7 @@ COPY plugins/ ./plugins/
|
||||
COPY scripts/ ./scripts/
|
||||
|
||||
# Install default plugin dependencies (apt packages + post-install hooks)
|
||||
RUN scripts/install-plugin-deps.sh
|
||||
RUN sh scripts/install-plugin-deps.sh
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV CAMOFOX_PORT=9377
|
||||
|
||||
+3
-1
@@ -74,7 +74,9 @@ COPY plugins/ ./plugins/
|
||||
COPY scripts/ ./scripts/
|
||||
|
||||
# Install default plugin dependencies
|
||||
RUN scripts/install-plugin-deps.sh
|
||||
# Note: sh is used explicitly (./scripts/) because COPY from Windows
|
||||
# does not preserve +x permission bits in Docker build contexts.
|
||||
RUN sh scripts/install-plugin-deps.sh
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV CAMOFOX_PORT=9377
|
||||
|
||||
@@ -117,6 +117,39 @@ make up ARCH=x86_64
|
||||
make up VERSION=135.0.1 RELEASE=beta.24
|
||||
```
|
||||
|
||||
#### Windows
|
||||
|
||||
On Windows, `make` is not available. Use the included `build.ps1` PowerShell script instead:
|
||||
|
||||
```powershell
|
||||
# Build and start
|
||||
.\build.ps1 up
|
||||
|
||||
# Stop and remove the container
|
||||
.\build.ps1 down
|
||||
|
||||
# Build image only
|
||||
.\build.ps1 build
|
||||
|
||||
# Force a clean rebuild
|
||||
.\build.ps1 reset
|
||||
|
||||
# Download binaries only (without building)
|
||||
.\build.ps1 fetch
|
||||
|
||||
# Override architecture
|
||||
.\build.ps1 up -Arch x86_64
|
||||
.\build.ps1 up -Arch aarch64
|
||||
```
|
||||
|
||||
> **Note:** PowerShell 7+ (`pwsh`) is recommended but `powershell.exe` (Windows PowerShell 5.1) also works. The script requires Docker Desktop for Windows with the WSL2 backend.
|
||||
>
|
||||
> **Line endings:** This project includes a `.gitattributes` file that forces Unix (`LF`) line endings for `.sh` files. If you've already cloned the repo and get `sh: not found` or `set: Illegal option -` errors during `docker build`, run:
|
||||
> ```powershell
|
||||
> Get-ChildItem -Recurse *.sh | ForEach-Object { (Get-Content $_) -join "`n" + "`n" | Set-Content $_ -NoNewline }
|
||||
> ```
|
||||
> This converts shell scripts to LF line endings. Future clones will handle this automatically thanks to `.gitattributes`.
|
||||
|
||||
> **WARNING: Do not run `docker build` directly.** The Dockerfile uses bind mounts to pull pre-downloaded binaries from `dist/`. Always use `make up` (or `make fetch` then `make build`) -- it downloads the binaries first.
|
||||
|
||||
### Fly.io
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
#!/usr/bin/env pwsh
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Build and manage camofox-browser on Windows (PowerShell alternative to Makefile).
|
||||
|
||||
.DESCRIPTION
|
||||
Provides the same targets as the Makefile for Windows users without make:
|
||||
build - Download Camoufox + yt-dlp, then build the Docker image.
|
||||
up - Build (if needed) and run the container.
|
||||
down - Stop and remove the container.
|
||||
reset - Full rebuild from scratch.
|
||||
clean - Remove downloaded binaries.
|
||||
fetch - Download Camoufox + yt-dlp binaries only.
|
||||
|
||||
.PARAMETER Target
|
||||
The action to perform: build, up, down, reset, clean, fetch (default: build).
|
||||
|
||||
.PARAMETER Arch
|
||||
Target architecture: x86_64 or aarch64 (default: x86_64).
|
||||
|
||||
.PARAMETER CamoufoxVersion
|
||||
Camoufox version (default: 135.0.1).
|
||||
|
||||
.PARAMETER CamoufoxRelease
|
||||
Camoufox release channel (default: beta.24).
|
||||
|
||||
.PARAMETER ContainerName
|
||||
Docker container name (default: camofox-browser).
|
||||
|
||||
.PARAMETER HostPort
|
||||
Host port to map (default: 9377).
|
||||
|
||||
.EXAMPLE
|
||||
.\build.ps1 up # Build + run
|
||||
.\build.ps1 down # Stop container
|
||||
.\build.ps1 fetch # Download binaries only
|
||||
#>
|
||||
|
||||
param(
|
||||
[ValidateSet('build', 'up', 'down', 'reset', 'clean', 'fetch')]
|
||||
[string]$Target = 'build',
|
||||
|
||||
[ValidateSet('x86_64', 'aarch64')]
|
||||
[string]$Arch = 'x86_64',
|
||||
|
||||
[string]$CamoufoxVersion = '135.0.1',
|
||||
[string]$CamoufoxRelease = 'beta.24',
|
||||
[string]$ContainerName = 'camofox-browser',
|
||||
[int]$HostPort = 9377
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$ProjectRoot = Split-Path -Parent $PSCommandPath
|
||||
$DistDir = Join-Path $ProjectRoot 'dist'
|
||||
$CamoufoxZip = Join-Path $DistDir "camoufox-$Arch.zip"
|
||||
$YtDlpBin = Join-Path $DistDir "yt-dlp-$Arch"
|
||||
$ImageTag = "camofox-browser:$CamoufoxVersion-$Arch"
|
||||
$ContainerPort = 9377
|
||||
|
||||
# Map architecture to upstream release filenames
|
||||
if ($Arch -eq 'aarch64') {
|
||||
$CamoufoxArch = 'arm64'
|
||||
$YtDlpSuffix = '_aarch64'
|
||||
} else {
|
||||
$CamoufoxArch = 'x86_64'
|
||||
$YtDlpSuffix = ''
|
||||
}
|
||||
|
||||
$CamoufoxUrl = "https://github.com/daijro/camoufox/releases/download/v$CamoufoxVersion-$CamoufoxRelease/camoufox-$CamoufoxVersion-$CamoufoxRelease-lin.$CamoufoxArch.zip"
|
||||
$YtDlpUrl = "https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux$YtDlpSuffix"
|
||||
|
||||
function Write-Step {
|
||||
param([string]$Message)
|
||||
Write-Host ">>> $Message" -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
function Invoke-Fetch {
|
||||
Write-Step "Creating dist directory..."
|
||||
New-Item -ItemType Directory -Path $DistDir -Force | Out-Null
|
||||
|
||||
if (-not (Test-Path $CamoufoxZip)) {
|
||||
Write-Step "Downloading Camoufox browser ($CamoufoxArch)..."
|
||||
Write-Host " URL: $CamoufoxUrl"
|
||||
curl.exe -L -o $CamoufoxZip $CamoufoxUrl
|
||||
Write-Host " Downloaded: $(Get-Item $CamoufoxZip | Select-Object -ExpandProperty Length) bytes"
|
||||
} else {
|
||||
Write-Host " [SKIP] Camoufox already downloaded"
|
||||
}
|
||||
|
||||
if (-not (Test-Path $YtDlpBin)) {
|
||||
Write-Step "Downloading yt-dlp ($Arch)..."
|
||||
Write-Host " URL: $YtDlpUrl"
|
||||
curl.exe -L -o $YtDlpBin $YtDlpUrl
|
||||
Write-Host " Downloaded: $(Get-Item $YtDlpBin | Select-Object -ExpandProperty Length) bytes"
|
||||
} else {
|
||||
Write-Host " [SKIP] yt-dlp already downloaded"
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-Build {
|
||||
Invoke-Fetch
|
||||
|
||||
Write-Step "Building Docker image: $ImageTag"
|
||||
docker build `
|
||||
--build-arg "ARCH=$Arch" `
|
||||
--build-arg "CAMOUFOX_VERSION=$CamoufoxVersion" `
|
||||
--build-arg "CAMOUFOX_RELEASE=$CamoufoxRelease" `
|
||||
-t $ImageTag `
|
||||
-f (Join-Path $ProjectRoot 'Dockerfile') `
|
||||
$ProjectRoot
|
||||
}
|
||||
|
||||
function Invoke-Up {
|
||||
# Check if image exists
|
||||
$imageExists = docker images -q $ImageTag 2>$null
|
||||
if (-not $imageExists) {
|
||||
Write-Step "Image not found — building first..."
|
||||
Invoke-Build
|
||||
}
|
||||
|
||||
# Stop & remove existing container
|
||||
docker stop $ContainerName 2>$null | Out-Null
|
||||
docker rm $ContainerName 2>$null | Out-Null
|
||||
|
||||
Write-Step "Starting container: $ContainerName on port $HostPort"
|
||||
docker run -d `
|
||||
--restart unless-stopped `
|
||||
--name $ContainerName `
|
||||
-p "${HostPort}:${ContainerPort}" `
|
||||
$ImageTag
|
||||
|
||||
Write-Host "Container started. Server should be available at http://localhost:$HostPort" -ForegroundColor Green
|
||||
Write-Host "Check logs: docker logs $ContainerName" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
function Invoke-Down {
|
||||
Write-Step "Stopping container: $ContainerName"
|
||||
docker stop $ContainerName 2>$null
|
||||
docker rm $ContainerName 2>$null
|
||||
Write-Host "Container stopped and removed." -ForegroundColor Green
|
||||
}
|
||||
|
||||
function Invoke-Reset {
|
||||
Invoke-Down
|
||||
|
||||
Write-Step "Removing Docker image: $ImageTag"
|
||||
docker rmi $ImageTag 2>$null
|
||||
|
||||
Invoke-Build
|
||||
Invoke-Up
|
||||
}
|
||||
|
||||
function Invoke-Clean {
|
||||
Write-Step "Removing dist directory..."
|
||||
if (Test-Path $DistDir) {
|
||||
Remove-Item -Recurse -Force $DistDir
|
||||
Write-Host "Removed: $DistDir" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "Nothing to clean." -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
|
||||
# --- Main dispatch ---
|
||||
switch ($Target) {
|
||||
'build' { Invoke-Build }
|
||||
'up' { Invoke-Up }
|
||||
'down' { Invoke-Down }
|
||||
'reset' { Invoke-Reset }
|
||||
'clean' { Invoke-Clean }
|
||||
'fetch' { Invoke-Fetch }
|
||||
}
|
||||
Reference in New Issue
Block a user