Copied to clipboard!

Server Setup Script Documentation

A comprehensive bash script that transforms a fresh RHEL-based server into a secure, Docker-ready production environment with SSL automation, intrusion detection, and enterprise-grade security configurations.

Installation at a Glance

Run one command on a fresh server. The script handles the complex setup, asking you for key decisions along the way.

1. Run Script

Pipe `curl` to `bash` on a fresh server.

2. Harden Base

Updates, SSH hardening, Firewall & Fail2ban setup.

3. Install Services

Docker, Portainer, and Nginx Proxy Manager.

4. Finalize

Set timezone, configure user, and reboot.

curl -sSL https://raw.githubusercontent.com/ronniebasak/install-sh/refs/heads/main/install.sh | sudo bash

Requirements

  • OS: Fresh Rocky Linux 9, AlmaLinux 9, or Fedora 39+
  • RAM: 2GB Minimum (4GB Recommended)
  • Access: Root access via SSH

Architecture Overview

The script establishes a layered security and application architecture. Traffic is filtered through a hardened firewall before reaching the reverse proxy, which then intelligently routes requests to the appropriate Docker containers.

graph LR subgraph "Internet" U[Users] end subgraph "Server Edge" F[Firewall
Allows 80, 443, 2222] FB[Fail2ban
Blocks Malicious IPs] SSH[SSH Daemon
Port 2222, Key Auth] end subgraph "Container Network (npm)" NPM[Nginx Proxy Manager
SSL & Routing] P[Portainer
Container Mgmt] D1[App 1] D2[App 2] DB[Database] end U -- HTTPS/443 --> F --> NPM U -- SSH/2222 --> F --> SSH NPM -- Routes traffic --> D1 NPM -- Routes traffic --> D2 P -- Manages --> D1 P -- Manages --> D2 P -- Manages --> DB D1 -- Connects to --> DB D2 -- Connects to --> DB FB -- Watches logs & updates --> F

Post-Installation Setup

After the script finishes and the server reboots, complete these initial setup steps to access your new environment.

1 Access Portainer

Login at https://your-server-ip:9443 to manage your Docker environment.

2 Configure Nginx Proxy Manager

Login at http://your-server-ip:81. Default login: admin@example.com / changeme. Change the password immediately.

3 Create Your First Sudo User

The script includes a helper to create a new user with sudo/docker access and configure SSH key authentication.

sudo /usr/local/bin/add_secure_user

Common Operations

User Management

Use the provided script to add new users securely. It handles creating the user, adding them to the correct groups, and setting up SSH key authentication.

# Add a new user with sudo/docker access
sudo /usr/local/bin/add_secure_user

# List users in the docker group
getent group docker

Firewall Management

The firewall is managed by firewalld. The script opens the required ports (80 for HTTP validation, 443 for HTTPS, and your custom SSH port). To open additional ports:

# Open a new port (e.g., for a game server)
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload

# View all open ports and services
sudo firewall-cmd --list-all

Container Management

Using the Portainer web UI is recommended for most operations. For quick command-line tasks, these commands are useful:

# List running containers
docker ps

# Check logs of a specific container
docker logs [container_name]

# Connect an existing container to the proxy network
docker network connect npm [container_name]

SSL Management

Nginx Proxy Manager handles all SSL certificate tasks. Point your domain's A record to the server IP, then add a "Proxy Host" in the Nginx Proxy Manager web UI. SSL certificates will be requested and renewed automatically via Let's Encrypt.

Common Scenarios

Deploying a Ghost Blog

This example demonstrates deploying a containerized application and exposing it securely with an SSL certificate.

  1. In Portainer, go to "Stacks" > "Add Stack".
  2. Give it a name (e.g., `ghost-blog`).
  3. Paste the following Docker Compose content into the web editor.
  4. Deploy the stack.
  5. In Nginx Proxy Manager, create a proxy host for `blog.yourdomain.com` that forwards to the hostname `ghost` on port `2368`.
  6. On the SSL tab for that host, request a new Let's Encrypt certificate.
version: '3.8'
services:
  ghost:
    image: ghost:latest
    restart: always
    networks:
      - npm
    environment:
      # This MUST match the domain you set up in Nginx Proxy Manager
      url: https://blog.yourdomain.com
    volumes:
      - ghost_content:/var/lib/ghost/content

volumes:
  ghost_content:

networks:
  npm:
    external: true

Troubleshooting

SSH Connection Refused

This is the most common issue after installation. It's almost always due to using the wrong port or an incorrect SSH key setup.

# Ensure you connect using the custom port (default is 2222)
ssh -p 2222 your_user@your_server_ip

# Use verbose mode to debug key issues
ssh -vvv -p 2222 your_user@your_server_ip

502 Bad Gateway Error

This error from Nginx Proxy Manager means it can't reach your application container. Check these things:

  • Is the container actually running? Check with `docker ps`.
  • Is the container connected to the `npm` network? Verify with `docker network inspect npm`.
  • Does the "Forward Hostname / IP" in Nginx Proxy Manager exactly match the container's name (e.g., `ghost`)?
  • Is the port correct? (e.g., `2368` for Ghost).

Maintenance

System Updates

Security updates are applied automatically. To run a full manual system upgrade, including non-security packages:

sudo dnf update -y

Docker Cleanup

Periodically reclaim disk space from unused Docker images, containers, and volumes. This is safe to run and will not remove any volumes currently in use.

# Remove all unused containers, networks, images (both dangling and unreferenced)
docker system prune -a --volumes