From 2a4d85825495d70f4531f6d2378a1e1739c92ff5 Mon Sep 17 00:00:00 2001 From: "push-app-to-main[bot]" <203845782+push-app-to-main[bot]@users.noreply.github.com> Date: Sun, 26 Jul 2026 11:04:31 +0000 Subject: [PATCH] Add discourse (ct) --- ct/discourse.sh | 74 ++++++++++++ ct/headers/discourse | 6 + install/discourse-install.sh | 222 +++++++++++++++++++++++++++++++++++ 3 files changed, 302 insertions(+) create mode 100644 ct/discourse.sh create mode 100644 ct/headers/discourse create mode 100644 install/discourse-install.sh diff --git a/ct/discourse.sh b/ct/discourse.sh new file mode 100644 index 000000000..30004dc2e --- /dev/null +++ b/ct/discourse.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +source "$(dirname "${BASH_SOURCE[0]}")/../misc/build.func" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main}/misc/build.func") + +# Copyright (c) 2021-2026 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://www.discourse.org/ + +APP="Discourse" +var_tags="${var_tags:-forum;community;discussion}" +var_cpu="${var_cpu:-4}" +var_ram="${var_ram:-4096}" +var_disk="${var_disk:-20}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +var_arm64="${var_arm64:-no}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + + if [[ ! -d /opt/discourse ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + if [[ ! -f /opt/discourse/.env ]]; then + msg_error "No Discourse Configuration Found!" + exit + fi + + msg_info "Stopping Service" + systemctl stop discourse + msg_ok "Stopped Service" + + create_backup /opt/discourse/.env + + msg_info "Updating Discourse" + PG_VERSION="16" PG_MODULES="pgvector" setup_postgresql + cd /opt/discourse + git pull origin main + $STD bundle install --deployment --without test development + $STD yarn install + $STD runuser -u postgres -- psql -d discourse -c "CREATE EXTENSION IF NOT EXISTS vector;" + $STD bundle exec rails assets:precompile + $STD bundle exec rails db:migrate + msg_ok "Updated Discourse" + + restore_backup + + msg_info "Starting Service" + systemctl start discourse + msg_ok "Started Service" + msg_ok "Updated successfully!" + 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 "${GATEWAY}${BGN}http://${IP}${CL}" +echo -e "${INFO}${YW} Credentials saved in:${CL}" +echo -e "${TAB}/root/discourse.creds" diff --git a/ct/headers/discourse b/ct/headers/discourse new file mode 100644 index 000000000..640f31219 --- /dev/null +++ b/ct/headers/discourse @@ -0,0 +1,6 @@ + ____ _ + / __ \(_)_____________ __ _______________ + / / / / / ___/ ___/ __ \/ / / / ___/ ___/ _ \ + / /_/ / (__ ) /__/ /_/ / /_/ / / (__ ) __/ +/_____/_/____/\___/\____/\__,_/_/ /____/\___/ + diff --git a/install/discourse-install.sh b/install/discourse-install.sh new file mode 100644 index 000000000..c9174092c --- /dev/null +++ b/install/discourse-install.sh @@ -0,0 +1,222 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://www.discourse.org/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt install -y \ + build-essential \ + git \ + libssl-dev \ + libreadline-dev \ + zlib1g-dev \ + libyaml-dev \ + imagemagick \ + gsfonts \ + brotli \ + nginx \ + redis-server +msg_ok "Installed Dependencies" + +PG_VERSION="17" PG_MODULES="pgvector" setup_postgresql +NODE_VERSION="24" setup_nodejs +RUBY_VERSION="3.4.4" setup_ruby + +msg_info "Configuring PostgreSQL for Discourse" +DISCOURSE_DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) +PG_HBA=$(find /etc/postgresql -name pg_hba.conf 2>/dev/null | head -n1) +sed -i 's/^local\s\+all\s\+all\s\+peer$/local all all md5/' "$PG_HBA" +$STD systemctl restart postgresql +PG_DB_NAME="discourse" PG_DB_USER="discourse" PG_DB_PASS="$DISCOURSE_DB_PASS" PG_DB_EXTENSIONS="vector" setup_postgresql_db +msg_ok "Configured PostgreSQL for Discourse" + +msg_info "Configuring Discourse" +DISCOURSE_SECRET_KEY=$(openssl rand -hex 64) +$STD git clone --depth 1 https://github.com/discourse/discourse.git /opt/discourse +cd /opt/discourse +cat </opt/discourse/.env +RAILS_ENV=production +RAILS_LOG_TO_STDOUT=true +RAILS_SERVE_STATIC_FILES=true +SECRET_KEY_BASE=${DISCOURSE_SECRET_KEY} +DISCOURSE_DB_HOST=/var/run/postgresql +DISCOURSE_DB_PORT=5432 +DISCOURSE_DB_NAME=discourse +DISCOURSE_DB_USERNAME=discourse +DISCOURSE_DB_PASSWORD=${DISCOURSE_DB_PASS} +DISCOURSE_REDIS_URL=redis://localhost:6379 +DISCOURSE_DEVELOPER_EMAILS=admin@discourse.local +DISCOURSE_HOSTNAME=${LOCAL_IP} +DISCOURSE_SMTP_ADDRESS=localhost +DISCOURSE_SMTP_PORT=25 +DISCOURSE_SMTP_AUTHENTICATION=none +DISCOURSE_NOTIFICATION_EMAIL=noreply@${LOCAL_IP} +DISCOURSE_SKIP_NEW_ACCOUNT_EMAIL=true +APP_ROOT=/opt/discourse +EOF + +mkdir -p /opt/discourse/tmp/sockets /opt/discourse/tmp/pids /opt/discourse/log +chown -R root:root /opt/discourse +chmod 755 /opt/discourse +msg_ok "Configured Discourse" + +msg_info "Installing Discourse Dependencies" +$STD systemctl enable --now redis-server +cd /opt/discourse +export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH" +eval "$(rbenv init - bash)" 2>/dev/null || true +export RAILS_ENV=production +export COREPACK_ENABLE_DOWNLOAD_PROMPT=0 +$STD corepack enable +$STD bundle config set --local deployment true +$STD bundle config set --local without 'test development' +$STD bundle install +$STD pnpm install +msg_ok "Installed Discourse Dependencies" + +msg_info "Setting Up Database" +cd /opt/discourse +export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH" +eval "$(rbenv init - bash)" 2>/dev/null || true +export RAILS_ENV=production +set -a +source /opt/discourse/.env +set +a +$STD bundle exec rails db:migrate +$STD bundle exec rails db:seed +msg_ok "Set Up Database" + +msg_info "Creating Admin Account" +ADMIN_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c16) +$STD bundle exec rails runner " +user = User.new(email: 'admin@discourse.local', username: 'admin', password: '${ADMIN_PASS}') +user.active = true +user.admin = true +user.approved = true +user.save!(validate: false) +user.activate +user.grant_admin! +user.change_trust_level!(TrustLevel[4]) +SiteSetting.has_login_hint = false +SiteSetting.wizard_enabled = false +" +{ + echo "Discourse Credentials" + echo "Admin Username: admin" + echo "Admin Email: admin@discourse.local" + echo "Admin Password: ${ADMIN_PASS}" + echo "Database Password: ${DISCOURSE_DB_PASS}" +} >~/discourse.creds +msg_ok "Created Admin Account" + +msg_info "Building Discourse Assets" +cd /opt/discourse +export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH" +eval "$(rbenv init - bash)" 2>/dev/null || true +export RAILS_ENV=production +set -a +source /opt/discourse/.env +set +a +$STD bundle exec rails assets:precompile +msg_ok "Built Discourse Assets" + +msg_info "Creating Services" +cat </etc/systemd/system/discourse.service +[Unit] +Description=Discourse Forum +After=network.target postgresql.service redis-server.service + +[Service] +Type=simple +User=root +WorkingDirectory=/opt/discourse +EnvironmentFile=/opt/discourse/.env +Environment=PATH=/root/.rbenv/shims:/root/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +ExecStart=/root/.rbenv/shims/bundle exec pitchfork -c config/pitchfork.conf.rb +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF + +cat </etc/systemd/system/discourse-sidekiq.service +[Unit] +Description=Discourse Sidekiq +After=network.target postgresql.service redis-server.service + +[Service] +Type=simple +User=root +WorkingDirectory=/opt/discourse +EnvironmentFile=/opt/discourse/.env +Environment=PATH=/root/.rbenv/shims:/root/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +ExecStart=/root/.rbenv/shims/bundle exec sidekiq -q critical -q default -q low -q ultra_low +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now discourse discourse-sidekiq +msg_ok "Created Services" + +msg_info "Configuring Nginx" +cat </etc/nginx/sites-available/discourse +server { + listen 80 default_server; + server_name _; + root /opt/discourse/public; + + client_max_body_size 100M; + proxy_busy_buffers_size 512k; + proxy_buffers 4 512k; + + location /assets/ { + gzip_static on; + expires max; + add_header Cache-Control public,immutable; + } + + location /uploads/ { + expires 1h; + } + + location / { + try_files \$uri @discourse; + } + + location @discourse { + proxy_pass http://127.0.0.1:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection "upgrade"; + 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; + proxy_set_header X-Accel-Mapping /opt/discourse/public/=/downloads/; + } +} +EOF + +ln -sf /etc/nginx/sites-available/discourse /etc/nginx/sites-enabled/discourse +rm -f /etc/nginx/sites-enabled/default +$STD nginx -t +$STD systemctl enable --now nginx +$STD systemctl reload nginx +msg_ok "Configured Nginx" + +motd_ssh +customize +cleanup_lxc