Self-Hosting Mbin (Kbin Fork) with Docker Compose

Docker Compose Configuration First — Then We’ll Explain What Mbin Actually Is

Mbin is the community-maintained fork of Kbin, a federated platform that combines Reddit-style link aggregation with Twitter-style microblogging in one ActivityPub-compatible package. The original Kbin developer went quiet in late 2023; Mbin picked up active development and ships monthly releases. Official site

# Quick reference: 6 containers, 6 GB RAM minimum, HTTPS required
# Services: PHP app, Messenger worker, PostgreSQL, Valkey, RabbitMQ, AMQP proxy

If you want just a Reddit replacement, Lemmy is simpler. Mbin’s value is the hybrid model — magazines (subreddits) and microblogs (tweets) on one platform, federating with the entire fediverse.

FeatureMbin
Link aggregationYes (magazines, like subreddits)
MicrobloggingYes (short posts, like tweets)
ActivityPubFull federation
Mastodon interopExcellent — microblogs appear as toots
Lemmy interopGood — magazines cross-federate
VotingUpvotes + downvotes (configurable)
ModerationPer-magazine + instance-level
Latest versionv1.9.1 (Feb 2026)
LicenseAGPL-3.0

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose v2+ installed (guide)
  • 6 GB RAM minimum (8 GB recommended)
  • 40 GB of free disk space
  • A domain name with DNS A record configured
  • Ports 80 and 443 open (Caddy handles HTTPS automatically)
RequirementMinimumRecommended
CPU4 cores (2 GHz+)4+ cores
RAM6 GB8 GB
Disk40 GB80 GB+
HTTPSRequired for federationRequired

Docker Compose Configuration

Mbin uses six services: the PHP application server, a Messenger worker for async jobs (federation delivery, notifications), PostgreSQL, Valkey (Redis fork), RabbitMQ for message queuing, and an AMQP proxy.

Create a .env file:

# Mbin environment configuration
SERVER_NAME=mbin.yourdomain.com
KBIN_DOMAIN=mbin.yourdomain.com
KBIN_TITLE="Your Mbin Instance"
KBIN_CONTACT_EMAIL=[email protected]
KBIN_STORAGE_URL=https://mbin.yourdomain.com/media

# Application secret — generate with: openssl rand -hex 32
APP_SECRET=generate-a-64-char-hex-string-here

# Database
POSTGRES_VERSION=17
POSTGRES_DB=mbin
POSTGRES_USER=mbin
POSTGRES_PASSWORD=change-this-strong-password

# Valkey (Redis-compatible cache)
VALKEY_PASSWORD=change-this-valkey-password

# RabbitMQ
RABBITMQ_DEFAULT_USER=mbin
RABBITMQ_DEFAULT_PASS=change-this-rabbitmq-password

# Mercure (real-time updates)
MERCURE_JWT_SECRET=generate-another-random-string-minimum-32-chars

# SMTP — optional but recommended for email verification
MAILER_DSN=smtp://user:[email protected]:587

Generate OAuth2 keys (required for API authentication):

mkdir -p config/oauth2
openssl genrsa -out config/oauth2/private.pem 4096
openssl rsa -in config/oauth2/private.pem -pubout -out config/oauth2/public.pem

Create docker-compose.yml:

services:
  php:
    image: ghcr.io/mbinorg/mbin:v1.9.1
    restart: unless-stopped
    env_file: .env
    volumes:
      - caddy_data:/data
      - caddy_config:/config
      - media:/var/www/mbin/public/media
      - ./config/oauth2:/var/www/mbin/config/oauth2:ro
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    depends_on:
      postgres:
        condition: service_healthy
      valkey:
        condition: service_healthy
      rabbitmq:
        condition: service_healthy

  messenger:
    image: ghcr.io/mbinorg/mbin:v1.9.1
    restart: unless-stopped
    env_file: .env
    command: bin/console messenger:consume async --time-limit=3600
    volumes:
      - media:/var/www/mbin/public/media
      - ./config/oauth2:/var/www/mbin/config/oauth2:ro
    depends_on:
      - php
    deploy:
      replicas: 6

  postgres:
    image: postgres:17-bookworm
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
      interval: 10s
      timeout: 5s
      retries: 5

  valkey:
    image: valkey/valkey:8-bookworm
    restart: unless-stopped
    command: valkey-server --requirepass ${VALKEY_PASSWORD} --appendonly yes
    volumes:
      - valkey_data:/data
    healthcheck:
      test: ["CMD", "valkey-cli", "-a", "${VALKEY_PASSWORD}", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  rabbitmq:
    image: rabbitmq:3-management-alpine
    restart: unless-stopped
    environment:
      RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER}
      RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS}
    volumes:
      - rabbitmq_data:/var/lib/rabbitmq
    healthcheck:
      test: ["CMD", "rabbitmq-diagnostics", "check_running"]
      interval: 30s
      timeout: 10s
      retries: 5

  amqproxy:
    image: cloudamqp/amqproxy:latest
    restart: unless-stopped
    command: amqproxy --listen 0.0.0.0 --port 5673 amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672
    depends_on:
      - rabbitmq

volumes:
  pgdata:
  caddy_data:
  caddy_config:
  media:
  valkey_data:
  rabbitmq_data:

Start the stack:

docker compose up -d

Initial Setup

Mbin uses Caddy internally, so HTTPS is automatic — Caddy obtains and renews Let’s Encrypt certificates. Once containers are running, the site should be accessible at https://mbin.yourdomain.com.

Create the admin account:

docker compose exec php bin/console mbin:user:create admin [email protected] --admin

Visit the site, log in with your admin credentials, and configure the instance:

  • Settings > General — instance name, description, contact email, about page
  • Settings > Content — default content language, NSFW policy, federation scope
  • Settings > Registration — open, approval-required, or invite-only

Configuration

Federation

Once your instance is live on HTTPS, federation works automatically. Other Mbin and Lemmy instances can discover your magazines. Mastodon users can follow your instance’s microblogs. To manage federation:

  • Admin > Federation — view connected instances
  • Block domains — prevent federation with specific instances
  • Defederation — fully disconnect from problematic instances

Magazines and Microblogs

Mbin has two content types that coexist on the same platform:

  • Magazines — equivalent to Reddit subreddits or Lemmy communities. Posts can be links or text. Comments, voting, and moderation per-magazine.
  • Microblogs — short-form posts, equivalent to Mastodon toots or Twitter posts. Appear in a separate tab. Federate as ActivityPub Notes.

Users access both from the same interface with tabbed navigation.

Moderation

Moderators can be assigned per-magazine. Instance-level admin tools include:

  • User management (ban, suspend, delete)
  • Content removal
  • Domain blocking (federation control)
  • Report queue
  • NSFW tagging enforcement

Advanced Configuration

Mercure (Real-Time Updates)

Mbin supports real-time content updates via Mercure (built into the Caddy server). The MERCURE_JWT_SECRET in your .env enables this. Users see new posts and comments appear without refreshing. Disable by removing the Mercure environment variables if you don’t need it.

Email Setup

While optional for basic operation, email is needed for:

  • User registration verification
  • Password resets
  • Notifications

Configure MAILER_DSN in .env with your SMTP provider.

Scaling Messenger Workers

The deploy.replicas: 6 on the messenger service runs six parallel workers for processing federated messages. For small instances (under 100 users), reduce to 2-3 replicas to save memory:

  messenger:
    deploy:
      replicas: 2

For large instances, increase replicas and monitor the RabbitMQ management UI at port 15672.

Reverse Proxy

Mbin uses Caddy internally for HTTPS and reverse proxying. If you want to run Mbin behind your own reverse proxy (Nginx Proxy Manager, Traefik), you need to disable Caddy’s automatic HTTPS and configure your proxy to handle SSL termination instead. See the Mbin documentation for reverse proxy configuration.

For general reverse proxy concepts, see Reverse Proxy Setup.

Backup

Critical data to back up:

DataLocationPriority
PostgreSQL databasepgdata volumeCritical — all content, users, federation state
Media filesmedia volumeImportant — uploaded images and thumbnails
OAuth2 keysconfig/oauth2/Critical — API authentication breaks without these
Environment file.envCritical — contains all secrets
Caddy datacaddy_data volumeMedium — TLS certificates (auto-renewed)

Back up the database:

docker compose exec postgres pg_dump -U mbin mbin > mbin-backup-$(date +%Y%m%d).sql

For automated backup strategies, see Backup Strategy.

Troubleshooting

Federation not working

Symptom: Other instances can’t discover your magazines, follows fail.

Fix: Mbin requires valid HTTPS. Verify your domain resolves and Caddy has obtained a certificate: docker compose logs php | grep certificate. Check that ports 80 and 443 are open. Verify KBIN_DOMAIN in .env matches your actual domain exactly.

Messenger workers dying

Symptom: Federation delivery stops, notifications delayed, RabbitMQ queue grows.

Fix: Check docker compose logs messenger. Common causes: RabbitMQ connection failures (verify credentials), out of memory (reduce replicas), or the --time-limit=3600 causing clean restarts (this is normal — workers restart hourly by design). If RabbitMQ is unhealthy, check docker compose logs rabbitmq.

High memory usage

Symptom: Server running out of memory, OOM kills.

Fix: Mbin with 6 messenger replicas uses ~4 GB total. Reduce messenger replicas to 2-3. Limit PostgreSQL: shared_buffers=256MB. Limit RabbitMQ: set vm_memory_high_watermark.relative = 0.3 in RabbitMQ config. Consider adding swap space (2 GB recommended).

OAuth2 errors on API access

Symptom: API calls return 401, third-party apps can’t authenticate.

Fix: Verify OAuth2 keys exist at config/oauth2/private.pem and config/oauth2/public.pem. Regenerate if missing: openssl genrsa -out config/oauth2/private.pem 4096 && openssl rsa -in config/oauth2/private.pem -pubout -out config/oauth2/public.pem. Restart the php container after regenerating.

Microblogs not appearing on Mastodon

Symptom: Mastodon users follow your account but don’t see microblog posts.

Fix: Mastodon only shows content published after the follow was established. Verify federation is working by checking Admin > Federation for the Mastodon instance. Send a new microblog post and check if it appears. If not, check messenger worker logs for delivery errors to that instance.

Resource Requirements

ComponentRAM (idle)RAM (active)CPUDisk
PHP (Caddy + app)~300 MB~600 MBMediumMinimal
Messenger (per replica)~150 MB~250 MBMediumMinimal
Messenger (6 replicas total)~900 MB~1.5 GBMedium-HighMinimal
PostgreSQL~200 MB~500 MBMediumGrows with content
Valkey~50 MB~100 MBLowMinimal
RabbitMQ~200 MB~400 MBLow-MediumMinimal
AMQP Proxy~30 MB~50 MBMinimalMinimal
Total (6 replicas)~1.7 GB~3.2 GBMedium-High40 GB+

Verdict

If you want a Reddit + Twitter hybrid on the fediverse, Mbin is the only serious option. The magazine system works well for link aggregation, the microblogging tab handles short-form posts, and ActivityPub federation means you’re connected to Mastodon, Lemmy, and the broader fediverse from day one.

The cost is complexity. Six containers, 6 GB RAM minimum, OAuth2 key generation, RabbitMQ management — this is not a casual self-host. If you just want a Reddit replacement, Lemmy deploys in four containers on 2 GB of RAM. But if the hybrid model genuinely appeals to you, Mbin delivers it well and the community is actively shipping improvements.

FAQ

Is Kbin dead? Should I use Mbin instead?

The original Kbin project is effectively abandoned — the developer has been unresponsive since late 2023. Mbin is the community-maintained fork with active development and monthly releases. Use Mbin.

Can Lemmy users interact with Mbin?

Yes. Lemmy communities can subscribe to Mbin magazines and vice versa. Votes, comments, and posts federate between them. Mbin microblogs appear as regular posts on Lemmy.

How does Mbin compare to Mastodon?

Mbin includes microblogging like Mastodon, but also has Reddit-style link aggregation that Mastodon lacks. Mastodon is better for pure microblogging (larger ecosystem, more apps). Mbin is better if you want both in one platform.

Can I run Mbin on a Raspberry Pi?

Not recommended. The minimum 6 GB RAM requirement rules out Pi 4 (4 GB max usable) and the CPU requirements are significant. Use a proper VPS or x86 server.

Is there a mobile app?

Interstellar is the primary mobile app for Mbin/Kbin. It’s available on Android and iOS. Some Mastodon apps can interact with Mbin microblogs but not the magazine/link aggregation features.

Comments