Skip to content

1001-digital/ipfs.server

Repository files navigation

IPFS Server

A production-ready IPFS node built on Kubo with Caddy as a reverse proxy for authentication, deployed via Kamal.

Architecture

A single Docker image bundles two services:

  • Kubo v0.40.0 — IPFS daemon providing content pinning, IPNS publishing, and a public gateway
  • Caddy — reverse proxy adding basic auth to the admin API and handling large uploads
                        ┌─────────────────────────────────┐
                        │         Docker Container        │
                        │                                 │
  ipfs.1001.digital ───▶│  :8080  Kubo Gateway (public)   │
                        │         read-only, pinned only  │
                        │                                 │
admin.ipfs.1001.digital▶│  :5080  Caddy ──▶ :5001 Kubo API│
                        │         basic auth              │
                        │                                 │
          swarm ◀──────▶│  :4001  Kubo Swarm (P2P)        │
                        └─────────────────────────────────┘

Features

  • Public gateway serves only locally pinned content (Gateway.NoFetch = true)
  • Admin API protected by basic auth via Caddy — supports the full Kubo HTTP API
  • Unlimited upload size with streaming support for large files
  • IPNS records with a 14-day lifetime to survive extended downtime
  • Web UI automatically pinned on startup for admin access
  • Persistent storage via a Docker volume (ipfs_data) or configurable bind mount

Prerequisites

  • Docker
  • Kamal (gem install kamal)
  • pnpm
  • A server with ports 4001, 8080, and 5080 available

Setup

  1. Copy the environment template and fill in your values:
cp .env.production.example .env.production
Variable Description
DOCKER_REGISTRY_USERNAME Docker Hub username
DEPLOY_HOST Target server IP or hostname
KAMAL_REGISTRY_PASSWORD Docker Hub access token
IPFS_HOST Public gateway domain
IPFS_ADMIN_HOST Admin API domain
ADMIN_PASSWORD Plaintext admin password (used by the upload script)
ADMIN_PASSWORD_HASH Bcrypt-hashed admin password (used by Caddy)
  1. Generate a bcrypt password hash for admin access:
caddy hash-password --plaintext 'your-password'
  1. Install dependencies and run initial setup:
pnpm install
pnpm kamal:setup

Node Configuration

These optional environment variables can be set in .env.production to tune node behavior:

Variable Default Description
GATEWAY_NO_FETCH true When true, only serves pinned/cached content. Set to false to fetch from the IPFS network on demand.
GATEWAY_DESERIALIZED_RESPONSES true Enables directory listings and deserialized responses.
IPNS_RECORD_LIFETIME 336h How long IPNS records remain valid. Default is 14 days.
STORAGE_MAX 20GB Maximum disk space for the IPFS datastore.
ENABLE_GC true Enable automatic garbage collection. Frees unpinned content when storage exceeds the GC watermark.
STORAGE_GC_WATERMARK 90 Percentage of STORAGE_MAX that triggers garbage collection.
GC_PERIOD 1h How often the daemon checks whether to run garbage collection.
CONN_MGR_HIGH_WATER 96 Maximum number of peer connections to maintain.
CONN_MGR_LOW_WATER 32 Peer connections to trim down to when HighWater is reached.
IPFS_VOLUME ipfs_data Storage volume for IPFS data. Use a host path (e.g. /mnt/ipfs/ipfs_data) for bind mounts.
CONTAINER_CPUS 2 CPU cores available to the Docker container.
CONTAINER_MEMORY 6G Maximum memory for the Docker container.
RESOURCE_MGR_MAX_MEMORY 4GB Maximum memory for the libp2p resource manager. Should be less than CONTAINER_MEMORY to leave headroom for Caddy, GC, and other overhead.
RESOURCE_MGR_MAX_FILE_DESCRIPTORS 4096 Maximum file descriptors for the libp2p resource manager.

Deployment

pnpm kamal:deploy

This builds the Docker image, pushes it to Docker Hub, and deploys to your server. Kamal handles zero-downtime deploys, health checks, and TLS.

Uploading Content

Upload files or directories to the node's MFS (Mutable File System) via the admin API:

# Upload a directory
pnpm upload ./dist

# Upload a single file
pnpm upload ./image.png

# Pin the content after uploading
pnpm upload ./dist --pin

# Specify a custom MFS path (defaults to /<name>)
pnpm upload ./dist --mfs-path /my-site

Requires IPFS_ADMIN_HOST and ADMIN_PASSWORD in .env.production. Set IPFS_HOST to use your own gateway in the output URL (defaults to ipfs.io).

Each upload is logged to uploads.log with the timestamp, CID, MFS path, and source path.

Usage

Public Gateway

Access pinned content over HTTP:

https://ipfs.1001.digital/ipfs/<CID>
https://ipfs.1001.digital/ipns/<name>

Only locally pinned content is served — the gateway does not fetch from the network.

Admin API

The full Kubo RPC API is available behind basic auth:

# Pin content
curl -u admin:<password> -X POST \
  "https://admin.ipfs.1001.digital/api/v0/pin/add?arg=<CID>"

# Add a file
curl -u admin:<password> -X POST -F file=@myfile.txt \
  "https://admin.ipfs.1001.digital/api/v0/add"

# Publish an IPNS record
curl -u admin:<password> -X POST \
  "https://admin.ipfs.1001.digital/api/v0/name/publish?arg=<CID>"

Shell Access

pnpm kamal:sh

Project Structure

├── Dockerfile                      # Multi-stage: Caddy + Kubo
├── config/
│   ├── Caddyfile                   # Reverse proxy config
│   ├── deploy.yml                  # Kamal deployment manifest
│   └── container-init.d/
│       ├── 001-server-config.sh    # IPFS daemon configuration
│       ├── 002-admin-proxy.sh      # Start Caddy
│       └── 003-pin-webui.sh        # Pin Web UI on startup
├── .kamal/
│   └── hooks/
│       ├── pre-deploy              # Stop containers to free ports
│       └── post-deploy             # Register admin proxy
├── scripts/
│   └── upload.ts                   # Upload files/directories to IPFS
├── package.json                    # Kamal deployment & upload scripts
└── .env.production.example         # Environment template

License

MIT

About

One command to set up a live and secure IPFS server.

Resources

Stars

Watchers

Forks

Releases

No releases published

Contributors