Skip to content
Trung Tiến
HomeBlogProjectsToolsCoursesAboutContact
vi
✦

Trung Tiến

Technology in service of all beings

BlogProjectsCoursesAboutContact

© 2026

← ← Back to courses
Lessons 6/6⏱️ 30 min

Real-world Project — Fullstack App

5/6

📐Tổng quan

Xây dựng Node.js + Express kết nối PostgreSQL, chạy hoàn toàn bằng Docker. Tổng hợp kiến thức: image, volume, network, Dockerfile, Compose.

📁Cấu trúc dự án

Project structure
fullstack-app/
├── docker-compose.yml
├── Dockerfile
├── server.js
├── package.json
└── init.sql

🗄️1. Database init

init.sql
CREATE TABLE IF NOT EXISTS users (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(100) UNIQUE NOT NULL
);
INSERT INTO users (name, email) VALUES
  ('Alice', 'alice@example.com'), ('Bob', 'bob@example.com');

⚡2. Express server

server.js
const express = require('express');
const { Pool } = require('pg');
const app = express();
const pool = new Pool({
  host: process.env.DB_HOST || 'db',
  user: 'postgres', password: process.env.DB_PASSWORD,
  database: 'fullstack',
});
app.get('/', async (req, res) => {
  const { rows } = await pool.query('SELECT * FROM users');
  res.json({ message: 'Hello from Docker!', users: rows });
});
app.listen(3000, () => console.log('Running on 3000 🐳'));
package.json
{ "name": "fullstack-app", "scripts": { "start": "node server.js" },
  "dependencies": { "express": "^4.21.0", "pg": "^8.13.0" } }

🔨3. Dockerfile & Compose

Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
docker-compose.yml
services:
  app:
    build: .
    ports: ["3000:3000"]
    environment: { DB_HOST: db, DB_PASSWORD: secret123 }
    depends_on: [db]
  db:
    image: postgres:16-alpine
    volumes:
      - pg-data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    environment: { POSTGRES_PASSWORD: secret123, POSTGRES_DB: fullstack }
volumes: { pg-data: }

🚀Chạy & Debug

Run & debug
docker compose up -d
curl http://localhost:3000
# {"message":"Hello from Docker!","users":[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}]}

docker exec -it app sh     # Vào container
docker logs -f app         # Logs realtime
docker system prune -a     # Dọn sạch
docker compose down        # Dừng toàn bộ

✅Tổng kết

  • ✅ Images: pull, search, tag, rmi
  • ✅ Containers: run, ps, stop, rm, exec, logs
  • ✅ Volumes: bind mount, named volume
  • ✅ Dockerfile: FROM, WORKDIR, COPY, RUN, CMD
  • ✅ Compose: services, ports, volumes, depends_on
  • ✅ Networks: DNS resolution, multi-container

🎯Thực hành

  1. Tạo thư mục fullstack-app với các file trên
  2. Chạy docker compose up -d
  3. Chạy curl http://localhost:3000
  4. Chạy docker exec -it app sh — vào container
  5. Chạy docker compose down — dừng toàn bộ
  6. Chạy lại — dữ liệu vẫn còn nhờ volume!

❓ Kiểm tra kiến thức

1. depends_on trong docker-compose.yml có tác dụng gì?

2. docker exec -it app sh dùng để làm gì?

← Previous6 / 6Complete 🎉