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 DOMAIN_NAME=demo.rybbit.io
BASE_URL="https://${DOMAIN_NAME}" BASE_URL="https://${DOMAIN_NAME}"
# Authentication and Security
BETTER_AUTH_SECRET=insecure-secret BETTER_AUTH_SECRET=insecure-secret
DISABLE_SIGNUP=false 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_DB=analytics
CLICKHOUSE_USER=default CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=frog CLICKHOUSE_PASSWORD=frog
# PostgreSQL Database Configuration
POSTGRES_DB=analytics POSTGRES_DB=analytics
POSTGRES_USER=frog POSTGRES_USER=frog
POSTGRES_PASSWORD=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: build:
context: ./server context: ./server
dockerfile: Dockerfile dockerfile: Dockerfile
ports:
- "${HOST_BACKEND_PORT:-127.0.0.1:3001}:3001"
environment: environment:
- NODE_ENV=production - NODE_ENV=production
- CLICKHOUSE_HOST=http://clickhouse:8123 - CLICKHOUSE_HOST=http://clickhouse:8123
@ -83,6 +85,8 @@ services:
dockerfile: Dockerfile dockerfile: Dockerfile
args: args:
NEXT_PUBLIC_BACKEND_URL: ${BASE_URL} NEXT_PUBLIC_BACKEND_URL: ${BASE_URL}
ports:
- "${HOST_CLIENT_PORT:-127.0.0.1:3002}:3002"
environment: environment:
- NODE_ENV=production - NODE_ENV=production
- NEXT_PUBLIC_BACKEND_URL=${BASE_URL} - 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. 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 ```bash
chmod +x setup.sh
./setup.sh your.domain.name ./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. 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 ### 5. Sign Up
Once the services are running and DNS has propagated, Caddy (the webserver) will automatically obtain an SSL certificate for your domain. 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! Create your admin account. You can then log in and start adding your websites!
</Steps> </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> <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. 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. # Exit immediately if a command exits with a non-zero status.
set -e set -e
# Check if domain name argument is provided # Default values
if [ -z "$1" ]; then USE_WEBSERVER="true"
echo "Usage: $0 <domain_name>" 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: $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 exit 1
fi fi
DOMAIN_NAME="$1"
BASE_URL="https://${DOMAIN_NAME}" BASE_URL="https://${DOMAIN_NAME}"
# Generate a secure random secret for BETTER_AUTH_SECRET # Generate a secure random secret for BETTER_AUTH_SECRET
@ -32,13 +109,31 @@ DOMAIN_NAME=${DOMAIN_NAME}
BASE_URL=${BASE_URL} BASE_URL=${BASE_URL}
BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET} BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
DISABLE_SIGNUP=false DISABLE_SIGNUP=false
USE_WEBSERVER=${USE_WEBSERVER}
HOST_BACKEND_PORT=${HOST_BACKEND_PORT}
HOST_CLIENT_PORT=${HOST_CLIENT_PORT}
EOL EOL
echo ".env file created successfully with domain ${DOMAIN_NAME}." 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 # Build and start the Docker Compose stack
echo "Building and starting Docker services..." 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 "Setup complete. Services are starting in the background."
echo "You can monitor logs with: docker compose logs -f" 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"