Docker revolutionizes application deployment by packaging your software, dependencies, and configuration into portable containers that run consistently across any environment. Whether you are deploying a web application, microservice architecture, or development environment, Docker on your SakuraHost VPS provides isolation, reproducibility, and simplified management.
Prerequisites: A SakuraHost VPS with Ubuntu 22.04+ and sudo access. We recommend at least 2 GB RAM for running Docker containers comfortably. Check our VPS plans at
sakurahost.co.tz.
1. Installing Docker Engine
Always install Docker from the official Docker repository rather than the Ubuntu default packages to get the latest version.
Remove any old Docker packages and install prerequisites:
sudo apt remove docker docker-engine docker.io containerd runc 2>/dev/null
sudo apt update
sudo apt install ca-certificates curl gnupg lsb-release -y
Add Docker's official GPG key and repository:
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Install Docker Engine and Docker Compose:
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
Add your user to the docker group (avoids needing sudo for every command):
sudo usermod -aG docker $USER
newgrp docker
Verify the installation:
docker --version
docker compose version
docker run hello-world
2. Docker Fundamentals
Essential Docker Commands
# Pull an image from Docker Hub
docker pull nginx:latest
# Run a container
docker run -d --name my-nginx -p 80:80 nginx:latest
# List running containers
docker ps
# List all containers (including stopped)
docker ps -a
# View container logs
docker logs my-nginx
# Stop and remove a container
docker stop my-nginx
docker rm my-nginx
# Remove unused images, containers, and volumes
docker system prune -a
Understanding Docker Volumes
Volumes persist data outside the container lifecycle, ensuring your data survives container restarts and updates:
# Create a named volume
docker volume create mydata
# Run a container with a volume mount
docker run -d --name mydb -v mydata:/var/lib/mysql mysql:8
# Bind mount a host directory
docker run -d --name web -v /var/www/html:/usr/share/nginx/html nginx
3. Building Custom Docker Images
A Dockerfile defines how your application's container image is built. Here is a production-ready example for a Node.js application:
# Dockerfile
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM node:22-alpine
WORKDIR /app
RUN addgroup -g 1001 -S nodejs && adduser -S nextjs -u 1001
COPY --from=builder /app/node_modules ./node_modules
COPY . .
USER nextjs
EXPOSE 3000
CMD ["node", "server.js"]
Build and run the image:
docker build -t myapp:latest .
docker run -d --name myapp -p 3000:3000 --restart unless-stopped myapp:latest
Multi-Stage Builds: The example above uses a multi-stage build to keep the final image small. The builder stage installs dependencies, and only the production artifacts are copied to the final image.
4. Docker Compose for Multi-Container Applications
Docker Compose orchestrates multiple containers as a single application stack. Create a docker-compose.yml file:
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=mysql://root:secret@db:3306/myapp
depends_on:
db:
condition: service_healthy
restart: unless-stopped
networks:
- app-network
db:
image: mysql:8
volumes:
- mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: myapp
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
networks:
- app-network
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- web
restart: unless-stopped
networks:
- app-network
volumes:
mysql-data:
networks:
app-network:
driver: bridge
Manage the stack:
# Start all services
docker compose up -d
# View logs
docker compose logs -f
# Stop all services
docker compose down
# Rebuild and restart
docker compose up -d --build
5. Container Security Best Practices
Security Matters: Containers share the host kernel. A misconfigured container can compromise your entire VPS.
- Never run containers as root - use the
USER directive in your Dockerfile
- Use official base images - preferably Alpine variants for smaller attack surfaces
- Scan for vulnerabilities - run
docker scout cves myapp:latest
- Limit resources - set memory and CPU limits with
--memory=512m --cpus=1.0
- Use Docker secrets for sensitive data instead of environment variables
- Keep Docker updated -
sudo apt update && sudo apt upgrade docker-ce
6. Docker Maintenance
# View disk usage by Docker
docker system df
# Clean up all unused resources
docker system prune -a --volumes
# Update a running container to a new image
docker compose pull
docker compose up -d