<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: lam duc</title>
    <description>The latest articles on DEV Community by lam duc (@lam_duc_5c2dc399e5f92f4bb).</description>
    <link>https://dev.to/lam_duc_5c2dc399e5f92f4bb</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4170396%2Fb78c30cf-9c4b-4cb1-ba1b-a3bfb616c8a4.png</url>
      <title>DEV Community: lam duc</title>
      <link>https://dev.to/lam_duc_5c2dc399e5f92f4bb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lam_duc_5c2dc399e5f92f4bb"/>
    <language>en</language>
    <item>
      <title>Hướng dẫn triển khai Docker cho ứng dụng Node.js (Cho người mới bắt đầu)</title>
      <dc:creator>lam duc</dc:creator>
      <pubDate>Fri, 09 Oct 2026 06:55:40 +0000</pubDate>
      <link>https://dev.to/lam_duc_5c2dc399e5f92f4bb/huong-dan-trien-khai-docker-cho-ung-dung-nodejs-cho-nguoi-moi-bat-dau-3383</link>
      <guid>https://dev.to/lam_duc_5c2dc399e5f92f4bb/huong-dan-trien-khai-docker-cho-ung-dung-nodejs-cho-nguoi-moi-bat-dau-3383</guid>
      <description>&lt;p&gt;Docker đã trở thành một công cụ không thể thiếu giúp chuẩn hóa môi trường phát triển và triển khai ứng dụng. Đối với các lập trình viên Node.js, việc đưa ứng dụng vào container giúp tránh được lỗi "chạy được trên máy tôi nhưng lỗi trên server".&lt;/p&gt;

&lt;p&gt;Trong bài viết này, chúng ta sẽ từng bước xây dựng một Dockerfile cơ bản, build image, chạy container và cấu hình các biến môi trường một cách an toàn.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Chuẩn bị ứng dụng Node.js đơn giản
&lt;/h3&gt;

&lt;p&gt;Giả sử bạn có một ứng dụng Node.js cơ bản sử dụng Express. &lt;/p&gt;

&lt;p&gt;File &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node-docker-demo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"index.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node index.js"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"express"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.18.2"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;File &lt;code&gt;index.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Hello World từ Docker! Môi trường: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Ứng dụng đang chạy trên cổng &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. Tạo file &lt;code&gt;.dockerignore&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Trước khi viết Dockerfile, bạn cần tạo một file &lt;code&gt;.dockerignore&lt;/code&gt; ở thư mục gốc của dự án. File này ngăn không cho các thư mục không cần thiết (như &lt;code&gt;node_modules&lt;/code&gt; hoặc file log) bị copy vào trong Docker image, giúp giảm dung lượng image và tăng tốc độ build.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node_modules
npm-debug.log
Dockerfile
.dockerignore
.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3. Viết Dockerfile cơ bản
&lt;/h3&gt;

&lt;p&gt;Tạo một file tên là &lt;code&gt;Dockerfile&lt;/code&gt; (không có phần mở rộng) tại thư mục gốc của dự án:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Bước 1: Chọn base image chính thức của Node.js (sử dụng phiên bản LTS và bản rút gọn alpine để tối ưu dung lượng)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:18-alpine&lt;/span&gt;

&lt;span class="c"&gt;# Bước 2: Thiết lập thư mục làm việc bên trong container&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/app&lt;/span&gt;

&lt;span class="c"&gt;# Bước 3: Sao chép package.json và package-lock.json (nếu có) trước&lt;/span&gt;
&lt;span class="c"&gt;# Điều này giúp tận dụng Docker layer cache khi không có thay đổi về dependency&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;

&lt;span class="c"&gt;# Bước 4: Cài đặt các dependencies&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--only&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production

&lt;span class="c"&gt;# Bước 5: Sao chép toàn bộ mã nguồn vào container&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="c"&gt;# Bước 6: Khai báo port mà container sẽ lắng nghe khi chạy&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;

&lt;span class="c"&gt;# Bước 7: Lệnh để khởi chạy ứng dụng&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; [ "npm", "start" ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  4. Build Docker Image
&lt;/h3&gt;

&lt;p&gt;Mở terminal tại thư mục chứa Dockerfile và chạy lệnh sau để build image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; node-docker-demo:1.0 &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Trong đó:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-t node-docker-demo:1.0&lt;/code&gt;: Đặt tên (tag) cho image là &lt;code&gt;node-docker-demo&lt;/code&gt; với phiên bản &lt;code&gt;1.0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.&lt;/code&gt;: Chỉ định ngữ cảnh build (build context) là thư mục hiện tại.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  5. Chạy Docker Container và Truyền Biến Môi Trường
&lt;/h3&gt;

&lt;p&gt;Sau khi build thành công, bạn có thể khởi chạy container từ image vừa tạo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:3000 &lt;span class="nt"&gt;--name&lt;/span&gt; my-node-app &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;NODE_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production node-docker-demo:1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Giải thích các tham số:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt;: Chạy container dưới nền (detached mode).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-p 8080:3000&lt;/code&gt;: Ánh xạ cổng &lt;code&gt;8080&lt;/code&gt; của máy host vào cổng &lt;code&gt;3000&lt;/code&gt; bên trong container.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--name my-node-app&lt;/code&gt;: Đặt tên cho container đang chạy để dễ quản lý.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-e NODE_ENV=production&lt;/code&gt;: Truyền biến môi trường vào ứng dụng.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;node-docker-demo:1.0&lt;/code&gt;: Tên image và tag đã build ở bước trước.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bây giờ, bạn có thể truy cập &lt;code&gt;http://localhost:8080&lt;/code&gt; trên trình duyệt để kiểm tra kết quả.&lt;/p&gt;




&lt;h3&gt;
  
  
  6. Các lưu ý quan trọng về bảo mật và tối ưu hóa
&lt;/h3&gt;

&lt;p&gt;Khi triển khai thực tế, lập trình viên cần lưu ý các điểm sau để đảm bảo an toàn cho ứng dụng:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Không chạy container bằng quyền root:&lt;/strong&gt;
Mặc định, các container Node.js chạy với quyền root. Điều này tiềm ẩn rủi ro bảo mật lớn. Image Node.js chính thức đã có sẵn một user bảo mật tên là &lt;code&gt;node&lt;/code&gt;. Hãy chuyển sang user này trước khi khởi chạy ứng dụng bằng cách thêm dòng sau vào trước lệnh &lt;code&gt;CMD&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;   USER node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sử dụng phiên bản Node.js cụ thể:&lt;/strong&gt;&lt;br&gt;
Tránh sử dụng tag &lt;code&gt;latest&lt;/code&gt; (ví dụ: &lt;code&gt;FROM node&lt;/code&gt;). Hãy luôn chỉ định rõ phiên bản ổn định (như &lt;code&gt;node:18-alpine&lt;/code&gt; hoặc &lt;code&gt;node:20-slim&lt;/code&gt;) để đảm bảo tính nhất quán trên mọi môi trường.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Quản lý biến môi trường nhạy cảm:&lt;/strong&gt;&lt;br&gt;
Không bao giờ lưu các thông tin nhạy cảm như API key, mật khẩu cơ sở dữ liệu trực tiếp trong &lt;code&gt;Dockerfile&lt;/code&gt;. Hãy truyền chúng qua tham số &lt;code&gt;-e&lt;/code&gt; khi chạy container, hoặc sử dụng các file &lt;code&gt;.env&lt;/code&gt; để bảo mật thông tin tốt hơn.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
  </channel>
</rss>
