fix self-hosting

This commit is contained in:
Carl-Gerhard Lindesvärd
2025-10-22 11:38:37 +02:00
parent 9790ba8937
commit 42d0fb8572
11 changed files with 202 additions and 38 deletions

View File

@@ -16,7 +16,7 @@ import { Step, Steps } from 'fumadocs-ui/components/steps';
### Quickstart
```bash
git clone https://github.com/Openpanel-dev/openpanel && cd openpanel/self-hosting && ./setup
git clone -b self-hosting https://github.com/Openpanel-dev/openpanel && cd openpanel/self-hosting && ./setup
# After setup is complete run `./start` to start OpenPanel
```
@@ -25,10 +25,10 @@ git clone https://github.com/Openpanel-dev/openpanel && cd openpanel/self-hostin
<Step>
### Clone
Clone the repository to your VPS
Clone the repository to your VPS and checkout the self-hosting tag
```bash
git clone https://github.com/Openpanel-dev/openpanel.git
git clone -b self-hosting https://github.com/Openpanel-dev/openpanel.git
```
</Step>
<Step>

View File

@@ -36,10 +36,7 @@ export async function bootCron() {
},
];
if (
(process.env.VITE_SELF_HOSTED === 'true' || process.env.SELF_HOSTED) &&
process.env.NODE_ENV === 'production'
) {
if (process.env.SELF_HOSTED && process.env.NODE_ENV === 'production') {
jobs.push({
name: 'ping',
type: 'ping',

View File

@@ -47,7 +47,7 @@ export async function deleteProjects(job: Job<CronQueuePayload>) {
for (const table of tables) {
const query =
process.env.VITE_SELF_HOSTED === 'true'
process.env.SELF_HOSTED === 'true'
? `ALTER TABLE ${table} DELETE WHERE ${where};`
: `ALTER TABLE ${table}_replicated ON CLUSTER '{cluster}' DELETE WHERE ${where};`;

View File

@@ -24,7 +24,7 @@ export function getIsCluster() {
}
export function getIsSelfHosting() {
return process.env.VITE_SELF_HOSTED === 'true' || !!process.env.SELF_HOSTED;
return process.env.SELF_HOSTED === 'true' || !!process.env.SELF_HOSTED;
}
export function getIsDry() {

View File

@@ -59,7 +59,7 @@ const getPrismaClient = () => {
subscriptionStatus: {
needs: { subscriptionStatus: true, subscriptionCanceledAt: true },
compute(org) {
if (process.env.VITE_SELF_HOSTED === 'true') {
if (process.env.SELF_HOSTED === 'true') {
return 'active';
}
@@ -69,7 +69,7 @@ const getPrismaClient = () => {
hasSubscription: {
needs: { subscriptionStatus: true, subscriptionEndsAt: true },
compute(org) {
if (process.env.VITE_SELF_HOSTED === 'true') {
if (process.env.SELF_HOSTED === 'true') {
return false;
}
@@ -94,7 +94,7 @@ const getPrismaClient = () => {
subscriptionPeriodEventsCountExceededAt: true,
},
compute(org) {
if (process.env.VITE_SELF_HOSTED === 'true') {
if (process.env.SELF_HOSTED === 'true') {
return null;
}
@@ -131,7 +131,7 @@ const getPrismaClient = () => {
isCanceled: {
needs: { subscriptionStatus: true, subscriptionCanceledAt: true },
compute(org) {
if (process.env.VITE_SELF_HOSTED === 'true') {
if (process.env.SELF_HOSTED === 'true') {
return false;
}
@@ -145,7 +145,7 @@ const getPrismaClient = () => {
subscriptionEndsAt: true,
},
compute(org) {
if (process.env.VITE_SELF_HOSTED === 'true') {
if (process.env.SELF_HOSTED === 'true') {
return false;
}
@@ -159,7 +159,7 @@ const getPrismaClient = () => {
subscriptionCanceledAt: true,
},
compute(org) {
if (process.env.VITE_SELF_HOSTED === 'true') {
if (process.env.SELF_HOSTED === 'true') {
return false;
}
@@ -182,7 +182,7 @@ const getPrismaClient = () => {
subscriptionPeriodEventsLimit: true,
},
compute(org) {
if (process.env.VITE_SELF_HOSTED === 'true') {
if (process.env.SELF_HOSTED === 'true') {
return false;
}
@@ -195,7 +195,7 @@ const getPrismaClient = () => {
subscriptionCurrentPeriodStart: {
needs: { subscriptionStartsAt: true, subscriptionInterval: true },
compute(org) {
if (process.env.VITE_SELF_HOSTED === 'true') {
if (process.env.SELF_HOSTED === 'true') {
return null;
}
@@ -229,7 +229,7 @@ const getPrismaClient = () => {
subscriptionInterval: true,
},
compute(org) {
if (process.env.VITE_SELF_HOSTED === 'true') {
if (process.env.SELF_HOSTED === 'true') {
return null;
}

View File

@@ -33,7 +33,7 @@ async function createOrGetOrganization(
},
});
if (process.env.VITE_SELF_HOSTED !== 'true' && !process.env.SELF_HOSTED) {
if (!process.env.SELF_HOSTED) {
await addTrialEndingSoonJob(
organization.id,
1000 * 60 * 60 * 24 * TRIAL_DURATION_IN_DAYS * 0.9,

View File

@@ -135,7 +135,7 @@ services:
environment:
# Common
- NODE_ENV=production
- VITE_SELF_HOSTED=true
- SELF_HOSTED=true
# URLs
- DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@opdb:5432/${OPENPANEL_POSTGRES_DB:-openpanel-db}?schema=public
- DATABASE_URL_DIRECT=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@opdb:5432/${OPENPANEL_POSTGRES_DB:-openpanel-db}?schema=public
@@ -166,7 +166,7 @@ services:
environment:
# Common
- NODE_ENV=production
- VITE_SELF_HOSTED=true
- SELF_HOSTED=true
# URLs
- DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@opdb:5432/${OPENPANEL_POSTGRES_DB:-openpanel-db}?schema=public
- REDIS_URL=redis://default:${SERVICE_PASSWORD_REDIS}@opkv:6379
@@ -193,7 +193,7 @@ services:
- SERVICE_FQDN_OPBULLBOARD
# Common
- NODE_ENV=production
- VITE_SELF_HOSTED=true
- SELF_HOSTED=true
# URLs
- DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@opdb:5432/${OPENPANEL_POSTGRES_DB:-openpanel-db}?schema=public
- DATABASE_URL_DIRECT=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@opdb:5432/${OPENPANEL_POSTGRES_DB:-openpanel-db}?schema=public

View File

@@ -77,6 +77,65 @@ while [[ $# -gt 0 ]]; do
esac
done
# Check if jq is installed (required for JSON parsing)
if ! command -v jq &> /dev/null; then
echo -e "${YELLOW}jq is required but not installed${NC}\n"
echo -e "${CYAN}jq is a lightweight JSON processor needed to parse GitHub API responses.${NC}\n"
# Detect OS and suggest installation
if [[ -f /etc/os-release ]]; then
. /etc/os-release
OS_ID=$ID
elif [[ "$OSTYPE" == "darwin"* ]]; then
OS_ID="macos"
else
OS_ID="unknown"
fi
# Determine installation command
case $OS_ID in
ubuntu|debian)
INSTALL_CMD="sudo apt-get update && sudo apt-get install -y jq"
;;
rhel|centos|fedora)
INSTALL_CMD="sudo yum install -y jq"
;;
alpine)
INSTALL_CMD="sudo apk add --no-cache jq"
;;
macos)
INSTALL_CMD="brew install jq"
;;
*)
echo -e "${RED}Could not detect your OS.${NC}"
echo -e "${YELLOW}Please install jq manually:${NC}"
echo -e " ${GREEN}Ubuntu/Debian:${NC} sudo apt-get update && sudo apt-get install -y jq"
echo -e " ${GREEN}RHEL/CentOS:${NC} sudo yum install -y jq"
echo -e " ${GREEN}Alpine:${NC} sudo apk add --no-cache jq"
echo -e " ${GREEN}macOS:${NC} brew install jq"
echo ""
exit 1
;;
esac
# Ask user if they want to install
read -p "$(echo -e ${GREEN}Would you like to install jq now? [Y/n]:${NC} )" -n 1 -r
echo
if [[ $REPLY =~ ^[Nn]$ ]]; then
echo -e "${RED}jq is required to continue. Please install it manually.${NC}"
exit 1
fi
# Install jq
echo -e "${BLUE}Installing jq...${NC}\n"
if eval "$INSTALL_CMD"; then
echo -e "\n${GREEN}✓ jq installed successfully!${NC}\n"
else
echo -e "\n${RED}✗ Failed to install jq. Please install it manually.${NC}"
exit 1
fi
fi
# Check if user needs to be logged in (for apply mode)
if [ "$APPLY_MODE" = true ]; then
# Check if Docker is available
@@ -135,11 +194,7 @@ fi
# List all tags if requested
if [ "$LIST_ALL" = true ]; then
echo -e "${GREEN}All available tags:${NC}\n"
if command -v jq &> /dev/null; then
echo "$TAGS_JSON" | jq -r '.[] | " \(.name) (\(.commit.sha[0:7]))"'
else
echo "$TAGS_JSON" | grep "\"name\":" | sed 's/.*"name": "\([^"]*\)".*/ \1/'
fi
echo "$TAGS_JSON" | jq -r '.[] | " \(.name) (\(.commit.sha[0:7]))"'
echo ""
exit 0
fi
@@ -150,15 +205,9 @@ get_latest_tag() {
local output_var_tag=$2
local output_var_sha=$3
if command -v jq &> /dev/null; then
# Use jq for better JSON parsing
local tag=$(echo "$TAGS_JSON" | jq -r "[.[] | select(.name | contains(\"${component}\"))] | .[0] | .name" 2>/dev/null)
local sha=$(echo "$TAGS_JSON" | jq -r "[.[] | select(.name | contains(\"${component}\"))] | .[0] | .commit.sha" 2>/dev/null)
else
# Fallback to grep/sed
local tag=$(echo "$TAGS_JSON" | grep -o "\"name\": \"[^\"]*${component}[^\"]*\"" | head -1 | cut -d'"' -f4)
local sha=$(echo "$TAGS_JSON" | grep -B5 "\"name\": \"${tag}\"" | grep "\"sha\"" | head -1 | cut -d'"' -f4)
fi
# Use jq for JSON parsing
local tag=$(echo "$TAGS_JSON" | jq -r "[.[] | select(.name | contains(\"${component}\"))] | .[0] | .name" 2>/dev/null)
local sha=$(echo "$TAGS_JSON" | jq -r "[.[] | select(.name | contains(\"${component}\"))] | .[0] | .commit.sha" 2>/dev/null)
if [ -z "$tag" ] || [ "$tag" == "null" ]; then
echo -e "${RED}✗${NC} ${component}: No matching tag found"

View File

@@ -46,7 +46,6 @@ build_image() {
--platform linux/amd64,linux/arm64 \
-t "$full_version" \
--build-arg DATABASE_URL="postgresql://p@p:5432/p" \
--build-arg VITE_SELF_HOSTED="true" \
-f "apps/$app/Dockerfile" \
--push \
.
@@ -57,7 +56,6 @@ build_image() {
-t "$full_version" \
-t "$image_name:latest" \
--build-arg DATABASE_URL="postgresql://p@p:5432/p" \
--build-arg VITE_SELF_HOSTED="true" \
-f "apps/$app/Dockerfile" \
--push \
.

60
sh/tag-self-hosting Executable file
View File

@@ -0,0 +1,60 @@
#!/bin/bash
# Tags to manage
TAGS=("self-hosting")
# Get commit from argument or default to HEAD
COMMIT="${1:-HEAD}"
echo "🏷️ Managing tags: ${TAGS[@]}"
echo "📍 Target commit: $COMMIT"
echo ""
# Verify commit exists
if ! git rev-parse --verify "$COMMIT" >/dev/null 2>&1; then
echo "❌ Error: Invalid commit reference: $COMMIT"
exit 1
fi
# Delete local tags
echo "🗑️ Deleting local tags..."
for tag in "${TAGS[@]}"; do
if git tag -l "$tag" | grep -q "$tag"; then
git tag -d "$tag"
echo " ✓ Deleted local tag: $tag"
else
echo " - Tag $tag doesn't exist locally"
fi
done
echo ""
# Delete remote tags
echo "🗑️ Deleting remote tags..."
for tag in "${TAGS[@]}"; do
if git ls-remote --tags origin | grep -q "refs/tags/$tag"; then
SKIP_HOOKS=1 git push origin ":refs/tags/$tag" 2>/dev/null
echo " ✓ Deleted remote tag: $tag"
else
echo " - Tag $tag doesn't exist on remote"
fi
done
echo ""
# Create new tags
echo "🏷️ Creating new tags on commit $COMMIT..."
for tag in "${TAGS[@]}"; do
git tag "$tag" "$COMMIT"
echo " ✓ Created tag: $tag"
done
echo ""
# Push tags
echo "🚀 Pushing tags to remote..."
SKIP_HOOKS=1 git push origin "${TAGS[@]}"
echo ""
echo "✅ Done! Tags updated successfully."

60
sh/tag-supporter Executable file
View File

@@ -0,0 +1,60 @@
#!/bin/bash
# Tags to manage
TAGS=("api" "worker" "dashboard")
# Get commit from argument or default to HEAD
COMMIT="${1:-HEAD}"
echo "🏷️ Managing tags: ${TAGS[@]}"
echo "📍 Target commit: $COMMIT"
echo ""
# Verify commit exists
if ! git rev-parse --verify "$COMMIT" >/dev/null 2>&1; then
echo "❌ Error: Invalid commit reference: $COMMIT"
exit 1
fi
# Delete local tags
echo "🗑️ Deleting local tags..."
for tag in "${TAGS[@]}"; do
if git tag -l "$tag" | grep -q "$tag"; then
git tag -d "$tag"
echo " ✓ Deleted local tag: $tag"
else
echo " - Tag $tag doesn't exist locally"
fi
done
echo ""
# Delete remote tags
echo "🗑️ Deleting remote tags..."
for tag in "${TAGS[@]}"; do
if git ls-remote --tags origin | grep -q "refs/tags/$tag"; then
SKIP_HOOKS=1 git push origin ":refs/tags/$tag" 2>/dev/null
echo " ✓ Deleted remote tag: $tag"
else
echo " - Tag $tag doesn't exist on remote"
fi
done
echo ""
# Create new tags
echo "🏷️ Creating new tags on commit $COMMIT..."
for tag in "${TAGS[@]}"; do
git tag "$tag" "$COMMIT"
echo " ✓ Created tag: $tag"
done
echo ""
# Push tags
echo "🚀 Pushing tags to remote..."
SKIP_HOOKS=1 git push origin "${TAGS[@]}"
echo ""
echo "✅ Done! Tags updated successfully."