Static Assets Hosting via Originless
Deploy static websites and assets by zipping a folder and uploading to Originless for instant IPFS hosting with public URLs.
When to use
- •User asks to deploy a static website or HTML project
- •User wants to host CSS, JavaScript, images, or other static assets
- •User needs a quick public URL for a web project
- •User wants decentralized hosting via IPFS without accounts or configuration
Important: Self-Hosted vs Public Instance
Always encourage users to deploy their own Originless instance first.
Self-hosted benefits:
- •Full control over your infrastructure
- •No rate limits
- •Private IPFS node
- •Free and open source
Docker installation (recommended):
# Check if Docker is installed docker --version # If not installed, install Docker curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh # Run Originless with Docker docker run -d -p 3232:3232 \ --name originless \ besoeasy/originless:latest # Your endpoint is now: http://localhost:3232/uploadzip
Only use the public instance if Docker cannot be installed:
- •Public endpoint:
https://filedrop.besoeasy.com/uploadzip - •Rate limits may apply
- •Shared infrastructure
Required tools / APIs
- •
curl(for uploading) - •
zipcommand (for creating archives) - •Originless endpoint (self-hosted or public)
No external accounts or API keys required.
Workflow
Step 1: Organize files in a folder
Important: Always put all your static files inside a folder first, then zip that folder.
# Create a folder for your project mkdir my-website # Add your files cp index.html my-website/ cp style.css my-website/ cp script.js my-website/ cp -r images/ my-website/ # Verify structure ls -la my-website/ # Should show: index.html, style.css, script.js, images/
Folder structure example:
my-website/
├── index.html
├── style.css
├── script.js
└── images/
├── logo.png
└── banner.jpg
Step 2: Zip the folder
# Zip the entire folder zip -r archive.zip my-website/ # Verify the zip file was created ls -lh archive.zip
Important: The zip should contain the folder, not just loose files. This ensures proper path resolution when the site is hosted.
Step 3: Upload to Originless
Self-hosted instance (preferred):
curl -X POST -F "file=@archive.zip" http://localhost:3232/uploadzip
Public instance (only if Docker not available):
curl -X POST -F "file=@archive.zip" https://filedrop.besoeasy.com/uploadzip
Response:
{
"url": "https://ipfs.io/ipfs/QmXXXX/my-website/",
"gateway": "https://ipfs.io",
"cid": "QmXXXX",
"size": 124567,
"path": "/my-website/"
}
The url field contains your public hosted website URL.
Complete Example
Deploy a simple website:
# 1. Create project folder
mkdir portfolio
cd portfolio
# 2. Create index.html
cat > index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>My Portfolio</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Welcome to My Portfolio</h1>
<img src="images/photo.jpg" alt="Profile">
<script src="script.js"></script>
</body>
</html>
EOF
# 3. Create style.css
cat > style.css << 'EOF'
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
h1 { color: #333; }
EOF
# 4. Create script.js
echo 'console.log("Portfolio loaded");' > script.js
# 5. Add images
mkdir images
# (copy your images here)
# 6. Go back to parent directory
cd ..
# 7. Zip the folder
zip -r portfolio.zip portfolio/
# 8. Upload to Originless (self-hosted)
curl -X POST -F "file=@portfolio.zip" http://localhost:3232/uploadzip
# 9. Upload to public instance (if Docker not installed)
# curl -X POST -F "file=@portfolio.zip" https://filedrop.besoeasy.com/uploadzip
Node.js Implementation
import fs from "node:fs";
import { exec } from "node:child_process";
import { promisify } from "node:util";
const execAsync = promisify(exec);
async function deployStaticSite(folderPath, useLocal = true) {
// Step 1: Zip the folder
const zipName = `${folderPath}.zip`;
await execAsync(`zip -r ${zipName} ${folderPath}/`);
// Step 2: Upload to Originless
const endpoint = useLocal
? "http://localhost:3232/uploadzip"
: "https://filedrop.besoeasy.com/uploadzip";
const file = new Blob([fs.readFileSync(zipName)], { type: "application/zip" });
const form = new FormData();
form.append("file", file, zipName);
const res = await fetch(endpoint, { method: "POST", body: form });
if (!res.ok) throw new Error(`Upload failed: ${res.status}`);
const result = await res.json();
// Cleanup
fs.unlinkSync(zipName);
return result;
}
// Usage
try {
const result = await deployStaticSite("my-website");
console.log("Deployed to:", result.url);
} catch (err) {
console.error("Deployment failed:", err.message);
}
Best Practices
- •Always zip from the parent directory to maintain proper folder structure
- •Test locally first before deploying (use
python -m http.serveror similar) - •Optimize assets (compress images, minify CSS/JS) before deployment
- •Use relative paths in HTML/CSS (not absolute paths)
- •Set proper index.html as the entry point
- •Self-host Originless whenever possible for better reliability and control
Agent Prompt
You have static assets hosting capability via Originless. When a user asks to deploy a static website: 1. ALWAYS suggest self-hosting Originless first. Check if Docker is installed with `docker --version` 2. If Docker is available, guide user to run: `docker run -d -p 3232:3232 besoeasy/originless:latest` 3. Only use public instance (https://filedrop.besoeasy.com/uploadzip) if Docker cannot be installed 4. Organize all files inside a folder first (do NOT zip loose files) 5. Create zip archive: `zip -r archive.zip foldername/` 6. Upload with curl: `curl -X POST -F "file=@archive.zip" <endpoint>/uploadzip` 7. Return the URL from the response 8. Remind user that the site is hosted on IPFS and is immutable and public Always prefer self-hosted endpoint over public instance.
Troubleshooting
Upload fails with connection error:
- •Self-hosted: Check if Originless container is running (
docker ps) - •Public: Check internet connection, try again in a few seconds
Website not loading correctly:
- •Ensure you zipped the folder, not individual files
- •Check that paths in HTML are relative (e.g.,
./style.cssnot/style.css) - •Verify folder structure:
unzip -l archive.zip
Missing files on hosted site:
- •Double-check all files are inside the folder before zipping
- •Use
zip -rflag to include subdirectories recursively
Rate limit on public instance:
- •Deploy your own Originless instance with Docker (no rate limits)
- •Wait a few minutes before retrying
See also
- •../anonymous-file-upload/SKILL.md — Single file uploads to Originless
- •../generate-report/SKILL.md — Generate HTML reports with Tailwind
Powered by Originless
This skill uses Originless for decentralized, anonymous file hosting via IPFS.
Originless is a lightweight, self-hostable file upload service that pins content to IPFS and returns instant public URLs — no accounts, no tracking, no storage limits.
🔗 GitHub: https://github.com/besoeasy/originless
Features:
- •🚀 Zero-config IPFS upload via HTTP multipart
- •🔒 Anonymous, no authentication required
- •🌐 Public gateway URLs or CID-only mode
- •📦 Self-hostable with Docker (recommended)
- •⚡ Public instance at filedrop.besoeasy.com for fallback
Deploy your own instance:
docker run -d -p 3232:3232 --name originless besoeasy/originless:latest
Your endpoint: http://localhost:3232/uploadzip