Skip to content

Install Folio on CapRover

You run CapRover. The template is a One-Click App (captainVersion 4): Folio, PostgreSQL and Redis, one persistent volume for Folio and one for the database, secrets generated by CapRover.

What you need

  • A CapRover instance, v1.12 or newer (for WebSocket support in one-click apps), with a root domain.
  • 2 GB of RAM or more on the server.

Steps

  1. Step 1: In CapRover go to Apps > One-Click Apps/Databases.

  2. Step 2: Choose >> TEMPLATE << at the bottom of the list, paste the whole file below, and press Next.

    Show folio.yml (86 lines) and copy it
    folio.yml
    captainVersion: 4
    services:
        $$cap_appname:
            image: ghcr.io/evergreen-it-dev/folio:$$cap_folio_version
            environment:
                NODE_ENV: production
                PORT: 4870
                DATABASE_URL: postgresql://folio:$$cap_db_password@srv-captain--$$cap_appname-db:5432/folio
                REDIS_URL: redis://srv-captain--$$cap_appname-redis:6379
                PUBLIC_URL: http://$$cap_appname.$$cap_root_domain
                ASSET_BACKEND: local
                FOLIO_SECRET: $$cap_folio_secret
                GOOGLE_CLIENT_ID: $$cap_google_client_id
                GOOGLE_CLIENT_SECRET: $$cap_google_client_secret
                GOOGLE_ALLOWED_DOMAINS: $$cap_google_allowed_domains
                CURSOR_API_KEY: $$cap_cursor_api_key
                CURSOR_AGENT_WORKSPACE_ROOT: /app/data/assistant/workspaces
                CURSOR_AGENT_STATE_DIR: /app/data/assistant/state
            volumes:
                - $$cap_appname-data:/app/data
            depends_on:
                - $$cap_appname-db
                - $$cap_appname-redis
            caproverExtra:
                containerHttpPort: '4870'
                websocketSupport: 'true'
        $$cap_appname-db:
            image: postgres:17-alpine
            environment:
                POSTGRES_USER: folio
                POSTGRES_PASSWORD: $$cap_db_password
                POSTGRES_DB: folio
            volumes:
                - $$cap_appname-db-data:/var/lib/postgresql/data
            caproverExtra:
                notExposeAsWebApp: 'true'
        $$cap_appname-redis:
            image: redis:7-alpine
            command: redis-server --save '' --appendonly no
            caproverExtra:
                notExposeAsWebApp: 'true'
    caproverOneClickApp:
        variables:
            - id: $$cap_folio_version
              label: Folio version
              defaultValue: latest
              description: Image tag. Use a release such as v0.1.0 to update only when you choose. Tags https://github.com/evergreen-it-dev/folio/pkgs/container/folio
              validRegex: /^([^\s^\/])+$/
            - id: $$cap_db_password
              label: Database password
              defaultValue: $$cap_gen_random_hex(24)
              description: Password of the PostgreSQL user. Generated for you. It is applied when the database is first created.
              validRegex: /^[0-9a-f]{20,}$/
            - id: $$cap_folio_secret
              label: Folio secret
              defaultValue: $$cap_gen_random_hex(32)
              description: Encrypts saved Git tokens and personal AI keys. Generated for you. Never change it afterwards.
              validRegex: /^[0-9a-f]{32,}$/
            - id: $$cap_google_client_id
              label: '[OPTIONAL] Google client ID'
              description: For "Sign in with Google". Redirect URI to register with Google is the https address of the app plus /api/auth/google/callback
            - id: $$cap_google_client_secret
              label: '[OPTIONAL] Google client secret'
            - id: $$cap_google_allowed_domains
              label: '[OPTIONAL] Google allowed email domains'
              description: Comma-separated, for example example.com. Empty means Google sign-in lets nobody in.
            - id: $$cap_cursor_api_key
              label: '[OPTIONAL] Cursor API key'
              description: Shared key for the AI assistant. Without it each person adds their own key.
        instructions:
            start: |-
                Folio is a git-native collaborative wiki: pages are plain files in a Git repository, edited together in real time.
                This installs Folio with its own PostgreSQL and Redis and one persistent volume.
                It needs about 2 GB of RAM on the CapRover server.
            end: |-
                Folio is deployed as $$cap_appname.
    
                IMPORTANT:
                1. It takes about a minute to start. Until then you may see a 502 page.
                2. Open the app's page in CapRover and enable HTTPS, then change the PUBLIC_URL environment variable to the https:// address and save. Folio builds invitation links from it, and signing in over HTTPS needs it.
                3. Open the address; the first account you create is the administrator.
                4. Websocket support is switched on for the app (real-time editing needs it).
        displayName: Folio
        isOfficial: false
        description: Git-native collaborative wiki with real-time editing, access rights, history and an MCP server for AI agents.
        documentation: https://github.com/evergreen-it-dev/folio/blob/main/docs/INSTALL.md
  3. Step 3: Give the app a name, for example folio. The database password and the Folio secret are already filled with generated values. Leave the optional fields empty unless you use them. Deploy.

  4. Step 4: When the app is up, open it in CapRover and Enable HTTPS. Then under App Configs change the environment variable PUBLIC_URL from http:// to https:// and Save & Update. Without that step, invitation links and the cookies' security flag do not match your address.

  5. Step 5: Open the address. The first account is the administrator.

Settings

Edit them under App Configs > Environmental Variables. The database password is set when the database is first created; changing it in the app later does not change it in PostgreSQL. The app is created with WebSocket support switched on, which real-time editing needs. If you set the app up by hand, tick Websocket Support in its HTTP settings.

Environment variables for Folio on CapRover
VariableDefaultWhat it does
PUBLIC_URLhttp://<app>.<root domain>The address people open, exactly as in the browser, including https.
FOLIO_SECRETgeneratedEncrypts saved Git tokens and AI keys. Never change it.
Folio version (install form)latestImage tag. Use a release such as v0.1.0 to update only when you choose.
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRETemptyTurn on "Sign in with Google". Register <your address>/api/auth/google/callback with Google.
GOOGLE_ALLOWED_DOMAINSemptyEmail domains allowed to sign in with Google. Empty means nobody.
CURSOR_API_KEYemptyShared key for the AI assistant. Without it each person adds their own.

Update

Open the app > Deployment and set the image name to a newer tag, for example ghcr.io/evergreen-it-dev/folio:v0.2.0. With latest, press Force Update. The database migrates itself on start. Back up before.

Back up

CapRover backs up its own configuration, not your volumes. On the server (folio is the app name you chose):

bash
docker exec $(docker ps -qf name=srv-captain--folio-db.1) pg_dump -U folio folio > folio-db.sql
docker exec $(docker ps -qf name=srv-captain--folio.1) tar czf - -C /app/data . > folio-data.tgz

Limits and honest notes

  • The app waits for no health check. If it starts before PostgreSQL is ready, Docker Swarm restarts it, so the first start may show a 502 for a minute.

Platform documentation

Check the installation

From a clone of the repository, run the smoke test against a fresh instance. It needs Node 18 or newer. It creates the first account, a space and a page, and opens a WebSocket connection to the page. Delete the instance, or that space, afterwards.

bash
node deploy/smoke.mjs https://wiki.example.com

Other ways to install

Compare all platforms

Not ready to install?

Try the public demo: https://demo.foliowiki.online. Pick Sam on the sign-in screen. The login is shared and the data resets every 24 hours, so don't enter personal data or API keys.

Open the demo