Skip to content
KhaiziNam Blog KhaiziNam Blog
Go back
Đọc bằng tiếng Việt

Optimizing Project Environment Setup Time with Docker for Low-Config VPS

1. What is Optimizing Project Environment Setup Time with Docker?

Optimizing project environment setup time with Docker is a method of using Containerization technology to package all software, libraries, and system configurations into a single unit called a “Container.” Instead of installing directly onto the operating system (Native Install) — a process that often causes version conflicts and is difficult to manage — Docker creates isolated, lightweight environments that run consistently across any server.

For low-configuration VPS lines, especially those running Debian (known as the lightest and most stable Linux distribution), optimizing Docker helps you squeeze every bit of hardware performance without overloading the system. Instead of installing dozens of scattered service packages, you only need to define everything through source code configuration files.

Read more:

Why is Debian the optimal choice for Docker on weak VPS?

When performing project environment setup optimization with Docker, the core goal is not just deployment speed (taking only seconds with the docker-compose up command), but also resource control. You can specify exactly how many MB of RAM for each service, ensuring that even on a 2 Core 2GB RAM VPS, the system operates smoothly without ever crashing.

Combining the leanness of Debian with the packaging power of Docker is the “golden formula” for web developers to manage infrastructure professionally at the lowest cost.


2. “Swap RAM” Lifesaver - How to Create 2GB Virtual RAM on Debian for Low-Config VPS

When working with a VPS with only 2GB RAM, running Nginx, PHP-FPM, MySQL, and Redis simultaneously is a major challenge. Just one complex MySQL query or a bot crawl can overflow the physical RAM, leading to the Out of Memory (OOM) Killer automatically disconnecting critical processes to protect the system. This is why you need to set up Swap immediately.

What is Swap RAM and why is it important?

Swap is a space on the hard drive (SSD/NVMe) used by the operating system to simulate RAM. When physical RAM is full, the system pushes less-used data from RAM to Swap to make room for priority tasks. For a 2GB RAM Debian VPS, adding 2GB Swap gives the system a total of 4GB virtual memory, creating an “oxygen tank” that prevents the server from freezing during overload.

Detailed Guide to Creating 2GB Swap on Debian

Copy and run the following commands in the Terminal with root privileges:

# 1. Check if the system already has Swap swapon —show

2. Create a swap file with 2GB capacity

sudo fallocate -l 2G /swapfile

3. Set permissions so only Root User can access (ensure security)

sudo chmod 600 /swapfile

4. Set this file to Swap format

sudo mkswap /swapfile

5. Activate Swap immediately

sudo swapon /swapfile

6. Set Swap to automatically activate every time the VPS reboots

echo ‘/swapfile none swap sw 0 0’ | sudo tee -a /etc/fstab

Check the Results

After running the commands, use the free -h command. You will see the “Swap” line displaying approximately 2.0Gi, confirming that your environment optimization was successful.

Expert Note: While Swap is very useful, SSD read/write speeds are always slower than physical RAM. Do not abuse Swap to completely replace RAM; our main goal remains optimizing project environment setup time with Docker so that containers use resources efficiently within the 2GB physical RAM limit.


3. Standardized Project Directory Structure for Docker

To professionally optimize project environment setup time with Docker, scientific file organization is mandatory. Instead of mixing configuration files with source code, we separate the “infrastructure” (DevOps) from the “application” (Source Code). This approach not only keeps the project cleaner but also makes future maintenance or upgrades much simpler.

3.1 Optimal Directory Structure Diagram

Here is the directory structure I recommend for projects running on a 2GB RAM VPS:

my-project/ ├── docker-compose.yml # Main service orchestration file (Root) ├── .env # Stores environment variables, DB passwords (Secure) ├── src/ # Entire application source code (PHP, Laravel, etc.) └── docker/ # Contains isolated infrastructure configurations ├── nginx/ │ └── default.conf # Web Server configuration ├── php/ │ └── Dockerfile # Script to build specific PHP environment └── mysql/ ├── my.cnf # RAM optimization config for MariaDB └── data/ # Data storage directory (Bind Mount)

3.2 Why split the structure this way?

3.3 Explaining the .env file at Root

In the process of optimizing project environment setup time with Docker, security is paramount. Instead of hard-coding MySQL passwords into the docker-compose.yml file, we put them in the .env file. This file will not be pushed to Git, ensuring your server’s sensitive information remains secure.

Pro Tip: Placing the docker-compose.yml file in the root directory allows you to run Docker commands fastest as soon as you SSH into the project folder, saving maximum time in the Terminal.


4. Detailed Guide to Optimizing Docker-Compose for 2GB RAM VPS

This is the most critical part of optimizing project environment setup time with Docker. The configuration file below has been fine-tuned to run smoothly on Debian, with strict Resource Limits to protect the VPS from freezing.

4.1 Cấu hình file docker-compose.yml (Standard Template)

Create the docker-compose.yml file at the project root with the following content:

version: ‘3.8’

services:

Web Server (Ultra-lightweight Nginx Alpine)

nginx: image: nginx:alpine container_name: web_server restart: always ports: - “80:80” volumes: - ./src:/var/www/html - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - php networks: - backend

PHP Engine (Built from Dockerfile in docker/ directory)

php: build: context: . dockerfile: docker/php/Dockerfile container_name: php_app restart: always volumes: - ./src:/var/www/html deploy: resources: limits: memory: 512M # Max RAM limit for PHP networks: - backend

Database (MariaDB is more optimized for low RAM than MySQL)

db: image: mariadb:10.6 container_name: database restart: always environment: MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} MYSQL_DATABASE: ${DB_NAME} # Bind Mount: Map data outside so it’s not lost when container stops volumes: - ./docker/mysql/data:/var/lib/mysql command: [ ‘mysqld’, ‘—innodb-buffer-pool-size=256M’, # Optimized for 2GB RAM VPS ‘—performance_schema=OFF’ # Disable to save an extra 100MB RAM ] deploy: resources: limits: memory: 800M networks: - backend

networks: backend: driver: bridge

4.2 Explaining the Data Bind Mount mechanism (MySQL Data)

In the configuration above, the line - ./docker/mysql/data:/var/lib/mysql is the Bind Mount technique. This is the key to protecting your data:

4.3 Optimizing MariaDB Parameters

To optimize project environment setup time with Docker on a 2GB VPS, we intervene directly in the startup command:


5. Common Mistakes Using Docker on Weak VPS and How to Fix Them

Deploying projects on resource-limited environments like 2GB RAM requires precision. During my community support and website optimization work, I’ve noticed 5 classic errors that lead to system instability. Here is how you can avoid them:

5.1 Using “Latest” Images or Bulky Images

5.2 Forgetting Resource Limits

Without the deploy: resources: limits line, a faulty or attacked container can “eat” 100% of the CPU and RAM, preventing you from SSH-ing into the VPS. 
Fix: Always set hard RAM limits for each service as shown in Section 4.

5.3 Excessive Log Storage Filling the Disk

Docker defaults to recording all container logs into JSON files. On cheap VPS lines with only 20GB - 40GB SSDs, these logs can bloat to dozens of GBs, leading to a total crash. 
Fix: Add logging configuration to your docker-compose.yml to limit log size.

5.4 Not Taking Advantage of Dockerfile Caching

If the Dockerfile isn’t optimized, Docker has to re-download all libraries from scratch every time you change code. 
Fix: Place system library installation commands (rarely changed) at the top of the Dockerfile, and Source Code copy commands (frequently changed) at the bottom.

5.5 Running Docker with Reckless Root Privileges

For convenience, many run everything as Root. If a container is hacked, the attacker can gain control of the VPS. 
Fix: Learn to define User in the Dockerfile and use .env files for sensitive data.


6. Frequently Asked Questions (FAQ) about Operating Docker on 2GB RAM VPS

Q: Which command should I use to monitor the RAM of running Containers?

A: Use the docker stats command. This displays a real-time table of CPU %, RAM usage, and the Limits you’ve set.

Q: Why did I create Swap but free -h still shows physical RAM almost full?

A: This is normal Linux behavior. The OS prioritizes using all physical RAM before pushing data to Swap. As long as the “Swap” line shows usage (used > 0) when RAM is full, your system is protected from crashing.

Q: Can I install management interfaces like Portainer on a 2GB RAM VPS?

A: Yes, but consider it carefully. Portainer consumes about 100MB - 150MB of RAM. It’s better to get used to the Docker CLI to save resources.

Q: How do I update new code without website interruption (Zero Downtime)?

A: When you change code in the src/ directory, simply run: 
docker-compose up -d --build 
Docker will only rebuild the changes and restart the container quickly.

Q: Should I install the Database directly on the VPS (Native) to save RAM?

A: No. While Native might save a tiny amount of Docker overhead, you lose Resource Limits. With Docker, you ensure MySQL never exceeds 800MB RAM.


7. Troubleshooting & Common Errors Q&A

Q: I get a “Killed” or “Exit 137” error when running docker-compose up, what is it?

A: This is a classic sign of Out of Memory (OOM). The OS killed the Docker process to protect the VPS. 
Solution: Check if Swap is active. If it is, lower the mem_limit for MySQL or PHP in docker-compose.yml.

Q: Why can’t I connect from management tools (like Navicat/DBeaver) to MySQL in Docker?

A: Two common reasons: You haven’t opened port 3306 in the ports section of docker-compose.yml, or the VPS firewall is blocking port 3306.

Q: I edited PHP code but the changes don’t appear in the browser?

A: You likely have OPcache or Nginx caching enabled. 
Solution: Disable OPcache in php.ini for Development, or run docker restart php_app to clear it in Production.

Q: MySQL container reports “InnoDb: Bytes writes failed” or “No space left on device”?

A: Your VPS disk is full. Docker doesn’t automatically delete old images/volumes. 
Solution: Clean up periodically with: 
docker system prune -a --volumes

Q: How do I auto-restart containers if the VPS reboots unexpectedly?

A: Ensure each service has the configuration: restart: always. This ensures Docker Engine reactivates your environment upon Debian boot.

Conclusion

Optimizing project environment setup time with Docker on a modest VPS is easy if you follow the principles: Use Debian + Create Swap + Limit Container RAM + Bind Mount Data. I hope this guide helps you confidently deploy your projects professionally and cost-effectively.

If you need a total solution for infrastructure or SEO to boost your project’s revenue, connect with me at khaizinam.io.vn. Good luck!

See also:


Share this post:

Related Posts

Secrets to Deploying React/Node.js on a 1GB RAM VPS with PM2: Never Run Out of Memory 2026

For web developers, owning a 1GB RAM VPS at a low cost is an ideal starting point. However, in practice, deployment often turns into a "nightmare" when applications constantly crash for no apparent reason. The core of the problem lies in the following two key factors:

Deploy PHP, Laravel, CodeIgniter on Linux VPS with Nginx + MySQL Docker + SSL 2026

You just spun up a Linux VPS and you're staring at a blank terminal not knowing where to start? Shared hosting works fine for simple PHP — but the moment you need to control PHP versions, configure MySQL your way, or run a Laravel queue worker, shared hosting falls short.

How to Deploy Node.js and React Apps on Linux Hosting with Nginx Reverse Proxy (PM2 + SSL Guide 2025)

You built a Node.js API or React app and now you're staring at a blank Linux VPS wondering how to actually get it live. Uploading files to shared hosting won't work here — Node.js needs a process manager, a reverse proxy, and proper server configuration to run reliably in production. This guide walks you through the complete deployment stack: PM2 to keep your app alive

IT Fresher & Junior Salary 2026: PHP, Node.js, React, Flutter - Real Market Data

Real salary benchmarks for IT freshers and junior developers in Vietnam in 2026, broken down by tech stack - so you know exactly what number to quote in interviews, or whether you're being underpaid right now.

IT Salary Levels in Ho Chi Minh City and Hanoi (2025 - 2026 Overview)

The IT industry in Vietnam continues to maintain a higher salary range compared to many other industries, especially in Ho Chi Minh City and Hanoi. These two cities are currently the country’s largest technology recruitment hubs, attracting outsourcing companies, product-based firms, fintech businesses, AI startups, and international tech corporations.

Salary Negotiation for Fresh IT Graduates: Stop Leaving Money on the Table

Salary negotiation for IT freshers is the process of discussing and adjusting your compensation after receiving a job offer — a step that most new graduates skip entirely because they believe "freshers have no bargaining power." The reality is the opposite: nearly every company builds a negotiation buffer into their offers even for entry-level candidates, and not negotiating means you're leaving m

Junior Developer Portfolio: What to Include to Get Interview Calls

A junior developer portfolio is the collection of real projects, skills, and professional information you present so employers can evaluate your abilities — substituting for the work experience section of your CV that's currently empty. For freshers and junior developers, a portfolio isn't something that's "nice to have" — it's the only evidence you can offer to prove you can actually build things

How to Write a Junior Developer Cover Letter With No Experience

Learn how to write a junior developer cover letter with no experience, including practical templates, real examples, common mistakes, and tips to pass the CV screening round.

I Failed My IT Job Interview — Here's What I Changed to Get Hired

Getting rejected from an IT job interview is something almost every fresher and junior developer goes through at least once — usually more. That first rejection can make you question your abilities, but in the vast majority of cases, interview failures have specific, identifiable, fixable causes that can be addressed in a matter of weeks if you know where to look.

Body Language in Tech Interviews: 7 Mistakes That Cost You the Offer

Body language in tech interviews refers to the non-verbal signals — posture, eye contact, hand gestures, and vocal tone — that recruiters observe alongside your technical answers. Mastering these signals helps you project confidence and professionalism from the very first second you walk into the room.


Previous Post
Nginx Configuration Guide: HTTP, HTTPS, Proxy Pass
Next Post
TeamSoHoa.com: Discover the Fascinating World of Technology & Life