Skip to content

Instantly share code, notes, and snippets.

@darmawan01
Last active January 8, 2026 12:01
Show Gist options
  • Select an option

  • Save darmawan01/55955cf64f50a0c4c64d0fac0b1158bc to your computer and use it in GitHub Desktop.

Select an option

Save darmawan01/55955cf64f50a0c4c64d0fac0b1158bc to your computer and use it in GitHub Desktop.
#!/bin/bash
# VPS Initial Setup Script
# Run as root: bash setup.sh
set -e
echo "========================================="
echo "VPS Initial Setup Script"
echo "========================================="
echo ""
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Check if running as root
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}This script must be run as root${NC}"
exit 1
fi
# Get user input
read -p "Enter new username: " USERNAME
read -p "Enter SSH port (default 2222): " SSH_PORT
SSH_PORT=${SSH_PORT:-2222}
read -p "Enter your timezone (default Asia/Jakarta): " TIMEZONE
TIMEZONE=${TIMEZONE:-Asia/Jakarta}
echo ""
echo -e "${GREEN}Starting setup...${NC}"
echo ""
# 1. Update system
echo -e "${YELLOW}[1/10] Updating system packages...${NC}"
apt update && apt upgrade -y
# 2. Create new user
echo -e "${YELLOW}[2/10] Creating user: $USERNAME${NC}"
adduser --gecos "" $USERNAME
usermod -aG sudo $USERNAME
# 3. Setup SSH directory for new user
echo -e "${YELLOW}[3/10] Setting up SSH for $USERNAME${NC}"
mkdir -p /home/$USERNAME/.ssh
chmod 700 /home/$USERNAME/.ssh
touch /home/$USERNAME/.ssh/authorized_keys
chmod 600 /home/$USERNAME/.ssh/authorized_keys
chown -R $USERNAME:$USERNAME /home/$USERNAME/.ssh
# Copy root's authorized_keys if exists
if [ -f /root/.ssh/authorized_keys ]; then
cat /root/.ssh/authorized_keys >> /home/$USERNAME/.ssh/authorized_keys
echo -e "${GREEN}Copied existing SSH keys to $USERNAME${NC}"
fi
# 4. Configure SSH
echo -e "${YELLOW}[4/10] Configuring SSH...${NC}"
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup
sed -i "s/^#Port 22/Port $SSH_PORT/" /etc/ssh/sshd_config
sed -i "s/^Port 22/Port $SSH_PORT/" /etc/ssh/sshd_config
sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/^#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config
# 5. Setup UFW firewall
echo -e "${YELLOW}[5/10] Setting up firewall...${NC}"
apt install ufw -y
ufw default deny incoming
ufw default allow outgoing
ufw allow $SSH_PORT/tcp
ufw --force enable
# 6. Install fail2ban
echo -e "${YELLOW}[6/10] Installing fail2ban...${NC}"
apt install fail2ban -y
cat > /etc/fail2ban/jail.local <<EOF
[sshd]
enabled = true
port = $SSH_PORT
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
EOF
systemctl enable fail2ban
systemctl start fail2ban
# 7. Setup automatic security updates
echo -e "${YELLOW}[7/10] Setting up automatic security updates...${NC}"
apt install unattended-upgrades -y
dpkg-reconfigure -plow unattended-upgrades
# 8. Install essential tools
echo -e "${YELLOW}[8/10] Installing essential tools...${NC}"
apt install curl wget git vim htop net-tools -y
# 9. Configure timezone
echo -e "${YELLOW}[9/10] Setting timezone to $TIMEZONE...${NC}"
timedatectl set-timezone $TIMEZONE
# 10. Setup swap (2GB)
echo -e "${YELLOW}[10/11] Setting up swap space...${NC}"
if [ ! -f /swapfile ]; then
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
echo -e "${GREEN}Swap created successfully${NC}"
else
echo -e "${YELLOW}Swap file already exists, skipping...${NC}"
fi
# 11. Install Docker
echo -e "${YELLOW}[11/11] Installing Docker...${NC}"
apt install apt-transport-https ca-certificates curl software-properties-common -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y
# Add user to docker group
usermod -aG docker $USERNAME
systemctl enable docker
systemctl start docker
echo -e "${GREEN}Docker installed successfully${NC}"
echo -e "${GREEN}User $USERNAME added to docker group${NC}"
# Restart SSH
echo ""
echo -e "${YELLOW}Restarting SSH service...${NC}"
systemctl restart sshd
echo ""
echo -e "${GREEN}=========================================${NC}"
echo -e "${GREEN}Setup Complete!${NC}"
echo -e "${GREEN}=========================================${NC}"
echo ""
echo -e "Important information:"
echo -e "- New user: ${GREEN}$USERNAME${NC}"
echo -e "- SSH port: ${GREEN}$SSH_PORT${NC}"
echo -e "- Root login: ${RED}DISABLED${NC}"
echo -e "- Password auth: ${RED}DISABLED${NC}"
echo -e "- Docker: ${GREEN}INSTALLED${NC}"
echo -e "- Docker Compose: ${GREEN}INSTALLED${NC}"
echo ""
echo -e "${YELLOW}BEFORE logging out:${NC}"
echo -e "1. Add your SSH public key to /home/$USERNAME/.ssh/authorized_keys"
echo -e "2. Test SSH login in a NEW terminal:"
echo -e " ${GREEN}ssh -p $SSH_PORT $USERNAME@$(hostname -I | awk '{print $1}')${NC}"
echo -e "3. Make sure you can login before closing this session!"
echo ""
echo -e "${YELLOW}After logging in as $USERNAME:${NC}"
echo -e "- Run ${GREEN}docker --version${NC} to verify Docker installation"
echo -e "- Run ${GREEN}docker compose version${NC} to verify Docker Compose"
echo -e "- You may need to re-login for docker group permissions to take effect"
echo ""
echo -e "${RED}WARNING: Do not close this terminal until you verify SSH access!${NC}"
echo ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment