Back to articles
Technology Insight

Deploying Applications with Docker on VPS

April 13, 2026
Deploying Docker Applications on VPS

Deploying Applications with Docker on VPS: A Complete A-Z Guide

In the era of cloud computing, traditional server management—installing software directly onto the operating system—is increasingly revealing its limitations in flexibility and scalability. This is where Docker and Containerization technology emerge as lifesavers. Deploying applications via Docker on a VPS not only helps you avoid the "it works on my machine" syndrome but also makes migration between VPS providers like Vultr, DigitalOcean, or Google Cloud simpler than ever before.

1. Understanding Docker and Its Benefits on VPS

Docker is an open-source platform that allows you to package an application along with all its libraries, dependencies, and configurations into a single unit called a Container. When running on a VPS, Docker provides a lightweight virtualization layer, helping you maximize hardware resources while ensuring complete isolation between services.

  • Consistency: The environment on your VPS will be identical to your local development machine.
  • Easy Scalability: You can spin up 10 identical containers with just one command.
  • Resource Management: Set RAM/CPU limits for specific services to prevent one crashing app from taking down the entire server.

2. Guide to Installing Docker on Linux VPS (Ubuntu 22.04/24.04)

To begin, access your VPS via SSH. Ensure your system is updated with the latest security patches.


// Simulating a TypeScript script to automate Docker version verification post-installation
interface DockerInfo {
    version: string;
    isActive: boolean;
    storageDriver: string;
}

function verifyDockerInstallation(rawOutput: string): DockerInfo {
    const isInstalled = rawOutput.includes("Docker version");
    return {
        version: isInstalled ? "24.0.7" : "Not Found",
        isActive: isInstalled,
        storageDriver: "overlay2"
    };
}

const status = verifyDockerInstallation("Docker version 24.0.7, build afdd53b");
console.log(`Docker Status: ${status.isActive ? "Ready" : "Error"}`);
    

Manual Installation Steps

1. Update the package index and install necessary dependencies:

sudo apt update && sudo apt install apt-transport-https ca-certificates curl software-properties-common

2. Add Docker's official GPG key:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

3. Install Docker Engine:

sudo apt install docker-ce docker-ce-cli containerd.io

3. Docker Compose - Managing Multi-Container Stacks

Most real-world web applications do not run in isolation. They require databases (MySQL, MongoDB), caching (Redis), and web servers (Nginx). Docker Compose allows you to define this entire infrastructure in a single docker-compose.yml file.


// Defining a data structure for a hypothetical Docker Compose file
interface ServiceConfig {
    image: string;
    ports: string[];
    environment?: Record;
    volumes?: string[];
    networks: string[];
}

interface DockerCompose {
    version: string;
    services: Record;
}

const myAppStack: DockerCompose = {
    version: "3.8",
    services: {
        web_app: {
            image: "my-nestjs-app:latest",
            ports: ["3000:3000"],
            networks: ["backend"],
            environment: { "NODE_ENV": "production" }
        },
        database: {
            image: "postgres:15-alpine",
            ports: ["5432:5432"],
            networks: ["backend"],
            volumes: ["db_data:/var/lib/postgresql/data"]
        }
    }
};

console.log("Infrastructure defined and ready to launch with 'docker-compose up -d'");
    

4. Packaging Your Application (Dockerfile)

To run your application in a container, you need to create a Dockerfile. This is the "recipe" that instructs Docker on how to build the Image for your app.

Dockerfile Command Description Example
FROM Selects the base image node:18-alpine
WORKDIR Sets the working directory /app
COPY Copies files from VPS to container package.json .
RUN Executes commands during image build npm install
CMD Initial command when container starts npm start

// Function simulating dynamic Dockerfile generation for a Node.js app
function generateDockerfile(nodeVersion: string, entryPoint: string): string {
    return `
    FROM node:${nodeVersion}-slim
    WORKDIR /usr/src/app
    COPY package*.json ./
    RUN npm install --production
    COPY . .
    EXPOSE 8080
    CMD ["node", "${entryPoint}"]
    `;
}

console.log(generateDockerfile("20", "dist/main.js"));
    

5. Data Management with Docker Volumes

A crucial characteristic of containers is that they are "ephemeral." If a container is deleted, all data inside it is lost. To solve this on a VPS, we use Volumes or Bind Mounts.

Example: When deploying a MySQL database, you must mount the MySQL storage directory inside the container to a physical directory on the VPS hard drive. This ensures that when you update to a new MySQL version, your customer data remains safe.

6. Reverse Proxy and Security with Nginx Proxy Manager

When running multiple web containers on the same VPS, how do you map different domains (e.g., app1.com, app2.com) to the correct containers? The answer is using a Reverse Proxy.

Nginx Proxy Manager is a Docker-based tool with a web interface that helps you manage proxy records and automatically renew Let's Encrypt SSL certificates with just a few clicks. This is a mandatory step for your website to meet secure HTTPS standards.


// TypeScript logic simulating request routing from a Reverse Proxy
interface ProxyRoute {
    domain: string;
    containerIp: string;
    internalPort: number;
    useSSL: boolean;
}

const routes: ProxyRoute[] = [
    { domain: "api.thaovien.com", containerIp: "172.18.0.5", internalPort: 3000, useSSL: true },
    { domain: "vps-sales.com", containerIp: "172.18.0.7", internalPort: 80, useSSL: true }
];

routes.forEach(route => {
    console.log(`Routing ${route.domain} to container ${route.containerIp}:${route.internalPort}`);
});
    

7. Optimizing Docker Performance on VPS

Deployment is not the end. To ensure your system runs stably 24/7, perform these optimization steps:

  • Clean up unused resources: Run docker system prune -a weekly to delete unused images and free up disk space.
  • Use Alpine Images: Prioritize base images with the -alpine suffix to reduce image sizes from hundreds of MBs to just a few dozen MBs.
  • Logging driver: Configure log file size limits in daemon.json to prevent log files from bloating and filling up your VPS storage.

8. Backup and Recovery Strategy

With Docker on a VPS, backups become highly structured. You only need to back up two things:

  1. All configuration files, including .env and docker-compose.yml.
  2. Data stored in Volume-mapped directories.

With these two components, you can restore your entire system on a brand-new VPS in less than 5 minutes.

9. Conclusion

Docker is not just a tool; it is a new mindset for application deployment. By applying Docker to your VPS, you have upgraded yourself from a "server admin" to a true "DevOps Engineer." Packaging everything into containers makes your system organized, secure, and incredibly easy to scale in the future.

Start by converting your smallest application to Docker today. Good luck on your journey to mastering container virtualization!