From 90a1e57de8f21af0b1bb10bba4442e823cd74833 Mon Sep 17 00:00:00 2001 From: Michael Banucu Date: Thu, 15 May 2025 21:49:24 +0200 Subject: [PATCH 1/3] add support for NixOS --- mkdocs.yml | 1 + shell.nix | 42 +++++++++++ src/docs/installing/os/nixos.md | 128 ++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 shell.nix create mode 100644 src/docs/installing/os/nixos.md diff --git a/mkdocs.yml b/mkdocs.yml index 4a3ec96..d1de6c1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -21,6 +21,7 @@ nav: - via OS: - 'installing/os/index.md' - 'Ubuntu (Recommended)': 'installing/os/ubuntu.md' + - 'NixOS (very easy)': 'installing/os/nixos.md' - 'Arch Linux': 'installing/os/arch.md' - 'CentOS': 'installing/os/centos.md' - 'installing/os/debian.md' diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..e6790be --- /dev/null +++ b/shell.nix @@ -0,0 +1,42 @@ +{pkgs ? import {}}: +pkgs.mkShell { + buildInputs = [ + pkgs.git + pkgs.nodejs_20 # Node.js for npm and compile.js + (pkgs.python3.withPackages (ps: + with ps; [ + mkdocs + mkdocs-material + pillow # Required for mkdocs-material[imaging] + cairosvg # Required for mkdocs-material[imaging] + ])) + ]; + + shellHook = '' + echo "Setting up environment for NodeBB documentation..." + + # Create symbolic link only if it doesn't exist + if [ ! -e docs ]; then + ln -sf ./src/docs docs + echo "Created symbolic link: docs -> src/docs" + else + echo "Symbolic link 'docs' already exists or is not needed, skipping" + fi + + # Run npm install if node_modules is missing + if [ ! -d node_modules ]; then + npm install + echo "Node.js dependencies installed" + else + echo "Node.js dependencies already installed, skipping" + fi + + # Run the compile script + node src/compile.js && echo "Compilation completed successfully" || { + echo "Error: Compilation failed" + exit 1 + } + + echo "Environment ready. Run 'mkdocs serve' to preview the documentation or 'mkdocs build' to generate the static site." + ''; +} diff --git a/src/docs/installing/os/nixos.md b/src/docs/installing/os/nixos.md new file mode 100644 index 0000000..2ba70df --- /dev/null +++ b/src/docs/installing/os/nixos.md @@ -0,0 +1,128 @@ +NixOS +===== + +MySQL +----- + +Create file `shell.nix` with the following content (adjust the variables as needed): +```nix +{pkgs ? import {}}: let + # adjust the following variables as needed + # Define NodeBB version and repository + nodebbRepo = "https://github.com/MBanucu/NodeBB.git"; + nodebbBranch = "mysql-backup2"; # MySQL branch + + # Define NodeBB admin credentials + nodebbAdminUsername = "admin"; # Set your admin username + nodebbAdminPassword = "admin_password"; # Set your admin password + nodebbAdminEmail = "your_nodebb_admin_email_here@gmail.com"; # Set your admin email + + # Define MySQL database credentials + mysqlUsername = "nodebb_user"; # MySQL username for NodeBB + mysqlPassword = "nodebb_user_password"; # MySQL password for NodeBB + mysqlDatabase = "nodebb"; # MySQL database for NodeBB +in + pkgs.mkShell { + name = "nodebb-dev-env"; + + buildInputs = with pkgs; [ + nodejs_22 # NodeBB recommends Node.js 20 or higher + git # For cloning NodeBB + mysql80 # MySQL 8.0 instead of MariaDB + gnused + ]; + + shellHook = '' + # Set up environment variables + export MYSQL_HOME="$PWD/mysql" + export MYSQL_DATADIR="$MYSQL_HOME/data" + export MYSQL_UNIX_PORT="$MYSQL_HOME/mysql.sock" + export MYSQL_PID_FILE="$MYSQL_HOME/mysql.pid" + alias mysql='mysql -u root' + + # Set up MySQL 8.0 + if [ ! -d "$MYSQL_HOME" ]; then + echo "Initializing MySQL 8.0..." + mkdir -p "$MYSQL_HOME" + mysqld --initialize-insecure --datadir="$MYSQL_DATADIR" --basedir="${pkgs.mysql80}" \ + --pid-file="$MYSQL_PID_FILE" + fi + + # Start MySQL daemon + echo "Starting MySQL 8.0..." + mysqld --no-defaults --skip-networking --datadir="$MYSQL_DATADIR" \ + --pid-file="$MYSQL_PID_FILE" --socket="$MYSQL_UNIX_PORT" \ + 2> "$MYSQL_HOME/mysql.log" & + MYSQL_PID=$! + + # Wait for MySQL to start + echo "Waiting for MySQL to be ready..." + while ! mysqladmin ping --socket="$MYSQL_UNIX_PORT" --silent; do + sleep 1 + done + + # Create NodeBB database and user + echo "Setting up NodeBB database..." + mysql --socket="$MYSQL_UNIX_PORT" -u root </dev/null + } + trap finish EXIT + + # Clone NodeBB if not already present + if [ ! -d "NodeBB" ]; then + echo "Cloning NodeBB repository..." + git clone -b ${nodebbBranch} ${nodebbRepo} NodeBB + fi + + # Navigate to NodeBB directory + cd NodeBB + + if [ ! -d "node_modules" ]; then + + # Generate UUID for secret + UUID_SECRET=$(uuidgen) + # after successful installation, you can change the secret in the config.json file + + JSON_CONFIG='{ + "url": "http://localhost:4567", + "secret": "'"$UUID_SECRET"'", + "database": "mysql", + "mysql:host": "127.0.0.1", + "mysql:port": "3306", + "mysql:socketPath": "'"$MYSQL_UNIX_PORT"'", + "mysql:username": "${mysqlUsername}", + "mysql:password": "${mysqlPassword}", + "mysql:database": "${mysqlDatabase}", + "port": "4567", + "admin:username": "${nodebbAdminUsername}", + "admin:password": "${nodebbAdminPassword}", + "admin:password:confirm": "${nodebbAdminPassword}", + "admin:email": "${nodebbAdminEmail}" + }' + node ./nodebb setup "$JSON_CONFIG" + fi + + # Instructions for running NodeBB + echo "NodeBB environment is set up!" + echo "To start NodeBB, run: ./nodebb start" + echo "Database: ${mysqlDatabase}, User: ${mysqlUsername}, Password: ${mysqlPassword}, Socket: $MYSQL_UNIX_PORT" + ''; + } +``` +Run +``` +nix-shell +``` +in the directory where `shell.nix` is located. +Leave the nix shell open or else everything closes. From cdc55cc38930145b52ebb8c4cbecbcd5cec1a967 Mon Sep 17 00:00:00 2001 From: Michael Banucu Date: Sat, 17 May 2025 14:34:31 +0200 Subject: [PATCH 2/3] add development environment setup for NixOS --- src/docs/installing/os/nixos.md | 305 ++++++++++++++++++++++---------- 1 file changed, 216 insertions(+), 89 deletions(-) diff --git a/src/docs/installing/os/nixos.md b/src/docs/installing/os/nixos.md index 2ba70df..8a6bd49 100644 --- a/src/docs/installing/os/nixos.md +++ b/src/docs/installing/os/nixos.md @@ -6,7 +6,10 @@ MySQL Create file `shell.nix` with the following content (adjust the variables as needed): ```nix -{pkgs ? import {}}: let +{ + pkgs ? import { }, +}: +let # adjust the following variables as needed # Define NodeBB version and repository nodebbRepo = "https://github.com/MBanucu/NodeBB.git"; @@ -21,104 +24,228 @@ Create file `shell.nix` with the following content (adjust the variables as need mysqlUsername = "nodebb_user"; # MySQL username for NodeBB mysqlPassword = "nodebb_user_password"; # MySQL password for NodeBB mysqlDatabase = "nodebb"; # MySQL database for NodeBB + + development = true; # Set to false for non-development mode + + MYSQL_HOME = "${builtins.getEnv "PWD"}/mysql"; + MYSQL_DATADIR = "${MYSQL_HOME}/data"; + MYSQL_UNIX_PORT = "${MYSQL_HOME}/mysql.sock"; + MYSQL_PID_FILE = "${MYSQL_HOME}/mysql.pid"; + + JSON_CONFIG_TEST = { + test_database = { + socketPath = "${MYSQL_UNIX_PORT}"; + username = "${mysqlUsername}_test"; + password = "${mysqlPassword}"; + database = "${mysqlDatabase}_test"; + }; + }; + + UUID_SECRET = builtins.replaceStrings [ "\n" ] [ "" ] ( + builtins.readFile ( + pkgs.runCommand "generate-uuid" { } '' + ${pkgs.util-linux}/bin/uuidgen > $out + '' + ) + ); + + JSON_CONFIG = { + url = "http://localhost:4567"; + secret = "${UUID_SECRET}"; + database = "mysql"; + mysql = { + host = "127.0.0.1"; + port = "3306"; + socketPath = "${MYSQL_UNIX_PORT}"; + username = "${mysqlUsername}"; + password = "${mysqlPassword}"; + database = "${mysqlDatabase}"; + }; + port = "4567"; + admin = { + username = "${nodebbAdminUsername}"; + password = { + value = "${nodebbAdminPassword}"; + confirm = "${nodebbAdminPassword}"; + }; + email = "${nodebbAdminEmail}"; + }; + }; + + # Function to flatten the attribute set with ":" as separator + flattenAttrs = + attrs: + let + flatten = + prefix: attrs: + builtins.foldl' ( + acc: key: + let + value = attrs.${key}; + newPrefix = if prefix == "" then key else "${prefix}:${key}"; + # Special case for i.e. admin.password.value to map to admin:password + finalKey = if key == "value" then "${prefix}" else newPrefix; + in + if builtins.isAttrs value then + acc // (flatten newPrefix value) + else + acc // { "${finalKey}" = value; } + ) { } (builtins.attrNames attrs); + in + flatten "" attrs; + + JSON_CONFIG_FLATTENED = flattenAttrs JSON_CONFIG; + + JSON_VSCODE_TASKS = { + version = "2.0.0"; + tasks = [ + { + label = "Run grunt"; + type = "shell"; + command = "node ./node_modules/.bin/grunt"; + runOptions = { + runOn = "folderOpen"; + }; + } + ]; + }; + + masterOverlays = [ + ( + self: super: + let + nixpkgsMaster = + import + (builtins.fetchTarball { + url = "https://github.com/NixOS/nixpkgs/archive/master.tar.gz"; + }) + { + config.allowUnfree = true; + }; + in + { + # nodejs_20 version is 20.18 of NixOS 24.11 but we need 20.19 for require(ESM) + nodejs_20 = nixpkgsMaster.nodejs_20; + vscode = nixpkgsMaster.vscode; + } + ) + ]; + pkgsMaster = import { overlays = masterOverlays; }; in - pkgs.mkShell { - name = "nodebb-dev-env"; +pkgs.mkShell { + name = "nodebb-env"; - buildInputs = with pkgs; [ - nodejs_22 # NodeBB recommends Node.js 20 or higher + buildInputs = + with pkgs; + [ + pkgsMaster.nodejs_20 # NodeBB recommends Node.js 20.19 or higher git # For cloning NodeBB - mysql80 # MySQL 8.0 instead of MariaDB - gnused - ]; + mysql80 # MySQL 8.0, because MariaDB doesn't work right now + jq # For JSON manipulation + ] + ++ ( + if development then + [ + nodePackages.grunt-cli + nixfmt-rfc-style + pkgsMaster.vscode + ] + else + [ ] + ); + + shellHook = '' + # Set up environment variables + export MYSQL_HOME="${MYSQL_HOME}" + export MYSQL_DATADIR="${MYSQL_DATADIR}" + export MYSQL_UNIX_PORT="${MYSQL_UNIX_PORT}" + export MYSQL_PID_FILE="${MYSQL_PID_FILE}" + alias mysql='mysql -u root' + + # Set up MySQL 8.0 + if [ ! -d "${MYSQL_HOME}" ]; then + echo "Initializing MySQL 8.0..." + mkdir -p "${MYSQL_HOME}" + mysqld --initialize-insecure --datadir="${MYSQL_DATADIR}" --basedir="${pkgs.mysql80}" \ + --pid-file="${MYSQL_PID_FILE}" + fi + + # Start MySQL daemon + echo "Starting MySQL 8.0..." + mysqld --no-defaults --skip-networking --datadir="${MYSQL_DATADIR}" \ + --pid-file="${MYSQL_PID_FILE}" --socket="${MYSQL_UNIX_PORT}" \ + 2> "${MYSQL_HOME}/mysql.log" & + MYSQL_PID=$! + + # Wait for MySQL to start + echo "Waiting for MySQL to be ready..." + while ! mysqladmin ping --socket="${MYSQL_UNIX_PORT}" --silent; do + sleep 1 + done + + # Create NodeBB database and user + echo "Setting up NodeBB database..." + mysql --socket="${MYSQL_UNIX_PORT}" -u root < "$MYSQL_HOME/mysql.log" & - MYSQL_PID=$! - - # Wait for MySQL to start - echo "Waiting for MySQL to be ready..." - while ! mysqladmin ping --socket="$MYSQL_UNIX_PORT" --silent; do - sleep 1 - done - - # Create NodeBB database and user - echo "Setting up NodeBB database..." - mysql --socket="$MYSQL_UNIX_PORT" -u root </dev/null - } - trap finish EXIT + # Clean up MySQL on shell exit + finish() { + echo "Shutting down MySQL..." + mysqladmin -u root --socket="${MYSQL_UNIX_PORT}" shutdown + } + trap finish EXIT + + # Clone NodeBB if not already present + if [ ! -d "NodeBB" ]; then + echo "Cloning NodeBB repository..." + git clone -b ${nodebbBranch} ${nodebbRepo} NodeBB + fi + + # Navigate to NodeBB directory + cd NodeBB + + if [ ! -d "node_modules" ]; then - # Clone NodeBB if not already present - if [ ! -d "NodeBB" ]; then - echo "Cloning NodeBB repository..." - git clone -b ${nodebbBranch} ${nodebbRepo} NodeBB + if [ ${toString development} ]; then + echo "Writing config.json for test_database for development mode..." + echo '${builtins.toJSON JSON_CONFIG_TEST}' | jq . --indent 4 > config.json fi - # Navigate to NodeBB directory - cd NodeBB - - if [ ! -d "node_modules" ]; then - - # Generate UUID for secret - UUID_SECRET=$(uuidgen) - # after successful installation, you can change the secret in the config.json file - - JSON_CONFIG='{ - "url": "http://localhost:4567", - "secret": "'"$UUID_SECRET"'", - "database": "mysql", - "mysql:host": "127.0.0.1", - "mysql:port": "3306", - "mysql:socketPath": "'"$MYSQL_UNIX_PORT"'", - "mysql:username": "${mysqlUsername}", - "mysql:password": "${mysqlPassword}", - "mysql:database": "${mysqlDatabase}", - "port": "4567", - "admin:username": "${nodebbAdminUsername}", - "admin:password": "${nodebbAdminPassword}", - "admin:password:confirm": "${nodebbAdminPassword}", - "admin:email": "${nodebbAdminEmail}" - }' - node ./nodebb setup "$JSON_CONFIG" + node ./nodebb setup '${builtins.toJSON JSON_CONFIG_FLATTENED}' + + if [ ${toString development} ]; then + echo "Running npm install for development mode..." + npm install + + echo "setting up grunt task for VSCode for development mode..." + mkdir -p .vscode + echo '${builtins.toJSON JSON_VSCODE_TASKS}' | jq . --indent 4 > .vscode/tasks.json fi + fi + + if [ ${toString development} ]; then + code . + fi - # Instructions for running NodeBB - echo "NodeBB environment is set up!" - echo "To start NodeBB, run: ./nodebb start" - echo "Database: ${mysqlDatabase}, User: ${mysqlUsername}, Password: ${mysqlPassword}, Socket: $MYSQL_UNIX_PORT" - ''; - } + echo "NodeBB environment is set up!" + ''; +} ``` Run ``` From 511128e7047c0d4b80dc2cef06404115933c94c6 Mon Sep 17 00:00:00 2001 From: Michael Banucu Date: Sat, 17 May 2025 20:44:11 +0200 Subject: [PATCH 3/3] include instruction to set up plugins for vscode in development mode for NixOS --- src/docs/installing/os/nixos.md | 152 ++++++++++++++++---------------- 1 file changed, 78 insertions(+), 74 deletions(-) diff --git a/src/docs/installing/os/nixos.md b/src/docs/installing/os/nixos.md index 8a6bd49..f9b8230 100644 --- a/src/docs/installing/os/nixos.md +++ b/src/docs/installing/os/nixos.md @@ -32,14 +32,16 @@ let MYSQL_UNIX_PORT = "${MYSQL_HOME}/mysql.sock"; MYSQL_PID_FILE = "${MYSQL_HOME}/mysql.pid"; - JSON_CONFIG_TEST = { - test_database = { - socketPath = "${MYSQL_UNIX_PORT}"; - username = "${mysqlUsername}_test"; - password = "${mysqlPassword}"; - database = "${mysqlDatabase}_test"; - }; - }; + JSON_CONFIG_TEST = '' + { + "test_database": { + "socketPath": "${MYSQL_UNIX_PORT}", + "username": "${mysqlUsername}_test", + "password": "${mysqlPassword}", + "database": "${mysqlDatabase}_test" + } + } + ''; UUID_SECRET = builtins.replaceStrings [ "\n" ] [ "" ] ( builtins.readFile ( @@ -49,71 +51,56 @@ let ) ); - JSON_CONFIG = { - url = "http://localhost:4567"; - secret = "${UUID_SECRET}"; - database = "mysql"; - mysql = { - host = "127.0.0.1"; - port = "3306"; - socketPath = "${MYSQL_UNIX_PORT}"; - username = "${mysqlUsername}"; - password = "${mysqlPassword}"; - database = "${mysqlDatabase}"; - }; - port = "4567"; - admin = { - username = "${nodebbAdminUsername}"; - password = { - value = "${nodebbAdminPassword}"; - confirm = "${nodebbAdminPassword}"; - }; - email = "${nodebbAdminEmail}"; - }; - }; - - # Function to flatten the attribute set with ":" as separator - flattenAttrs = - attrs: - let - flatten = - prefix: attrs: - builtins.foldl' ( - acc: key: - let - value = attrs.${key}; - newPrefix = if prefix == "" then key else "${prefix}:${key}"; - # Special case for i.e. admin.password.value to map to admin:password - finalKey = if key == "value" then "${prefix}" else newPrefix; - in - if builtins.isAttrs value then - acc // (flatten newPrefix value) - else - acc // { "${finalKey}" = value; } - ) { } (builtins.attrNames attrs); - in - flatten "" attrs; - - JSON_CONFIG_FLATTENED = flattenAttrs JSON_CONFIG; - - JSON_VSCODE_TASKS = { - version = "2.0.0"; - tasks = [ - { - label = "Run grunt"; - type = "shell"; - command = "node ./node_modules/.bin/grunt"; - runOptions = { - runOn = "folderOpen"; - }; + JSON_CONFIG = '' + { + "url": "http://localhost:4567", + "port": "4567", + "secret": "${UUID_SECRET}", + "database": "mysql", + "mysql:host": "127.0.0.1", + "mysql:port": "3306", + "mysql:socketPath": "${MYSQL_UNIX_PORT}", + "mysql:username": "${mysqlUsername}", + "mysql:password": "${mysqlPassword}", + "mysql:database": "${mysqlDatabase}", + "admin:username": "${nodebbAdminUsername}", + "admin:password": "${nodebbAdminPassword}", + "admin:password:confirm": "${nodebbAdminPassword}", + "admin:email": "${nodebbAdminEmail}" + } + ''; + + JSON_VSCODE_TASKS = '' + { + "version": "2.0.0", + "tasks": [ + { + "label": "Run grunt", + "type": "shell", + "command": "node ./node_modules/.bin/grunt", + "runOptions": { + "runOn": "folderOpen" + } + } + ] + } + ''; + + JSON_VSCODE_SETTINGS = '' + { + "mochaExplorer.env": { + "CI": "true" } - ]; - }; + } + ''; masterOverlays = [ ( self: super: let + nix-vscode-extensions = import ( + fetchTarball "https://github.com/nix-community/nix-vscode-extensions/archive/master.tar.gz" + ); nixpkgsMaster = import (builtins.fetchTarball { @@ -121,12 +108,26 @@ let }) { config.allowUnfree = true; + overlays = [ + nix-vscode-extensions.overlays.default + ]; }; in { # nodejs_20 version is 20.18 of NixOS 24.11 but we need 20.19 for require(ESM) nodejs_20 = nixpkgsMaster.nodejs_20; - vscode = nixpkgsMaster.vscode; + vscode = ( + nixpkgsMaster.vscode-with-extensions.override { + vscode = nixpkgsMaster.vscode; + vscodeExtensions = with nixpkgsMaster.vscode-marketplace; [ + ms-vscode.test-adapter-converter + hbenl.vscode-test-explorer + hbenl.vscode-mocha-test-adapter + + jnoortheen.nix-ide + ]; + } + ); } ) ]; @@ -224,18 +225,21 @@ pkgs.mkShell { if [ ${toString development} ]; then echo "Writing config.json for test_database for development mode..." - echo '${builtins.toJSON JSON_CONFIG_TEST}' | jq . --indent 4 > config.json + echo '${JSON_CONFIG_TEST}' | jq . --indent 4 > config.json + + echo "setting up grunt task for VSCode for development mode..." + mkdir -p .vscode + echo '${JSON_VSCODE_TASKS}' | jq . --indent 4 > .vscode/tasks.json + + echo "setting up Mocha Test Explorer plugin for VSCode for development mode..." + echo '${JSON_VSCODE_SETTINGS}' | jq . --indent 4 > .vscode/settings.json fi - node ./nodebb setup '${builtins.toJSON JSON_CONFIG_FLATTENED}' + node ./nodebb setup '${JSON_CONFIG}' if [ ${toString development} ]; then echo "Running npm install for development mode..." npm install - - echo "setting up grunt task for VSCode for development mode..." - mkdir -p .vscode - echo '${builtins.toJSON JSON_VSCODE_TASKS}' | jq . --indent 4 > .vscode/tasks.json fi fi