Published on

Setting up Servers with Bash Scripts

Authors

Ubuntu Servers

#!/bin/bash

# Variables
USERNAME=""
USEREMAIL=""
EDITOR="vim"

# Prompt for variables if not set
if [ -z "$USERNAME" ]; then
  read -p "Enter your name: " USERNAME
fi

if [ -z "$USEREMAIL" ]; then
  read -p "Enter your email address: " USEREMAIL
fi

# Update and Upgrade
echo "Updating and Upgrading System..."
sudo apt update --yes
sudo apt upgrade --yes

# Install Essential Build Tools
echo "Installing Build Essentials..."
sudo apt install -y build-essential

# Install Development Software
echo "Installing Development Software..."

# Visual Studio Code
echo "Installing Visual Studio Code..."
sudo snap install code --classic

# Git
echo "Installing Git..."
sudo apt install -y git
git config --global user.name "$USERNAME"
git config --global user.email "$USEREMAIL"

# Node Version Manager (NVM)
echo "Installing NVM..."
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm install node

# Docker
echo "Installing Docker..."
sudo apt remove docker docker-engine docker.io containerd runc -y
sudo apt install -y ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# Other Useful Tools
echo "Installing Other Useful Tools..."
sudo apt install -y \
    $EDITOR \
    htop \
    tmux \
    zsh \
    curl \
    wget \
    unzip \
    zip \
    sudo

# Clean Up
echo "Cleaning Up..."
sudo apt autoremove -y
sudo apt autoclean -y


# Docker
## Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

sudo systemctl start|stop|status|enable|disable docker
sudo docker run hello-world

echo "Setup Complete!"

Setup Java Apps

#!/bin/bash
set -e

# Configuration
JAR_FILE_PATH="$1"
APP_NAME="myjavaapp"
APP_USER="appuser"
SERVICE_NAME="${APP_NAME}.service"
APP_DIR="/opt/${APP_NAME}"
LOG_DIR="/var/log/${APP_NAME}"
CONFIG_FILE="/etc/${APP_NAME}.conf"
JVM_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC"
SERVER_PORT="${2:-8080}" # Default port is 8080

# Validate input
if [ -z "$JAR_FILE_PATH" ] || [ ! -f "$JAR_FILE_PATH" ]; then
  echo "Usage: $0 <path-to-jar-file> [server-port]"
  echo "Please provide a valid path to your Java application JAR file"
  exit 1
fi

# Check root privileges
if [ "$EUID" -ne 0 ]; then
  echo "Please run this script as root"
  exit 1
fi

# Detect OS and set package manager
detect_os() {
  if [ -f /etc/os-release ]; then
    . /etc/os-release
    OS=$ID
  else
    echo "Unable to detect OS"
    exit 1
  fi

  case $OS in
    "amzn")
      PKG_MANAGER="yum"
      JAVA_PKG="java-21-amazon-corretto-headless"
      ;;
    "ubuntu")
      PKG_MANAGER="apt-get"
      JAVA_PKG="openjdk-21-jdk"
      ;;
    *)
      echo "Unsupported OS: $OS"
      exit 1
      ;;
  esac
}

# Install required packages
install_packages() {
  echo "Updating system packages..."
  $PKG_MANAGER update -y

  echo "Installing Java and utilities..."
  $PKG_MANAGER install -y $JAVA_PKG \
    curl \
    htop \
    unzip \
    logrotate

  if [ "$OS" = "ubuntu" ]; then
    $PKG_MANAGER install -y ufw
  fi
}

# Setup application user
setup_user() {
  if ! id "$APP_USER" &>/dev/null; then
    echo "Creating application user..."
    useradd -r -s /bin/false "$APP_USER"
  fi
}

# Configure firewall
configure_firewall() {
  echo "Configuring firewall on port $SERVER_PORT..."
  case $OS in
    "amzn")
      if ! firewall-cmd --list-ports | grep -q "${SERVER_PORT}/tcp"; then
        firewall-cmd --permanent --add-port=${SERVER_PORT}/tcp
        firewall-cmd --reload
      fi
      ;;
    "ubuntu")
      ufw allow ${SERVER_PORT}/tcp
      ufw --force enable
      ;;
  esac
}

# Setup application directory structure
setup_app_dirs() {
  echo "Creating application directories..."
  mkdir -p "$APP_DIR"
  mkdir -p "$LOG_DIR"

  echo "Deploying application..."
  cp "$JAR_FILE_PATH" "$APP_DIR/app.jar"
  chown -R "$APP_USER:$APP_USER" "$APP_DIR" "$LOG_DIR"
}

# Create environment configuration
create_app_config() {
  echo "Creating environment configuration..."
  cat << EOF > "$CONFIG_FILE"
# Application environment variables
JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))
APP_ENV=production
SERVER_PORT=$SERVER_PORT
EOF

  chown "$APP_USER:$APP_USER" "$CONFIG_FILE"
  chmod 600 "$CONFIG_FILE"
}

# Create systemd service
create_systemd_service() {
  echo "Creating systemd service..."
  cat << EOF > "/etc/systemd/system/${SERVICE_NAME}"
[Unit]
Description=Java Application Service
After=network.target

[Service]
User=$APP_USER
EnvironmentFile=$CONFIG_FILE
ExecStart=/usr/bin/java \$JVM_OPTS -jar $APP_DIR/app.jar --server.port=\$SERVER_PORT
SuccessExitStatus=143
Restart=always
RestartSec=10
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=$APP_NAME

[Install]
WantedBy=multi-user.target
EOF

  systemctl daemon-reload
  systemctl enable "$SERVICE_NAME"
}

# Setup log rotation
setup_log_rotation() {
  echo "Configuring log rotation..."
  cat << EOF > "/etc/logrotate.d/${APP_NAME}"
$LOG_DIR/*.log {
    daily
    rotate 7
    missingok
    compress
    delaycompress
    notifempty
    create 0640 $APP_USER $APP_USER
    sharedscripts
    postrotate
        systemctl restart $SERVICE_NAME >/dev/null 2>&1 || true
    endscript
}
EOF
}

# Main installation process
main() {
  detect_os
  install_packages
  setup_user
  configure_firewall
  setup_app_dirs
  create_app_config
  create_systemd_service
  setup_log_rotation

  echo "Starting application service..."
  systemctl restart "$SERVICE_NAME"

  echo "Installation complete!"
  echo "Application status: systemctl status $SERVICE_NAME"
  echo "Logs: journalctl -u $SERVICE_NAME -f"
}

# Execute main function
main