Docker for Beginners: How to Build, Run, and Deploy Containers on a VPS/Cloud

Docker for Beginners: How to Build, Run, and Deploy Containers on a VPS/Cloud

 Docker has become one of the most practical tools in modern software development because it solves a common problem: “It works on my laptop, but it doesn’t work on the server.” With Docker, you package your application and its dependencies into a container so it can run consistently across environments—local machine, VPS, or cloud.

This beginner-friendly guide will walk you through Docker from the ground up: what it is, how it works, how to create and run containers, and how to deploy them safely on a VPS or cloud instance.

1) What Is Docker (and What Is a Container)?

Docker in one sentence

Docker is a platform for building, shipping, and running applications inside containers.

Container vs Virtual Machine (VM)

A container is not a full virtual machine. Instead:
A VM includes a full guest OS (heavier, more resources).
A container shares the host OS kernel but isolates the app and its dependencies (lighter, faster startup).
Containers are ideal for deploying web apps, APIs, background workers, and services because they are:
Portable (same behavior anywhere)
Reproducible (same build, same result)
Isolated (dependencies won’t conflict with other apps)
Easy to roll back (deploy by version/tag)

2) Key Docker Terms You Must Know

Image

An image is a blueprint (read-only template) for a container. It includes:
your app code (optional)
runtime (Node, Python, PHP, etc.)
OS libraries
dependencies
Images are usually built from a Dockerfile.

Container

A container is a running instance of an image.
You can start/stop/restart containers without reinstalling everything.

Dockerfile

A Dockerfile is a set of instructions that tells Docker how to build an image.

Registry (Docker Hub, GHCR, etc.)

A registry is where images are stored so servers can pull them:
Docker Hub
GitHub Container Registry (GHCR)
GitLab Registry
AWS ECR, GCP Artifact Registry, etc.

Volumes

Volumes store persistent data outside the container lifecycle, useful for:
databases
uploaded files
application state that must survive restarts

3) Installing Docker (High-Level Guidance)

On a VPS/cloud instance, Docker is typically installed via official repositories. Since different Linux distros vary (Ubuntu, Debian, AlmaLinux, etc.), follow Docker’s official documentation for your OS. After installing, validate with:
docker --version
docker run hello-world
If you’re deploying professionally, also install Docker Compose (now commonly
docker compose
).

4) Basic Docker Commands (Beginner Toolkit)

Here are the commands you’ll use constantly:

Pull an image

docker pull nginx:latest

Run a container

docker run -d --name web -p 8080:80 nginx:latest
-d
runs in background (detached)
--name
gives it a readable name
-p 8080:80
maps host port 8080 → container port 80

List containers

docker ps docker ps -a

View logs

docker logs web docker logs -f web

Stop and remove

docker stop web docker rm web

Remove images

docker rmi nginx:latest

5) Creating Your First Dockerfile (Example: Node.js Web App)

Let’s assume a simple Node.js app:
package.json
server.js
listening on port
3000

Example Dockerfile

Create a file named
Dockerfile
:
FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . ENV NODE_ENV=production EXPOSE 3000 CMD ["node", "server.js"]
What this does:
Uses a lightweight Node base image
Copies dependencies first (better caching)
Installs production dependencies
Copies your app code
Exposes port 3000
Runs the app

Build the image

docker build -t myapp:1.0 .

Run it

docker run -d --name myapp -p 3000:3000 myapp:1.0
Then test:
http://YOUR_SERVER_IP:3000

6) A Better Way: Multi-Container Apps with Docker Compose

Real production apps often have multiple services:
web app
database (PostgreSQL/MySQL)
cache (Redis)
Docker Compose lets you manage them as one “stack.”

Example: App + Postgres (docker-compose.yml)

services: app: build: . container_name: myapp ports: - "3000:3000" environment: - DATABASE_URL=postgres://postgres:postgres@db:5432/mydb depends_on: - db db: image: postgres:16 container_name: mydb environment: - POSTGRES_PASSWORD=postgres - POSTGRES_DB=mydb volumes: - db_data:/var/lib/postgresql/data volumes: db_data:

Start the stack

docker compose up -d --build

Stop the stack

docker compose down

Stop and remove (including volumes)

Be careful—this deletes database data:
docker compose down -v

7) Docker Networking: How Containers Talk to Each Other

In Docker Compose, services share a network by default. That means:
The
app
container can reach the database at hostname
db
You don’t need to expose DB ports publicly
Only expose ports that must be accessed from the internet (usually 80/443 via reverse proxy)
This is a big security win compared to running everything directly on the host.

8) Deploying Containers to a VPS/Cloud (Step-by-Step)

Here’s a clean and practical deployment flow used by many teams.

Step 1: Provision your VPS / cloud VM

Choose a server near your users. Make sure you have:
SSH access
firewall rules
enough RAM/CPU for your workload

Step 2: Install Docker + Docker Compose

After installation, ensure:
Docker daemon is running
your user can run Docker (or you use sudo)

Step 3: Upload your project (Git-based workflow)

On the server:
git clone https://github.com/yourname/yourrepo.git cd yourrepo

Step 4: Create production environment variables

Do not hardcode secrets in Compose. Common approaches:
.env
file on the server (not committed to Git)
secret manager tools (more advanced)
platform environment variable systems (PaaS)
Example
.env
:
DATABASE_URL=... JWT_SECRET=...
Compose will auto-load
.env
by default in the project directory.

Step 5: Build and run

docker compose up -d --build

Step 6: Verify logs and health

docker compose ps docker compose logs -f

9) Making It Production-Ready: Reverse Proxy + HTTPS

Running your app on port 3000 is fine for testing, but production should use:
HTTPS
standard ports 80 and 443
a reverse proxy (often Nginx, Traefik, or Caddy)

Common production pattern

Reverse proxy listens on 80/443
Routes traffic to internal container ports
Terminates SSL (Let’s Encrypt)
If you’re a beginner, two approachable options:
Caddy (simple auto-HTTPS, minimal config)
Nginx + Certbot (classic, more manual)
You can run the reverse proxy as a container too, but keep configuration clean and avoid exposing internal services directly.

10) Deploy Strategy: Updating Your App Without Downtime

At minimum, you want a repeatable update process.

Simple redeploy (basic)

On the server:
git pull docker compose up -d --build
This rebuilds the image if code changed and restarts containers as needed.

Better: Tag and push images to a registry

Instead of building on the server, you can:
Build image in CI (GitHub Actions)
Push to registry (GHCR/Docker Hub)
Pull on server and restart
This is more professional because:
server doesn’t need build toolchains
deployment is faster and consistent
you can roll back by image tag

11) Docker Volumes and Backups (Critical for Databases)

If you run Postgres/MySQL in Docker, the data must persist in a volume.

Backup mindset

A container is disposable; data is not.
Good backup practices:
Scheduled database dumps (daily)
Store backups off-server (S3, another storage provider)
Test restores regularly
If you can afford it, consider managed databases (easier backups, monitoring, scaling).

12) Security Basics for Docker on a VPS

Docker simplifies deployment, but you still must secure the host.
Minimum best practices:
Keep OS packages updated
Use SSH keys, disable password auth if possible
Configure firewall: expose only 80/443 (and maybe SSH)
Do not publish database ports publicly (avoid
-p 5432:5432
unless necessary)
Use strong secrets (not “admin123”)
Limit container privileges (avoid
--privileged
unless required)
Monitor logs and disk usage (containers can fill disk with logs)
Also: never expose the Docker daemon port to the internet.

13) Common Beginner Mistakes (and How to Avoid Them)

Putting secrets in the Dockerfile
Docker images can be shared. Keep secrets in env vars, not inside images.
Not using volumes for databases
If the container is removed, your data disappears unless stored in a volume.
Publishing every service port
Only publish what must be publicly accessible.
Using
latest
everywhere
Pin versions for reliability:
postgres:16
node:20-alpine
nginx:1.26
Ignoring logs and monitoring
At least set up basic log review and uptime checks.

Conclusion

Docker is one of the best technologies a beginner can learn for modern deployment. It helps you package apps reliably, run them consistently, and deploy them to VPS/cloud environments with fewer “it broke in production” surprises.
To get started confidently:
learn the core concepts (image, container, Dockerfile, volume)
build and run locally
use Docker Compose for multi-service apps
deploy to a VPS with a secure configuration
add HTTPS and a reverse proxy for real production use
With these fundamentals, you’ll be able to deploy everything from a simple website to a full production API stack in a clean, repeatable way.

Komentar

Postingan populer dari blog ini

Free CI/CD with GitHub Actions: Automatically Build, Test, and Deploy to a VPS