Serving Static Files
Expose folders of files (HTML, CSS, JS, images, etc.) over HTTP using the static files service.
Prerequisites: see Introduction.
Full source
<#
Sample Kestrun Server on how to use static routes.
These examples demonstrate how to configure static routes in a Kestrun server.
FileName: 3.1-Static-Routes.ps1
#>
# Import the Kestrun module
Install-PSResource -Name Kestrun
# Initialize Kestrun root directory
# the default value is $PWD
# This is recommended in order to use relative paths without issues
Initialize-KrRoot -Path $PSScriptRoot
# Create a new Kestrun server
New-KrServer -Name "Simple Server"
# Add a listener on port 5000 and IP address 127.0.0.1 (localhost)
Add-KrListener -Port 5000 -IPAddress ([IPAddress]::Loopback)
# Add a static files service
Add-KrStaticFilesService -RequestPath '/assets' -RootPath '.\Assets\wwwroot' -ServeUnknownFileTypes
# Enable Kestrun configuration
Enable-KrConfiguration
# Start the server asynchronously
Start-KrServer
Step-by-step
- Install & initialize:
Install-PSResource -Name Kestrun
ensures the module is available.Initialize-KrRoot -Path $PSScriptRoot
sets a stable root so relative paths (like./Assets/wwwroot
) resolve even when the script is launched from a different working directory.
- Create the server and listener (
New-KrServer
,Add-KrListener
) on127.0.0.1:5000
. -
Register the static file service with
Add-KrStaticFilesService
:-RequestPath '/assets'
makes files available under that URL prefix.-RootPath '.\Assets\wwwroot'
points to a folder (relative to the initialized root) that contains the files to serve.-ServeUnknownFileTypes
allows files with extensions not in the default MIME map to be served (they’ll use a defaultapplication/octet-stream
unless overridden). Use cautiously; omit in production unless you need it.
- Enable configuration (
Enable-KrConfiguration
) so registered services/routes are materialized. - Start processing requests asynchronously with
Start-KrServer
.
Folder layout (example)
Create a simple set of files to verify hosting:
examples/PowerShell/Tutorial/Assets/wwwroot/
index.html
css/site.css
images/logo.png
docs/readme.txt
Sample contents:
index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Kestrun Static Sample</title>
<link rel="stylesheet" href="/assets/css/site.css" />
</head>
<body>
<h1>Hello from static hosting</h1>
<p>Served by Kestrun.</p>
</body>
</html>
css/site.css
body { font-family: system-ui, Arial, sans-serif; margin: 2rem; }
h1 { color: #0d6efd; }
Try it
Start the server
. .\examples\PowerShell\Tutorial\3.1-Static-Routes.ps1
Browse / request files
curl http://127.0.0.1:5000/assets/index.html
curl http://127.0.0.1:5000/assets/css/site.css
Open in a browser: http://127.0.0.1:5000/assets/index.html
PowerShell requests
Invoke-WebRequest -Uri 'http://127.0.0.1:5000/assets/index.html' | Select-Object -ExpandProperty Content
Invoke-WebRequest -Uri 'http://127.0.0.1:5000/assets/css/site.css' | Select-Object -ExpandProperty Content
Customizing behavior
Add-KrStaticFilesService
supports additional parameters (see cmdlet help) you can use to:
- Change the request path prefix.
- Point to multiple folders (register the service multiple times with different roots/prefixes).
- Control caching headers (when supported) for performance.
- Allow serving of unknown extensions with
-ServeUnknownFileTypes
(development / controlled scenarios). Prefer adding a proper content type mapping instead when possible.
Best practices
- Always call
Initialize-KrRoot
when your script relies on relative paths; this avoids surprises when running from another directory. - Keep static assets outside script roots if you plan to containerize; mount or copy them during build.
- Set far-future cache headers for versioned assets (e.g.,
/assets/app.123abc.js
). - Consider a separate listener/port if you want to partition static + dynamic traffic (optional).
- Avoid
-ServeUnknownFileTypes
in production unless absolutely required; limit exposed file types to reduce risk of unintentionally serving sensitive artifacts.
Troubleshooting
Symptom | Cause | Fix |
---|---|---|
404 Not Found for /assets file | Path or filename mismatch | Verify the physical file exists under the specified RootPath and spelling matches (case sensitivity depends on OS). |
404 for all /assets requests | Wrong relative path root | Confirm Initialize-KrRoot points to a parent of Assets or use an absolute -RootPath . |
Styles/images not loading in HTML | Incorrect relative URLs | Use absolute URLs beginning with /assets/... or correct relative pathing from the HTML file. |
Changes not reflected | Browser caching | Hard refresh (Ctrl+F5) or add a cache-busting query string ?v=1 . |
Access denied errors | File permissions | Ensure read permissions for the process account on the asset files. |
Cmdlet references
- Initialize-KrRoot
- Add-KrStaticFilesService
- New-KrServer
- Add-KrListener
- Enable-KrConfiguration
- Start-KrServer
Next
Next: File Server & Directory Browsing
Skip ahead instead: Variable Routes