This project provides a set of scripts to automate the provisioning and hardening of a new Ubuntu LTS server, culminating in a production-ready Docker Swarm environment managed by a secure Traefik reverse proxy.
The entire process is designed to be repeatable, secure, and based on modern Infrastructure as Code (IaC) principles.
This setup is built on several key professional practices:
- Separation of Concerns: The process is split into distinct parts. System hardening (
rootuser tasks) is separate from application environment setup (deployuser tasks), which is separate from application deployment. This makes the system cleaner and easier to manage. - Infrastructure as Code (IaC): This Git repository is the single source of truth. The state of the server is defined by code, not by manual actions. This ensures consistency and enables perfect disaster recovery.
- Security by Default: The scripts apply a strong security baseline from the start, including a hardened SSH configuration, a restrictive firewall, and the principle of least privilege for user accounts.
- Modern Docker Practices: We use Docker-managed named volumes to avoid host-level permission issues and Docker Secrets to securely manage sensitive data like passwords, which are never stored in configuration files.
Before you begin, you will need:
- A fresh VPS running the latest Ubuntu LTS.
- An SSH key pair generated on your local computer.
- A domain name that you own.
- Your DNS provider configured with an A record pointing your domain (e.g.,
traefik.yourdomain.com) to your VPS's public IP address.
Follow these steps in order. Do not skip any steps.
This script performs all initial system-level security hardening and creates the non-root deploy user.
- Log into your new VPS as the
rootuser. - Create the script file:
nano part1_root_setup.sh - Copy the content of
part1_root_setup.shinto the file and save it. - Make the script executable:
chmod +x part1_root_setup.sh - Run the script:
./part1_root_setup.sh - The script will prompt you to paste the public SSH key for the
deployuser. - When the script is complete, it will give you final instructions. Follow them immediately.
➡️ ACTION REQUIRED: Log out of the root session.
This script installs Docker and prepares the Swarm environment, including shared networks and volumes.
- Log into your VPS as the new
deployuser with your SSH key:ssh -p 2222 deploy@<your_vps_ip>
- Create the script file:
nano part2_docker_setup.sh - Copy the content of
part2_docker_setup.shinto the file and save it. - Make the script executable:
chmod +x part2_docker_setup.sh - Run the script:
./part2_docker_setup.sh - The script will ask you to create a password for the
deployuser. This password is only used forsudocommands. - The script will finish by preparing the Docker environment.
➡️ ACTION REQUIRED: Log out and log back in one more time. This is critical for your user's new docker group membership to take effect in your shell.
This script deploys the main Traefik reverse proxy.
- Log in again as the
deployuser. Your shell now has the correct permissions to use Docker. - Create the script file:
nano part3_traefik_setup.sh - Copy the content of
part3_traefik_setup.shinto the file and save it. - Make the script executable:
chmod +x part3_traefik_setup.sh - Run the script:
./part3_traefik_setup.sh - Follow the prompts to configure your Traefik domain, email, and dashboard credentials.
- Once complete, Traefik will be running and accessible at the domain you provided.
This script deploys the Portainer management UI.
- Create the script file:
nano part4_portainer_setup.sh - Copy the content of
part4_portainer_setup.shinto the file and save it. - Make the script executable:
chmod +x part4_portainer_setup.sh - Run the script:
./part4_portainer_setup.sh - Follow the prompts to configure your Portainer domain.
- Once complete, Portainer will be running and accessible at the domain you provided.
This script deploys a secure PostgreSQL database server.
- Create the script file:
nano part5_postgres_setup.sh - Copy the content of
part5_postgres_setup.shinto the file and save it. - Make the script executable:
chmod +x part5_postgres_setup.sh - Run the script:
./part5_postgres_setup.sh - Follow the prompts to configure your PostgreSQL credentials.
- The script will create a secure PostgreSQL instance with Docker secrets management.
This script deploys a Redis server with password protection.
- Create the script file:
nano part7_redis_setup.sh - Copy the content of
part7_redis_setup.shinto the file and save it. - Make the script executable:
chmod +x part7_redis_setup.sh - Run the script:
./part7_redis_setup.sh - Follow the prompts to set up Redis with password protection.
- The script will create a secure Redis instance with Docker secrets management.
This script deploys PgAdmin, a web-based PostgreSQL administration tool.
- Create the script file:
nano part8_pgadmin_setup.sh - Copy the content of
part8_pgadmin_setup.shinto the file and save it. - Make the script executable:
chmod +x part8_pgadmin_setup.sh - Run the script:
./part8_pgadmin_setup.sh - Follow the prompts to configure your PgAdmin domain and credentials.
- Once complete, PgAdmin will be accessible at the domain you provided.
This script deploys MinIO, an S3-compatible object storage server.
- Create the script file:
nano part9_minio_setup.sh - Copy the content of
part9_minio_setup.shinto the file and save it. - Make the script executable:
chmod +x part9_minio_setup.sh - Run the script:
./part9_minio_setup.sh - Follow the prompts to configure your MinIO domain and access credentials.
- Once complete, MinIO will be accessible at the domain you provided.
This script deploys the Evolution API with integration to PostgreSQL, Redis, and MinIO.
- Create the script file:
nano part10_evolution_setup.sh - Copy the content of
part10_evolution_setup.shinto the file and save it. - Make the script executable:
chmod +x part10_evolution_setup.sh - Run the script:
./part10_evolution_setup.sh - Follow the prompts to configure your Evolution API domain and credentials.
- The script will automatically integrate with the previously deployed services.
The complete infrastructure includes:
- Traefik: Reverse proxy and SSL termination
- Portainer: Docker management UI
- PostgreSQL: Primary database server
- Redis: In-memory cache and message broker
- PgAdmin: PostgreSQL administration interface
- MinIO: S3-compatible object storage
- Evolution API: API service with full infrastructure integration
Each component is:
- Deployed as a Docker Swarm service
- Protected by Traefik's SSL/TLS encryption
- Configured with Docker secrets for sensitive data
- Using Docker volumes for persistent storage
- Accessible via custom domains through Traefik
- Check Stack Status:
docker stack ps <stack_name>(e.g.,docker stack ps traefik) - View Service Logs:
docker service logs <stack_name>_<service_name> - Update an Application: To update an application's image version, edit the corresponding
partX_..._setup.shscript, change theimage:tag in the YAML block, and re-run the script. This ensures your Git repository always reflects the true state of your server.
Important directories and volumes to backup:
- PostgreSQL data:
postgres_datavolume - MinIO data:
minio_datavolume - Evolution API instances:
evolution_datavolume - Redis data:
redis_datavolume (if persistence is enabled)
Use Docker's volume backup capabilities or configure automated backups using the respective service's backup tools.
- All services are only accessible through HTTPS
- Passwords and sensitive data are managed via Docker secrets
- Each service runs in isolation with its own network namespace
- Inter-service communication is controlled via Docker networks
- Regular updates should be performed on both the host system and containers
This setup provides a professional-grade foundation for hosting modern containerized applications securely and reliably.