setting up a VPS with Docker
Running apps in the cloud buys you reliability, reach, and easy scaling. This guide sets up a Virtual Private Server (VPS) with Docker and a simple Swarm stack, using environment variables so you can reuse the same workflow across projects.
prerequisites
Section titled “prerequisites”Before you start, define a few environment variables locally:
# Server detailsexport SERVER_IP="your-server-ip"export DOMAIN="your-domain.com"export PROJECT_NAME="your-project-name"
# User and email you will use for deployment and notificationsexport DEPLOY_USER="deploy"export DEPLOY_EMAIL="${DEPLOY_USER}@${DOMAIN}"connect to the VPS
Section titled “connect to the VPS”SSH into the freshly provisioned server:
ssh root@${SERVER_IP}install Docker
Section titled “install Docker”Once you are in, install Docker and its dependencies:
sudo apt-get updatesudo apt-get install ca-certificates curlsudo install -m 0755 -d /etc/apt/keyringssudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.ascsudo chmod a+r /etc/apt/keyrings/docker.ascecho \ "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/nullsudo apt-get updatesudo apt-get install docker-ce docker-ce-cli containerd.io -yAt this point, docker ps should work on the server.
configure DNS
Section titled “configure DNS”Create an A record pointing your domain to SERVER_IP. After DNS propagates, you can SSH using the domain instead of the raw IP:
ssh root@${DOMAIN}create a Docker context
Section titled “create a Docker context”To run Docker commands against the VPS from your local machine, create a remote Docker context:
docker context create ${PROJECT_NAME} --docker host=ssh://root@${DOMAIN}docker context use ${PROJECT_NAME}From now on, any docker ... command you run targets the VPS through this context.
initialize Docker Swarm
Section titled “initialize Docker Swarm”Turn the VPS into a single-node Swarm manager:
docker swarm init # Optionally: --advertise-addr ${SERVER_IP}Docker prints a join command with a token. Keep it somewhere safe if you plan to add worker nodes later:
# Example output, your token will differdocker swarm join --token SWMTKN-1-xxxxxxxxxxxxxxxxxxxx ${SERVER_IP}:2377deploy the application stack
Section titled “deploy the application stack”With Swarm running, deploy your stack using your docker-compose.yml (Swarm treats it as a stack file):
docker stack deploy -c docker-compose.yml ${PROJECT_NAME}If your compose file defines a service bound to port 80, your app should now respond at:
http://${DOMAIN}To inspect logs from your main service:
docker service logs ${PROJECT_NAME}_appAdjust the service name if your compose file uses something different.
wrap-up
Section titled “wrap-up”You now have:
- a VPS reachable through your own domain
- Docker installed and accessible via a remote context
- a Swarm stack deployed from
docker-compose.yml
From here you can iterate: add more services, attach extra nodes to the Swarm, set up HTTPS with a reverse proxy (Traefik, Caddy, or Nginx), and lock down the box with a non-root deploy user, firewall rules, and backups.