Skip to content

kruschid/refine-pocketbase-starter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Discord

Refine PocketBase Starter

Packages your full-stack tool/app/product in a single Docker image (~33 MB) and stores it in a centralized location (GitHub Container Registry by default), making it easily accessible for distribution across different environments.

Why

  • Refine provides business logic for your UI elements, supporting CRUD functions, security, state management, and live updates.
  • PocketBase is a powerful combination of a database, real-time API, authentication with a dynamic authorization system, file storage, backup management, and an admin dashboard with robust user management.
  • This template combines these two open-source tools, saving you days of setting up dependencies, build-scripts, pipelines, and distribution, allowing you to start shipping features right away.

Features

  • Frontend

    • Refine (React meta-framework for CRUD-heavy web applications)
    • Refine providers for PocketBase using the refine-pocketbase library and PocketBase JS SDK
    • Headless, use any UI framework you like
    • Real-time updates enabled
    • E2E tests with Playwright (optional)
    • Typesafe routes using the typesafe-routes library (optional)
    • Pre-configured TypeScript type generation from database schema with pocketbase-typegen (optional)
    • Vite, TypeScript, ESLint
  • Backend (Pocketbase)

  • Distribution

    • Preconfigured GitHub Actions pipeline (build, test, container registry push)
    • Frontend & backend in a single Docker image
    • Stores Docker images in GitHub Container Registry by default
    • Easy self-hosting on VPS (Hetzner, Linode, Fly.io, etc.) or using your own hardware (e.g., Raspberry Pi)
    • Ready for cloud deployment via Google Cloud Run

Quickstart

To begin developing your features, you need to start PocketBase, Inbucket, and the frontend. Below are the commands to start the necessary services, along with their URLs and default credentials.

Pocketbase

PocketBase serves as the backend and can be started using the following Docker Compose command:

cd pocketbase
docker compose up

Admin Dashboard

The admin dashboard is part of PocketBase and can be accessed through a web browser using the following credentials:

Important

The default credentials can be changed in the admin dashboard to maintain security.

Inbucket

Inbucket is a local email service that can be used for testing purposes. For example, you can send password recovery emails or OTP codes from PocketBase to Inbucket. PocketBase is preconfigured to use Inbucket, so no additional setup is required. It starts automatically with PocketBase.

This setup allows you to easily test email functionalities without needing an external email service.

Frontend

The frontend is a React application with basic dependencies such as Refine, ESLint, and Vite. You can start the development server with the following command:

cd app
npm run dev # starts dev server on port 8080

This will launch the application, making it accessible in your browser at the specified URL. Ensure that all necessary dependencies are installed before running the development server.

Now you are all set up to add more frontend dependencies and start turning your app ideas into code. If you're interested in learning how to deploy your application and make your features available to users, continue reading the distribution section.

cd app
npm run codegen           # updates generated database schema types
npx playwright test --ui  # runs playwright tests with gui

Database Migrations

Database migrations are a way to manage versions of your database schema. They allow you to update your database schema in production while preserving existing data. Migrations are generated automatically whenever the database schema is modified using the PocketBase dashboard. However, you also have the option to create migrations manually. Since migrations are part of the distribution process, they must be included in your git commits to ensure they are part of the final Docker image.

Tip

Remember to regularly commit and test migration changes to prevent issues during deployment.

Distribution

The default distribution method is via GitHub Container Registry. Other container registries (Dockerhub, gcr.io, etc.) can also be used, but they require minor adjustments to the GitHub Action workflow file.

A GitHub workflow will build a single Docker image that can be deployed with a single command (docker compose up -d) on your server or using tools like Portainer and Docker, etc.

Note:
If you prefer not to manage your own server, you can opt-out of the GitHub Actions workflow by deleting the .github/workflows/build.yml file and switching to Google Cloud Run or similar cloud hosting services.

You can find deployment instructions for Google Cloud Run here, and here is the corresponding discussion thread.

This approach allows for flexible distribution options depending on your infrastructure preferences and requirements.

Publishing

You can build and push a new Docker image of a new version by creating a git tag following semver-like syntax:

git tag 1.0.0     # creates a tag for the latest commit
git push --tags   # pushes the created tag to github

Only tags that match the [0-9]+.[0-9]+.[0-9]+ format will trigger the build workflow. However, if you want to support more complex version patterns, you can modify the format by editing the .github/workflows/build.yml file.

This flexibility allows you to adjust the versioning scheme to fit your project's needs.

Note

All Docker images will be pushed to the GitHub Container Registry associated with your Git repository.

This ensures that your images are stored in a centralized location, making them easily accessible for deployment across different environments.

Pushing a new tag will trigger a workflow that builds a Docker image, which is then pushed to the GitHub Container Registry by default.

The default architecture is linux/amd64. Modify the .github/workflows/build.yml file if you want to self-host the Docker image on a Raspberry Pi or deploy to a server with an ARM architecture.

Building multiple architectures (e.g., linux/amd64,linux/arm64,linux/arm/v7) simultaneously is also possible. Considerations for architecture and infrastructure are important for ensuring compatibility with your environment.

For deploying PocketBase on a Synology NAS, refer to this guide: How to Install PocketBase on Your Synology NAS.

Sample Docker Compose File

Deploying a Docker image on your server is straightforward. The fastest method is to create a docker-compose.yaml file on your server with the following content, describing your service:

name: refine-pocketbase-starter

services:
  refine-pocketbase-starter:
    image: ghcr.io/kruschid/refine-pocketbase-starter:latest # replace with your image
    restart: always
    ports:
      - 8090:8090
    volumes:
      - ./volumes/pb_data:/pb/pb_data

After that, simply navigate to that file in your terminal and enter:

docker compose up -d

This will start all services defined in the docker-compose.yaml file and keep them running in the background, even after you disconnect from your server. In this example there is only one service refine-pocketbase-starter.

Your GitHub repository might be private. In that case, you might see an unauthorized error in your terminal. Read the next section to learn how to generate a GitHub token to download from your private container registry.

Generate a Personal Access Token (required for private repositories)

The following steps are required to pull Docker images from a private GitHub container registry.

  • Go to GitHub and log in to your account.
  • Navigate to Settings > Developer settings > Personal access tokens.
  • Click on Generate new token.
  • Set a note for the token, like GitHub Container Registry.
  • Set the expiration for the token as per your requirement.
  • Under Select scopes, ensure you check read:packages.
  • Click Generate token and copy the token somewhere safe, as you won't be able to view it again.

After completing these steps, connect to your server and type the following command in the terminal. You will be asked for a Username and Password. The Username is your GitHub username, and for the Password, you need to use the GitHub token you just created.

docker login ghcr.io/kruschid # replace with your namespace
Username: kruschid            # replace with your github username
Password: *****               # replace with your github token

Pocketbase Settings

After the initial deployment, you will need to perform a few manual steps to improve security and prevent data loss.

  1. Change the default admin credentials to a secure email/password combination.
  2. Update the SMTP settings to use our production email server/service (AWS SES, etc.).
  3. Enable scheduled backups in the admin dashboard by using a remote bucket (S3, Backblaze, etc.).

More details can be found on the pocketbase "Going to production" page

Automatic HTTPS

You can extend your Docker Compose file with caddy-docker-proxy to serve your app over HTTPS with a certificate for your domain.

Caddy is a web server that supports automatic provisioning of TLS certificates. By using caddy-docker-proxy, Caddy can be configured using labels. The docker-compose.yaml file below serves the app via the fictional domain refine-pocketbase-starter.com.

Make sure to replace the example domain with your actual domain and configure the necessary DNS settings to enable HTTPS for your application.

name: refine-pocketbase-starter

services:
  refine-pocketbase-starter:
    image: ghcr.io/kruschid/refine-pocketbase-starter:latest # replace with your image
    restart: always
    networks:
      - caddy
    volumes:
      - ./volumes/pb_data:/pb/pb_data
    labels:
      caddy: refine-pocketbase-starter.com # replace with your domain
      caddy.reverse_proxy: "{{upstreams 8090}}"
    healthcheck: # optional but recommended
      test: wget --no-verbose --tries=1 --spider http://localhost:8090/api/health || exit 1
      interval: 5s
      timeout: 5s
      retries: 5

  caddy:
    image: lucaslorentz/caddy-docker-proxy:2.8-alpine
    ports:
      - 80:80
      - 443:443
    networks:
      - caddy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./volumes/caddy:/data
    restart: unless-stopped
    environment:
      - CADDY_INGRESS_NETWORKS=caddy

How to Contribute

  • leave a star ⭐
  • report a bug 🐞
  • open a pull request 🏗️
  • help others ❤️
  • buy me a coffee ☕

Buy Me A Coffee