Sign inSign up

cludseo/corkboard

By cludseo

•Updated about 11 hours ago

Personal hosting for single HTML files and videos at stable URLs

Image
0

51

cludseo/corkboard repository overview

⁠corkboard

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.

⁠Before you start

  • Platform: The image is published for linux/arm64 only.
  • MongoDB: Stores artifact metadata.
  • S3-compatible storage: Stores HTML and video content. The app does not create buckets, so a private bucket must already exist.
TagContents
latestLatest build of the main branch
sha-<commit>Build of a specific commit. Use it to pin a version

⁠Run the container

  1. Create a private bucket in your S3-compatible storage. Put its name in S3_BUCKET in step 2.

  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
    
  3. Open http://127.0.0.1:3000⁠ and check that the list page loads. If it does, the MongoDB connection works.

  4. 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.

⁠Environment variables

Every key has a default meant for local development. In production, change at least the public address and the storage keys.

NameDefaultWhat it sets
MONGODB_URImongodb://127.0.0.1:27017/corkboardMetadata store connection string
S3_ENDPOINThttp://127.0.0.1:9000S3-compatible storage endpoint
S3_REGIONus-east-1Region required by the AWS SDK. MinIO does not check it
S3_BUCKETcorkboardPrivate bucket that holds HTML and video objects
S3_ACCESS_KEY_IDminioadminStorage access key. Always change it
S3_SECRET_ACCESS_KEYminioadminStorage secret key. Always change it
S3_FORCE_PATH_STYLEtrueAccepts only true or false. true for MinIO, false for AWS S3
PUBLIC_BASE_URLhttp://127.0.0.1:3000Base for absolute URLs in responses. Change it when the public address changes
ARTIFACT_MAX_BYTES5242880Size limit for one HTML file (5 MiB)
VIDEO_MAX_BYTES52428800Size 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.

⁠Upload artifacts

  • 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.

⁠Troubleshooting

SymptomCauseFix
List page returns 500Usually MongoDB is not up yet, or MONGODB_URI points elsewhereCheck MongoDB and MONGODB_URI
List loads but uploads failLikely a bucket problemCheck that the bucket exists and that the storage keys and S3_FORCE_PATH_STYLE are correct
Requests return 500 config_errorAn environment variable has an invalid valueFind the key name in the container logs and fix its value

⁠Limitations

  • PRIVATE is a label for sorting, not access control. Private artifacts still appear in the list and open at the same URL.
  • An upload uses about 5 times the file size in memory. At the default limit (50 MiB), one upload takes about 250 MiB, so raise container memory before raising the limit.
  • Deletion cannot be undone. After a slug changes, the old URL returns 404.

Tag summary

Content type

Image

Digest

sha256:341f20912…

Size

67.3 MB

Last updated

about 11 hours ago

docker pull cludseo/corkboard