Enhance setup and configuration for self-hosting (#125)

* Enhance setup and configuration for self-hosting

- Updated `.env.example` to include new webserver configuration options.
- Modified `docker-compose.yml` to support custom port bindings for backend and client services when not using the built-in webserver.
- Enhanced `setup.sh` to handle `--no-webserver` flag, allowing users to run their own webserver and exposing necessary ports.
- Expanded documentation in `self-hosting.mdx` to include instructions for using a custom webserver and managing services.

* Refactor environment variable configuration and enhance setup script

- Updated `.env.example` to use HOST_BACKEND_PORT and HOST_CLIENT_PORT for clearer port mapping.
- Modified `docker-compose.yml` to reflect changes in environment variable names for backend and client services.
- Enhanced `setup.sh` to support custom port options and improved error handling for missing `.env` file.
- Updated documentation in `self-hosting.mdx` to include new setup script options and examples for custom port configurations.

* docker publish
This commit is contained in:
Bill Yang 2025-05-06 13:08:41 -07:00 committed by GitHub
parent 9da01364ea
commit cd5e8796d0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 407 additions and 10 deletions

View file

@ -1,12 +1,25 @@
# Domain and URL Configuration
DOMAIN_NAME=demo.rybbit.io
BASE_URL="https://${DOMAIN_NAME}"
# Authentication and Security
BETTER_AUTH_SECRET=insecure-secret
DISABLE_SIGNUP=false
# Webserver Configuration
# Set to false to disable the built-in Caddy webserver
USE_WEBSERVER=true
# Host port mappings - these control how services are exposed
# Format: "host_binding:container_port" or "port:container_port"
HOST_BACKEND_PORT=127.0.0.1:3001
HOST_CLIENT_PORT=127.0.0.1:3002
# ClickHouse Database Configuration
CLICKHOUSE_DB=analytics
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=frog
# PostgreSQL Database Configuration
POSTGRES_DB=analytics
POSTGRES_USER=frog
POSTGRES_PASSWORD=frog

72
.github/workflows/docker-publish.yml vendored Normal file
View file

@ -0,0 +1,72 @@
name: Docker Publish
on:
push:
branches:
- master
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker - Backend
id: meta_backend
uses: docker/metadata-action@v5
with:
# Images will be ghcr.io/rybbit-io/rybbit-backend
images: ghcr.io/${{ github.repository_owner }}/rybbit-backend
tags: |
type=ref,event=branch # Creates tag like :master
type=sha # Creates tag like :<commit_sha_short>
# Tags 'master' branch pushes additionally with 'latest'
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
- name: Build and push Backend Docker image
uses: docker/build-push-action@v6
with:
context: ./server #
file: ./server/Dockerfile
push: true
tags: ${{ steps.meta_backend.outputs.tags }}
labels: ${{ steps.meta_backend.outputs.labels }}
# Optional: Enable build cache for potentially faster builds
cache-from: type=gha,scope=${{ github.workflow }}-backend
cache-to: type=gha,scope=${{ github.workflow }}-backend,mode=max
- name: Extract metadata (tags, labels) for Docker - Client
id: meta_client
uses: docker/metadata-action@v5
with:
# Images will be ghcr.io/rybbit-io/rybbit-client
images: ghcr.io/${{ github.repository_owner }}/rybbit-client
tags: |
type=ref,event=branch
type=sha
# Tags 'master' branch pushes additionally with 'latest'
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
- name: Build and push Client Docker image
uses: docker/build-push-action@v6
with:
context: ./client
file: ./client/Dockerfile
push: true
tags: ${{ steps.meta_client.outputs.tags }}
labels: ${{ steps.meta_client.outputs.labels }}
# Optional: Enable build cache for potentially faster builds
cache-from: type=gha,scope=${{ github.workflow }}-client
cache-to: type=gha,scope=${{ github.workflow }}-client,mode=max

View file

@ -56,6 +56,8 @@ services:
build:
context: ./server
dockerfile: Dockerfile
ports:
- "${HOST_BACKEND_PORT:-127.0.0.1:3001}:3001"
environment:
- NODE_ENV=production
- CLICKHOUSE_HOST=http://clickhouse:8123
@ -83,6 +85,8 @@ services:
dockerfile: Dockerfile
args:
NEXT_PUBLIC_BACKEND_URL: ${BASE_URL}
ports:
- "${HOST_CLIENT_PORT:-127.0.0.1:3002}:3002"
environment:
- NODE_ENV=production
- NEXT_PUBLIC_BACKEND_URL=${BASE_URL}

View file

@ -52,14 +52,97 @@ cd rybbit
The repository includes a setup script that configures the necessary environment variables (including generating a secure secret) and starts the application using Docker Compose.
Run the script, replacing `your.domain.name` with the domain or subdomain you configured in the prerequisites:
<Callout type="warning">
Important: Make all scripts executable before proceeding!
```bash
chmod +x *.sh
```
</Callout>
Run the setup script, replacing `your.domain.name` with the domain or subdomain you configured in the prerequisites:
```bash
chmod +x setup.sh
./setup.sh your.domain.name
```
The script will create a `.env` file and then build and start the containers. This might take a few minutes the first time.
#### Setup Script Options
The setup script supports several options:
```bash
./setup.sh <domain_name> [options]
```
Available options:
- `--no-webserver`: Disable the built-in Caddy webserver
- `--backend-port <port>`: Set custom host port for backend (default: 3001)
- `--client-port <port>`: Set custom host port for client (default: 3002)
- `--help`: Show help message
Examples:
```bash
# Custom ports with built-in webserver
./setup.sh tracking.example.com --backend-port 8080 --client-port 8081
# Custom ports with your own webserver
./setup.sh tracking.example.com --no-webserver --backend-port 8080 --client-port 8081
```
<Callout type="info">
When you specify custom ports, only the host port mapping changes. Inside the Docker containers, the services still use ports 3001 and 3002.
</Callout>
#### Using Your Own Web Server
If you prefer to use your own web server (such as Nginx or Apache) instead of the built-in Caddy server, you can use the `--no-webserver` flag:
```bash
./setup.sh your.domain.name --no-webserver
```
This will:
- Not start the Caddy container
- Expose the backend service on host port 3001 (or your custom port)
- Expose the client service on host port 3002 (or your custom port)
You'll need to configure your web server to proxy requests to these services. Here's an example Nginx configuration:
```nginx
server {
listen 80;
server_name your.domain.name;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name your.domain.name;
# SSL configuration (using Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/your.domain.name/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your.domain.name/privkey.pem;
# API requests - adjust port if you customized it
location /api/ {
proxy_pass http://localhost:3001; # or your custom port
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Client app - adjust port if you customized it
location / {
proxy_pass http://localhost:3002; # or your custom port
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
### 5. Sign Up
Once the services are running and DNS has propagated, Caddy (the webserver) will automatically obtain an SSL certificate for your domain.
@ -68,11 +151,38 @@ Open your browser and navigate to `https://your.domain.name/signup` (using the d
Create your admin account. You can then log in and start adding your websites!
</Steps>
Congratulations! You have successfully self-hosted Rybbit.
## Managing Your Installation
Rybbit comes with several helper scripts to manage your installation:
<Callout type="info">
If you haven't done so already, make sure all scripts are executable:
```bash
chmod +x *.sh
```
</Callout>
- **start.sh**: Start all services after they've been stopped
```bash
./start.sh
```
- **stop.sh**: Stop all running services
```bash
./stop.sh
```
- **restart.sh**: Restart all services
```bash
./restart.sh
```
- **update.sh**: Update to the latest version by pulling new code and rebuilding containers
```bash
./update.sh
```
<Callout>
If you are using your self-hosted Rybbit without anyone else, you can disable new user signups by setting `DISABLE_SIGNUP=true` in the `.env` file at the root of the repository.

30
restart.sh Normal file
View file

@ -0,0 +1,30 @@
#!/bin/bash
# Exit immediately if a command exits with a non-zero status.
set -e
echo "Restarting services..."
# Stop all services
docker compose stop
# Check if .env file exists
if [ ! -f .env ]; then
echo "Error: .env file not found. Please run setup.sh first."
echo "Usage: ./setup.sh <domain_name>"
exit 1
fi
# Load environment variables
source .env
# Start the appropriate services
if [ "$USE_WEBSERVER" = "false" ]; then
# Start without the caddy service when using --no-webserver
docker compose start backend client clickhouse postgres
else
# Start all services including caddy
docker compose start
fi
echo "Services restarted. You can monitor logs with: docker compose logs -f"

105
setup.sh
View file

@ -3,14 +3,91 @@
# Exit immediately if a command exits with a non-zero status.
set -e
# Check if domain name argument is provided
if [ -z "$1" ]; then
echo "Usage: $0 <domain_name>"
# Default values
USE_WEBSERVER="true"
BACKEND_PORT="3001"
CLIENT_PORT="3002"
HOST_BACKEND_PORT="127.0.0.1:3001"
HOST_CLIENT_PORT="127.0.0.1:3002"
# Help function
show_help() {
echo "Usage: $0 <domain_name> [options]"
echo "Example: $0 myapp.example.com"
echo "Example with no webserver: $0 myapp.example.com --no-webserver"
echo ""
echo "Options:"
echo " --no-webserver Disable the built-in Caddy webserver"
echo " --backend-port <port> Set custom host port for backend (default: 3001)"
echo " --client-port <port> Set custom host port for client (default: 3002)"
echo " --help Show this help message"
}
# Parse arguments
while [[ "$#" -gt 0 ]]; do
case $1 in
--no-webserver)
USE_WEBSERVER="false"
shift
;;
--backend-port)
if [[ -z "$2" || "$2" =~ ^- ]]; then
echo "Error: --backend-port requires a port number"
show_help
exit 1
fi
BACKEND_PORT="$2"
shift 2
;;
--client-port)
if [[ -z "$2" || "$2" =~ ^- ]]; then
echo "Error: --client-port requires a port number"
show_help
exit 1
fi
CLIENT_PORT="$2"
shift 2
;;
--help)
show_help
exit 0
;;
-*)
echo "Unknown option: $1"
show_help
exit 1
;;
*)
if [ -z "$DOMAIN_NAME" ]; then
DOMAIN_NAME="$1"
else
echo "Error: Only one domain name can be specified"
show_help
exit 1
fi
shift
;;
esac
done
# Update port mappings after all args are parsed
if [ "$USE_WEBSERVER" = "false" ]; then
# When not using the built-in webserver, expose ports to host
HOST_BACKEND_PORT="${BACKEND_PORT}:3001"
HOST_CLIENT_PORT="${CLIENT_PORT}:3002"
else
# Keep ports only accessible via localhost when using Caddy
HOST_BACKEND_PORT="127.0.0.1:3001"
HOST_CLIENT_PORT="127.0.0.1:3002"
fi
# Check if domain name argument is provided
if [ -z "$DOMAIN_NAME" ]; then
echo "Error: Domain name is required"
show_help
exit 1
fi
DOMAIN_NAME="$1"
BASE_URL="https://${DOMAIN_NAME}"
# Generate a secure random secret for BETTER_AUTH_SECRET
@ -32,13 +109,31 @@ DOMAIN_NAME=${DOMAIN_NAME}
BASE_URL=${BASE_URL}
BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
DISABLE_SIGNUP=false
USE_WEBSERVER=${USE_WEBSERVER}
HOST_BACKEND_PORT=${HOST_BACKEND_PORT}
HOST_CLIENT_PORT=${HOST_CLIENT_PORT}
EOL
echo ".env file created successfully with domain ${DOMAIN_NAME}."
if [ "$USE_WEBSERVER" = "false" ]; then
echo "Caddy webserver is disabled. You'll need to set up your own webserver."
if [ "$BACKEND_PORT" = "3001" ] && [ "$CLIENT_PORT" = "3002" ]; then
echo "The backend service will be available on port 3001 and the client on port 3002."
else
echo "The backend service will be available on port ${BACKEND_PORT} (mapped to container port 3001)"
echo "The client service will be available on port ${CLIENT_PORT} (mapped to container port 3002)"
fi
fi
# Build and start the Docker Compose stack
echo "Building and starting Docker services..."
docker compose up --build -d
if [ "$USE_WEBSERVER" = "false" ]; then
# Start without the caddy service when using --no-webserver
docker compose up --build -d backend client clickhouse postgres
else
# Start all services including caddy
docker compose up --build -d
fi
echo "Setup complete. Services are starting in the background."
echo "You can monitor logs with: docker compose logs -f"

26
start.sh Normal file
View file

@ -0,0 +1,26 @@
#!/bin/bash
# Exit immediately if a command exits with a non-zero status.
set -e
echo "Starting services..."
# Check if .env file exists
if [ ! -f .env ]; then
echo "Error: .env file not found. Please run setup.sh first."
echo "Usage: ./setup.sh <domain_name>"
exit 1
fi
# Load environment variables
source .env
if [ "$USE_WEBSERVER" = "false" ]; then
# Start without the caddy service when using --no-webserver
docker compose start backend client clickhouse postgres
else
# Start all services including caddy
docker compose start
fi
echo "Services started. You can monitor logs with: docker compose logs -f"

9
stop.sh Normal file
View file

@ -0,0 +1,9 @@
#!/bin/bash
# Exit immediately if a command exits with a non-zero status.
set -e
echo "Stopping services..."
docker compose stop
echo "Services stopped."

38
update.sh Normal file
View file

@ -0,0 +1,38 @@
#!/bin/bash
# Exit immediately if a command exits with a non-zero status.
set -e
echo "Updating to the latest version..."
# Pull latest changes from git repository
echo "Pulling latest code..."
git pull
# Stop running containers
echo "Stopping current services..."
docker compose down
# Check if .env file exists
if [ ! -f .env ]; then
echo "Error: .env file not found. Please run setup.sh first."
echo "Usage: ./setup.sh <domain_name>"
exit 1
fi
# Rebuild and start containers
echo "Rebuilding and starting updated services..."
# Load environment variables
source .env
if [ "$USE_WEBSERVER" = "false" ]; then
# Start without the caddy service when using --no-webserver
docker compose up --build -d backend client clickhouse postgres
else
# Start all services including caddy
docker compose up --build -d
fi
echo "Update complete. Services are running with the latest version."
echo "You can monitor logs with: docker compose logs -f"