Personal hosting for single HTML files and videos at stable URLs
51
A personal hosting service: upload a single HTML file or video and open it at a stable /a/{slug} URL.
People upload through a web form, and agents use the same features through MCP tools.
Warning: There is no authentication or authorization. Anyone who can reach the address can create, edit, and delete artifacts. Run it only on loopback or inside a trusted network. To expose it publicly, put an authenticating reverse proxy in front of it.
linux/arm64 only.| Tag | Contents |
|---|---|
latest | Latest build of the main branch |
sha-<commit> | Build of a specific commit. Use it to pin a version |
Create a private bucket in your S3-compatible storage. Put its name in S3_BUCKET in step 2.
Start the container with your environment variables. Use addresses reachable from inside the container. With a host loopback address such as 127.0.0.1, the container starts but requests fail.
docker run -d --name corkboard -p 127.0.0.1:3000:3000 \
-e MONGODB_URI=mongodb://mongo:27017/corkboard \
-e S3_ENDPOINT=http://minio:9000 \
-e S3_BUCKET=corkboard \
-e S3_ACCESS_KEY_ID=<access-key> \
-e S3_SECRET_ACCESS_KEY=<secret-key> \
-e PUBLIC_BASE_URL=http://127.0.0.1:3000 \
cludseo/corkboard:latest
Open http://127.0.0.1:3000 and check that the list page loads. If it does, the MongoDB connection works.
Upload a file at /new and check that its detail page renders. If it does, the storage connection works too.
To verify: the container runs as a non-root user on port 3000 and uses the list page (/) as its health check. Once docker ps shows healthy, it is ready.
Every key has a default meant for local development. In production, change at least the public address and the storage keys.
| Name | Default | What it sets |
|---|---|---|
MONGODB_URI | mongodb://127.0.0.1:27017/corkboard | Metadata store connection string |
S3_ENDPOINT | http://127.0.0.1:9000 | S3-compatible storage endpoint |
S3_REGION | us-east-1 | Region required by the AWS SDK. MinIO does not check it |
S3_BUCKET | corkboard | Private bucket that holds HTML and video objects |
S3_ACCESS_KEY_ID | minioadmin | Storage access key. Always change it |
S3_SECRET_ACCESS_KEY | minioadmin | Storage secret key. Always change it |
S3_FORCE_PATH_STYLE | true | Accepts only true or false. true for MinIO, false for AWS S3 |
PUBLIC_BASE_URL | http://127.0.0.1:3000 | Base for absolute URLs in responses. Change it when the public address changes |
ARTIFACT_MAX_BYTES | 5242880 | Size limit for one HTML file (5 MiB) |
VIDEO_MAX_BYTES | 52428800 | Size limit for one video (50 MiB) |
PUBLIC_BASE_URL never falls back to the Host header. If you do not update it, the url in API and MCP responses keeps pointing at the old address.
Web: Upload HTML (.html, .htm) or video (.mp4, .webm, .ogv) at /new. The uploaded file opens at /a/{slug}.
REST API: Send multipart data to POST /api/artifacts.
curl -i -X POST http://127.0.0.1:3000/api/artifacts \
-F 'title=Hello World' \
-F 'visibility=PUBLIC' \
-F 'file=@./hello.html;type=text/html'
MCP: /mcp provides five tools: list, get, create, update, and delete. In Claude Code, register it with claude mcp add --transport http corkboard http://127.0.0.1:3000/mcp. The app's /connect page also shows how to connect.
| Symptom | Cause | Fix |
|---|---|---|
| List page returns 500 | Usually MongoDB is not up yet, or MONGODB_URI points elsewhere | Check MongoDB and MONGODB_URI |
| List loads but uploads fail | Likely a bucket problem | Check that the bucket exists and that the storage keys and S3_FORCE_PATH_STYLE are correct |
Requests return 500 config_error | An environment variable has an invalid value | Find the key name in the container logs and fix its value |
PRIVATE is a label for sorting, not access control. Private artifacts still appear in the list and open at the same URL.Content type
Image
Digest
sha256:341f20912…
Size
67.3 MB
Last updated
about 11 hours ago
docker pull cludseo/corkboard