Installation

Installation

Pala is currently in V3 Beta and available both as a cloud service and self-hosted. This guide walks through setting up Pala's three core infrastructure components for self-hosting the application:

  • Supabase for database, authentication, and realtime features

  • Cloudflare for site hosting and content delivery

  • Vercel or Netlify for application hosting

  • Resend for sending transactional emails

Note: Cloudflare is currently unsupported as an application host due to its cloud function size limit.

1. Setting Up Supabase

  1. Visit Supabase and sign in or create an account

  2. Create a new project:

    • Click "New Project"

    • Choose a name for your project

    • Generate a database password

    • Choose your region (pick one close to your users)

    • Click "Create new project"

  3. Gather the following credentials from the project dashboard:

    • Project URL

    • Public (anon) key

    • Private (service_role) key

  4. Set up the database schema:

Once you’ve set up your project, you’ll have the following environment variables:

  • PUBLIC_SUPABASE_URL (Your Project URL)

  • PUBLIC_SUPABASE_PUBLIC_KEY (Public API Key)

  • PRIVATE_SUPABASE_PRIVATE_KEY (Service Role Key)

2. Setting up Resend

  1. Visit Resend and sign in or create an account.

3. Setting Up Cloudflare

Cloudflare handles hosting and serving your sites. You'll need to set up three components:

  • Domain configuration

  • R2 storage bucket

  • Worker for routing

Note: While Cloudflare requires a credit card or PayPal, there are no charges for the first 100 sites. Additional sites are $0.10 each.

2.1 Domain Configuration

  1. Create or login to your Cloudflare account

  2. Connect your domain:

    • Enter an existing domain or purchase one (Porkbun recommended, some domains as low as $1 for first year)

    • Select the free plan (scroll down)

    • Don’t import any DNS records

    • Click ‘Add Record’ and add the following DNS record:

      • Type: A

      • Name: *

      • Content: 192.0.0.0

    • Follow prompts to set up Cloudflare nameservers

    • Copy your Zone ID and Account ID for later use

2.2 Enable Custom Hostnames

2.3 Setting Up R2 Storage

  1. From the Cloudflare dashboard, navigate to "R2 Object Storage"

  2. Sign up for R2 (requires payment method)

  3. Create a new bucket:

    • Name: weave-sites

    • Storage class: "Automatic"

    • Durability: "Standard"

  4. Configure R2 Bucket CORS policy

    • Under Settings → ‘CORS policy’, click ‘Edit CORS Policy’

    • Replace contents with the following JSON array, replacing* your-domain-name *with your domain name:

      [
        {
          "AllowedOrigins": [
            "*"
          ],
          "AllowedMethods": [
            "GET",
            "PUT",
            "POST",
            "DELETE"
          ],
          "AllowedHeaders": [
            "*"
          ],
          "ExposeHeaders": [
            "ETag"
          ],
          "MaxAgeSeconds": 3000
        }
      ]
      
  5. Create API credentials:

    • Go to R2 Overview > API > Manage API Tokens

    • Click "Create API token"

    • Select "Object Read & Write" permissions

    • Copy the following values:

      • Token Value

      • Access Key ID

      • Secret Access Key

2.4 Configuring the Worker

  1. Go to "Compute (Workers)" in the sidebar

  2. Create a new Worker:

    • Click "Hello World" template

    • Name it ‘weave-sites-worker’

    • Click "Deploy" (we'll modify it later)

    • Click "Continue to project"

  3. Set up environment variables:

    • Go to Settings

    • Under "Variables and Settings", click "+ Add"

    • Create a Text variable:

      • Name: BASE_DOMAIN_NAME

      • Value: Your domain name

      • Click "Deploy"

  4. Configure R2 bucket binding:

    • Under "Bindings" click "+ Add"

    • Select "R2 Bucket"

    • Variable Name: SITES_BUCKET

    • Select the "weave-sites" bucket

  5. Add Worker route

    • Under ‘Settings’ → ‘Domains & Routes’, click “+ Add”

    • Select ‘Route’

  6. Deploy the Worker script:

    • Click the code button (top right)

    • Replace contents with the following Worker script:

      export default {
        async fetch(request, env, ctx) {
          const url = new URL(request.url);
          const host = url.hostname;
          const path = decodeURIComponent(url.pathname.slice(1))
          const subdomain = host.split('.')[0]
          const custom_domain = host
          const folder_name = host.includes(env.BASE_DOMAIN_NAME) ? subdomain : custom_domain
          if (host === `cdn.${env.BASE_DOMAIN_NAME}`) {
            let object = await env.SITES_BUCKET.get(path);
            const content_type = object.httpMetadata?.contentType || 'application/octet-stream';
            return new Response(object.body, {
              headers: {
                'Access-Control-Allow-Origin': '*',
                'Access-Control-Allow-Methods': 'GET, OPTIONS',
                'content-type': content_type,
              },
            });
          }
          // Construct the key with the site_id prefix
          const key = `${folder_name}/live${url.pathname}`;
          // Try to get the object from R2
          let object = await env.SITES_BUCKET.get(key);
          if (object === null) {
            // If the exact path is not found, try appending 'index.html'
            const index_key = `${key}/index.html`.replace(/\/+/g, '/');
            object = await env.SITES_BUCKET.get(index_key);<pre><code>  if (object === null) {
          const index_key = `${folder_name}/live/404/index.html`.replace(/\/+/g, '/');
          object = await env.SITES_BUCKET.get(index_key);<pre><code>if (object === null) {
        return new Response('404', { status: 404 });
      }
      </code></pre>  }
      }
      // Determine the content type
      const content_type = object.httpMetadata?.contentType || 'application/octet-stream';
      // Return the object
      return new Response(object.body, {
        headers: {
          'content-type': content_type,
        },
      });
      </code></pre>  },
      };
      
    • Click "Deploy"

2.5 API Access Configuration

  1. Create API Access Token:

    • Navigate to Manage Account > Account API Tokens

    • Click "Create Token" > "Custom Token" > "Get started"

    • Add required permissions:

      • Zone > Zone (Edit) - For domain connection

      • Zone > Workers Routes (Edit) - For hostname routing

    • Under Zone Resources:

      • Select "Include" > "Specific zone" > [your domain]
    • Complete token creation and copy the token

2.6 Enable Custom Domains

  1. Configure SSL/TLS:

    • From dashboard, select your root domain

    • Go to SSL/TLS encryption > Configure

    • Select "Full (strict)" > Save

  2. Set up custom hostnames:

    • Navigate to SSL/TLS > Custom Hostnames

    • Enable "Cloudflare for SaaS"

    • Add fallback origin:

      • Enter "proxy.[your-domain-name]"

      • Click "Add Fallback Origin"

Once you’ve set up your project, you’ll have the following environment variables:

  • PUBLIC_BASE_DOMAIN_NAME (Your configured domain name)

  • PRIVATE_CLOUDFLARE_ZONE_ID

  • PRIVATE_CLOUDFLARE_ACCOUNT_ID

  • PRIVATE_R2_TOKEN

  • PRIVATE_R2_ACCESS_KEY_ID

  • PRIVATE_R2_SECRET_ACCESS_KEY

4. Setting Up Vercel/Netlify

Environment Variables

After completing all installations, you'll need to configure the following environment variables in your Vercel project:

# Supabase PUBLIC_SUPABASE_URL=
PUBLIC_SUPABASE_PUBLIC_KEY=
PRIVATE_SUPABASE_PRIVATE_KEY=

# ResendPRIVATE_RESEND_KEY=
PRIVATE_RESEND_EMAIL_DOMAIN=

# Cloudflare PRIVATE_CLOUDFLARE_ZONE_ID=
PRIVATE_CLOUDFLARE_ACCOUNT_ID=
PRIVATE_R2_TOKEN=
PRIVATE_R2_ACCESS_KEY_ID=
PRIVATE_R2_SECRET_ACCESS_KEY=
PRIVATE_CLOUDFLARE_ACCOUNT_TOKEN=
PUBLIC_BASE_DOMAIN_NAME=

Creating an Account

Once your Pala server is running, you’ll be greeted by the login screen. Append `?signup` to the url to show the sign up form (e.g. `myweaveserver.vercel.app/auth?signup`). This is where other users will also be able to create accounts on your server to manage their own sites.

Verification

To verify your installation:

  1. Deploy your application to Vercel

  2. Create a new site in Pala

  3. Add some content and publish

  4. Verify the site is accessible at your configured domain

Troubleshooting

Need help? Join our Community Discord or email support@palacms.org


Local installation

Useful for local development on the CMS, for contributions or modifying it for your own uses, or just for getting started more quickly.

  1. Create necessary service accounts (i.e. Supabase, Vercel/Netlify, Cloudflare, Resend)

  2. git clone github.com/@palacms/palacms

  3. cd palacms && npm install

  4. cp .env.example .env

  5. Update .env with your service credentials

  6. Initialize the database: Copy the contents of weave_schema.sql and run it in your Supabase SQL editor.

  7. Start the dev server npm run build &amp;&amp; npm run preview

  8. Access the server at http://localhost:4173

Updating Your Instance

Since Pala is actively developed, you'll want to keep your instance up to date with the latest features and security patches. Note that Pala v3 is in Beta, so you’ll also want to check the changelog for any necessary manual updates.

Local

  1. Get the latest changes git pull origin main

  2. Install any new dependencies npm install

  3. Rebuild the application npm run build

  4. Manual updates: breaking changes, database migrations, environment variables

Remote

  1. Go to your forked repository on GitHub

  2. Click "Sync fork"

  3. Click "Update branch" to get latest changes. Your site should automatically rebuild with the updates.

  4. Manual updates: breaking changes, database migrations, environment variables


Frequently Asked Questions

Do I need the paid versions of the required services?

The free tiers of Supabase, Vercel/Netlify, Cloudflare, and Resend should work fine for development and small projects. You may need to upgrade as your usage grows.

Can I deploy to other platforms besides Vercel/Netlify?

Yes, Pala can be deployed to any platform that supports SvelteKit applications (besides Cloudflare, as noted above). However, Vercel and Netlify are recommended for their simple deployment process and build optimizations.