Repository navigation
feat: add Rocket.Chat LXC script #2314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 7 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
b5d56d2
Add Rocket.Chat LXC script
william-aqn 14e9ff5
Use fetch_and_deploy_from_url for the bundle
william-aqn e4eaa90
Seed the admin from env and skip the setup wizard
william-aqn fce3efb
Ask for the admin email via var_admin_email
william-aqn ec19a31
Leave var_arm64 unset rather than claiming "no"
william-aqn a27c3d7
Strip whitespace before validating the admin email
william-aqn 2a67cde
Follow the new binding AGENTS.md rules
william-aqn 67b8229
Address review: trim comments, drop the redundant || exit
william-aqn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| #!/usr/bin/env bash | ||
| # Engine comes from community-scripts/core; this repo only ships the scripts. | ||
| # A local core checkout wins (COMMUNITY_SCRIPTS_CORE_DIR, else a sibling ../core), | ||
| # so a fork or branch of core can be tested without editing this file. | ||
| _cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func" | ||
| source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func") | ||
| # Copyright (c) 2021-2026 community-scripts ORG | ||
| # Author: william-aqn | ||
| # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE | ||
| # Source: https://www.rocket.chat/ | ||
|
|
||
| APP="Rocket.Chat" | ||
| var_tags="${var_tags:-chat;messaging}" | ||
| var_cpu="${var_cpu:-2}" | ||
| var_ram="${var_ram:-4096}" | ||
| var_disk="${var_disk:-20}" | ||
| var_os="${var_os:-debian}" | ||
| var_version="${var_version:-13}" | ||
| var_arm64="${var_arm64:-yes}" | ||
| var_unprivileged="${var_unprivileged:-1}" | ||
|
|
||
| # lxc-attach carries the caller's environment, but only what was exported, so | ||
| # without this the install script never sees the answer and always prompts. | ||
| export var_admin_email="${var_admin_email:-}" | ||
|
|
||
| header_info "$APP" | ||
| variables | ||
| # variables() derives NSAPP from APP by lowercasing and stripping spaces only, | ||
| # so the dot in "Rocket.Chat" would send it looking for rocket.chat-install.sh. | ||
| NSAPP="rocketchat" | ||
| var_install="${NSAPP}-install" | ||
| color | ||
| catch_errors | ||
|
|
||
| function update_script() { | ||
| header_info | ||
| check_container_storage | ||
| check_container_resources | ||
|
|
||
| if [[ ! -d /opt/rocketchat ]]; then | ||
| msg_error "No ${APP} Installation Found!" | ||
| exit | ||
| fi | ||
|
|
||
| # Rocket.Chat ships no GitHub release assets, so check_for_gh_release cannot be | ||
| # used. releases.rocket.chat/latest/info is the authoritative stable tag. | ||
| RELEASE=$(curl -fsSL https://releases.rocket.chat/latest/info | jq -r '.tag') | ||
| if [[ "${RELEASE}" != "$(cat ~/.rocketchat 2>/dev/null)" ]]; then | ||
| msg_info "Stopping Service" | ||
| systemctl stop rocketchat | ||
| msg_ok "Stopped Service" | ||
|
|
||
| CLEAN_INSTALL=1 fetch_and_deploy_from_url "https://releases.rocket.chat/${RELEASE}/download" "/opt/rocketchat" | ||
| echo "${RELEASE}" >~/.rocketchat | ||
|
|
||
| msg_info "Building Rocket.Chat ${RELEASE} (Patience)" | ||
| cd /opt/rocketchat/programs/server || exit | ||
| $STD npm install | ||
| msg_ok "Built Rocket.Chat ${RELEASE}" | ||
|
|
||
| msg_info "Starting Service" | ||
| systemctl start rocketchat | ||
| msg_ok "Started Service" | ||
| msg_ok "Updated Successfully!" | ||
| else | ||
| msg_ok "No update required. Rocket.Chat is already at ${RELEASE}" | ||
| fi | ||
| 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}:3000${CL}" | ||
| echo -e "${INFO}${YW}Admin credentials: ~/rocketchat.creds (inside the container)${CL}" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,159 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| # Copyright (c) 2021-2026 community-scripts ORG | ||
| # Author: william-aqn | ||
| # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE | ||
| # Source: https://www.rocket.chat/ | ||
|
|
||
| source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" | ||
| color | ||
| verb_ip6 | ||
| catch_errors | ||
| setting_up_container | ||
| network_check | ||
| update_os | ||
|
|
||
| # Asked up front, before the ~250 MB download and the native-module build, so an | ||
| # interactive run is not left sitting on a prompt minutes in. An unattended run | ||
| # sets var_admin_email in the environment and is never asked. | ||
| if [[ -z "${var_admin_email:-}" ]]; then | ||
| # `|| true` is load-bearing: an unattended run reaches this over lxc-attach | ||
| # with no tty, so read hits EOF and returns 1, which the error trap would | ||
| # otherwise turn into a failed install before anything is downloaded. | ||
| read -r -p "${TAB3}Admin email address: " var_admin_email || true | ||
| fi | ||
| # The Proxmox web console sends a carriage return with the line and read keeps | ||
| # it, so a perfectly good address arrives as $'user@host\r' and fails the check | ||
| # below. Strip whitespace before validating; an address cannot contain any. | ||
| var_admin_email="${var_admin_email//[[:space:]]/}" | ||
| var_admin_email="${var_admin_email:-admin@example.com}" | ||
| if [[ ! "$var_admin_email" =~ ^[^@[:space:]]+@[^@[:space:]]+\.[^@[:space:]]+$ ]]; then | ||
| # Rocket.Chat silently drops an invalid ADMIN_EMAIL and leaves the admin with | ||
| # no address at all, which is harder to notice than this warning. | ||
| msg_warn "Invalid email '${var_admin_email}', falling back to admin@example.com" | ||
| var_admin_email="admin@example.com" | ||
| fi | ||
|
|
||
| msg_info "Installing Dependencies" | ||
| # build-essential and python3 are for node-gyp: the bundle compiles native | ||
| # modules on install and @sematext/gc-stats has no prebuilt binary to fall back | ||
| # on. graphicsmagick is the image backend named by the official Debian guide. | ||
| $STD apt install -y \ | ||
| build-essential \ | ||
| python3 \ | ||
| graphicsmagick \ | ||
| jq | ||
| msg_ok "Installed Dependencies" | ||
|
|
||
| # Rocket.Chat 8.x exits on MongoDB <7.0 and warns below 8.0 (support for <8.0 is | ||
| # dropped in Rocket.Chat 9). releases.rocket.chat reports 8.0 as the compatible | ||
| # series, so that is what gets installed. | ||
| MONGO_VERSION="8.0" setup_mongodb | ||
|
|
||
| # The server bundle validates only the Node.js MAJOR line against the version it | ||
| # was built with (bundle/.node_version.txt, currently v22.x), so the NodeSource | ||
| # 22 line satisfies it. | ||
| # | ||
| # npm is pinned to 10 because the bundle is built with npm 10 and does not | ||
| # install under npm 12: npm 12 refuses the bundle's remote tarball dependency | ||
| # (EALLOWREMOTE on source-map-support), and the bundle's own npm-rebuild.js | ||
| # calls `npm rebuild --update-binary`, a flag npm 12 rejects outright. | ||
| NODE_VERSION="22" NPM_VERSION="10" setup_nodejs | ||
|
|
||
| msg_info "Configuring MongoDB Replica Set" | ||
| # Rocket.Chat requires a replica set: it dropped oplog tailing in 8.0 and now | ||
| # relies on change streams and multi-document transactions, neither of which a | ||
| # standalone mongod provides. A single member is enough. | ||
| if ! grep -q "^replication:" /etc/mongod.conf; then | ||
| cat <<EOF >>/etc/mongod.conf | ||
| replication: | ||
| replSetName: rs0 | ||
| EOF | ||
| fi | ||
| systemctl restart mongod | ||
| for _ in {1..60}; do | ||
| mongosh --quiet --eval "db.adminCommand('ping')" &>/dev/null && break | ||
| sleep 1 | ||
| done | ||
| if ! mongosh --quiet --eval "rs.status().ok" &>/dev/null; then | ||
| $STD mongosh --quiet --eval 'rs.initiate({ _id: "rs0", members: [{ _id: 0, host: "127.0.0.1:27017" }] })' | ||
| fi | ||
| for _ in {1..60}; do | ||
| [[ "$(mongosh --quiet --eval "db.hello().isWritablePrimary" 2>/dev/null)" == "true" ]] && break | ||
| sleep 1 | ||
| done | ||
| msg_ok "Configured MongoDB Replica Set" | ||
|
|
||
| # The prebuilt Meteor bundle is published on releases.rocket.chat, not as a | ||
| # GitHub release asset, so fetch_and_deploy_gh_release does not apply. | ||
| # /latest/info names the current stable tag; the GitHub API cannot be used here | ||
| # because backport releases on older majors are published after newer ones and | ||
| # would win a "latest" query. The archive unpacks to a single bundle/ directory, | ||
| # which fetch_and_deploy_from_url strips into the target. | ||
| RELEASE=$(curl -fsSL https://releases.rocket.chat/latest/info | jq -r '.tag') | ||
| fetch_and_deploy_from_url "https://releases.rocket.chat/${RELEASE}/download" "/opt/rocketchat" | ||
| echo "${RELEASE}" >~/.rocketchat | ||
|
|
||
| msg_info "Building Rocket.Chat ${RELEASE} (Patience)" | ||
| cd /opt/rocketchat/programs/server || exit | ||
| $STD npm install | ||
| msg_ok "Built Rocket.Chat ${RELEASE}" | ||
|
|
||
| msg_info "Creating Configuration" | ||
| # Kept outside /opt/rocketchat so an update, which replaces the bundle | ||
| # wholesale, leaves it untouched. | ||
| # | ||
| # The admin is seeded from the environment and the setup wizard is marked | ||
| # completed on purpose. The wizard's last step ("Awaiting confirmation") mails a | ||
| # confirmation code, and a fresh bare-metal install has no MAIL_URL, so the mail | ||
| # never leaves the box and the wizard cannot be finished from the UI -- the | ||
| # admin created in step 1 is then locked out behind it. insertAdminUserFromEnv() | ||
|
william-aqn marked this conversation as resolved.
Resolved
|
||
| # only fires while no admin exists, so these stay inert on every later boot. | ||
| ADMIN_PASS=$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | cut -c1-24) | ||
| mkdir -p /etc/rocketchat | ||
| cat <<EOF >/etc/rocketchat/rocketchat.env | ||
| NODE_ENV=production | ||
| PORT=3000 | ||
| ROOT_URL=http://${LOCAL_IP}:3000 | ||
| MONGO_URL=mongodb://127.0.0.1:27017/rocketchat?replicaSet=rs0 | ||
| ADMIN_USERNAME=admin | ||
| ADMIN_NAME=Administrator | ||
| ADMIN_EMAIL=${var_admin_email} | ||
| ADMIN_PASS=${ADMIN_PASS} | ||
| OVERWRITE_SETTING_Show_Setup_Wizard=completed | ||
| EOF | ||
| chmod 600 /etc/rocketchat/rocketchat.env | ||
| { | ||
| echo "Rocket.Chat Admin" | ||
| echo "Username: admin" | ||
| echo "Password: ${ADMIN_PASS}" | ||
| echo "Email: ${var_admin_email}" | ||
| } >~/rocketchat.creds | ||
| chmod 600 ~/rocketchat.creds | ||
| msg_ok "Created Configuration" | ||
|
|
||
| msg_info "Creating Service" | ||
| cat <<EOF >/etc/systemd/system/rocketchat.service | ||
| [Unit] | ||
| Description=Rocket.Chat Server | ||
| After=network.target mongod.service | ||
| Requires=mongod.service | ||
|
|
||
| [Service] | ||
| Type=simple | ||
| User=root | ||
| WorkingDirectory=/opt/rocketchat | ||
| EnvironmentFile=/etc/rocketchat/rocketchat.env | ||
| ExecStart=/usr/bin/node /opt/rocketchat/main.js | ||
| Restart=on-failure | ||
| RestartSec=10 | ||
|
|
||
| [Install] | ||
| WantedBy=multi-user.target | ||
| EOF | ||
| systemctl enable -q --now rocketchat | ||
| msg_ok "Created Service" | ||
|
|
||
| motd_ssh | ||
| customize | ||
| cleanup_lxc | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| { | ||
| "name": "Rocket.Chat", | ||
| "slug": "rocketchat", | ||
| "categories": [ | ||
| 22 | ||
| ], | ||
| "date_created": "2026-09-09", | ||
| "type": "ct", | ||
| "updateable": true, | ||
| "privileged": false, | ||
| "architectures": [ | ||
| "amd64", | ||
| "arm64" | ||
| ], | ||
| "interface_port": 3000, | ||
| "documentation": "https://docs.rocket.chat/docs/deploy-rocketchat", | ||
| "website": "https://www.rocket.chat/", | ||
| "repository": "https://github.com/RocketChat/Rocket.Chat", | ||
| "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/rocket-chat.webp", | ||
| "description": "Rocket.Chat is an open-source communications platform for team chat, channels, direct messages, file sharing, voice and video calls, and omnichannel customer support. This script performs a manual (non-Docker) install of the official prebuilt Meteor server bundle, backed by a local MongoDB.", | ||
| "install_methods": [ | ||
| { | ||
| "type": "default", | ||
| "script": "ct/rocketchat.sh", | ||
| "config_path": "/etc/rocketchat/rocketchat.env", | ||
| "resources": { | ||
| "cpu": 2, | ||
| "ram": 4096, | ||
| "hdd": 20, | ||
| "os": "Debian", | ||
| "version": "13" | ||
| } | ||
| } | ||
| ], | ||
| "default_credentials": { | ||
| "username": "admin", | ||
| "password": null | ||
| }, | ||
| "app_vars": [ | ||
| { | ||
| "name": "var_admin_email", | ||
| "label": "Admin Email", | ||
| "type": "text", | ||
| "default": "admin@example.com", | ||
| "help": "Email address for the generated admin account. Rocket.Chat needs a valid address here; it is not used to send mail unless you configure SMTP." | ||
| } | ||
| ], | ||
| "notes": [ | ||
| { | ||
| "text": "Log in at http://IP:3000 as `admin`; the generated password is in `~/rocketchat.creds` inside the container. The setup wizard is skipped deliberately: its final step mails a confirmation code, and a fresh install has no mail server configured, so the wizard cannot be completed and would lock you out of the admin account it just created.", | ||
| "type": "info" | ||
| }, | ||
| { | ||
| "text": "The admin password is generated, not chosen. Change it, and review the admin email, before real use. If you kept the default admin@example.com, set a real address in Admin > Users.", | ||
| "type": "warning" | ||
| }, | ||
| { | ||
| "text": "The install downloads the official prebuilt server bundle (~250 MB) and compiles native npm modules, so it takes several minutes. The service needs roughly 20-30 seconds after start before the web UI answers.", | ||
| "type": "info" | ||
| }, | ||
| { | ||
| "text": "ROOT_URL in /etc/rocketchat/rocketchat.env is set to the container IP. Change it to the public URL and restart with `systemctl restart rocketchat` before putting Rocket.Chat behind a reverse proxy or domain, otherwise logins, uploads and OAuth redirects break.", | ||
| "type": "warning" | ||
| }, | ||
| { | ||
| "text": "MongoDB runs as a single-node replica set (rs0), which Rocket.Chat 8.x requires: it dropped oplog tailing in 8.0 and relies on change streams and multi-document transactions. Do not convert mongod back to standalone.", | ||
| "type": "warning" | ||
| }, | ||
| { | ||
| "text": "All chat data lives in the local MongoDB (database `rocketchat`, files in /var/lib/mongodb). Back that up together with /etc/rocketchat/rocketchat.env.", | ||
| "type": "warning" | ||
| } | ||
| ] | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.