Running applications in the cloud gives you reliability, accessibility, and the power to scale. In this guide, I'll walk through setting up a Virtual Private Server (VPS) with Docker, using environment variables to make this guide reusable for your own projects.

Prerequisites

Before we begin, set these variables according to your project:

# Your server details
export SERVER_IP="your-server-ip"
export DOMAIN="your-domain.com"
export PROJECT_NAME="your-project-name"

# User credentials for deployment
export DEPLOY_USER="deploy"
export DEPLOY_EMAIL="${DEPLOY_USER}@${DOMAIN}"

🔑 Connecting to Your VPS

First, connect to your newly provisioned server:

ssh root@${SERVER_IP}

🔧 Installing Docker

After connecting to the server, install Docker:

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
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo \"${UBUNTU_CODENAME:-$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 -y

🌐 Configuring DNS

Create a DNS A record pointing your domain to the server IP. Once propagated, you can SSH using the domain:

ssh root@${DOMAIN}

🐳 Creating a Docker Context

To make working with remote Docker commands easier, create a Docker context:

docker context create ${PROJECT_NAME} --docker host=ssh://root@${DOMAIN}
docker context use ${PROJECT_NAME}

Now all Docker commands will run on the VPS via this context.

🚀 Setting Up Docker Swarm

Initialize Docker Swarm on your VPS:

docker swarm init # Optionally add: --advertise-addr ${SERVER_IP}

The command will output a join token. Save this for adding worker nodes later if needed:

# Example output - your token will be different
docker swarm join --token SWMTKN-1-xxxxxxxxxxxxxxxxxxxx ${SERVER_IP}:2377

📦 Deploying Your Application Stack

Deploy your application stack using docker-compose:

docker stack deploy -c docker-compose.yml ${PROJECT_NAME}

Your application should now be accessible at:

http://${DOMAIN}

To check service logs:

docker service logs ${PROJECT_NAME}_app

👤 Creating a Deployment User

For better security, create a dedicated deployment user:

adduser ${DEPLOY_USER}
# Set a password when prompted
usermod -aG docker ${DEPLOY_USER}
su - ${DEPLOY_USER}

🔐 SSH Key Setup for Deployment

Generate an SSH key for the deployment user:

ssh-keygen -t ed25519 -C "${DEPLOY_EMAIL}"

Add the key to your local SSH agent:

ssh-add /path/to/your/private/key

Test the connection:

ssh ${DEPLOY_USER}@${DOMAIN}

🔄 Continuous Deployment

Now you have a solid foundation for implementing continuous deployment:

  1. Add the deployment user's public key to your CI/CD platform
  2. Configure your CI/CD pipeline to deploy to your swarm
  3. Push changes to your repository to trigger automatic deployments

🔒 Additional Security Considerations

Consider these additional security measures:

  • Configure a firewall (UFW)
  • Set up SSL with Let's Encrypt
  • Disable password authentication for SSH
  • Implement regular backups

Conclusion

You now have a production-ready Docker environment on your VPS with a secure deployment user. This setup provides a solid foundation for running containerized applications in production with proper separation of concerns.

Happy deploying!