# Bài 20. Anti-patterns khi sử dụng Docker

### 1\. Không sử dụng `.dockerignore`:

* **Nguyên nhân**: Nếu bạn không sử dụng `.dockerignore`, Docker sẽ copy tất cả các file vào image, làm tăng kích thước của image và làm chậm quá trình build.
    
    ```bash
    # .dockerignore
    !target/
    ```
    

### 2\. Sử dụng `latest` tag:

* **Nguyên nhân**: Sử dụng tag `latest` có thể gây ra vấn đề về phiên bản, vì `latest` không đảm bảo rằng bạn sẽ luôn có phiên bản phù hợp.
    
    ```bash
    FROM openjdk:latest
    ```
    

### 3\. Chạy nhiều quy trình trong một container:

* **Nguyên nhân**: Điều này vi phạm nguyên tắc "one process per container" của Docker, làm cho việc quản lý và debug trở nên khó khăn.
    
    ```bash
    CMD service nginx start && java -jar my-app.jar
    ```
    

### 4\. Sử dụng root user:

* **Nguyên nhân**: Chạy ứng dụng như root có thể tạo ra các vấn đề bảo mật, bởi vì nó có thể được sử dụng để tấn công các dịch vụ khác.
    
    ```bash
    USER root
    ```
    

### 5\. Không đặt resource limits:

* **Nguyên nhân**: Không giới hạn resource có thể dẫn đến tình trạng một container sử dụng hết resource và làm ảnh hưởng đến các container khác.
    
    ```bash
    docker run my-java-app
    ```
    

### 6\. Cài đặt package không cần thiết:

* **Nguyên nhân**: Điều này làm tăng kích thước của image và cũng có thể tạo ra các vấn đề bảo mật.
    
    ```bash
    RUN apt-get update && apt-get install vim wget curl -y
    ```
    

### 7\. Hardcoding Configuration:

* **Nguyên nhân**: Hardcode cấu hình trong Dockerfile hoặc code nguồn Java sẽ làm giảm tính linh hoạt và tái sử dụng của image.
    
    ```bash
    ENV DB_URL "jdbc:mysql://my-db:3306/mydb"
    ```
    

### 8\. Không sử dụng Health Checks:

* **Nguyên nhân**: Không có health checks có thể gây ra các vấn đề khi sử dụng Docker trong một môi trường có nhiều container như Docker Swarm hoặc Kubernetes.
    

### 9\. Không xem xét startup time:

* **Nguyên nhân**: Các ứng dụng Java thường có thời gian khởi động lâu, đặc biệt là các ứng dụng Spring Boot. Nếu không xem xét điều này, các hệ thống như Kubernetes có thể xem ứng dụng là đã "chết" trước khi nó hoàn toàn sẵn sàng.
    

### 10\. Không đọc logs:

* **Nguyên nhân**: Để giảm bớt sự phức tạp và tăng cường khả năng quản lý, bạn nên định cấu hình ứng dụng Java để ghi logs ra `stdout` và `stderr` để Docker có thể lấy logs.
    

### 11\. Sử dụng Docker cho môi trường không giống nhau:

* **Nguyên nhân**: Một trong những lợi ích lớn của Docker là tính nhất quán giữa các môi trường. Nếu bạn sử dụng các Dockerfile hoặc image khác nhau cho môi trường development, testing, và production, điều này có thể dẫn đến các sự cố không mong muốn.
    

Sự hiểu biết và tránh các anti-patterns này không chỉ giúp bạn tạo ra các Docker image và container tốt hơn, mà còn giúp đảm bảo rằng ứng dụng của bạn chạy đáng tin cậy và an toàn trong bất kỳ môi trường nào.
