Skip to content

Automated Ubuntu VPS provisioning script that sets up your server with user management, SSH hardening, Docker, reverse proxy, and more.

Notifications You must be signed in to change notification settings

Dev-Toolbelt/vps-setup

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 

Repository files navigation

VPS Setup Script

From zero to production-ready in one command.

Automated Ubuntu VPS provisioning script that sets up your server with user management, SSH hardening, Docker, reverse proxy, and more — all executed remotely over SSH from your local machine.

./vps-setup.sh --host=192.168.1.100 --use-password=yes --identity=~/.ssh/id_rsa --target-user=deploy --yes

What does it do?

Feature Description
User Management Creates a new user with sudo privileges
SSH Hardening Key-based auth, disables password login
Docker + Compose Installs Docker Engine and Docker Compose v2
Reverse Proxy Deploys nginx-proxy with automatic HTTPS
Firewall Configures UFW rules (if active)
Shell Customization Docker aliases, auto-cd to projects folder
Idempotent Safe to run multiple times — skips what's already done

Prerequisites

Local Machine

  • Bash shell
  • SSH client
  • sshpass (only if using password authentication)
    # Ubuntu/Debian
    sudo apt-get install -y sshpass
    
    # macOS
    brew install hudochenkov/sshpass/sshpass

Remote VPS

  • Fresh Ubuntu server (20.04, 22.04, 24.04 or newer)
  • Root access or a user with sudo privileges
  • SSH access enabled

Quick Start

1. Clone and prepare

git clone https://github.com/dersonsena/vps-setup.git
cd vps-setup
chmod +x vps-setup.sh

2. Run it

Interactive mode — the script asks you everything:

./vps-setup.sh

CLI mode — pass flags and only type passwords:

./vps-setup.sh --host=10.0.0.1 --use-password=yes --target-user=deploy --yes

3. Save the credentials

At the end, you'll receive:

  • Generated username and password (if applicable)
  • Server SSH keys (for backup)
  • Access URLs for your server

Usage

CLI Flags

Flag Description Default
--host=<host> Remote host/IP (required)
--user=<user> Remote SSH user root
--port=<port> Remote SSH port 22
--use-password=yes|no Use password authentication (prompted)
--identity=<path> Path to SSH private key ~/.ssh/id_rsa
--target-user=<user> Username to create on server dev
--pubkey=<path> Path to SSH public key file ~/.ssh/id_rsa.pub
--projects-dir=<dir> Projects directory on server /projects
--yes, -y Skip confirmation prompt
--help, -h Show help message

Security: Passwords are never accepted via CLI — they are always prompted interactively.

CLI mode: When any flag is provided, fields with defaults are auto-filled without prompting. Only passwords require interaction.

Authentication Modes

The script supports three authentication modes to handle different server configurations:

Password only

For servers that accept password authentication:

./vps-setup.sh --host=10.0.0.1 --use-password=yes --yes
# Prompts: SSH password

Key only

For servers that only accept public key authentication:

./vps-setup.sh --host=10.0.0.1 --use-password=no --identity=~/.ssh/id_rsa --yes
# No password prompts

MFA (Key + Password)

For servers that require public key and password (two-factor):

./vps-setup.sh --host=10.0.0.1 --use-password=yes --identity=~/.ssh/id_rsa --yes
# Prompts: SSH password (used after key auth succeeds)

How to know which mode? If your manual ssh user@host asks for a password after key auth, your server uses MFA. The script's debug output will show Authenticated using "publickey" with partial success in this case.

Non-Root Users

When connecting as a non-root user (e.g., --user=deploy), the script needs sudo access for provisioning. It will:

  1. Reuse the SSH password as sudo password (if available)
  2. Or prompt separately for the sudo password
./vps-setup.sh --host=10.0.0.1 --user=deploy --use-password=yes --identity=~/.ssh/id_rsa --yes
# Prompts: SSH password (also used for sudo)

Examples

Minimal setup (interactive)

./vps-setup.sh

Everything is prompted. Great for first-time use.

Standard VPS setup

./vps-setup.sh \
  --host=203.0.113.50 \
  --use-password=no \
  --identity=~/.ssh/id_ed25519 \
  --target-user=app \
  --pubkey=~/.ssh/id_ed25519.pub \
  --yes

Connects with SSH key, creates user app with auto-generated password, uses ed25519 keys.

Corporate server with MFA

./vps-setup.sh \
  --host=10.100.0.5 \
  --user=admin \
  --port=2222 \
  --use-password=yes \
  --identity=~/.ssh/corporate_key \
  --target-user=deployer \
  --projects-dir=/opt/services \
  --yes

Connects on custom port with MFA (key + password), creates deployer user, uses /opt/services as projects dir.

Re-running on an already provisioned server

./vps-setup.sh --host=203.0.113.50 --use-password=no --identity=~/.ssh/id_rsa --yes

Safely skips everything that's already configured:

✅ User 'dev' already exists.
✅ ~/.ssh for root already exists.
✅ Client public key already exists in root's authorized_keys. Skipping.
✅ ~/.ssh for 'dev' already exists.
✅ Client public key already exists in 'dev' authorized_keys. Skipping.
✅ Server SSH key with comment 'server@domain.com' already exists. Skipping key generation.
✅ Alias 'dc' already exists in /home/dev/.bash_aliases
✅ Alias 'dps' already exists in /home/dev/.bash_aliases
✅ Alias 'dstop' already exists in /home/dev/.bash_aliases
✅ Alias 'drm' already exists in /home/dev/.bash_aliases
✅ Alias 'lsa' already exists in /home/dev/.bash_aliases
✅ Projects directory already exists (/projects)
⚠️ Reverse proxy already installed and configured (docker network 'reverse-proxy' found). Skipping.

What Gets Configured

System Updates

  • Updates all packages to latest versions
  • Installs essential tools: curl, git, ca-certificates, lsof, ufw

User Setup

  • Creates a new user (or detects existing one)
  • Adds user to sudo group for administrative tasks
  • Adds both root and target user to docker group

SSH Security

  • Adds your public key to authorized_keys for root and target user (only if not already present)
  • Disables password authentication (SSH keys only)
  • Keeps root login enabled (accessible via SSH key)
  • Generates a server ed25519 SSH key pair (skips if key with comment server@domain.com already exists)
  • Creates timestamped backup of sshd_config before modifications

Docker Environment

  • Installs Docker Engine and Docker Compose v2
  • Creates a reverse-proxy Docker network
  • Stops conflicting web servers (apache2, nginx, caddy, traefik)
  • Frees ports 80 and 443

Reverse Proxy

  • Clones Dev-Toolbelt/reverse-proxy
  • Starts nginx-proxy for automatic container routing
  • Enables HTTP (80) and HTTPS (443) access
  • Skipped entirely if docker network reverse-proxy already exists

Shell Customization

Aliases added to ~/.bash_aliases (each checked individually, no duplicates):

Alias Command
dc docker compose
dps docker ps with formatted table output
dstop Stop all running containers
drm Remove all containers
lsa ls -lah

Auto-cd to projects directory is configured on SSH login for both root and target user.

Firewall (if UFW is active)

  • Allows SSH (port 22)
  • Allows HTTP (port 80)
  • Allows HTTPS (port 443)

UFW is only configured if already active. The script never force-enables the firewall.


Example Output

╔════════════════════════════════════════════════════════════╗
║                                                            ║
║  ✅  VPS Setup Completed Successfully!                     ║
║                                                            ║
╚════════════════════════════════════════════════════════════╝

   Username: deploy
   Password: kR4mN7xQp2wT5vB

🌐 Your server is now accessible at:
   • http://203.0.113.50
   • https://203.0.113.50

Post-Installation

Connect to Your VPS

# As the created user
ssh deploy@203.0.113.50

# As root
ssh root@203.0.113.50

You'll land directly in the projects directory thanks to auto-cd.

Deploy Your First Application

Create a docker-compose.yml with reverse proxy labels:

services:
  web:
    image: nginx:alpine
    environment:
      - VIRTUAL_HOST=your-domain.com
      - LETSENCRYPT_HOST=your-domain.com
      - LETSENCRYPT_EMAIL=you@example.com
    networks:
      - reverse-proxy

networks:
  reverse-proxy:
    external: true
docker compose up -d

The reverse proxy automatically detects your container and routes traffic to it.


Security Features

Feature Detail
No passwords in CLI Passwords are always typed interactively, never in command arguments
Key-only SSH Password authentication is disabled after setup
MFA support Works with servers requiring key + password
Strong passwords Auto-generated 15-char passwords (A-Za-z0-9@#%+=_)
Safe transmission Sensitive data is base64-encoded through SSH
Temp file security Password files use mode 600 and are cleaned up on exit

Troubleshooting

SSH connection test fails

The script shows detailed debug output on failure. Look for these patterns:

Debug message Meaning Solution
Authentications that can continue: publickey Server only accepts keys Use --use-password=no --identity=<key>
Authenticated using "publickey" with partial success Server requires MFA Use --use-password=yes --identity=<key>
Permission denied (password) Wrong password Check your password
Permission denied (publickey) Wrong key or no key Check --identity path

"Permission denied" when using docker

newgrp docker
# or logout and login again

"Connection refused" when accessing server

sudo ufw status
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Can't login after script completes

ssh -i ~/.ssh/your_key user@server-ip

Reverse proxy not working

docker compose ps
docker logs reverse-proxy

Sudo password required (non-root user)

When connecting as a non-root user, the script prompts for the sudo password. If you provided an SSH password, it's reused automatically.


Contributing

Contributions are welcome! Feel free to open an issue or submit a pull request.

License

This project is open source and available under the MIT License.

Author

Kilderson Sena


Note: This script makes significant changes to your server's SSH and firewall configuration. Always test on a development server first and ensure you have console access to your VPS in case something goes wrong.

About

Automated Ubuntu VPS provisioning script that sets up your server with user management, SSH hardening, Docker, reverse proxy, and more.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages