Thứ sáu, 10/07/2020 | 00:00 GMT+7

Cách mở rộng và bảo mật một ứng dụng Django với Docker, Nginx và Let's Encrypt

Trong môi trường dựa trên cloud , có nhiều cách để mở rộng quy mô và bảo mật ứng dụng Django . Bằng cách mở rộng quy mô theo chiều ngang và chạy một số bản sao của ứng dụng, bạn có thể xây dựng một hệ thống có khả năng chịu lỗi cao và khả dụng hơn, đồng thời tăng thông lượng của nó để các yêu cầu có thể được xử lý đồng thời.

Một cách để mở rộng ứng dụng Django theo chiều ngang là cung cấp các server ứng dụng bổ sung chạy ứng dụng Django của bạn và server WSGI HTTP của nó (như Gunicorn hoặc uWSGI ). Để định tuyến và phân phối các yêu cầu đến trên tập hợp các server ứng dụng này, bạn có thể sử dụng trình cân bằng tải reverse-proxy như Nginx . Nginx cũng có thể lưu nội dung tĩnh vào bộ nhớ cache và chấm dứt kết nối Bảo mật lớp truyền tải (TLS), được sử dụng để cung cấp HTTPS và kết nối an toàn cho ứng dụng của bạn.


Chạy ứng dụng Django và proxy Nginx của bạn bên trong vùng chứa Docker đảm bảo các thành phần này hoạt động theo cùng một cách dù chúng được triển khai trong môi trường nào. Ngoài ra, các container cung cấp nhiều tính năng tạo điều kiện thuận lợi cho việc đóng gói và cấu hình ứng dụng của bạn.

Trong hướng dẫn này, bạn sẽ mở rộng quy mô ứng dụng Django và Gunicorn Polls theo chiều ngang bằng cách cung cấp hai server ứng dụng, mỗi server sẽ chạy một bản sao của containers ứng dụng Django và Gunicorn.

Bạn cũng sẽ bật HTTPS bằng cách cấp phép và cấu hình server proxy thứ ba sẽ chạy containers Reverse Proxy Nginx và vùng chứa ứng dụng client Certbot . Certbot sẽ cung cấp certificate TLS cho Nginx từ cơ quan cấp certificate Let's Encrypt . Điều này sẽ đảm bảo trang web nhận được xếp hạng bảo mật cao từ SSL Labs . Server proxy này sẽ nhận tất cả các yêu cầu bên ngoài của ứng dụng của bạn và nằm trước hai server ứng dụng Django ngược dòng . Cuối cùng, bạn sẽ củng cố hệ thống phân tán này bằng cách hạn chế quyền truy cập bên ngoài chỉ vào server proxy.

Yêu cầu

Để làm theo hướng dẫn này, bạn cần :

  • Ba server Ubuntu 18.04:

    • Hai server sẽ là server ứng dụng , được sử dụng để chạy ứng dụng Django và Gunicorn của bạn.
    • Một server sẽ là server proxy , được sử dụng để chạy Nginx và Certbot.
    • Tất cả phải có user không phải root với quyền sudo và firewall hoạt động. Để được hướng dẫn về cách cài đặt những điều này, vui lòng xem hướng dẫn Cài đặt Server Ban đầu này.
  • Docker được cài đặt trên cả ba server . Để được hướng dẫn cài đặt Docker, hãy làm theo Bước 1 và 2 của Cách cài đặt và sử dụng Docker trên Ubuntu 18.04 .

  • Tên domain đã đăng ký. Hướng dẫn này sẽ sử dụng your_domain.com xuyên suốt. Bạn có thể nhận một miễn phí tại Freenom hoặc sử dụng công ty đăng ký domain mà bạn chọn.

  • A bản ghi DNS với your_domain.com trỏ đến địa chỉ IP công cộng của server proxy của bạn. Bạn có thể theo dõi phần giới thiệu này về DigitalOcean DNS để biết chi tiết về cách thêm nó vào account DigitalOcean, nếu đó là những gì bạn đang sử dụng.

  • Một group lưu trữ đối tượng S3 chẳng hạn như DigitalOcean để lưu trữ các file tĩnh của dự án Django của bạn và một bộ Khóa truy cập cho Không gian này. Để tìm hiểu cách tạo Không gian, hãy tham khảo tài liệu sản phẩm Cách tạo Không gian . Để tìm hiểu cách tạo Khóa truy cập cho Không gian, hãy tham khảo Chia sẻ quyền truy cập vào Không gian bằng Khóa truy cập .Với những thay đổi nhỏ, bạn có thể sử dụng bất kỳ dịch vụ lưu trữ đối tượng nào mà plugin django-storages hỗ trợ.

  • Một version server PostgreSQL, database và user cho ứng dụng Django của bạn. Với những thay đổi nhỏ, bạn có thể sử dụng bất kỳ database nào mà Django hỗ trợ .

Bước 1 - Cấu hình server ứng dụng Django đầu tiên

Để bắt đầu, ta sẽ sao chép kho ứng dụng Django vào server ứng dụng đầu tiên. Sau đó, ta sẽ cấu hình và xây dựng Docker image của ứng dụng và kiểm tra ứng dụng bằng cách chạy containers Django.

Lưu ý: Nếu bạn đang tiếp tục từ Cách tạo ứng dụng Django và Gunicorn bằng Docker , bạn đã hoàn thành Bước 1 và có thể chuyển sang Bước 2 để cấu hình server ứng dụng thứ hai .

Bắt đầu bằng cách đăng nhập vào server đầu tiên của hai server ứng dụng Django và sử dụng git để sao chép nhánh polls-docker của kho lưu trữ Ứng dụng Django Tutorial Polls GitHub . Kho này chứa mã cho ứng dụng Cuộc thăm dò mẫu của tài liệu Django. Nhánh polls-docker có chứa version Tài liệu hóa của ứng dụng Cuộc thăm dò ý kiến. Để tìm hiểu cách ứng dụng Polls đã được sửa đổi để hoạt động hiệu quả trong môi trường chứa đựng, vui lòng xem Cách tạo ứng dụng Django và Gunicorn bằng Docker .

  • git clone --single-branch --branch polls-docker https://github.com/do-community/django-polls.git

Điều hướng vào folder django-polls :

cd django-polls 

Thư mục này chứa mã Python của ứng dụng Django, Dockerfile Docker mà Docker sẽ sử dụng để tạo containers images , cũng như file env chứa danh sách các biến môi trường sẽ được chuyển vào môi trường đang chạy của containers . Kiểm tra Dockerfile bằng cách sử dụng cat :

cat Dockerfile 
Output
FROM python:3.7.4-alpine3.10  ADD django-polls/requirements.txt /app/requirements.txt  RUN set -ex \     && apk add --no-cache --virtual .build-deps postgresql-dev build-base \     && python -m venv /env \     && /env/bin/pip install --upgrade pip \     && /env/bin/pip install --no-cache-dir -r /app/requirements.txt \     && runDeps="$(scanelf --needed --nobanner --recursive /env \         | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \         | sort -u \         | xargs -r apk info --installed \         | sort -u)" \     && apk add --virtual rundeps $runDeps \     && apk del .build-deps  ADD django-polls /app WORKDIR /app  ENV VIRTUAL_ENV /env ENV PATH /env/bin:$PATH  EXPOSE 8000  CMD ["gunicorn", "--bind", ":8000", "--workers", "3", "mysite.wsgi"] 

Dockerfile này sử dụng Docker image Python 3.7.4 chính thức làm cơ sở và cài đặt các yêu cầu gói Python của Django và Gunicorn, như được định nghĩa trong file django-polls/requirements.txt Request.txt. Sau đó, nó loại bỏ một số file xây dựng không cần thiết, sao chép mã ứng dụng vào hình ảnh và đặt PATH thực thi. Cuối cùng, nó tuyên bố rằng cổng 8000 sẽ được sử dụng để chấp nhận các kết nối container đến và chạy gunicorn với 3 công nhân, lắng nghe trên cổng 8000 .

Để tìm hiểu thêm về từng bước trong Dockerfile này, vui lòng xem Bước 6 của Cách tạo Ứng dụng Django và Gunicorn bằng Docker .

Bây giờ, xây dựng hình ảnh bằng cách sử dụng bản docker build :

  • docker build -t polls .

Ta đặt tên các polls hình ảnh bằng cách sử dụng cờ -t và chuyển vào folder hiện tại làm bối cảnh xây dựng , tập hợp các file để tham chiếu khi xây dựng hình ảnh.

Sau khi Docker xây dựng và gắn thẻ hình ảnh, hãy liệt kê các hình ảnh có sẵn bằng cách sử dụng docker images :

docker images 

Bạn sẽ thấy hình ảnh polls được liệt kê:

Output
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE polls               latest              80ec4f33aae1        2 weeks ago         197MB python              3.7.4-alpine3.10    f309434dea3a        8 months ago        98.7MB 

Trước khi chạy containers Django, ta cần cấu hình môi trường chạy của nó bằng cách sử dụng file env có trong folder hiện tại. Tệp này sẽ được chuyển vào lệnh docker run được sử dụng để chạy containers và Docker sẽ đưa các biến môi trường đã cấu hình vào môi trường đang chạy của containers .

Mở file env bằng nano hoặc editor bạn quen dùng :

nano env 

Ta sẽ cấu hình file như vậy và bạn cần thêm một số giá trị bổ sung như được nêu bên dưới.

django-polls / env
DJANGO_SECRET_KEY= DEBUG=True DJANGO_ALLOWED_HOSTS= DATABASE_ENGINE=postgresql_psycopg2 DATABASE_NAME=polls DATABASE_USERNAME= DATABASE_PASSWORD= DATABASE_HOST= DATABASE_PORT= STATIC_ACCESS_KEY_ID= STATIC_SECRET_KEY= STATIC_BUCKET_NAME= STATIC_ENDPOINT_URL= DJANGO_LOGLEVEL=info 

Điền vào các giá trị còn thiếu cho các khóa sau:

  • DJANGO_SECRET_KEY : Đặt giá trị này thành giá trị duy nhất, không thể đoán trước, như được nêu chi tiết trong tài liệu Django . Một phương pháp tạo khóa này được cung cấp trong Điều chỉnh cài đặt ứng dụng của hướng dẫn Ứng dụng Django có thể mở rộng .
  • DJANGO_ALLOWED_HOSTS : Biến này bảo mật ứng dụng và ngăn chặn các cuộc tấn công tiêu đề Server HTTP. Đối với mục đích thử nghiệm, hãy đặt giá trị này thành * , một ký tự đại diện sẽ trùng với tất cả các server . Trong quá trình production , bạn nên đặt mục này thành your_domain.com . Để tìm hiểu thêm về cài đặt Django này, hãy tham khảo Cài đặt cốt lõi từ tài liệu Django.
  • DATABASE_USERNAME : Đặt cài đặt này cho user database PostgreSQL được tạo trong các bước yêu cầu .
  • DATABASE_NAME : Đặt giá trị này thành polls hoặc tên của database PostgreSQL được tạo trong các bước yêu cầu .
  • DATABASE_PASSWORD : Đặt password này thành password user PostgreSQL được tạo trong các bước yêu cầu .
  • DATABASE_HOST : Đặt giá trị này thành tên server database của bạn.
  • DATABASE_PORT : Đặt cái này thành cổng database của bạn.
  • STATIC_ACCESS_KEY_ID : Đặt cái này thành group S3 của bạn hoặc khóa truy cập của Space.
  • STATIC_SECRET_KEY : Đặt cái này thành group S3 của bạn hoặc khóa truy cập Bí mật của Space.
  • STATIC_BUCKET_NAME : Đặt cái này thành group S3 hoặc tên Không gian của bạn.
  • STATIC_ENDPOINT_URL : Đặt mục này thành group S3 hoặc URL điểm cuối không gian thích hợp, ví dụ https:// space-name .nyc3.digitaloceanspaces.com nếu Không gian của bạn nằm trong vùng nyc3 .

Khi bạn đã chỉnh sửa xong, hãy lưu file .

Bây giờ ta sẽ sử dụng docker run để overrides bộ CMD trong Dockerfile và tạo schemas database bằng cách sử dụng các manage.py makemigrationsmanage.py makemigrations manage.py migrate :

docker run --env-file env polls sh -c "python manage.py makemigrations && python manage.py migrate" 

Ta chạy các polls:latest containers images polls:latest , chuyển vào file biến môi trường mà ta vừa sửa đổi và overrides lệnh Dockerfile bằng sh -c "python manage.py makemigrations && python manage.py migrate" , sẽ tạo schemas database được xác định bởi mã ứng dụng. Nếu bạn đang chạy điều này lần đầu tiên, bạn sẽ thấy:

Output
No changes detected Operations to perform:   Apply all migrations: admin, auth, contenttypes, polls, sessions Running migrations:   Applying contenttypes.0001_initial... OK   Applying auth.0001_initial... OK   Applying admin.0001_initial... OK   Applying admin.0002_logentry_remove_auto_add... OK   Applying admin.0003_logentry_add_action_flag_choices... OK   Applying contenttypes.0002_remove_content_type_name... OK   Applying auth.0002_alter_permission_name_max_length... OK   Applying auth.0003_alter_user_email_max_length... OK   Applying auth.0004_alter_user_username_opts... OK   Applying auth.0005_alter_user_last_login_null... OK   Applying auth.0006_require_contenttypes_0002... OK   Applying auth.0007_alter_validators_add_error_messages... OK   Applying auth.0008_alter_user_username_max_length... OK   Applying auth.0009_alter_user_last_name_max_length... OK   Applying auth.0010_alter_group_name_max_length... OK   Applying auth.0011_update_proxy_permissions... OK   Applying polls.0001_initial... OK   Applying sessions.0001_initial... OK 

Điều này cho biết schemas database đã được tạo thành công.

Nếu bạn đang chạy migrate lần tiếp theo, Django sẽ thực hiện không chọn trừ khi schemas database đã thay đổi.

Tiếp theo, ta sẽ chạy một version khác của containers ứng dụng và sử dụng một shell tương tác bên trong nó để tạo admin-user cho dự án Django.

docker run -i -t --env-file env polls sh 

Điều này sẽ cung cấp cho bạn dấu nhắc shell bên trong containers đang chạy mà bạn có thể sử dụng để tạo user Django:

python manage.py createsuperuser 

Nhập tên user , địa chỉ email và password cho user và sau khi tạo user , nhấn CTRL+D để thoát khỏi containers và loại bỏ nó.

Cuối cùng, ta sẽ tạo các file tĩnh cho ứng dụng và tải chúng lên DigitalOcean bằng cách sử dụng collectstatic . Lưu ý điều này có thể mất một chút thời gian để hoàn thành.

docker run --env-file env polls sh -c "python manage.py collectstatic --noinput" 

Sau khi các file này được tạo và tải lên, bạn sẽ nhận được kết quả sau.

Output
121 static files copied. 

Bây giờ ta có thể chạy ứng dụng:

docker run --env-file env -p 80:8000 polls 
Output
[2019-10-17 21:23:36 +0000] [1] [INFO] Starting gunicorn 19.9.0 [2019-10-17 21:23:36 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1) [2019-10-17 21:23:36 +0000] [1] [INFO] Using worker: sync [2019-10-17 21:23:36 +0000] [7] [INFO] Booting worker with pid: 7 [2019-10-17 21:23:36 +0000] [8] [INFO] Booting worker with pid: 8 [2019-10-17 21:23:36 +0000] [9] [INFO] Booting worker with pid: 9 

Ở đây, ta chạy lệnh mặc định được xác định trong Dockerfile, gunicorn --bind :8000 --workers 3 mysite.wsgi:application và hiển thị cổng containers 8000 để cổng 80 trên server Ubuntu được ánh xạ tới cổng 8000 của containers polls .

Như vậy, bạn có thể chuyển đến ứng dụng polls bằng trình duyệt web bằng lệnh http:// APP_SERVER_1_IP vào thanh URL. Vì không có tuyến đường nào được xác định cho / path, bạn có thể sẽ nhận được lỗi 404 Page Not Found , điều này được mong đợi.

Cảnh báo: Khi sử dụng firewall UFW với Docker, Docker bỏ qua mọi luật firewall UFW đã cấu hình , như được nêu trong vấn đề GitHub này . Điều này giải thích tại sao bạn có quyền truy cập vào cổng 80 của server , mặc dù bạn chưa tạo luật truy cập UFW rõ ràng trong bất kỳ bước yêu cầu nào. Trong Bước 5, ta sẽ giải quyết lỗ hổng bảo mật này bằng cách vá cấu hình UFW. Nếu bạn không sử dụng UFW và đang sử dụng Tường lửa cloud của DigitalOcean, bạn có thể an toàn bỏ qua cảnh báo này.

Điều hướng đến http:// APP_SERVER_1_IP /polls để xem giao diện ứng dụng Cuộc thăm dò:

Giao diện ứng dụng thăm dò ý kiến

Để xem giao diện quản trị, hãy truy cập http:// APP_SERVER_1_IP /admin . Bạn sẽ thấy cửa sổ xác thực quản trị ứng dụng Polls:

Trang xác thực  administrator  thăm dò ý kiến

Nhập tên user và password quản trị mà bạn đã tạo bằng lệnh createsuperuser .

Sau khi xác thực, bạn có thể truy cập vào giao diện quản trị của ứng dụng Polls:

Giao diện chính của  administrator  thăm dò

Lưu ý nội dung tĩnh cho ứng dụng adminpolls đang được phân phối trực tiếp từ bộ nhớ đối tượng. Để xác nhận điều này, hãy tham khảo Kiểm tra phân phối file tĩnh trong Spaces .

Khi bạn khám phá xong, nhấn CTRL+C trong cửa sổ dòng lệnh chạy containers Docker để hủy containers .

Đến đây bạn đã xác nhận containers ứng dụng chạy như mong đợi, bạn có thể chạy nó ở chế độ tách rời , chế độ này sẽ chạy trong nền và cho phép bạn đăng xuất khỏi phiên SSH của bạn :

docker run -d --rm --name polls --env-file env -p 80:8000 polls 

Cờ -d hướng dẫn Docker chạy containers ở chế độ tách rời, cờ -rm dọn dẹp hệ thống file của containers sau khi containers thoát và ta đặt tên cho các polls containers .

Đăng xuất khỏi server ứng dụng Django đầu tiên và chuyển đến http:// APP_SERVER_1_IP /polls để xác nhận containers đang chạy như mong đợi.

Bây giờ server ứng dụng Django đầu tiên của bạn đã được cài đặt và đang chạy, bạn có thể cài đặt server ứng dụng Django thứ hai của bạn .

Bước 2 - Cấu hình server ứng dụng Django thứ hai

Vì nhiều lệnh để cài đặt server này sẽ giống với các lệnh trong bước trước, chúng sẽ được trình bày ở đây dưới dạng viết tắt. Vui lòng xem lại Bước 1 để biết thêm thông tin về bất kỳ lệnh cụ thể nào trong bước này.

Bắt đầu bằng cách đăng nhập vào server ứng dụng Django thứ hai .

Sao polls-docker nhánh polls-docker của repository GitHub django-polls :

  • git clone --single-branch --branch polls-docker https://github.com/do-community/django-polls.git

Điều hướng vào folder django-polls :

cd django-polls 

Xây dựng hình ảnh bằng cách sử dụng bản docker build :

  • docker build -t polls .

Mở file env bằng nano hoặc editor bạn quen dùng :

nano env 
django-polls / env
DJANGO_SECRET_KEY= DEBUG=True DJANGO_ALLOWED_HOSTS= DATABASE_ENGINE=postgresql_psycopg2 DATABASE_NAME=polls DATABASE_USERNAME= DATABASE_PASSWORD= DATABASE_HOST= DATABASE_PORT= STATIC_ACCESS_KEY_ID= STATIC_SECRET_KEY= STATIC_BUCKET_NAME= STATIC_ENDPOINT_URL= DJANGO_LOGLEVEL=info 

Điền vào các giá trị còn thiếu như trong Bước 1 . Khi bạn đã chỉnh sửa xong, hãy lưu file .

Cuối cùng, chạy containers ứng dụng ở chế độ tách rời:

docker run -d --rm --name polls --env-file env -p 80:8000 polls 

Điều hướng đến http:// APP_SERVER_2_IP /polls để xác nhận containers đang chạy như mong đợi. Bạn có thể đăng xuất an toàn khỏi server ứng dụng thứ hai mà không cần chấm dứt containers đang chạy của bạn .

Với cả hai containers ứng dụng Django được cài đặt và đang chạy, bạn có thể chuyển sang cấu hình containers Reverse Proxy Nginx.

Bước 3 - Cấu hình Vùng chứa Nginx Docker

Nginx là một web server đa năng cung cấp một số tính năng bao gồm reverse-proxy , cân bằng tảibộ nhớ đệm . Trong hướng dẫn này, ta đã tải bớt các tài sản tĩnh của Django vào bộ nhớ đối tượng, vì vậy ta sẽ không sử dụng khả năng bộ nhớ đệm của Nginx. Tuy nhiên, ta sẽ sử dụng Nginx làm Reverse Proxy cho hai server ứng dụng Django backend và phân phối các yêu cầu đến giữa chúng. Ngoài ra, Nginx sẽ thực hiện việc chấm dứt và chuyển hướng TLS bằng cách sử dụng certificate TLS do Certbot cấp. Điều này nghĩa là nó sẽ buộc các client sử dụng HTTPS, chuyển hướng các yêu cầu HTTP đến cổng 443. Sau đó, nó sẽ giải mã các yêu cầu HTTPS và ủy quyền chúng đến các server Django ngược dòng.

Trong hướng dẫn này, ta đã đưa ra quyết định thiết kế để tách các containers Nginx khỏi các server backend . Tùy thuộc vào trường hợp sử dụng của bạn, bạn có thể chọn chạy containers Nginx trên một trong các server ứng dụng Django, các yêu cầu proxy local , cũng như server Django khác. Một kiến trúc khả thi khác sẽ là chạy hai containers Nginx, một containers trên mỗi server backend , với bộ cân bằng tải cloud ở phía trước. Mỗi kiến trúc có những ưu điểm về hiệu suất và bảo mật khác nhau, và bạn nên tải thử nghiệm hệ thống của bạn để phát hiện ra các điểm nghẽn. Kiến trúc linh hoạt được mô tả trong hướng dẫn này cho phép bạn mở rộng cả lớp ứng dụng Django backend , cũng như lớp ủy quyền Nginx. Khi containers Nginx đơn lẻ trở thành nút cổ chai, bạn có thể mở rộng quy mô cho nhiều proxy Nginx và thêm bộ cân bằng tải trên cloud hoặc bộ cân bằng tải L4 nhanh như HAProxy .

Với cả hai server ứng dụng Django được cài đặt và chạy, ta có thể bắt đầu cài đặt server proxy Nginx. Đăng nhập vào server proxy của bạn và tạo một folder có tên là conf :

mkdir conf 

Tạo file cấu hình có tên nginx.conf bằng nano hoặc editor bạn quen dùng :

nano conf/nginx.conf 

Dán vào cấu hình Nginx sau:

conf / nginx.conf
 upstream django {     server APP_SERVER_1_IP;     server APP_SERVER_2_IP; }  server {     listen 80 default_server;     return 444; }  server {     listen 80;     listen [::]:80;     server_name your_domain.com;     return 301 https://$server_name$request_uri; }  server {     listen 443 ssl http2;     listen [::]:443 ssl http2;     server_name your_domain.com;      # SSL     ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;     ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;      ssl_session_cache shared:le_nginx_SSL:10m;     ssl_session_timeout 1440m;     ssl_session_tickets off;      ssl_protocols TLSv1.2 TLSv1.3;     ssl_prefer_server_ciphers off;      ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";      client_max_body_size 4G;     keepalive_timeout 5;          location / {           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;           proxy_set_header X-Forwarded-Proto $scheme;           proxy_set_header Host $http_host;           proxy_redirect off;           proxy_pass http://django;         }      location ^~ /.well-known/acme-challenge/ {         root /var/www/html;     }  } 

Các khối upstream , serverlocation cấu hình Nginx để chuyển hướng các yêu cầu HTTP đến HTTPS và cân bằng tải chúng trên hai server ứng dụng Django được cấu hình ở Bước 1 và 2. Để tìm hiểu thêm về cấu trúc file cấu hình Nginx, vui lòng tham khảo bài viết này về Hiểu Cấu trúc file cấu hình và khung cảnh cấu hình Nginx . Ngoài ra, bài viết này về Hiểu server Nginx và các thuật toán lựa chọn khối vị trí có thể hữu ích.

Cấu hình này được tập hợp từ các file cấu hình mẫu do Gunicorn , CerbotNginx cung cấp và nghĩa là cấu hình Nginx tối thiểu để cấu hình này bắt đầu và chạy. Việc điều chỉnh cấu hình Nginx này nằm ngoài phạm vi của bài viết này, nhưng bạn có thể sử dụng một công cụ như NGINXConfig để tạo các file cấu hình Nginx hiệu quả và an toàn cho kiến trúc của bạn.

Khối upstream xác định group server được sử dụng để yêu cầu proxy sử dụng chỉ thị proxy_pass :

conf / nginx.conf
upstream django {     server APP_SERVER_1_IP;     server APP_SERVER_2_IP; } . . . 

Trong khối này, ta đặt tên cho django ngược dòng và bao gồm địa chỉ IP của cả hai server ứng dụng Django. Nếu server ứng dụng đang chạy trên DigitalOcean và đã bật Mạng VPC, bạn nên sử dụng địa chỉ IP riêng của chúng tại đây. Để tìm hiểu cách bật Mạng VPC trên DigitalOcean, vui lòng xem Cách bật Mạng VPC trên các server hiện có .

Khối server đầu tiên nắm bắt các yêu cầu không trùng với domain của bạn và chấm dứt kết nối. Ví dụ: một yêu cầu HTTP trực tiếp đến địa chỉ IP của server sẽ được xử lý bởi khối này:

conf / nginx.conf
. . . server {     listen 80 default_server;     return 444; } . . . 

Khối server tiếp theo chuyển hướng các yêu cầu HTTP đến domain của bạn thành HTTPS bằng cách sử dụng chuyển hướng HTTP 301 . Các yêu cầu này sau đó được xử lý bởi khối server cuối cùng:

conf / nginx.conf
. . . server {     listen 80;     listen [::]:80;     server_name your_domain.com;     return 301 https://$server_name$request_uri; } . . . 

Hai chỉ thị này xác định các đường dẫn đến certificate TLS và khóa bí mật. Chúng sẽ được cấp phép bằng Certbot và được gắn vào containers Nginx trong bước tiếp theo.

conf / nginx.conf
. . . ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem; . . . 

Các tham số này là mặc định bảo mật SSL do Certbot khuyến nghị. Để tìm hiểu thêm về chúng, vui lòng xem Mô-đun ngx_http_ssl_module từ tài liệu Nginx. Bảo mật / TLS phía server của Mozilla là một hướng dẫn hữu ích khác mà bạn có thể sử dụng để điều chỉnh cấu hình SSL của bạn .

conf / nginx.conf
. . .     ssl_session_cache shared:le_nginx_SSL:10m;     ssl_session_timeout 1440m;     ssl_session_tickets off;      ssl_protocols TLSv1.2 TLSv1.3;     ssl_prefer_server_ciphers off;      ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"; . . . 

Hai chỉ thị này từ cấu hình Nginx mẫu của Gunicorn đặt kích thước tối đa cho phép của thân yêu cầu ứng dụng client và ấn định thời gian chờ cho các kết nối duy trì hoạt động với ứng dụng client . Nginx sẽ đóng các kết nối với client sau vài giây keepalive_timeout .

conf / nginx.conf
. . . client_max_body_size 4G; keepalive_timeout 5; . . . 

Khối location đầu tiên hướng dẫn Nginx yêu cầu proxy tới các server upstream django qua HTTP. Nó cũng bảo tồn các tiêu đề HTTP của client nắm bắt địa chỉ IP root , giao thức được sử dụng để kết nối và server đích:

conf / nginx.conf
. . . location / {     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;     proxy_set_header X-Forwarded-Proto $scheme;     proxy_set_header Host $http_host;     proxy_redirect off;     proxy_pass http://django; } . . . 

Để tìm hiểu thêm về các chỉ thị này, vui lòng xem Triển khai GunicornMô-đun ngx_http_proxy_module từ tài liệu Nginx.

Khối location cuối cùng nắm bắt các yêu cầu tới đường dẫn /well-known/acme-challenge/ , được Certbot sử dụng cho các thử thách HTTP-01 để xác minh domain của bạn bằng Let's Encrypt và cung cấp hoặc gia hạn certificate TLS. Để biết thêm thông tin về thử thách HTTP-01 được Certbot sử dụng, vui lòng xem Các loại thử thách từ tài liệu Let's Encrypt.

conf / nginx.conf
. . . location ^~ /.well-known/acme-challenge/ {         root /var/www/html; } 

Khi bạn đã chỉnh sửa xong, hãy lưu file .

Đến đây bạn có thể sử dụng file cấu hình này để chạy containers Nginx Docker. Trong hướng dẫn này, ta sẽ sử dụng hình ảnh nginx:1.19.0 , version 1.19.0 của Docker image chính thức do Nginx duy trì.

Khi ta chạy containers lần đầu tiên, Nginx sẽ gặp lỗi và không thành công vì ta chưa cấp phép các certificate được xác định trong file cấu hình. Tuy nhiên, ta sẽ vẫn chạy lệnh để download hình ảnh Nginx local và kiểm tra xem mọi thứ khác có hoạt động bình thường không:

docker run --rm --name nginx -p 80:80 -p 443:443 \     -v ~/conf/nginx.conf:/etc/nginx/conf.d/nginx.conf:ro \     -v /var/www/html:/var/www/html \     nginx:1.19.0 

Ở đây ta đặt tên cho containers là nginx và ánh xạ các cổng server 80443 thành các cổng containers tương ứng. Cờ -v gắn file cấu hình vào containers Nginx tại /etc/nginx/conf.d/nginx.conf , file này được cấu hình trước để tải hình ảnh Nginx. Nó được gắn ở chế độ ro hoặc “chỉ đọc”, vì vậy containers không thể sửa đổi file . Thư mục root của web /var/www/html cũng được gắn vào containers . Cuối cùng nginx:1.19.0 hướng dẫn Docker kéo và chạy hình ảnh nginx:1.19.0 từ Dockerhub.

Docker sẽ kéo và chạy hình ảnh, sau đó Nginx sẽ thông báo lỗi khi không tìm thấy certificate TLS đã cấu hình và khóa bí mật. Trong bước tiếp theo, ta sẽ cung cấp những điều này bằng cách sử dụng ứng dụng client Dockerized Certbot và cơ quan cấp certificate Let's Encrypt.

Bước 4 - Cấu hình Certbot và Gia hạn Chứng chỉ Let's Encrypt

Certbot là một ứng dụng Let's Encrypt được phát triển bởi Electronic Frontier Foundation . Nó cung cấp certificate TLS miễn phí từ cơ quan cấp certificate Let's Encrypt , cho phép các trình duyệt xác minh danh tính của web server . Cho rằng ta đã cài đặt Docker trên server proxy Nginx của bạn , ta sẽ sử dụng hình ảnh Certbot Docker để cung cấp và gia hạn certificate TLS.

Bắt đầu bằng cách đảm bảo bạn có bản ghi DNS A được ánh xạ tới địa chỉ IP công cộng của server proxy. Sau đó, trên server proxy của bạn, cung cấp version theo giai đoạn của certificate bằng cách sử dụng hình ảnh certbot Docker:

docker run -it --rm -p 80:80 --name certbot \          -v "/etc/letsencrypt:/etc/letsencrypt" \          -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \          certbot/certbot certonly --standalone --staging -d your_domain.com 

Lệnh này chạy hình ảnh certbot Docker ở chế độ tương tác và chuyển tiếp cổng 80 trên server đến cổng containers 80 . Nó tạo và gắn hai folder server vào containers : /etc/letsencrypt//var/lib/letsencrypt/ . certbot được chạy ở chế độ standalone , không có Nginx và sẽ sử dụng server staging Let's Encrypt để thực hiện xác thực domain .

Khi được yêu cầu , hãy nhập địa chỉ email của bạn và đồng ý với Điều khoản dịch vụ. Nếu xác thực domain thành công, bạn sẽ thấy kết quả sau:

Output
Obtaining a new certificate Performing the following challenges: http-01 challenge for stubb.dev Waiting for verification... Cleaning up challenges  IMPORTANT NOTES:  - Congratulations! Your certificate and chain have been saved at:    /etc/letsencrypt/live/your_domain.com/fullchain.pem    Your key file has been saved at:    /etc/letsencrypt/live/your_domain.com/privkey.pem    Your cert will expire on 2020-09-15. To obtain a new or tweaked    version of this certificate in the future, simply run certbot    again. To non-interactively renew *all* of your certificates, run    "certbot renew"  - Your account credentials have been saved in your Certbot    configuration directory at /etc/letsencrypt. You should make a    secure backup of this folder now. This configuration directory will    also contain certificates and private keys obtained by Certbot so    making regular backups of this folder is ideal. 

Bạn có thể kiểm tra certificate bằng cách sử dụng cat :

sudo cat /etc/letsencrypt/live/your_domain.com/fullchain.pem 

Với certificate TLS được cung cấp, ta có thể kiểm tra cấu hình Nginx được lắp ráp ở bước trước:

docker run --rm --name nginx -p 80:80 -p 443:443 \     -v ~/conf/nginx.conf:/etc/nginx/conf.d/nginx.conf:ro \     -v /etc/letsencrypt:/etc/letsencrypt \     -v /var/lib/letsencrypt:/var/lib/letsencrypt \     -v /var/www/html:/var/www/html \     nginx:1.19.0 

Đây là lệnh tương tự được chạy trong Bước 3 , với việc bổ sung cả hai folder Let's Encrypt được tạo gần đây.

Sau khi Nginx bắt đầu và chạy, hãy chuyển đến http:// your_domain.com . Bạn có thể nhận được cảnh báo trong trình duyệt của bạn rằng tổ chức phát hành certificate không hợp lệ. Điều này được mong đợi vì ta đã cung cấp certificate theo giai đoạn chứ không phải certificate Let's Encrypt production . Kiểm tra thanh URL của trình duyệt của bạn để xác nhận yêu cầu HTTP của bạn đã được chuyển hướng đến HTTPS.

Nhấn CTRL+C trong terminal để thoát Nginx và chạy lại ứng dụng certbot , lần này bỏ qua cờ --staging :

docker run -it --rm -p 80:80 --name certbot \          -v "/etc/letsencrypt:/etc/letsencrypt" \          -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \          certbot/certbot certonly --standalone -d your_domain.com 

Khi được yêu cầu giữ certificate hiện có hoặc gia hạn và thay thế certificate , hãy nhấn 2 để gia hạn certificate rồi ENTER để xác nhận lựa chọn của bạn.

Với certificate TLS production được cấp phép, hãy chạy lại server Nginx:

docker run --rm --name nginx -p 80:80 -p 443:443 \     -v ~/conf/nginx.conf:/etc/nginx/conf.d/nginx.conf:ro \     -v /etc/letsencrypt:/etc/letsencrypt \     -v /var/lib/letsencrypt:/var/lib/letsencrypt \     -v /var/www/html:/var/www/html \     nginx:1.19.0 

Trong trình duyệt của bạn, chuyển đến http:// your_domain.com . Trong thanh URL, xác nhận yêu cầu HTTP đã được chuyển hướng đến HTTPS. Do ứng dụng Polls không có cấu hình tuyến đường mặc định, bạn sẽ thấy lỗi không tìm thấy Trang Django. Điều hướng đến https:// your_domain.com /polls và bạn sẽ thấy giao diện ứng dụng Polls tiêu chuẩn:

Giao diện ứng dụng thăm dò ý kiến

Đến đây, bạn đã cấp certificate TLS production bằng ứng dụng client Certbot Docker và đang đảo ngược proxy và cân bằng tải các yêu cầu bên ngoài tới hai server ứng dụng Django.

Chứng chỉ Let's Encrypt hết hạn sau 90 ngày. Để đảm bảo certificate của bạn vẫn còn hiệu lực, bạn nên gia hạn nó thường xuyên trước khi hết hạn theo lịch trình. Với Nginx đang chạy, bạn nên sử dụng ứng dụng client Certbot ở chế độ webroot thay vì chế độ standalone . Điều này nghĩa là Certbot sẽ thực hiện xác thực bằng cách tạo một file trong folder /var/www/html/.well-known/acme-challenge/ và các yêu cầu xác thực Let's Encrypt tới đường dẫn này sẽ được luật location xác định trong Cấu hình Nginx ở Bước 3 . Sau đó, Certbot sẽ xoay các certificate và bạn có thể reload Nginx để nó sử dụng certificate mới được cấp phép này.

Có nhiều cách để tự động hóa quy trình này và việc tự động gia hạn certificate TLS nằm ngoài phạm vi của hướng dẫn này. Để có quy trình tương tự bằng cách sử dụng trình lập lịch cron , vui lòng xem Bước 6 của Cách bảo mật ứng dụng Node.js được chứa chứa bằng Nginx, Let's Encrypt và Docker Compose .

Trong terminal , nhấn CTRL+C để loại bỏ containers Nginx. Chạy lại nó ở chế độ tách rời bằng cách thêm cờ -d :

docker run --rm --name nginx -d -p 80:80 -p 443:443 \     -v ~/conf/nginx.conf:/etc/nginx/conf.d/nginx.conf:ro \     -v /etc/letsencrypt:/etc/letsencrypt \     -v /var/lib/letsencrypt:/var/lib/letsencrypt \   -v /var/www/html:/var/www/html \     nginx:1.19.0 

Với Nginx đang chạy trong nền, hãy sử dụng lệnh sau để thực hiện chạy nhanh quy trình gia hạn certificate :

docker run -it --rm --name certbot \     -v "/etc/letsencrypt:/etc/letsencrypt" \   -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \   -v "/var/www/html:/var/www/html" \   certbot/certbot renew --webroot -w /var/www/html --dry-run 

Ta sử dụng plugin --webroot , chỉ định đường dẫn root của web và sử dụng cờ --dry-run để xác minh mọi thứ đang hoạt động chính xác mà không thực sự thực hiện gia hạn certificate .

Nếu mô phỏng gia hạn thành công, bạn sẽ thấy kết quả sau:

Output
Cert not due for renewal, but simulating renewal for dry run Plugins selected: Authenticator webroot, Installer None Renewing an existing certificate Performing the following challenges: http-01 challenge for your_domain.com Using the webroot path /var/www/html for all unmatched domains. Waiting for verification... Cleaning up challenges  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - new certificate deployed without reload, fullchain is /etc/letsencrypt/live/your_domain.com/fullchain.pem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ** DRY RUN: simulating 'certbot renew' close to cert expiry **          (The test certificates below have not been saved.)  Congratulations, all renewals succeeded. The following certs have been renewed:   /etc/letsencrypt/live/your_domain.com/fullchain.pem (success) ** DRY RUN: simulating 'certbot renew' close to cert expiry **          (The test certificates above have not been saved.) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

Trong cài đặt production , sau khi gia hạn certificate , bạn nên reload Nginx để các thay đổi có hiệu lực. Để reload Nginx, hãy chạy lệnh sau:

docker kill -s HUP nginx 

Lệnh này sẽ gửi một tín hiệu HUP Unix đến tiến trình Nginx đang chạy bên trong containers nginx Docker. Khi nhận được tín hiệu này, Nginx sẽ reload cấu hình và các certificate được gia hạn.

Với HTTPS được bật và tất cả các thành phần của kiến trúc này đang hoạt động, bước cuối cùng là khóa cài đặt bằng cách ngăn truy cập bên ngoài vào hai server ứng dụng backend ; tất cả các yêu cầu HTTP phải chuyển qua proxy Nginx.

Bước 5 - Ngăn truy cập bên ngoài vào Server ứng dụng Django

Trong kiến trúc được mô tả trong hướng dẫn này, việc chấm dứt SSL xảy ra tại proxy Nginx. Điều này nghĩa là Nginx giải mã kết nối SSL và các gói được ủy quyền cho server ứng dụng Django không được mã hóa. Đối với nhiều trường hợp sử dụng, mức độ bảo mật này là đủ. Đối với các ứng dụng liên quan đến dữ liệu tài chính hoặc sức khỏe, bạn có thể cần triển khai mã hóa terminal . Bạn có thể thực hiện việc này bằng cách chuyển tiếp các gói được mã hóa thông qua bộ cân bằng tải và giải mã trên server ứng dụng hoặc mã hóa lại tại proxy và giải mã trên server ứng dụng Django. Các kỹ thuật này vượt ra ngoài phạm vi của bài viết này, nhưng để tìm hiểu thêm, vui lòng tham khảo Mã hóa terminal .

Nginx proxy hoạt động như một cổng kết nối giữa lưu lượng bên ngoài và mạng nội bộ. Về mặt lý thuyết, không có client bên ngoài nào có quyền truy cập trực tiếp vào server ứng dụng nội bộ và tất cả các yêu cầu phải chuyển qua server Nginx. Lưu ý trong Bước 1 mô tả ngắn gọn một sự cố mở với Docker trong đó Docker bỏ qua cài đặt firewall ufw theo mặc định và mở các cổng ra bên ngoài, điều này có thể không an toàn. Để giải quyết mối lo ngại về bảo mật này, bạn nên sử dụng tường lửa cloud khi làm việc với các server hỗ trợ Docker. Để biết thêm thông tin về cách tạo Tường lửa trên cloud với DigitalOcean, hãy tham khảo Cách tạo Tường lửa . Bạn cũng có thể thao tác iptables trực tiếp thay vì sử dụng ufw . Để tìm hiểu thêm về cách sử dụng iptables với Docker, vui lòng xem Docker và iptables .

Trong bước này, ta sẽ sửa đổi cấu hình của UFW để chặn truy cập bên ngoài vào các cổng server do Docker mở. Khi chạy Django trên server ứng dụng, ta đã chuyển cờ -p 80:8000 tới docker , cờ này chuyển tiếp cổng 80 trên server tới cổng containers 8000 . Điều này cũng mở ra cổng 80 cho các ứng dụng client bên ngoài, bạn có thể xác minh bằng cách truy cập http:// your_app_server_1_IP . Để ngăn truy cập trực tiếp, ta sẽ sửa đổi cấu hình của UFW bằng phương pháp được mô tả trong kho lưu trữ ufw-docker GitHub .

Bắt đầu bằng cách đăng nhập vào server ứng dụng Django đầu tiên. Sau đó, mở file / /etc/ufw/after.rules với các quyền của superuser, sử dụng nano hoặc editor bạn quen dùng :

sudo nano /etc/ufw/after.rules 

Nhập password của bạn khi được yêu cầu và nhấn ENTER để xác nhận.

Bạn sẽ thấy các-luật ufw sau:

/etc/ufw/ after.rules
# # rules.input-after # # Rules that should be run after the ufw command line added rules. Custom # rules should be added to one of these chains: #   ufw-after-input #   ufw-after-output #   ufw-after-forward #  # Don't delete these required lines, otherwise there will be errors *filter :ufw-after-input - [0:0] :ufw-after-output - [0:0] :ufw-after-forward - [0:0] # End required lines  # don't log noisy services by default -A ufw-after-input -p udp --dport 137 -j ufw-skip-to-policy-input -A ufw-after-input -p udp --dport 138 -j ufw-skip-to-policy-input -A ufw-after-input -p tcp --dport 139 -j ufw-skip-to-policy-input -A ufw-after-input -p tcp --dport 445 -j ufw-skip-to-policy-input -A ufw-after-input -p udp --dport 67 -j ufw-skip-to-policy-input -A ufw-after-input -p udp --dport 68 -j ufw-skip-to-policy-input  # don't log noisy broadcast -A ufw-after-input -m addrtype --dst-type BROADCAST -j ufw-skip-to-policy-input  # don't delete the 'COMMIT' line or these rules won't be processed COMMIT 

Cuộn xuống dưới cùng và paste vào khối luật cấu hình UFW sau:

/etc/ufw/ after.rules
. . .  # BEGIN UFW AND DOCKER *filter :ufw-user-forward - [0:0] :DOCKER-USER - [0:0] -A DOCKER-USER -j RETURN -s 10.0.0.0/8 -A DOCKER-USER -j RETURN -s 172.16.0.0/12 -A DOCKER-USER -j RETURN -s 192.168.0.0/16  -A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN  -A DOCKER-USER -j ufw-user-forward  -A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16 -A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8 -A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12 -A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 192.168.0.0/16 -A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 10.0.0.0/8 -A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 172.16.0.0/12  -A DOCKER-USER -j RETURN COMMIT # END UFW AND DOCKER 

Các-luật này hạn chế quyền truy cập vào các cổng do Docker mở và cho phép truy cập từ các dải IP riêng 10.0.0.0/8 , 172.16.0.0/12192.168.0.0/16 . Nếu bạn đang sử dụng VPC với DigitalOcean, thì Server trong mạng VPC của bạn sẽ có quyền truy cập vào cổng mở qua network interface riêng, nhưng các client bên ngoài thì không. Để biết thêm thông tin về VPC, vui lòng xem tài liệu chính thức của VPC . Để tìm hiểu thêm về các-luật được triển khai trong đoạn mã này, vui lòng xem Cách hoạt động? từ ufw-docker README .

Nếu bạn không sử dụng VPC với DigitalOcean và đã nhập địa chỉ IP công cộng của server ứng dụng trong khối upstream của cấu hình Nginx của bạn , bạn sẽ phải sửa đổi firewall UFW một cách rõ ràng để cho phép lưu lượng truy cập từ server Nginx qua cổng 80 trên Server ứng dụng Django. Để biết hướng dẫn về cách tạo luật allow với firewall UFW, vui lòng xem Cơ bản về UFW: Các-luật và lệnh firewall chung .

Khi bạn đã chỉnh sửa xong, hãy lưu file .

Khởi động lại ufw để nó nhận cấu hình mới:

sudo systemctl restart ufw 

Điều hướng đến http:// APP_SERVER_1_IP trong trình duyệt web để xác nhận bạn không thể truy cập server ứng dụng qua cổng 80 nữa.

Lặp lại quá trình này trên server ứng dụng Django thứ hai.

Đăng xuất khỏi server ứng dụng đầu tiên hoặc mở một cửa sổ terminal khác và đăng nhập vào server ứng dụng Django thứ hai. Sau đó, mở file / /etc/ufw/after.rules với các quyền của superuser, sử dụng nano hoặc editor bạn quen dùng :

sudo nano /etc/ufw/after.rules 

Nhập password của bạn khi được yêu cầu và nhấn ENTER để xác nhận.

Cuộn xuống dưới cùng và paste vào khối luật cấu hình UFW sau:

/etc/ufw/ after.rules
. . .  # BEGIN UFW AND DOCKER *filter :ufw-user-forward - [0:0] :DOCKER-USER - [0:0] -A DOCKER-USER -j RETURN -s 10.0.0.0/8 -A DOCKER-USER -j RETURN -s 172.16.0.0/12 -A DOCKER-USER -j RETURN -s 192.168.0.0/16  -A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN  -A DOCKER-USER -j ufw-user-forward  -A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16 -A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8 -A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12 -A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 192.168.0.0/16 -A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 10.0.0.0/8 -A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 172.16.0.0/12  -A DOCKER-USER -j RETURN COMMIT # END UFW AND DOCKER 

Khi bạn đã chỉnh sửa xong, hãy lưu file .

Khởi động lại ufw để nó nhận cấu hình mới:

sudo systemctl restart ufw 

Điều hướng đến http:// APP_SERVER_2_IP trong trình duyệt web để xác nhận bạn không thể truy cập server ứng dụng qua cổng 80 nữa.

Cuối cùng, chuyển đến https:// your_domain_here /polls để xác nhận proxy Nginx vẫn có quyền truy cập vào các server Django ngược dòng. Bạn sẽ thấy giao diện ứng dụng Polls mặc định.

Kết luận

Trong hướng dẫn này, bạn đã cài đặt ứng dụng Django Polls có thể mở rộng bằng cách sử dụng containers Docker. Khi lưu lượng truy cập của bạn tăng lên và tải trên hệ thống tăng lên, bạn có thể mở rộng từng lớp riêng biệt: lớp ủy quyền Nginx, lớp ứng dụng backend Django và lớp database PostgreSQL.

Khi xây dựng một hệ thống phân tán, bạn thường phải đối mặt với nhiều quyết định thiết kế và một số kiến trúc có thể đáp ứng trường hợp sử dụng của bạn. Kiến trúc được mô tả trong hướng dẫn này nghĩa là một bản thiết kế linh hoạt để thiết kế các ứng dụng có thể mở rộng với Django và Docker.

Bạn có thể cần kiểm soát hành vi của containers khi chúng gặp lỗi hoặc chạy containers tự động khi hệ thống của bạn khởi động. Để làm điều này, bạn có thể sử dụng trình quản lý tiến trình như Systemd hoặc triển khai các policy khởi động lại. Để biết thêm thông tin về những điều này, vui lòng xem Bắt đầu containers tự động từ tài liệu Docker.

Khi làm việc ở quy mô lớn với nhiều server chạy cùng một Docker image , có thể hiệu quả hơn nếu bạn tự động hóa các bước bằng công cụ quản lý cấu hình như Ansible hoặc Chef . Để tìm hiểu thêm về quản lý cấu hình, vui lòng tham khảo Giới thiệu về Quản lý cấu hìnhTự động hóa Cài đặt Server với Ansible: A DigitalOcean Workshop Kit .

Thay vì xây dựng cùng một hình ảnh trên mọi server , bạn cũng có thể hợp lý hóa việc triển khai bằng cách sử dụng register hình ảnh như Docker Hub , công cụ này xây dựng, lưu trữ và phân phối Docker image một cách tập trung cho nhiều server . Cùng với register hình ảnh, quy trình tích hợp và triển khai liên tục có thể giúp bạn xây dựng, kiểm tra và triển khai hình ảnh tới các server ứng dụng của bạn . Để biết thêm thông tin về CI / CD, vui lòng tham khảo phần Giới thiệu về Các phương pháp hay nhất về CI / CD .


Tags:

Các tin liên quan

Cách tạo ứng dụng Node.js với Docker trên Ubuntu 20.04
2020-06-30
Cách cài đặt Docker Compose trên Ubuntu 20.04 [Quickstart]
2020-06-11
Cách cài đặt và thiết lập Laravel với Docker Compose trên Ubuntu 20.04
2020-06-09
Cách cài đặt và sử dụng Docker trên Ubuntu 20.04
2020-06-09
Cách cài đặt và sử dụng Docker Compose trên Ubuntu 20.04
2020-06-05
Cách chia sẻ dữ liệu giữa các container Docker
2020-05-21
Cách sử dụng Traefik 1.7.21 làm Reverse Proxy cho Docker Containers trên CentOS 7
2020-05-12
Cách cài đặt Drupal với Docker Compose
2020-04-25
Cách xây dựng và triển khai ứng dụng Flask bằng Docker trên Ubuntu 18.04
2020-04-05
Como Conteinerizar um aplicativo Laravel para desenvolvimento com o Docker Compose em Ubuntu 18.04
2020-02-20