Cap, self-hosted Loom alternative: VPS deployment guide

Comparison9 min read7 steps

In February 2026, Loom removed the Creator Lite role: teams of 2 to 5 people who recorded short async videos without paying full price now face plans at $18 per seat per month. Cap (CapSoftware/Cap, AGPL-3.0, over 23,000 GitHub stars) is an open-source alternative that self-hosts on a VPS with Docker Compose. This guide explains why this change forces agencies to act, how to evaluate Cap, and how to deploy it cleanly.

Contents· Why Loom's pricing change forces agencies to act1/8
  1. 01Why Loom's pricing change forces agencies to act
  2. 02Why Cap suits an agency
  3. 03VPS prerequisites for deploying Cap
  4. 04Deploying Cap on your VPS
  5. 05Post-deployment hardening
  6. 06Post-deployment configuration: domain, storage and team
  7. 07Troubleshooting: common errors
  8. 08Cap in your self-hosted agency stack

Why Loom's pricing change forces agencies to act

The Creator Lite role allowed adding workspace members to Loom without billing them as full paid creators. A designer or project manager who records a short client demo once a week fit this role at no extra cost. Atlassian, which acquired Loom, removed this role for all accounts created after February 2026, and existing accounts are switching to Atlassian billing as they migrate.

In practice, for a small team with 10 paid creators and 20 Creator Lite users: the monthly bill goes from $180 to $540 the month of migration. Individual user reports describe invoices jumping from $18 to $220 per month overnight. The Business plan is billed at $18 per user per month, with no exceptions.

For an agency that bills clients on fixed-scope projects, this cost variability is unacceptable. Async screen capture is an internal and client communication tool — it needs a predictable cost, or it needs to be self-hosted.

Why Cap suits an agency

  • Fixed cost: you pay for the VPS, not a per-seat subscription that grows with every hire.
  • Data hosted on your infrastructure: mockup captures, demos and code never leave your server.
  • AGPL-3.0 license: the code is auditable, the roadmap is public and the project is active (over 23,000 GitHub stars as of October 5, 2026).
  • Link sharing: your clients receive a signed URL, just like with Loom, without creating an account.
  • Custom domain: you expose Cap under cap.your-domain.com, not a third-party domain.
  • Configurable storage: embedded MinIO to start, or an external S3/Cloudflare R2 bucket for production.
  • Clean interface, without an imposed paid AI overlay: the tool does what it promises, nothing more.
  • One-command deployment: docker compose up -d from the official repository.

VPS prerequisites for deploying Cap

Cap consists of four Docker services: the web application (cap-web), a MySQL 8.0 database (ps-mysql), a media server for transcoding (cap-media-server) and MinIO for S3-compatible object storage. The stack consumes about 1 GB of RAM at idle; under production conditions with several simultaneous recordings, plan for 2 vCPU and 4 GB of RAM as a baseline. Allow 20 GB of SSD/NVMe disk for binaries and initial videos, then add or externalize storage according to volume.

Other prerequisites:
- Docker Engine 24+ and Docker Compose v2 installed on the VPS.
- A dedicated subdomain (for example cap.your-domain.com) pointed at the VPS IP.
- A reverse proxy handling HTTPS (Caddy or Nginx with Certbot).
- Ports 3000 (app), 3456 (media server), 3902/3903 (MinIO) accessible from the reverse proxy, but not directly exposed to the public.

Deploying Cap on your VPS

  1. Clone the official repository

    On your VPS, clone the CapSoftware repository and navigate to the root directory:

    git clone https://github.com/CapSoftware/Cap.git
    cd Cap

    The repository includes a docker-compose.template.yml file. Copy it as docker-compose.yml to avoid overwriting your changes on a future git pull:

    cp docker-compose.template.yml docker-compose.yml
  2. Configure environment variables

    Create a .env file at the root from the provided template, then edit the critical values:

    cp .env.example .env

    Variables to set before any public exposure:

    # Public application URL
    NEXTAUTH_URL=https://cap.your-domain.com
    WEB_URL=https://cap.your-domain.com
    
    # Secrets — regenerate these values, NEVER leave defaults
    NEXTAUTH_SECRET=<random-32-char-string>
    DATABASE_ENCRYPTION_KEY=<random-32-char-string>
    
    # MySQL database
    DATABASE_URL=mysql://root:your-password@ps-mysql:3306/planetscale
    
    # Embedded MinIO storage (replace with external S3 in production)
    CAP_AWS_ACCESS_KEY=minioadmin
    CAP_AWS_SECRET_KEY=minioadmin
    CAP_AWS_BUCKET=cap-media
    CAP_AWS_REGION=us-east-1
    S3_PUBLIC_ENDPOINT=https://cap.your-domain.com/s3
    S3_INTERNAL_ENDPOINT=http://minio:9000
    
    # Media server
    MEDIA_SERVER_URL=http://cap-media-server:3456
    MEDIA_SERVER_WEBHOOK_SECRET=<random-32-char-string>

    If you do not configure an SMTP server, login links appear in the cap-web container logs: docker compose logs cap-web. This is sufficient for initial testing.

  3. Start the stack

    Launch the four services in the background:

    docker compose up -d

    Verify that all containers are in running state:

    docker compose ps

    The web application listens on port 3000, the media server on 3456, MinIO on 3902 (API) and 3903 (console). Check the logs if a service stays in restarting:

    docker compose logs cap-web --tail 50
  4. Configure the HTTPS reverse proxy with Caddy

    Caddy is the most straightforward solution: it handles Let's Encrypt certificates automatically. Create a /etc/caddy/Caddyfile file or add a block to your existing configuration:

    cap.your-domain.com {
        reverse_proxy localhost:3000
    }

    Reload Caddy:

    systemctl reload caddy

    If you use Nginx, create a vhost with proxy_pass http://127.0.0.1:3000; and obtain a certificate via certbot --nginx -d cap.your-domain.com.

  5. First login and admin account creation

    Open https://cap.your-domain.com in your browser. Cap prompts you to create an account by entering your email address. If you have not configured an SMTP server, retrieve the login link from the logs:

    docker compose logs cap-web 2>&1 | grep -i 'signin\|magic\|link'

    Copy the displayed URL and paste it into your browser to log in. The first account created becomes the instance administrator.

  6. Configure external S3 storage (recommended for production)

    Embedded MinIO is suitable for testing, but for production prefer an external S3 bucket (AWS S3, Cloudflare R2 or Backblaze B2). In Cap instance settings (Storage section), fill in:

    - Access Key and Secret Key from your provider
    - Bucket name and Region
    - Public URL of the bucket (for sharing links)

    Update the CAP_AWS_* variables in your .env, then restart the service:

    docker compose up -d cap-web
  7. Invite the team and test a recording

    From the Cap dashboard, invite your collaborators by email. Each member installs the Cap desktop application (macOS, Windows) or uses the browser extension, and points to your instance URL in settings ("Custom server" field). Make a test recording and verify that the video appears in the dashboard and that the sharing link is accessible from an external browser.

Post-deployment hardening

Before inviting clients to view videos, verify these four points:

1. Default secrets replaced — NEXTAUTH_SECRET, DATABASE_ENCRYPTION_KEY and MEDIA_SERVER_WEBHOOK_SECRET must never be those from the repository. openssl rand -hex 32 generates a solid value.
2. MinIO not publicly exposed — ports 3902 and 3903 should only be accessible from the reverse proxy or via an internal Docker network. Add 127.0.0.1:3902:9000 in docker-compose.yml to bind the port to localhost only.
3. Automatic updates disabled by default — Cap does not self-update. Schedule a monthly docker compose pull && docker compose up -d, preceded by a MySQL volume snapshot.
4. MySQL database backups — a daily mysqldump is sufficient for metadata (the videos themselves are in MinIO or S3). Cron example: 0 2 * * * docker exec ps-mysql mysqldump -u root -pyour-pwd planetscale > /backups/cap-$(date +%F).sql.

Post-deployment configuration: domain, storage and team

Once Cap is operational, three adjustments make the instance ready for agency use:

Custom domain: if you used a temporary subdomain during deployment, update NEXTAUTH_URL and WEB_URL in .env, restart cap-web and update the DNS entry. Existing sharing links remain valid as long as you redirect the old subdomain.

Workspace: Cap organizes recordings into Spaces. Create one space per client or project to keep videos separate. Guests can view without an account if the link is public.

Storage quota: if you store videos on local MinIO, monitor VPS disk space with df -h. A Cap recording weighs between 10 and 50 MB depending on duration and resolution. Consider an additional volume or migration to external S3 once the volume exceeds a few dozen GB.

Troubleshooting: common errors

Error: connect ECONNREFUSED 127.0.0.1:3306 — the MySQL container is not yet started or its password in DATABASE_URL does not match the one defined in the ps-mysql service. Check with docker compose logs ps-mysql and ensure that the MYSQL_ROOT_PASSWORD variables in docker-compose.yml and DATABASE_URL in .env are consistent.

The login URL does not arrive by email — without SMTP configured, the link appears only in cap-web container logs. Run docker compose logs cap-web 2>&1 | grep http to find it.

The video loads indefinitely after recording — the media server (cap-media-server) is not reachable from cap-web. Check that MEDIA_SERVER_URL=http://cap-media-server:3456 is set and that both services are on the same Docker network (docker compose ps should show both as running).

The sharing link returns a 404 error — S3_PUBLIC_ENDPOINT may point to an incorrect URL or MinIO is not externally accessible. If using local MinIO, expose it behind the reverse proxy under a dedicated path (e.g., /s3/) or migrate to an external S3 bucket.

The client cannot point the desktop app to your instance — check that the "Custom server" field in Cap Desktop preferences accepts exactly the public URL without a trailing slash: https://cap.your-domain.com.

Cap in your self-hosted agency stack

Cap integrates naturally into a stack where async capture replaces client review meetings. Paired with Penpot for collaborative design and Chatwoot for client support, it covers the three asynchronous communication channels of an agency without a variable SaaS subscription.

If your infrastructure already relies on Atlassian tools migrated to self-hosted alternatives — Jira replaced by Plane, Confluence by Outline — migrating from Loom to Cap follows the same logic: fixed cost, controlled data, updates at your own pace.

Cap remains a young project with a rapidly growing community. For production use today, the Docker Compose + MinIO or external S3 combination is stable. The macOS desktop application is the most polished; the Windows version is functional. The browser extension covers tab capture use cases without heavy installation.

Your team self-hosts its production tools

Cap deploys in minutes on a ServOrbit VPS. Root access, dedicated IPv4, preconfigured Docker and NVMe storage for your async videos.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.

Message us on WhatsAppopens in a new tab