Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions ct/ghostfolio.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: lucasfell
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://ghostfol.io/

APP="Ghostfolio"
var_tags="${var_tags:-finance;investment}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"

header_info "$APP"
variables
color
catch_errors

function update_script() {
header_info
check_container_storage
check_container_resources

if [[ ! -f /opt/ghostfolio/dist/apps/api/main.js ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi

msg_info "Stopping $APP"
systemctl stop ghostfolio
msg_ok "Stopped $APP"

msg_info "Creating Backup"
tar -czf "/opt/ghostfolio_backup_$(date +%F).tar.gz" /opt/ghostfolio
msg_ok "Backup Created"

msg_info "Updating $APP"
systemctl stop ghostfolio

if [[ -d /opt/ghostfolio ]]; then
rm -rf /opt/ghostfolio_backup
mv /opt/ghostfolio /opt/ghostfolio_backup
fi

if fetch_and_deploy_gh_release "ghostfolio" "ghostfolio/ghostfolio" "tarball" "latest" "/opt/ghostfolio"; then
cd /opt/ghostfolio
npm ci
npm run build:production
npx prisma migrate deploy
msg_ok "Updated $APP"
else
if [[ -d /opt/ghostfolio_backup ]]; then
rm -rf /opt/ghostfolio
mv /opt/ghostfolio_backup /opt/ghostfolio
fi
msg_ok "No update required or update failed. ${APP} is up to date"
fi

msg_info "Starting $APP"
systemctl start ghostfolio
msg_ok "Started $APP"

msg_info "Cleaning Up"
npm cache clean --force
msg_ok "Cleanup Completed"
exit
}

start
build_container
description

msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3333${CL}"
56 changes: 56 additions & 0 deletions frontend/public/json/ghostfolio.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"name": "Ghostfolio",
"slug": "ghostfolio",
"categories": [
23
],
"date_created": "2025-08-14",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 3333,
"documentation": "https://github.com/ghostfolio/ghostfolio?tab=readme-ov-file#self-hosting",
"website": "https://ghostfol.io/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/ghostfolio.webp",
"config_path": "/opt/ghostfolio/.env",
"description": "Ghostfolio is an open source wealth management software built with web technology. The application empowers busy people to keep track of stocks, ETFs or cryptocurrencies and make solid, data-driven investment decisions.",
"install_methods": [
{
"type": "default",
"script": "ct/ghostfolio.sh",
"resources": {
"cpu": 2,
"ram": 4096,
"hdd": 8,
"os": "debian",
"version": "12"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Create your first user account by visiting the web interface and clicking 'Get Started'. The first user will automatically get admin privileges.",
"type": "info"
},
{
"text": "Database and Redis credentials: `cat ~/ghostfolio.creds`",
"type": "info"
},
{
"text": "Configuration file: `/opt/ghostfolio/.env`",
"type": "info"
},
{
"text": "Optional: CoinGecko API keys can be added during installation or later in the .env file for enhanced cryptocurrency data.",
"type": "info"
},
{
"text": "Build process requires 4GB RAM (runtime: ~2GB). A temporary swap file will be created automatically if insufficient memory is detected.",
"type": "warning"
}
]
}
149 changes: 149 additions & 0 deletions install/ghostfolio-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#!/usr/bin/env bash

# Copyright (c) 2021-2025 community-scripts ORG
# Author: lucasfell
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://ghostfol.io/

source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os

msg_info "Installing Dependencies"
$STD apt-get install -y \
build-essential \
python3 \
openssl \
curl \
ca-certificates
msg_ok "Installed Dependencies"

PG_VERSION="15" setup_postgresql
NODE_VERSION="22" setup_nodejs

msg_info "Installing Redis"
$STD apt-get install -y redis-server
msg_ok "Installed Redis"

msg_info "Setting up Database"
DB_NAME=ghostfolio
DB_USER=ghostfolio
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
REDIS_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
ACCESS_TOKEN_SALT=$(openssl rand -base64 32)
JWT_SECRET_KEY=$(openssl rand -base64 32)
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME;"
$STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH ENCRYPTED PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;"
$STD sudo -u postgres psql -c "ALTER USER $DB_USER CREATEDB;"
$STD sudo -u postgres psql -d $DB_NAME -c "GRANT ALL ON SCHEMA public TO $DB_USER;"
$STD sudo -u postgres psql -d $DB_NAME -c "GRANT CREATE ON SCHEMA public TO $DB_USER;"
$STD sudo -u postgres psql -d $DB_NAME -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO $DB_USER;"
$STD sudo -u postgres psql -d $DB_NAME -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO $DB_USER;"
{
echo "Ghostfolio Credentials"
echo "Database User: $DB_USER"
echo "Database Password: $DB_PASS"
echo "Database Name: $DB_NAME"
echo "Redis Password: $REDIS_PASS"
echo "Access Token Salt: $ACCESS_TOKEN_SALT"
echo "JWT Secret Key: $JWT_SECRET_KEY"
if [[ -n "${COINGECKO_DEMO_KEY:-}" ]]; then
echo "CoinGecko Demo API Key: $COINGECKO_DEMO_KEY"
fi
if [[ -n "${COINGECKO_PRO_KEY:-}" ]]; then
echo "CoinGecko Pro API Key: $COINGECKO_PRO_KEY"
fi
echo ""
echo "To add CoinGecko API keys later, edit: /opt/ghostfolio/.env"
} >>~/ghostfolio.creds
msg_ok "Set up Database"

msg_info "Configuring Redis"
sed -i "s/# requirepass foobared/requirepass $REDIS_PASS/" /etc/redis/redis.conf
systemctl restart redis-server
msg_ok "Configured Redis"

fetch_and_deploy_gh_release "ghostfolio" "ghostfolio/ghostfolio" "tarball" "latest" "/opt/ghostfolio"

msg_info "Installing Ghostfolio Dependencies"
cd /opt/ghostfolio
npm ci
msg_ok "Installed Dependencies"

msg_info "Building Ghostfolio (This may take several minutes)"
npm run build:production
msg_ok "Built Ghostfolio"

msg_ok "Optional CoinGecko API Configuration"
echo
echo -e "${YW}CoinGecko API keys are optional but provide better cryptocurrency data.${CL}"
echo -e "${YW}You can skip this and add them later by editing /opt/ghostfolio/.env${CL}"
echo
read -rp "${TAB3}CoinGecko Demo API key (press Enter to skip): " COINGECKO_DEMO_KEY
read -rp "${TAB3}CoinGecko Pro API key (press Enter to skip): " COINGECKO_PRO_KEY

msg_info "Setting up Environment"
cat <<EOF >/opt/ghostfolio/.env
DATABASE_URL=postgresql://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME?connect_timeout=300&sslmode=prefer
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=$REDIS_PASS
ACCESS_TOKEN_SALT=$ACCESS_TOKEN_SALT
JWT_SECRET_KEY=$JWT_SECRET_KEY
NODE_ENV=production
PORT=3333
HOST=0.0.0.0
EOF

if [[ -n "${COINGECKO_DEMO_KEY:-}" ]]; then
echo "API_KEY_COINGECKO_DEMO=$COINGECKO_DEMO_KEY" >>/opt/ghostfolio/.env
fi

if [[ -n "${COINGECKO_PRO_KEY:-}" ]]; then
echo "API_KEY_COINGECKO_PRO=$COINGECKO_PRO_KEY" >>/opt/ghostfolio/.env
fi
msg_ok "Set up Environment"

msg_info "Running Database Migrations"
cd /opt/ghostfolio
npx prisma migrate deploy
npx prisma db seed
msg_ok "Database Migrations Complete"

msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/ghostfolio.service
[Unit]
Description=Ghostfolio Investment Tracker
After=network.target postgresql.service redis-server.service
Wants=postgresql.service redis-server.service

[Service]
Type=simple
User=root
WorkingDirectory=/opt/ghostfolio/dist/apps/api
Environment=NODE_ENV=production
EnvironmentFile=/opt/ghostfolio/.env
ExecStart=/usr/bin/node main.js
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

systemctl enable -q --now ghostfolio
msg_ok "Created Service"

motd_ssh
customize

msg_info "Cleaning up"
npm cache clean --force
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"
Loading