Setting Up Ubuntu Server 24.04 with Essential Tools

UbuntuServer-1.md Public

This document provides a comprehensive guide for setting up an Ubuntu Server 24.04 LTS environment, including installation of essential tools like tree, Oh My Zsh, and Node.js. It also covers configuring Nginx, setting up GitHub, and managing services using systemctl.

Ubuntu Server

Set up 2025-12-14

Using Ubuntu 24.04 LTS which already has python3.12

1. install tree

sudo apt update
sudo apt upgrade -y
sudo apt-get install tree
sudo apt install python3.12-venv

2. Install Oh My Zsh

sudo apt install zsh -y
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

modify .zshrc

  • sudo nano ~/.zshrc
  • make changes:
# Nick added
alias python=python3.12
alias ss_status="sudo systemctl status"
alias ss_start="sudo systemctl start"
alias ss_stop="sudo systemctl stop"

echo ".zshrc loaded ✅"

3. node

global for nick and app_runner

curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt install -y nodejs

install claude

  • I did this in the nws-kv23 server 2026-02-16, if this still works then continue using it.
1. make server level .npm
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH=$HOME/.npm-global/bin:$PATH' >> ~/.zshrc
source ~/.zshrc
2. install claude

npm install -g @anthropic-ai/claude-code

4. Install GitHub

  1. from terminal: ssh-keygen -t ed25519 -C "nrodrig1@gmail.com"
  2. start ssh-agent: eval "$(ssh-agent -s)"
  3. create or modify ~/.ssh/config file
  • nano ~/.ssh/config
Host github.com
AddKeysToAgent yes
IdentityFile ~/.ssh/id_ed25519
  1. place your ssh key in the Github page: https://github.com/settings/keys
  • copy SSH public key from terminal command: cat ~/.ssh/id_ed25519.pub

6. Create folder structure

mkdir applications
mkdir databases
mkdir environments
mkdir project_resources
mkdir _config_files
mkdir logs

7.1 Clone TheServerManagerAPI

git clone git@github.com:costa-rica/TheServerManagerAPI.git

7.2 Set sudoer permissions

  1. create the nick-systemctl.csv file
  2. add the /home/nick/update-nick-systemctl.sh file
  3. run the update-nick-systemctl.sh file by typing to terminal: /home/nick/update-nick-systemctl.sh
  4. make file executable: chmod +x /home/nick/update-nick-systemctl.sh

8. nginx

sudo apt install nginx -y

sudo apt install ufw -y
sudo ufw allow ssh
sudo ufw allow "Nginx full"
sudo ufw allow from 192.168.100.166 to any port 8000
sudo ufw allow 8000
sudo ufw allow from 192.168.1.134 # allows to all ports on this machine
sudo ufw enable
  • change ownership sudo chown -R nick:nick /etc/nginx/conf.d/
    • !important for the404Back

https certify

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d what-sticks.com -d www.what-sticks.com -d what-sticks-health.com -d www.what-sticks-health.com -d api.what-sticks.com -d api.what-sticks-health.com

sudo certbot --nginx -d venturer.dashanddata.com -d dev.what-sticks.com -d dev.api10.what-sticks.com -d pioneer02.dashanddata.com

sudo certbot --nginx -d nhtsa-dash.kineticmetrics.com -d demo.kmdashboard.dashboardsanddatabases.com

# certbot auto renewal
sudo systemctl status certbot.timer

# check certbo auto renewal
sudo certbot renew --dry-run

# starts service on boot
sudo systemctl enable ws08web

service file commands

sudo systemctl daemon-reload
sudo systemctl enable personalweb03-api
sudo systemctl start personalweb03-api
sudo systemctl status personalweb03-api

# see logs
sudo journalctl -u personalweb03-api
sudo journalctl -u newsnexus10api.service -f

# Stop the timer (prevents future runs)
sudo systemctl stop personalweb03-services.timer

# Disable it (won't start on boot)
sudo systemctl disable personalweb03-services.timer

# Verify it's stopped
sudo systemctl list-timers

# reset failed (i.e. due to `StartLimitIntervalSec=1d`)
sudo systemctl reset-failed newsnexusrequesternewsapi01.service

Permissions

Example:

➜  NewsNexus10API git:(dev_02_logging) ls -ld /home/nick/logs
drwxr-xr-x 2 nick nick 4096 Dec 22 23:58 /home/nick/logs

Breakdown:

  • drwxr-xr-x 2 nick nick breaks down as follows:

    • d → directory
    • rwx (owner: nick) → read, write, enter directory
    • r-x (group: nick) → read, enter directory, no write
    • r-x (others) → read, enter directory, no write
  • 2 = number of hard links (directory + parent reference).

  • Ownership:

    • User: nick
    • Group: nick

Set off .timer files

1.

sudo systemctl daemon-reload
sudo systemctl enable --now personalweb03-services.timer

check status

systemctl list-timers

############################## ############################## ############################## ############################## ############################## ##############################

Set up 2025 (nick)

Using Ubuntu 24.04 LTS which already has python3.12

1. install tree

sudo apt update
sudo apt upgrade -y
sudo apt-get install tree
sudo apt install python3.12-venv

2. Install Oh My Zsh

sudo apt install zsh -y
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

modify .zshrc

  • sudo nano ~/.zshrc
  • make changes:
# Nick added
alias python=python3.12

echo ".zshrc loaded ✅"

3. node

  1. Download with curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash

  2. nvm install 24

4. Install pm2

npm install -g pm2

5. Install GitHub

  1. from terminal: ssh-keygen -t ed25519 -C "nrodrig1@gmail.com"
  2. start ssh-agent: eval "$(ssh-agent -s)"
  3. create or modify ~/.ssh/config file
  • touch ~/.ssh/config
Host github.com
AddKeysToAgent yes
IdentityFile ~/.ssh/id_ed25519
  1. place your ssh key in the Github page: https://github.com/settings/keys
  • copy SSH public key from terminal command: cat ~/.ssh/id_ed25519.pub

6. Create folder structure

mkdir applications
mkdir databases
mkdir environments
mkdir project_resources
mkdir _config_files

7 deleted incorreclty

8. nginx

sudo apt install nginx -y

sudo apt install ufw -y
sudo ufw allow ssh
sudo ufw allow "Nginx full"
sudo ufw allow from 192.168.100.166 to any port 8000
sudo ufw allow 8000
sudo ufw allow from 192.168.1.134 # allows to all ports on this machine
sudo ufw enable

handle writing to nginx/sites-available

Create a new group and add the user to it:

 # On maestro06 — run these as a sudoer
  sudo groupadd nginxmanagers
  sudo usermod -aG nginxmanagers nick
  sudo chown -R root:nginxmanagers /etc/nginx/sites-available
  sudo chmod -R 775 /etc/nginx/sites-available

OR

  • change ownership sudo chown -R nick:nick /etc/nginx/sites-available/

https certify

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d what-sticks.com -d www.what-sticks.com -d what-sticks-health.com -d www.what-sticks-health.com -d api.what-sticks.com -d api.what-sticks-health.com

sudo certbot --nginx -d venturer.dashanddata.com -d dev.what-sticks.com -d dev.api10.what-sticks.com -d pioneer02.dashanddata.com

sudo certbot --nginx -d nhtsa-dash.kineticmetrics.com -d demo.kmdashboard.dashboardsanddatabases.com

# certbot auto renewal
sudo systemctl status certbot.timer

# check certbo auto renewal
sudo certbot renew --dry-run

# starts service on boot
sudo systemctl enable ws08web

number of workers

1- get number of cores

nproc --all

2- calc number of workers based on gunicorn documenetation (CoreyS): 2 x num_cores

change computer (host name)

sudo hostnamectl set-hostname newNameHere
## edit this file with all the old names:
sudo nano /etc/hosts
sudo reboot
## This worked even in a WMWare VM

sudo unable to resolve host name or service not known

su - root
cat /etc/hosts
nano /etc/hosts
  • add name of machine like this 127.0.0.1 dev0
  • source: https://www.globo.tech/learning-center/sudo-unable-to-resolve-host-explained/

Multipathd warnings on server sys.log file

  • For NWS in Rochester - to stop Multipathd warnings from clogging up syslog
  • Commands to turn this off:
sudo systemctl stop multipathd
sudo systemctl disable multipathd

VMWare

Reverser Proxy Server:

  • CPU: 1
  • Memory: 2GB
  • Hard Disk: 40GM

VM Options > Configuration Parameters to add:

  • disk.EnableUUID: True

Change password

  1. terminal passwd

To allow short and simple password must edit file

  1. terminal: sudo nano /etc/pam.d/common-password
  2. To allow for short and simple password replace line password [success=1 default=ignore] pam_unix.so obscure sha512 to password [success=1 default=ignore] pam_unix.so sha512 minlen=4

pm2

pm2 cron_restart

  • cron_restart: "42 6 * * *" # restarts at 6:42 AM every day
    • params: m h day_of_month month day_of_week
  • If you start the app with this paramter, it will start automatically at the specified time run until it ends and then restart again.
    • If you stop the app manually by pm2 stop NewsNexusGNewsRequest or pm2 stop 16 it will restart
    • you can verify by seeing this:
➜  ~ pm2 stop 16
[PM2] Applying action stopProcessId on app [16](ids: [ '16' ])
[PM2] [NewsNexusGNewRequester](16) ✓
[PM2][WARN] App NewsNexusGNewRequester stopped but CRON RESTART is still UP 42 6 * * *

pm2 Commands

  • run only: pm2 start ecosystem.config.js --only DevelopmentWebApp
  • delete (after stopping app): pm2 delete DevelopmentWebApp
  • clear all logs: pm2 flush

install pm2

install global

npm install -g pm2

run app using pm2

  1. pm2 start app.js or pm2 start server.js
  2. give it a name pm2 start server.js --name ExpressApi01

pm2 start on boot, reboot, or whenever the server is off and back on again

  • This process assumes you have an ecosystem.config.js file
  1. 'pm2 startup`
  2. pm2 will display a line of code to copy and paste like this one:
sudo env PATH=$PATH:/usr/bin /home/dashanddata_user/.config/yarn/global/node_modules/pm2/bin/pm2 startup systemd -u dashanddata_user --hp /home/dashanddata_user
  1. 'pm2 save`

undo pm2 start on boot

pm2 unstartup systemd

  • This will remove the script added by step 2 of the pm2 start on boot section.

Run Express App on server

  1. move files to server
  2. install yarn
  3. use nginx .conf
    • if nginx sudo nginx -t shows a problem search for duplicates of directed route by using: grep -r "server_name expressapi01.dashanddata.com" /etc/nginx/sites-available/ or some variation. If this is the case probably need to replace the default file in the /etc/nginx/sites-available/ directory.
  4. open ports that app is running on

Trouble shooting

Terminal warning: "manpath: can't set the locale; make sure $LC_* and $LANG are correct"

  • if running .zshrc terminal there is a line that is export MANPATH="/usr/local/man:$MANPATH" in the .zshrc file. Make sure it is not commented. If so, uncomment.

Create Jump User

  1. create jumpuser sudo adduser jumpuser on both machine01 (reverse proxy) and kv09 (destintion)
  2. add rule in machine01's sshd_config file (/etc/ssh/sshd_config) with the correct instructions you must sudo systemctl restart ssh
Match User jumpuser
        ForceCommand ssh jumpuser@192.168.1.72
        PermitTTY yes
        AllowTcpForwarding yes
  1. jumpuser's workstation they need to create a ssh-keygen file like: ssh-keygen -t ed25519 -C "jumpuser_to_machine01"
  2. jumpuser's workstation they need to copy the public key to machine01 like: ssh-copy-id jumpuser@82.66.246.192 where the ip address is the public ip that will get routed to the port 22 of the reverse proxy server.
  3. jumpuser should be able to ssh jumpuser@82.66.246.192

Other stuff that seemed to kind of work Tunneling one terminal:

  1. both work locally to access machine01 ssh -L 2222:192.168.1.134:22 jumpuser@82.66.246.192 ssh -L 0.0.0.0:2222:192.168.1.136:22 jumpuser@82.66.246.192

but this does not work to access Machine02 from Machine01 ssh dashanddata_user@localhost -p 2222 ssh dashanddata_user@192.168.1.134 -p 2222

END OBE Jumpuser

VMWare Cloning VM

Step 1: copy vmdk and vmx files to new folder with new VM name

  • original VM should be turned off
  • copy vmdk and vmx files to new folder with new VM name

Step 2: ☝️ [After copy is finished] turn on old VM

  • after finished copy turn ON the old VM
    • This will help because when you get back to the Virtual Machines page / list you'll see two VMs with the same name

Step 3: register the cloned VM

  • From datastore browser navigate to the new VM folder and right click on .vmx file and select "Register VM"
  • From the Virtual Machines page / list rename new VM (which will be the one with the same name but turned off)
  • Turn on the new VM
  • rename the new VM from VMWare
  • hostname from inside terminal of new machine sudo hostnamectl set-hostname <new_hostname>

Step 4 (Ubuntu 24.04 LTS): update IP address

Regenerate the machine ID (this is the key part)

sudo rm -f /etc/machine-id
sudo rm -f /var/lib/dbus/machine-id
sudo systemd-machine-id-setup
sudo systemctl restart systemd-networkd
sudo reboot

Step 4 (Ubuntu 20.04 LTS): apply new static IP address

  • turn on new vm
  • if ip address in not different create a new static IP address
    • sudo nano /etc/netplan/00-installer-config.yaml, enter:
network:
  ethernets:
    ens160:
      dhcp4: false
      addresses:
        - 192.168.100.<unused_ip>/24
      gateway4: 192.168.100.1
      nameservers:
        addresses:
          - 8.8.8.8
  version: 2

Step 5: shutdown and restart server

  • on boot up the new / used IP address should be applied to this VM

Running Python Flask App on Ubuntu / PM2

  • as of 2025-08-11

the pm2 ecosystem.config.js file

  • this one started working as of 2025-08-11
    {
      name: "Samurai02APIRag",
      script: "/home/shared/applications/Samurai02APIRag/run.py",
      interpreter: "/home/shared/environments/samurai02/bin/python",
      cwd: "/home/shared/applications/Samurai02APIRag",
      env: {
        FLASK_CONFIG_TYPE: "prod",
      },
    },

Neosmay Server Device

  • esc only once or twice as soon as you press the on button (like immediately)
  • if you get to screen with grub> you pressed too many times
  • you should get an option that has "Firmware" in it