@powerhousedao/ph-cli 4.1.0-dev.60 → 4.1.0-dev.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -9
- package/dist/scripts/generate-commands-md.ts +0 -84
- package/dist/scripts/generate-version.ts +0 -22
- package/dist/scripts/manage-environment +0 -191
- package/dist/scripts/setup-environment +0 -392
- package/dist/scripts/setup-environment.ps1 +0 -313
- package/dist/scripts/setup.sh +0 -24
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powerhousedao/ph-cli",
|
|
3
|
-
"version": "4.1.0-dev.
|
|
3
|
+
"version": "4.1.0-dev.61",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"type": "module",
|
|
@@ -32,13 +32,13 @@
|
|
|
32
32
|
"colorette": "^2.0.20",
|
|
33
33
|
"commander": "^12.1.0",
|
|
34
34
|
"pm2": "^5.4.3",
|
|
35
|
-
"@powerhousedao/builder-tools": "4.1.0-dev.
|
|
36
|
-
"@powerhousedao/
|
|
37
|
-
"@powerhousedao/
|
|
38
|
-
"@powerhousedao/
|
|
39
|
-
"@powerhousedao/
|
|
40
|
-
"document-
|
|
41
|
-
"document-
|
|
35
|
+
"@powerhousedao/builder-tools": "4.1.0-dev.61",
|
|
36
|
+
"@powerhousedao/config": "4.1.0-dev.61",
|
|
37
|
+
"@powerhousedao/reactor-local": "4.1.0-dev.61",
|
|
38
|
+
"@powerhousedao/switchboard": "4.1.0-dev.61",
|
|
39
|
+
"@powerhousedao/codegen": "4.1.0-dev.61",
|
|
40
|
+
"document-drive": "4.1.0-dev.61",
|
|
41
|
+
"document-model": "4.1.0-dev.61"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"pretsc": "tsx scripts/generate-version.ts",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"lint": "eslint",
|
|
47
47
|
"generate-commands-md": "tsx scripts/generate-commands-md.ts",
|
|
48
48
|
"generate-version": "tsx scripts/generate-version.ts",
|
|
49
|
-
"build": "npm run generate-commands-md && npm run generate-version && npm run copy-scripts",
|
|
49
|
+
"build:misc": "npm run generate-commands-md && npm run generate-version && tsc && npm run copy-scripts",
|
|
50
50
|
"copy-scripts": "copyfiles scripts/* dist/",
|
|
51
51
|
"dev": "concurrently -P 'pnpm -w run tsc --watch' 'nodemon --watch \"../..\" -e ts,tsx,js,json dist/src/cli.js -- {@}' --",
|
|
52
52
|
"test": "vitest --run"
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import * as fs from "fs";
|
|
2
|
-
import * as path from "path";
|
|
3
|
-
import { fileURLToPath } from "url";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Generate COMMANDS.md file from the help texts in help.ts
|
|
7
|
-
*/
|
|
8
|
-
async function generateCommandsMd() {
|
|
9
|
-
try {
|
|
10
|
-
// Define paths for ES modules
|
|
11
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
-
const __dirname = path.dirname(__filename);
|
|
13
|
-
const rootDir = path.resolve(__dirname, "..");
|
|
14
|
-
const helpFilePath = path.join(rootDir, "src", "help.ts");
|
|
15
|
-
const outputPath = path.join(rootDir, "COMMANDS.md");
|
|
16
|
-
|
|
17
|
-
// Read the help.ts file
|
|
18
|
-
const helpFileContent = fs.readFileSync(helpFilePath, "utf8");
|
|
19
|
-
|
|
20
|
-
// Extract all help text constants using regex
|
|
21
|
-
const helpTextRegex = /export const (\w+)Help = `([\s\S]+?)`;/g;
|
|
22
|
-
const commands: { name: string; content: string }[] = [];
|
|
23
|
-
|
|
24
|
-
let match;
|
|
25
|
-
while ((match = helpTextRegex.exec(helpFileContent)) !== null) {
|
|
26
|
-
const commandName = match[1];
|
|
27
|
-
const helpContent = match[2];
|
|
28
|
-
commands.push({ name: commandName, content: helpContent });
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Sort commands alphabetically
|
|
32
|
-
commands.sort((a, b) => a.name.localeCompare(b.name));
|
|
33
|
-
|
|
34
|
-
// Generate the markdown content
|
|
35
|
-
let markdown = "# Powerhouse CLI Commands\n\n";
|
|
36
|
-
markdown +=
|
|
37
|
-
"This document provides detailed information about the available commands in the Powerhouse CLI.\n\n";
|
|
38
|
-
markdown += "## Table of Contents\n\n";
|
|
39
|
-
|
|
40
|
-
// Add table of contents
|
|
41
|
-
commands.forEach((command) => {
|
|
42
|
-
const displayName = formatCommandName(command.name);
|
|
43
|
-
const anchor = displayName.toLowerCase().replace(/\s+/g, "-");
|
|
44
|
-
markdown += `- [${displayName}](#${anchor})\n`;
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
markdown += "\n";
|
|
48
|
-
|
|
49
|
-
// Add command details
|
|
50
|
-
commands.forEach((command) => {
|
|
51
|
-
const displayName = formatCommandName(command.name);
|
|
52
|
-
markdown += `## ${displayName}\n\n`;
|
|
53
|
-
markdown += "```\n";
|
|
54
|
-
markdown += command.content.trim();
|
|
55
|
-
markdown += "\n```\n\n";
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
// Add footer
|
|
59
|
-
markdown += "---\n\n";
|
|
60
|
-
markdown +=
|
|
61
|
-
"*This document was automatically generated from the help text in the codebase.*\n";
|
|
62
|
-
|
|
63
|
-
// Write to COMMANDS.md
|
|
64
|
-
fs.writeFileSync(outputPath, markdown);
|
|
65
|
-
|
|
66
|
-
console.log(`✅ COMMANDS.md has been generated at ${outputPath}`);
|
|
67
|
-
} catch (error) {
|
|
68
|
-
console.error("Failed to generate COMMANDS.md:", error);
|
|
69
|
-
process.exit(1);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Format command name for display (e.g., "setupGlobals" -> "Setup Globals")
|
|
75
|
-
*/
|
|
76
|
-
function formatCommandName(commandName: string): string {
|
|
77
|
-
// Convert camelCase to separate words with spaces
|
|
78
|
-
const name = commandName.replace(/([A-Z])/g, " $1").trim();
|
|
79
|
-
// Capitalize first letter and convert the rest to lowercase
|
|
80
|
-
return name.charAt(0).toUpperCase() + name.slice(1);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Run the script
|
|
84
|
-
generateCommandsMd();
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync } from "fs";
|
|
2
|
-
import { join } from "path";
|
|
3
|
-
import { fileURLToPath } from "url";
|
|
4
|
-
|
|
5
|
-
interface PackageJson {
|
|
6
|
-
version: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
|
10
|
-
|
|
11
|
-
// Read package.json
|
|
12
|
-
const packageJson = JSON.parse(
|
|
13
|
-
readFileSync(join(__dirname, "../package.json"), "utf-8"),
|
|
14
|
-
) as PackageJson;
|
|
15
|
-
|
|
16
|
-
// Generate version.ts content
|
|
17
|
-
const versionFileContent = `// This file is auto-generated. DO NOT EDIT.
|
|
18
|
-
export const version = "${packageJson.version}";
|
|
19
|
-
`;
|
|
20
|
-
|
|
21
|
-
// Write version.ts
|
|
22
|
-
writeFileSync(join(__dirname, "../src/version.ts"), versionFileContent);
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
|
|
3
|
-
# =============================================================================
|
|
4
|
-
# Configuration
|
|
5
|
-
# =============================================================================
|
|
6
|
-
PROJECT_NAME=${1:-"global"}
|
|
7
|
-
ACTION=${2:-"status"}
|
|
8
|
-
|
|
9
|
-
# Get Switchboard port from .env or use default
|
|
10
|
-
if [ -f ".env" ]; then
|
|
11
|
-
SWITCHBOARD_PORT=$(grep "SWITCHBOARD_PORT=" .env | cut -d'=' -f2)
|
|
12
|
-
fi
|
|
13
|
-
SWITCHBOARD_PORT=${SWITCHBOARD_PORT:-4001}
|
|
14
|
-
|
|
15
|
-
# =============================================================================
|
|
16
|
-
# OS Detection and Windows Handling
|
|
17
|
-
# =============================================================================
|
|
18
|
-
if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
|
|
19
|
-
if [ -f "$0.ps1" ]; then
|
|
20
|
-
powershell -ExecutionPolicy Bypass -File "$0.ps1" -PROJECT_NAME "$PROJECT_NAME" -ACTION "$ACTION"
|
|
21
|
-
else
|
|
22
|
-
echo "Error: Windows management script (manage-environment.ps1) not found"
|
|
23
|
-
exit 1
|
|
24
|
-
fi
|
|
25
|
-
else
|
|
26
|
-
# =============================================================================
|
|
27
|
-
# Service Management
|
|
28
|
-
# =============================================================================
|
|
29
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
30
|
-
echo " Managing project: $PROJECT_NAME"
|
|
31
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
32
|
-
|
|
33
|
-
# Function to check if service is properly set up
|
|
34
|
-
check_setup() {
|
|
35
|
-
local project_name=$1
|
|
36
|
-
local error=0
|
|
37
|
-
|
|
38
|
-
# Check if .env file exists
|
|
39
|
-
if [ ! -f ".env" ]; then
|
|
40
|
-
echo "Error: .env file not found in project directory"
|
|
41
|
-
error=1
|
|
42
|
-
fi
|
|
43
|
-
|
|
44
|
-
# Check if Nginx configuration exists
|
|
45
|
-
if [ ! -f "/etc/nginx/sites-available/$project_name" ]; then
|
|
46
|
-
echo "Error: Nginx configuration not found"
|
|
47
|
-
error=1
|
|
48
|
-
fi
|
|
49
|
-
|
|
50
|
-
# Check if database is configured
|
|
51
|
-
if ! grep -q "DATABASE_URL" ".env"; then
|
|
52
|
-
echo "Error: Database configuration not found in .env file"
|
|
53
|
-
error=1
|
|
54
|
-
fi
|
|
55
|
-
|
|
56
|
-
if [ $error -eq 1 ]; then
|
|
57
|
-
echo "Please run 'ph setup-environment' first to set up the service"
|
|
58
|
-
exit 1
|
|
59
|
-
fi
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
# Function to enable/disable Nginx site
|
|
63
|
-
manage_nginx_site() {
|
|
64
|
-
local action=$1
|
|
65
|
-
local site_path="/etc/nginx/sites-available/$PROJECT_NAME"
|
|
66
|
-
local enabled_path="/etc/nginx/sites-enabled/$PROJECT_NAME"
|
|
67
|
-
|
|
68
|
-
if [ ! -f "$site_path" ]; then
|
|
69
|
-
echo "Error: Nginx site configuration for $PROJECT_NAME not found"
|
|
70
|
-
return 1
|
|
71
|
-
fi
|
|
72
|
-
|
|
73
|
-
case "$action" in
|
|
74
|
-
"enable")
|
|
75
|
-
if [ ! -L "$enabled_path" ]; then
|
|
76
|
-
sudo ln -sf "$site_path" "$enabled_path"
|
|
77
|
-
sudo nginx -t && sudo nginx -s reload
|
|
78
|
-
fi
|
|
79
|
-
;;
|
|
80
|
-
"disable")
|
|
81
|
-
if [ -L "$enabled_path" ]; then
|
|
82
|
-
sudo rm -f "$enabled_path"
|
|
83
|
-
sudo nginx -t && sudo nginx -s reload
|
|
84
|
-
fi
|
|
85
|
-
;;
|
|
86
|
-
esac
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
# Function to start services
|
|
90
|
-
start_services() {
|
|
91
|
-
check_setup "$PROJECT_NAME"
|
|
92
|
-
echo "Starting services..."
|
|
93
|
-
# Build Connect
|
|
94
|
-
echo "Building Connect..."
|
|
95
|
-
ph connect build
|
|
96
|
-
sudo rm -rf /var/www/html/${PROJECT_NAME}
|
|
97
|
-
sudo cp -r .ph/connect-build/dist /var/www/html/${PROJECT_NAME}
|
|
98
|
-
|
|
99
|
-
# Enable Nginx site
|
|
100
|
-
manage_nginx_site "enable"
|
|
101
|
-
|
|
102
|
-
# Start Switchboard via PM2
|
|
103
|
-
if ! pm2 list | grep -q "switchboard_${PROJECT_NAME}"; then
|
|
104
|
-
cd $PROJECT_NAME
|
|
105
|
-
pm2 start "pnpm switchboard --port $SWITCHBOARD_PORT" --name "switchboard_${PROJECT_NAME}"
|
|
106
|
-
pm2 save
|
|
107
|
-
else
|
|
108
|
-
pm2 start "switchboard_${PROJECT_NAME}"
|
|
109
|
-
fi
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
# Function to stop services
|
|
113
|
-
stop_services() {
|
|
114
|
-
check_setup "$PROJECT_NAME"
|
|
115
|
-
echo "Stopping services..."
|
|
116
|
-
# Stop Switchboard via PM2
|
|
117
|
-
if pm2 list | grep -q "switchboard_${PROJECT_NAME}"; then
|
|
118
|
-
pm2 stop "switchboard_${PROJECT_NAME}"
|
|
119
|
-
fi
|
|
120
|
-
|
|
121
|
-
# Disable Nginx site
|
|
122
|
-
manage_nginx_site "disable"
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
case "$ACTION" in
|
|
126
|
-
"start")
|
|
127
|
-
start_services
|
|
128
|
-
;;
|
|
129
|
-
|
|
130
|
-
"stop")
|
|
131
|
-
stop_services
|
|
132
|
-
;;
|
|
133
|
-
|
|
134
|
-
"restart")
|
|
135
|
-
echo "Restarting services..."
|
|
136
|
-
stop_services
|
|
137
|
-
start_services
|
|
138
|
-
;;
|
|
139
|
-
|
|
140
|
-
"status")
|
|
141
|
-
check_setup "$PROJECT_NAME"
|
|
142
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
143
|
-
echo " Service Status for $PROJECT_NAME"
|
|
144
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
145
|
-
|
|
146
|
-
# Create table header
|
|
147
|
-
printf "%-15s %-10s %-15s %-10s %-10s\n" "Service" "Status" "Memory" "Uptime" "Health"
|
|
148
|
-
echo "────────────────────────────────────────────────────────────────────"
|
|
149
|
-
|
|
150
|
-
# Check Connect status
|
|
151
|
-
connect_status="Disabled"
|
|
152
|
-
connect_health="❌"
|
|
153
|
-
connect_memory="N/A"
|
|
154
|
-
connect_uptime="N/A"
|
|
155
|
-
if [ -L "/etc/nginx/sites-enabled/$PROJECT_NAME" ]; then
|
|
156
|
-
connect_status="Enabled"
|
|
157
|
-
# Check if Connect is reachable
|
|
158
|
-
if curl -s -f "http://localhost/$PROJECT_NAME" > /dev/null; then
|
|
159
|
-
connect_health="✅"
|
|
160
|
-
fi
|
|
161
|
-
# Get Nginx memory usage for the site
|
|
162
|
-
nginx_pid=$(pgrep -f "nginx.*$PROJECT_NAME" | head -n 1)
|
|
163
|
-
if [ -n "$nginx_pid" ]; then
|
|
164
|
-
connect_memory=$(ps -o rss= -p "$nginx_pid" 2>/dev/null | awk '{printf "%.1fmb", $1/1024}')
|
|
165
|
-
connect_uptime=$(ps -o etime= -p "$nginx_pid" 2>/dev/null)
|
|
166
|
-
fi
|
|
167
|
-
fi
|
|
168
|
-
printf "%-15s %-10s %-15s %-10s %-10s\n" "Connect" "$connect_status" "$connect_memory" "$connect_uptime" "$connect_health"
|
|
169
|
-
|
|
170
|
-
# Check Switchboard status
|
|
171
|
-
switchboard_info=$(pm2 list | grep "switchboard_${PROJECT_NAME}")
|
|
172
|
-
if [ -n "$switchboard_info" ]; then
|
|
173
|
-
switchboard_status="Enabled"
|
|
174
|
-
switchboard_memory=$(echo "$switchboard_info" | awk '{print $12}')
|
|
175
|
-
switchboard_uptime=$(echo "$switchboard_info" | awk '{print $7}')
|
|
176
|
-
switchboard_health="✅"
|
|
177
|
-
printf "%-15s %-10s %-15s %-10s %-10s\n" "Switchboard" "$switchboard_status" "$switchboard_memory" "$switchboard_uptime" "$switchboard_health"
|
|
178
|
-
else
|
|
179
|
-
printf "%-15s %-10s %-15s %-10s %-10s\n" "Switchboard" "Disabled" "N/A" "N/A" "❌"
|
|
180
|
-
fi
|
|
181
|
-
echo "────────────────────────────────────────────────────────────────────"
|
|
182
|
-
;;
|
|
183
|
-
|
|
184
|
-
*)
|
|
185
|
-
echo "Usage: $0 [project_name] {start|stop|restart|status}"
|
|
186
|
-
echo "Default project_name: global"
|
|
187
|
-
echo "Default action: status"
|
|
188
|
-
exit 1
|
|
189
|
-
;;
|
|
190
|
-
esac
|
|
191
|
-
fi
|
|
@@ -1,392 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
|
|
3
|
-
# =============================================================================
|
|
4
|
-
# Configuration
|
|
5
|
-
# =============================================================================
|
|
6
|
-
TARGET_TAG=${1:-"latest"}
|
|
7
|
-
PROJECT_NAME=${2:-"global"}
|
|
8
|
-
|
|
9
|
-
# Function to find an available port
|
|
10
|
-
find_available_port() {
|
|
11
|
-
local port=4001
|
|
12
|
-
while netstat -tuln | grep -q ":$port "; do
|
|
13
|
-
port=$((port + 1))
|
|
14
|
-
done
|
|
15
|
-
echo $port
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
# =============================================================================
|
|
19
|
-
# OS Detection and Windows Handling
|
|
20
|
-
# =============================================================================
|
|
21
|
-
if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
|
|
22
|
-
if [ -f "$0.ps1" ]; then
|
|
23
|
-
powershell -ExecutionPolicy Bypass -File "$0.ps1" -TARGET_TAG "$TARGET_TAG"
|
|
24
|
-
else
|
|
25
|
-
echo "Error: Windows setup script (setup-environment.ps1) not found"
|
|
26
|
-
exit 1
|
|
27
|
-
fi
|
|
28
|
-
else
|
|
29
|
-
# =============================================================================
|
|
30
|
-
# Package Installation
|
|
31
|
-
# =============================================================================
|
|
32
|
-
sudo apt install -y postgresql postgresql-contrib nginx libnginx-mod-http-brotli-static libnginx-mod-http-brotli-filter
|
|
33
|
-
sudo sed -i 's/# gzip_vary/gzip_vary/; s/# gzip_proxied/gzip_proxied/; s/# gzip_comp_level/gzip_comp_level/; s/# gzip_buffers/gzip_buffers/; s/# gzip_http_version/gzip_http_version/; s/# gzip_types/gzip_types/' /etc/nginx/nginx.conf
|
|
34
|
-
|
|
35
|
-
# =============================================================================
|
|
36
|
-
# Interactive Package Installation
|
|
37
|
-
# =============================================================================
|
|
38
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
39
|
-
echo " Package Installation"
|
|
40
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
41
|
-
while true; do
|
|
42
|
-
read -p "Enter package name to install (or press Enter to skip): " package_name
|
|
43
|
-
if [ -z "$package_name" ]; then
|
|
44
|
-
break
|
|
45
|
-
fi
|
|
46
|
-
ph install "$package_name"
|
|
47
|
-
done
|
|
48
|
-
|
|
49
|
-
# =============================================================================
|
|
50
|
-
# Connect Build
|
|
51
|
-
# =============================================================================
|
|
52
|
-
ph connect build
|
|
53
|
-
cp -r .ph/connect-build/dist /var/www/html/$PROJECT_NAME
|
|
54
|
-
|
|
55
|
-
# =============================================================================
|
|
56
|
-
# Database Configuration
|
|
57
|
-
# =============================================================================
|
|
58
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
59
|
-
echo " Database Configuration"
|
|
60
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
61
|
-
echo "Choose database type:"
|
|
62
|
-
echo "1) Local PostgreSQL database"
|
|
63
|
-
echo "2) Remote PostgreSQL database"
|
|
64
|
-
read -p "Enter your choice (1 or 2): " db_choice
|
|
65
|
-
|
|
66
|
-
if [ "$db_choice" = "1" ]; then
|
|
67
|
-
echo "Setting up local PostgreSQL database..."
|
|
68
|
-
|
|
69
|
-
# Generate database credentials
|
|
70
|
-
DB_PASSWORD="powerhouse"
|
|
71
|
-
DB_USER="powerhouse"
|
|
72
|
-
# Convert to lowercase, replace dots with underscores, replace special chars with underscore, ensure starts with letter
|
|
73
|
-
DB_NAME="powerhouse_$(echo "${PROJECT_NAME}" | tr '[:upper:]' '[:lower:]' | sed 's/\./_/g' | sed 's/[^a-z0-9]/_/g' | sed 's/^[^a-z]/p_/' | cut -c1-63)"
|
|
74
|
-
|
|
75
|
-
# Check if database already exists
|
|
76
|
-
if sudo -u postgres psql -lqt | cut -d \| -f 1 | grep -qw $DB_NAME; then
|
|
77
|
-
echo "Database $DB_NAME already exists"
|
|
78
|
-
read -p "Do you want to recreate it? (y/n): " recreate_db
|
|
79
|
-
if [ "$recreate_db" = "y" ]; then
|
|
80
|
-
sudo -u postgres psql -c "DROP DATABASE $DB_NAME;"
|
|
81
|
-
else
|
|
82
|
-
echo "Using existing database"
|
|
83
|
-
fi
|
|
84
|
-
fi
|
|
85
|
-
|
|
86
|
-
# Create database and user if they don't exist
|
|
87
|
-
sudo -u postgres psql << EOF
|
|
88
|
-
DO
|
|
89
|
-
\$do\$
|
|
90
|
-
BEGIN
|
|
91
|
-
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = '$DB_USER') THEN
|
|
92
|
-
CREATE USER $DB_USER WITH PASSWORD '$DB_PASSWORD';
|
|
93
|
-
END IF;
|
|
94
|
-
END
|
|
95
|
-
\$do\$;
|
|
96
|
-
|
|
97
|
-
CREATE DATABASE $DB_NAME OWNER $DB_USER;
|
|
98
|
-
GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;
|
|
99
|
-
EOF
|
|
100
|
-
|
|
101
|
-
# Configure PostgreSQL
|
|
102
|
-
sudo sed -i "s/#listen_addresses = 'localhost'/listen_addresses = 'localhost'/" /etc/postgresql/*/main/postgresql.conf
|
|
103
|
-
|
|
104
|
-
# Set DATABASE_URL for local database
|
|
105
|
-
DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost:5432/$DB_NAME"
|
|
106
|
-
|
|
107
|
-
echo "Local database configured successfully!"
|
|
108
|
-
echo "Database URL: $DATABASE_URL"
|
|
109
|
-
echo "Please save these credentials securely!"
|
|
110
|
-
else
|
|
111
|
-
echo "Enter remote PostgreSQL URL (format: postgresql://user:password@host:port/db)"
|
|
112
|
-
echo "Example: postgresql://powerhouse:password@db.example.com:5432/powerhouse"
|
|
113
|
-
read -p "DATABASE_URL: " DATABASE_URL
|
|
114
|
-
fi
|
|
115
|
-
|
|
116
|
-
# Save DATABASE_URL to .env file
|
|
117
|
-
echo "DATABASE_URL=$DATABASE_URL" | sudo tee -a .env
|
|
118
|
-
|
|
119
|
-
# =============================================================================
|
|
120
|
-
# SSL Configuration
|
|
121
|
-
# =============================================================================
|
|
122
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
123
|
-
echo " SSL Configuration"
|
|
124
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
125
|
-
|
|
126
|
-
# Find an available port for Switchboard
|
|
127
|
-
SWITCHBOARD_PORT=$(find_available_port)
|
|
128
|
-
echo "Using port $SWITCHBOARD_PORT for Switchboard"
|
|
129
|
-
|
|
130
|
-
# Save Switchboard port to configuration
|
|
131
|
-
echo "SWITCHBOARD_PORT=$SWITCHBOARD_PORT" | sudo tee -a .env
|
|
132
|
-
|
|
133
|
-
# Add compression settings to nginx.conf if not exists
|
|
134
|
-
if ! grep -q "brotli_comp_level" /etc/nginx/nginx.conf || ! grep -q "gzip_comp_level" /etc/nginx/nginx.conf; then
|
|
135
|
-
echo "Adding compression settings to nginx.conf..."
|
|
136
|
-
# Find the http block in nginx.conf
|
|
137
|
-
if ! grep -q "brotli_comp_level" /etc/nginx/nginx.conf; then
|
|
138
|
-
sudo sed -i '/http {/a \ # Brotli compression\n brotli on;\n brotli_comp_level 6;\n brotli_types text/plain text/css application/javascript application/json image/svg+xml application/xml+rss;\n brotli_static on;' /etc/nginx/nginx.conf
|
|
139
|
-
fi
|
|
140
|
-
if ! grep -q "gzip_comp_level" /etc/nginx/nginx.conf; then
|
|
141
|
-
sudo sed -i '/http {/a \ # Gzip compression\n gzip on;\n gzip_vary on;\n gzip_proxied any;\n gzip_comp_level 6;\n gzip_buffers 16 8k;\n gzip_http_version 1.1;\n gzip_types text/plain text/css application/javascript application/json image/svg+xml application/xml+rss;' /etc/nginx/nginx.conf
|
|
142
|
-
fi
|
|
143
|
-
else
|
|
144
|
-
echo "Compression settings already present in nginx.conf"
|
|
145
|
-
fi
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
echo "Choose SSL configuration:"
|
|
150
|
-
echo "1) Let's Encrypt certificates for domains"
|
|
151
|
-
echo "2) Self-signed certificate for machine hostname"
|
|
152
|
-
read -p "Enter your choice (1 or 2): " ssl_choice
|
|
153
|
-
|
|
154
|
-
if [ "$ssl_choice" = "1" ]; then
|
|
155
|
-
# Install certbot
|
|
156
|
-
sudo apt install -y certbot python3-certbot-nginx
|
|
157
|
-
|
|
158
|
-
# =============================================================================
|
|
159
|
-
# Domain Setup
|
|
160
|
-
# =============================================================================
|
|
161
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
162
|
-
echo " Domain Setup"
|
|
163
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
164
|
-
read -p "Enter Connect domain (e.g. connect.google.com): " connect_domain
|
|
165
|
-
read -p "Enter Switchboard domain (e.g. switchboard.google.com): " switchboard_domain
|
|
166
|
-
read -p "Enter admin email for Let's Encrypt notifications: " admin_email
|
|
167
|
-
|
|
168
|
-
echo "Using domains:"
|
|
169
|
-
echo "Connect: $connect_domain"
|
|
170
|
-
echo "Switchboard: $switchboard_domain"
|
|
171
|
-
|
|
172
|
-
# Create initial Nginx configuration for certbot
|
|
173
|
-
echo "Creating initial Nginx configuration..."
|
|
174
|
-
sudo tee /etc/nginx/sites-available/$PROJECT_NAME > /dev/null << EOF
|
|
175
|
-
server {
|
|
176
|
-
listen 80;
|
|
177
|
-
server_name $connect_domain $switchboard_domain;
|
|
178
|
-
|
|
179
|
-
location / {
|
|
180
|
-
root /var/www/html/$PROJECT_NAME;
|
|
181
|
-
try_files \$uri \$uri/ /index.html;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
location /.well-known/acme-challenge/ {
|
|
185
|
-
root /var/www/html;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
EOF
|
|
189
|
-
|
|
190
|
-
# Enable the site
|
|
191
|
-
sudo ln -sf /etc/nginx/sites-available/$PROJECT_NAME /etc/nginx/sites-enabled/
|
|
192
|
-
sudo rm -f /etc/nginx/sites-enabled/default
|
|
193
|
-
|
|
194
|
-
# Test Nginx configuration
|
|
195
|
-
sudo nginx -t
|
|
196
|
-
|
|
197
|
-
# Restart Nginx to apply changes
|
|
198
|
-
sudo systemctl restart nginx
|
|
199
|
-
|
|
200
|
-
# Obtain SSL certificates
|
|
201
|
-
echo "Obtaining SSL certificates..."
|
|
202
|
-
sudo certbot --nginx -d $connect_domain --non-interactive --agree-tos --email $admin_email --redirect
|
|
203
|
-
sudo certbot --nginx -d $switchboard_domain --non-interactive --agree-tos --email $admin_email --redirect
|
|
204
|
-
|
|
205
|
-
# Wait for certbot to finish and certificates to be installed
|
|
206
|
-
sleep 5
|
|
207
|
-
|
|
208
|
-
# Check if certificates were installed
|
|
209
|
-
if [ ! -f "/etc/letsencrypt/live/$connect_domain/fullchain.pem" ] || [ ! -f "/etc/letsencrypt/live/$switchboard_domain/fullchain.pem" ]; then
|
|
210
|
-
echo "Error: SSL certificates were not installed properly"
|
|
211
|
-
echo "Please check the certbot logs at /var/log/letsencrypt/letsencrypt.log"
|
|
212
|
-
exit 1
|
|
213
|
-
fi
|
|
214
|
-
|
|
215
|
-
# Update Nginx configuration with proper SSL settings
|
|
216
|
-
echo "Updating Nginx configuration with SSL settings..."
|
|
217
|
-
sudo tee /etc/nginx/sites-available/$PROJECT_NAME > /dev/null << EOF
|
|
218
|
-
server {
|
|
219
|
-
listen 80;
|
|
220
|
-
server_name $connect_domain $switchboard_domain;
|
|
221
|
-
return 301 https://\$host\$request_uri;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
server {
|
|
225
|
-
listen 443 ssl;
|
|
226
|
-
http2 on;
|
|
227
|
-
server_name $connect_domain;
|
|
228
|
-
|
|
229
|
-
ssl_certificate /etc/letsencrypt/live/$connect_domain/fullchain.pem;
|
|
230
|
-
ssl_certificate_key /etc/letsencrypt/live/$connect_domain/privkey.pem;
|
|
231
|
-
|
|
232
|
-
# SSL configuration
|
|
233
|
-
ssl_protocols TLSv1.2 TLSv1.3;
|
|
234
|
-
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
|
|
235
|
-
ssl_prefer_server_ciphers off;
|
|
236
|
-
ssl_session_timeout 1d;
|
|
237
|
-
ssl_session_cache shared:SSL:50m;
|
|
238
|
-
ssl_session_tickets off;
|
|
239
|
-
ssl_stapling on;
|
|
240
|
-
ssl_stapling_verify on;
|
|
241
|
-
resolver 8.8.8.8 8.8.4.4 valid=300s;
|
|
242
|
-
resolver_timeout 5s;
|
|
243
|
-
|
|
244
|
-
# Security headers
|
|
245
|
-
add_header Strict-Transport-Security "max-age=63072000" always;
|
|
246
|
-
add_header X-Frame-Options DENY;
|
|
247
|
-
add_header X-Content-Type-Options nosniff;
|
|
248
|
-
add_header X-XSS-Protection "1; mode=block";
|
|
249
|
-
|
|
250
|
-
if (\$http_x_forwarded_proto = "http") {
|
|
251
|
-
return 301 https://\$server_name\$request_uri;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
location / {
|
|
255
|
-
root /var/www/html/$PROJECT_NAME;
|
|
256
|
-
try_files \$uri \$uri/ /index.html;
|
|
257
|
-
add_header Cache-Control "no-cache";
|
|
258
|
-
add_header X-Forwarded-Proto \$scheme;
|
|
259
|
-
add_header X-Forwarded-Host \$host;
|
|
260
|
-
add_header X-Forwarded-Port \$server_port;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
location /.well-known/acme-challenge/ {
|
|
264
|
-
root /var/www/html;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
server {
|
|
269
|
-
listen 443 ssl;
|
|
270
|
-
http2 on;
|
|
271
|
-
server_name $switchboard_domain;
|
|
272
|
-
|
|
273
|
-
ssl_certificate /etc/letsencrypt/live/$switchboard_domain/fullchain.pem;
|
|
274
|
-
ssl_certificate_key /etc/letsencrypt/live/$switchboard_domain/privkey.pem;
|
|
275
|
-
|
|
276
|
-
# SSL configuration
|
|
277
|
-
ssl_protocols TLSv1.2 TLSv1.3;
|
|
278
|
-
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
|
|
279
|
-
ssl_prefer_server_ciphers off;
|
|
280
|
-
ssl_session_timeout 1d;
|
|
281
|
-
ssl_session_cache shared:SSL:50m;
|
|
282
|
-
ssl_session_tickets off;
|
|
283
|
-
ssl_stapling on;
|
|
284
|
-
ssl_stapling_verify on;
|
|
285
|
-
resolver 8.8.8.8 8.8.4.4 valid=300s;
|
|
286
|
-
resolver_timeout 5s;
|
|
287
|
-
|
|
288
|
-
# Security headers
|
|
289
|
-
add_header Strict-Transport-Security "max-age=63072000" always;
|
|
290
|
-
add_header X-Frame-Options DENY;
|
|
291
|
-
add_header X-Content-Type-Options nosniff;
|
|
292
|
-
add_header X-XSS-Protection "1; mode=block";
|
|
293
|
-
|
|
294
|
-
location / {
|
|
295
|
-
proxy_pass http://localhost:$SWITCHBOARD_PORT;
|
|
296
|
-
proxy_http_version 1.1;
|
|
297
|
-
proxy_set_header Upgrade \$http_upgrade;
|
|
298
|
-
proxy_set_header Connection 'upgrade';
|
|
299
|
-
proxy_set_header Host \$host;
|
|
300
|
-
proxy_cache_bypass \$http_upgrade;
|
|
301
|
-
proxy_set_header X-Real-IP \$remote_addr;
|
|
302
|
-
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
303
|
-
proxy_set_header X-Forwarded-Proto \$scheme;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
location /.well-known/acme-challenge/ {
|
|
307
|
-
root /var/www/html;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
EOF
|
|
311
|
-
|
|
312
|
-
# Test and reload Nginx configuration
|
|
313
|
-
sudo nginx -t && sudo systemctl reload nginx
|
|
314
|
-
|
|
315
|
-
# Set up automatic renewal
|
|
316
|
-
echo "Setting up automatic certificate renewal..."
|
|
317
|
-
sudo systemctl enable certbot.timer
|
|
318
|
-
sudo systemctl start certbot.timer
|
|
319
|
-
|
|
320
|
-
else
|
|
321
|
-
# Get machine hostname
|
|
322
|
-
hostname=$(hostname)
|
|
323
|
-
|
|
324
|
-
# Generate self-signed certificate
|
|
325
|
-
echo "Generating self-signed certificate for $hostname..."
|
|
326
|
-
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
|
|
327
|
-
-keyout /etc/ssl/private/$hostname.key \
|
|
328
|
-
-out /etc/ssl/certs/$hostname.crt \
|
|
329
|
-
-subj "/CN=$hostname" \
|
|
330
|
-
-addext "subjectAltName = DNS:$hostname"
|
|
331
|
-
|
|
332
|
-
# Create Nginx configuration for self-signed
|
|
333
|
-
echo "Creating Nginx configuration..."
|
|
334
|
-
sudo tee /etc/nginx/sites-available/$PROJECT_NAME > /dev/null << EOF
|
|
335
|
-
server {
|
|
336
|
-
listen 80;
|
|
337
|
-
server_name $hostname;
|
|
338
|
-
return 301 https://\$host\$request_uri;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
server {
|
|
342
|
-
listen 443 ssl;
|
|
343
|
-
http2 on;
|
|
344
|
-
server_name $hostname;
|
|
345
|
-
|
|
346
|
-
ssl_certificate /etc/ssl/certs/$hostname.crt;
|
|
347
|
-
ssl_certificate_key /etc/ssl/private/$hostname.key;
|
|
348
|
-
|
|
349
|
-
location /connect {
|
|
350
|
-
proxy_pass http://localhost:3000;
|
|
351
|
-
proxy_http_version 1.1;
|
|
352
|
-
proxy_set_header Upgrade \$http_upgrade;
|
|
353
|
-
proxy_set_header Connection 'upgrade';
|
|
354
|
-
proxy_set_header Host \$host;
|
|
355
|
-
proxy_cache_bypass \$http_upgrade;
|
|
356
|
-
proxy_set_header X-Real-IP \$remote_addr;
|
|
357
|
-
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
358
|
-
proxy_set_header X-Forwarded-Proto \$scheme;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
location /switchboard {
|
|
362
|
-
proxy_pass http://localhost:$SWITCHBOARD_PORT;
|
|
363
|
-
proxy_http_version 1.1;
|
|
364
|
-
proxy_set_header Upgrade \$http_upgrade;
|
|
365
|
-
proxy_set_header Connection 'upgrade';
|
|
366
|
-
proxy_set_header Host \$host;
|
|
367
|
-
proxy_cache_bypass \$http_upgrade;
|
|
368
|
-
proxy_set_header X-Real-IP \$remote_addr;
|
|
369
|
-
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
370
|
-
proxy_set_header X-Forwarded-Proto \$scheme;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
EOF
|
|
374
|
-
|
|
375
|
-
# Enable the site
|
|
376
|
-
sudo ln -sf /etc/nginx/sites-available/$PROJECT_NAME /etc/nginx/sites-enabled/
|
|
377
|
-
sudo rm -f /etc/nginx/sites-enabled/default
|
|
378
|
-
|
|
379
|
-
# Test Nginx configuration
|
|
380
|
-
sudo nginx -t
|
|
381
|
-
fi
|
|
382
|
-
|
|
383
|
-
# =============================================================================
|
|
384
|
-
# Database Schema Setup
|
|
385
|
-
# =============================================================================
|
|
386
|
-
pnpm prisma db push --schema node_modules/document-drive/dist/prisma/schema.prisma
|
|
387
|
-
|
|
388
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
389
|
-
echo " Environment setup complete!"
|
|
390
|
-
echo " Use 'ph service start' to start services"
|
|
391
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
392
|
-
fi
|
|
@@ -1,313 +0,0 @@
|
|
|
1
|
-
# PowerShell script for setting up Powerhouse environment on Windows
|
|
2
|
-
param(
|
|
3
|
-
[string]$TARGET_TAG = "latest"
|
|
4
|
-
)
|
|
5
|
-
|
|
6
|
-
# Function to check if running as administrator
|
|
7
|
-
function Test-Administrator {
|
|
8
|
-
$user = [Security.Principal.WindowsIdentity]::GetCurrent()
|
|
9
|
-
$principal = New-Object Security.Principal.WindowsPrincipal $user
|
|
10
|
-
$principal.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
# Check if running as administrator
|
|
14
|
-
if (-not (Test-Administrator)) {
|
|
15
|
-
Write-Host "Please run this script as Administrator" -ForegroundColor Red
|
|
16
|
-
exit 1
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
# Install required packages using winget
|
|
20
|
-
Write-Host "Installing required packages..."
|
|
21
|
-
winget install -e --id PostgreSQL.PostgreSQL
|
|
22
|
-
winget install -e --id NGINX.NGINX
|
|
23
|
-
|
|
24
|
-
Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
25
|
-
Write-Host " Setting up global project"
|
|
26
|
-
Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
27
|
-
|
|
28
|
-
# Create installation directory if it doesn't exist
|
|
29
|
-
$installPath = "C:\www"
|
|
30
|
-
if (-not (Test-Path $installPath)) {
|
|
31
|
-
New-Item -ItemType Directory -Path $installPath
|
|
32
|
-
}
|
|
33
|
-
Set-Location $installPath
|
|
34
|
-
|
|
35
|
-
# Initialize Powerhouse project
|
|
36
|
-
ph init powerhouse --$TARGET_TAG
|
|
37
|
-
Set-Location powerhouse
|
|
38
|
-
|
|
39
|
-
# Interactive package installation loop
|
|
40
|
-
Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
41
|
-
Write-Host " Package Installation"
|
|
42
|
-
Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
43
|
-
while ($true) {
|
|
44
|
-
$package_name = Read-Host "Enter package name to install (or press Enter to skip)"
|
|
45
|
-
if ([string]::IsNullOrEmpty($package_name)) {
|
|
46
|
-
break
|
|
47
|
-
}
|
|
48
|
-
ph install $package_name
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
# Build Connect
|
|
52
|
-
ph connect build
|
|
53
|
-
|
|
54
|
-
# Database Configuration
|
|
55
|
-
Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
56
|
-
Write-Host " Database Configuration"
|
|
57
|
-
Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
58
|
-
Write-Host "Choose database type:"
|
|
59
|
-
Write-Host "1) Local PostgreSQL database"
|
|
60
|
-
Write-Host "2) Remote PostgreSQL database"
|
|
61
|
-
$db_choice = Read-Host "Enter your choice (1 or 2)"
|
|
62
|
-
|
|
63
|
-
if ($db_choice -eq "1") {
|
|
64
|
-
Write-Host "Setting up local PostgreSQL database..."
|
|
65
|
-
|
|
66
|
-
# Generate database credentials
|
|
67
|
-
$DB_PASSWORD = "powerhouse"
|
|
68
|
-
$DB_USER = "powerhouse"
|
|
69
|
-
$DB_NAME = "powerhouse"
|
|
70
|
-
|
|
71
|
-
# Create database and user using psql
|
|
72
|
-
$env:PGPASSWORD = "postgres" # Default PostgreSQL password
|
|
73
|
-
psql -U postgres -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASSWORD';"
|
|
74
|
-
psql -U postgres -c "CREATE DATABASE $DB_NAME OWNER $DB_USER;"
|
|
75
|
-
psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;"
|
|
76
|
-
|
|
77
|
-
# Set DATABASE_URL for local database
|
|
78
|
-
$DATABASE_URL = "postgresql://$DB_USER`:$DB_PASSWORD@localhost:5432/$DB_NAME"
|
|
79
|
-
|
|
80
|
-
Write-Host "Local database configured successfully!"
|
|
81
|
-
Write-Host "Database URL: $DATABASE_URL"
|
|
82
|
-
Write-Host "Please save these credentials securely!"
|
|
83
|
-
} else {
|
|
84
|
-
Write-Host "Enter remote PostgreSQL URL (format: postgresql://user:password@host:port/db)"
|
|
85
|
-
Write-Host "Example: postgresql://powerhouse:password@db.example.com:5432/powerhouse"
|
|
86
|
-
$DATABASE_URL = Read-Host "DATABASE_URL"
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
# Save DATABASE_URL to .env file
|
|
90
|
-
Add-Content -Path "$installPath\powerhouse\.env" -Value "DATABASE_URL=$DATABASE_URL"
|
|
91
|
-
|
|
92
|
-
# SSL Configuration choice
|
|
93
|
-
Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
94
|
-
Write-Host " SSL Configuration"
|
|
95
|
-
Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
96
|
-
Write-Host "Choose SSL configuration:"
|
|
97
|
-
Write-Host "1) Let's Encrypt certificates for domains"
|
|
98
|
-
Write-Host "2) Self-signed certificate for machine hostname"
|
|
99
|
-
$ssl_choice = Read-Host "Enter your choice (1 or 2)"
|
|
100
|
-
|
|
101
|
-
if ($ssl_choice -eq "1") {
|
|
102
|
-
# Install certbot for Let's Encrypt
|
|
103
|
-
winget install -e --id Certbot.Certbot
|
|
104
|
-
|
|
105
|
-
# Domain setup
|
|
106
|
-
Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
107
|
-
Write-Host " Domain Setup"
|
|
108
|
-
Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
109
|
-
$base_domain = Read-Host "Enter base domain (e.g. powerhouse.xyz)"
|
|
110
|
-
$connect_subdomain = Read-Host "Enter subdomain for Connect service (default: connect)"
|
|
111
|
-
$switchboard_subdomain = Read-Host "Enter subdomain for Switchboard service (default: switchboard)"
|
|
112
|
-
|
|
113
|
-
# Set default subdomains if not provided
|
|
114
|
-
if ([string]::IsNullOrEmpty($connect_subdomain)) { $connect_subdomain = "connect" }
|
|
115
|
-
if ([string]::IsNullOrEmpty($switchboard_subdomain)) { $switchboard_subdomain = "switchboard" }
|
|
116
|
-
|
|
117
|
-
# Construct full domains
|
|
118
|
-
$connect_domain = "$connect_subdomain.$base_domain"
|
|
119
|
-
$switchboard_domain = "$switchboard_subdomain.$base_domain"
|
|
120
|
-
|
|
121
|
-
Write-Host "Using domains:"
|
|
122
|
-
Write-Host "Connect: $connect_domain"
|
|
123
|
-
Write-Host "Switchboard: $switchboard_domain"
|
|
124
|
-
|
|
125
|
-
# Generate temporary SSL certificates
|
|
126
|
-
Write-Host "Generating temporary SSL certificates..."
|
|
127
|
-
$sslPath = "C:\nginx\ssl"
|
|
128
|
-
if (-not (Test-Path $sslPath)) {
|
|
129
|
-
New-Item -ItemType Directory -Path $sslPath
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
# Create Nginx configuration for domains
|
|
133
|
-
$nginxConfig = @"
|
|
134
|
-
# Security headers
|
|
135
|
-
add_header Strict-Transport-Security "max-age=63072000" always;
|
|
136
|
-
add_header X-Frame-Options DENY;
|
|
137
|
-
add_header X-Content-Type-Options nosniff;
|
|
138
|
-
add_header X-XSS-Protection "1; mode=block";
|
|
139
|
-
|
|
140
|
-
server {
|
|
141
|
-
listen 80;
|
|
142
|
-
server_name $connect_domain $switchboard_domain;
|
|
143
|
-
return 301 https://`$host`$request_uri;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
server {
|
|
147
|
-
listen 443 ssl http2;
|
|
148
|
-
server_name $connect_domain;
|
|
149
|
-
|
|
150
|
-
ssl_certificate $sslPath\temp.crt;
|
|
151
|
-
ssl_certificate_key $sslPath\temp.key;
|
|
152
|
-
|
|
153
|
-
# SSL configuration
|
|
154
|
-
ssl_protocols TLSv1.2 TLSv1.3;
|
|
155
|
-
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
|
|
156
|
-
ssl_prefer_server_ciphers off;
|
|
157
|
-
ssl_session_timeout 1d;
|
|
158
|
-
ssl_session_cache shared:SSL:50m;
|
|
159
|
-
ssl_session_tickets off;
|
|
160
|
-
ssl_stapling on;
|
|
161
|
-
ssl_stapling_verify on;
|
|
162
|
-
|
|
163
|
-
if (`$http_x_forwarded_proto = "http") {
|
|
164
|
-
return 301 https://`$server_name`$request_uri;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
location / {
|
|
168
|
-
root C:/www/powerhouse/.ph/connect-build/dist;
|
|
169
|
-
try_files `$uri `$uri/ /index.html;
|
|
170
|
-
add_header Cache-Control "no-cache";
|
|
171
|
-
add_header X-Forwarded-Proto `$scheme;
|
|
172
|
-
add_header X-Forwarded-Host `$host;
|
|
173
|
-
add_header X-Forwarded-Port `$server_port;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
server {
|
|
178
|
-
listen 443 ssl http2;
|
|
179
|
-
server_name $switchboard_domain;
|
|
180
|
-
|
|
181
|
-
ssl_certificate $sslPath\temp.crt;
|
|
182
|
-
ssl_certificate_key $sslPath\temp.key;
|
|
183
|
-
|
|
184
|
-
location / {
|
|
185
|
-
proxy_pass http://localhost:4001;
|
|
186
|
-
proxy_http_version 1.1;
|
|
187
|
-
proxy_set_header Upgrade `$http_upgrade;
|
|
188
|
-
proxy_set_header Connection 'upgrade';
|
|
189
|
-
proxy_set_header Host `$host;
|
|
190
|
-
proxy_cache_bypass `$http_upgrade;
|
|
191
|
-
proxy_set_header X-Real-IP `$remote_addr;
|
|
192
|
-
proxy_set_header X-Forwarded-For `$proxy_add_x_forwarded_for;
|
|
193
|
-
proxy_set_header X-Forwarded-Proto `$scheme;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
"@
|
|
197
|
-
|
|
198
|
-
# Save Nginx configuration
|
|
199
|
-
$nginxConfig | Out-File -FilePath "C:\nginx\conf\sites-available\powerhouse.conf" -Encoding UTF8
|
|
200
|
-
|
|
201
|
-
# Create symbolic link to enable the site
|
|
202
|
-
if (-not (Test-Path "C:\nginx\conf\sites-enabled")) {
|
|
203
|
-
New-Item -ItemType Directory -Path "C:\nginx\conf\sites-enabled"
|
|
204
|
-
}
|
|
205
|
-
New-Item -ItemType SymbolicLink -Path "C:\nginx\conf\sites-enabled\powerhouse.conf" -Target "C:\nginx\conf\sites-available\powerhouse.conf" -Force
|
|
206
|
-
|
|
207
|
-
# Test Nginx configuration
|
|
208
|
-
nginx -t
|
|
209
|
-
|
|
210
|
-
# Restart Nginx
|
|
211
|
-
Stop-Service nginx
|
|
212
|
-
Start-Service nginx
|
|
213
|
-
|
|
214
|
-
# Obtain SSL certificates
|
|
215
|
-
Write-Host "Obtaining SSL certificates..."
|
|
216
|
-
certbot --nginx -d $connect_domain -d $switchboard_domain --non-interactive --agree-tos --email "admin@$base_domain"
|
|
217
|
-
|
|
218
|
-
} else {
|
|
219
|
-
# Get machine hostname
|
|
220
|
-
$hostname = [System.Net.Dns]::GetHostName()
|
|
221
|
-
|
|
222
|
-
# Generate self-signed certificate
|
|
223
|
-
Write-Host "Generating self-signed certificate for $hostname..."
|
|
224
|
-
$sslPath = "C:\nginx\ssl"
|
|
225
|
-
if (-not (Test-Path $sslPath)) {
|
|
226
|
-
New-Item -ItemType Directory -Path $sslPath
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
# Create Nginx configuration for self-signed
|
|
230
|
-
$nginxConfig = @"
|
|
231
|
-
# Security headers
|
|
232
|
-
add_header Strict-Transport-Security "max-age=63072000" always;
|
|
233
|
-
add_header X-Frame-Options DENY;
|
|
234
|
-
add_header X-Content-Type-Options nosniff;
|
|
235
|
-
add_header X-XSS-Protection "1; mode=block";
|
|
236
|
-
|
|
237
|
-
server {
|
|
238
|
-
listen 80;
|
|
239
|
-
server_name $hostname;
|
|
240
|
-
return 301 https://`$host`$request_uri;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
server {
|
|
244
|
-
listen 443 ssl http2;
|
|
245
|
-
server_name $hostname;
|
|
246
|
-
|
|
247
|
-
ssl_certificate $sslPath\$hostname.crt;
|
|
248
|
-
ssl_certificate_key $sslPath\$hostname.key;
|
|
249
|
-
|
|
250
|
-
location /connect {
|
|
251
|
-
proxy_pass http://localhost:3000;
|
|
252
|
-
proxy_http_version 1.1;
|
|
253
|
-
proxy_set_header Upgrade `$http_upgrade;
|
|
254
|
-
proxy_set_header Connection 'upgrade';
|
|
255
|
-
proxy_set_header Host `$host;
|
|
256
|
-
proxy_cache_bypass `$http_upgrade;
|
|
257
|
-
proxy_set_header X-Real-IP `$remote_addr;
|
|
258
|
-
proxy_set_header X-Forwarded-For `$proxy_add_x_forwarded_for;
|
|
259
|
-
proxy_set_header X-Forwarded-Proto `$scheme;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
location /switchboard {
|
|
263
|
-
proxy_pass http://localhost:4001;
|
|
264
|
-
proxy_http_version 1.1;
|
|
265
|
-
proxy_set_header Upgrade `$http_upgrade;
|
|
266
|
-
proxy_set_header Connection 'upgrade';
|
|
267
|
-
proxy_set_header Host `$host;
|
|
268
|
-
proxy_cache_bypass `$http_upgrade;
|
|
269
|
-
proxy_set_header X-Real-IP `$remote_addr;
|
|
270
|
-
proxy_set_header X-Forwarded-For `$proxy_add_x_forwarded_for;
|
|
271
|
-
proxy_set_header X-Forwarded-Proto `$scheme;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
"@
|
|
275
|
-
|
|
276
|
-
# Save Nginx configuration
|
|
277
|
-
$nginxConfig | Out-File -FilePath "C:\nginx\conf\sites-available\powerhouse.conf" -Encoding UTF8
|
|
278
|
-
|
|
279
|
-
# Create symbolic link to enable the site
|
|
280
|
-
if (-not (Test-Path "C:\nginx\conf\sites-enabled")) {
|
|
281
|
-
New-Item -ItemType Directory -Path "C:\nginx\conf\sites-enabled"
|
|
282
|
-
}
|
|
283
|
-
New-Item -ItemType SymbolicLink -Path "C:\nginx\conf\sites-enabled\powerhouse.conf" -Target "C:\nginx\conf\sites-available\powerhouse.conf" -Force
|
|
284
|
-
|
|
285
|
-
# Test Nginx configuration
|
|
286
|
-
nginx -t
|
|
287
|
-
|
|
288
|
-
# Restart Nginx
|
|
289
|
-
Stop-Service nginx
|
|
290
|
-
Start-Service nginx
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
# Install PM2 globally if not already installed
|
|
294
|
-
if (-not (Get-Command pm2 -ErrorAction SilentlyContinue)) {
|
|
295
|
-
pnpm install -g pm2
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
# Run database migrations
|
|
299
|
-
pnpm prisma db push --schema node_modules/document-drive/dist/prisma/schema.prisma
|
|
300
|
-
|
|
301
|
-
# Start services with PM2
|
|
302
|
-
Write-Host "Starting services with PM2..."
|
|
303
|
-
if ($ssl_choice -eq "2") {
|
|
304
|
-
# Self-signed certificate - use base paths
|
|
305
|
-
pm2 start pnpm switchboard --name "switchboard" -- --base-path /switchboard
|
|
306
|
-
} else {
|
|
307
|
-
# Let's Encrypt - no base paths needed
|
|
308
|
-
pm2 start "pnpm switchboard" --name "switchboard"
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
# Save PM2 process list and setup startup script
|
|
312
|
-
pm2 save
|
|
313
|
-
pm2 startup
|
package/dist/scripts/setup.sh
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
|
|
3
|
-
\. ~/.nvm/nvm.sh
|
|
4
|
-
export NVM_DIR="$HOME/.nvm"
|
|
5
|
-
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
|
6
|
-
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
|
|
7
|
-
nvm --version
|
|
8
|
-
nvm install 22
|
|
9
|
-
curl -fsSL https://get.pnpm.io/install.sh | sh -
|
|
10
|
-
export PNPM_HOME="/home/$USER/.local/share/pnpm"
|
|
11
|
-
export PATH="$PNPM_HOME:$PATH"
|
|
12
|
-
pnpm install -g ph-cmd
|
|
13
|
-
echo ""
|
|
14
|
-
echo " 🎉 Setup Complete! 🎉"
|
|
15
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
16
|
-
echo " To complete installation:"
|
|
17
|
-
echo " 1. Restart your terminal"
|
|
18
|
-
echo " OR"
|
|
19
|
-
echo " Run: source ~/.bashrc"
|
|
20
|
-
echo ""
|
|
21
|
-
echo " 2. Start using Powerhouse by typing:"
|
|
22
|
-
echo " ph"
|
|
23
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
24
|
-
echo ""
|