Mặc dù làm việc với Python thường xuyên là một trải nghiệm tuyệt vời đối với tôi, nhưng việc quản lý các môi trường phát triển phức tạp thường đặt ra một số thách thức khi các dự án mở rộng quy mô. Để kể tên một vài ví dụ, đây là 3 vấn đề chính với Python mà tôi đã gặp phải: 1. Các ứng dụng phụ thuộc vào các biến môi trường có thể cần đặt các biến này trước khi ứng dụng có thể chạy. 2. Các ứng dụng sử dụng chứng chỉ xác thực để liên lạc giữa các dịch vụ khác nhau, có thể yêu cầu tạo cục bộ các chứng chỉ này trước khi chạy ứng dụng. 3. Các xung đột về phiên bản phụ thuộc có thể xảy ra giữa các vi dịch vụ khác nhau trong cùng một dự án. Mọi thứ có thể trở nên đặc biệt khó khăn khi làm việc với nhiều dịch vụ siêu nhỏ phụ thuộc lẫn nhau và thành thật mà nói, với tư cách là nhà phát triển, tôi thực sự không muốn quản lý tất cả chi phí hoạt động này chỉ để bắt đầu và chạy. Điều này đặc biệt đúng nếu tôi mới bắt đầu tham gia một dự án mới. Một giải pháp phổ biến mà tôi thấy được sử dụng khi phát triển ứng dụng Python là sử dụng , là môi trường biệt lập có cài đặt Python và các gói bắt buộc. Tuy nhiên, việc quản lý nhiều môi trường ảo và các cấu hình liên quan đến môi trường khác vẫn có thể tốn thời gian và cồng kềnh, vì môi trường ảo chỉ cung cấp sự cô lập ở cấp trình thông dịch Python. Điều này có nghĩa là thiết lập khác liên quan đến môi trường, chẳng hạn như biến môi trường và phân bổ cổng, vẫn được chia sẻ trên toàn cầu cho tất cả các thành phần dự án. môi trường ảo Python Giải pháp mà tôi sẽ trình bày trong bài viết này là sử dụng container hóa, đây là một phương pháp đóng gói một ứng dụng và các phần phụ thuộc của nó thành một đơn vị độc lập có thể dễ dàng triển khai và chạy trên bất kỳ nền tảng nào. là một nền tảng phổ biến để phát triển, triển khai và chạy các ứng dụng được chứa trong bộ chứa và là một công cụ giúp dễ dàng xác định và chạy các ứng dụng Docker nhiều bộ chứa bằng một tệp YAML duy nhất (thường được đặt tên là ). Mặc dù có các giải pháp thay thế như , nhưng để đơn giản, tôi sẽ sử dụng Docker và Docker Compose trong ví dụ này. Docker Docker Compose docker-compose.yml minikube Tôi sẽ trình bày cách thiết lập và sử dụng môi trường phát triển được đóng gói bằng Docker và Docker Compose. Tôi cũng sẽ thảo luận về một số thách thức khi sử dụng môi trường phát triển được đóng gói và cách khắc phục chúng bằng cách định cấu hình Docker và Docker soạn thảo để phù hợp với các yêu cầu chính sau đây cho môi trường phát triển hiệu quả: 1. Chạy - Chạy các kịch bản từ đầu đến cuối mô phỏng quá trình thực thi trên môi trường sản xuất mục tiêu. 2. Triển khai - Thực hiện thay đổi mã và triển khai lại một cách nhanh chóng, như với ngăn xếp thời gian chạy ứng dụng không được chứa. 3. Gỡ lỗi - Đặt điểm ngắt và sử dụng trình gỡ lỗi để duyệt qua mã, như với ngăn xếp thời gian chạy ứng dụng không được chứa, để xác định và sửa lỗi. Thiết lập dự án Để minh họa điều này bằng ví dụ, tôi sẽ định nghĩa một ứng dụng Python đơn giản sử dụng khung web Python nhẹ, , để tạo API RESTful để truy vấn thông tin về tác giả và bài đăng của họ. API có một điểm cuối duy nhất, , có thể được sử dụng để truy xuất thông tin về một tác giả cụ thể bằng cách chỉ định ID của họ làm tham số đường dẫn. Sau đó, ứng dụng sử dụng mô-đun để thực hiện các yêu cầu HTTP tới một dịch vụ bài đăng riêng biệt, dịch vụ này dự kiến sẽ cung cấp danh sách các bài đăng của tác giả đó. Để giữ cho mã ngắn gọn, tất cả dữ liệu sẽ được tạo ngẫu nhiên một cách nhanh chóng bằng thư viện . Flask /authors/{author_id} yêu cầu Faker Để bắt đầu, tôi sẽ khởi tạo và sau đó mở một thư mục trống cho dự án. Tiếp theo, tôi sẽ tạo hai thư mục con: Thư mục đầu tiên sẽ được gọi là , va thu hai . Trong mỗi thư mục này, tôi sẽ tạo 3 tệp: authors_service posts_service 1. : Điểm vào chính cho ứng dụng Flask, xác định ứng dụng, thiết lập các tuyến và chỉ định các chức năng sẽ được gọi khi có yêu cầu đối với các tuyến đó. app.py 2. : Một tệp văn bản thuần túy chỉ định các gói Python cần thiết để chạy ứng dụng. requirements.txt 3. : Tệp văn bản chứa hướng dẫn xây dựng hình ảnh Docker, như đã đề cập ở trên, là một gói nhẹ, độc lập và có thể thực thi, bao gồm mọi thứ cần thiết để chạy ứng dụng, bao gồm mã, thời gian chạy, thư viện, biến môi trường, và khá nhiều thứ khác. Dockerfile Trong mỗi tệp, tôi sẽ triển khai một vi dịch vụ Flask với logic mong muốn. app.py cho , các tập tin trông như sau: authors_service app.py app = flask.Flask(__name__) author = { } response = requests.get( ) app.run( ) import os import flask import requests from faker import Faker @app.route( "/authors/<string:author_id>" , methods=[ "GET" ] ) def get_author_by_id ( author_id: str ): "id" : author_id, "name" : Faker().name(), "email" : Faker().email(), "posts" : _get_authors_posts(author_id) return flask.jsonify(author) def _get_authors_posts ( author_id: str ): f' {os.environ[ "POSTS_SERVICE_URL" ]} / {author_id} ' return response.json() if __name__ == "__main__" : host=os.environ[ 'SERVICE_HOST' ], port= int (os.environ[ 'SERVICE_PORT' ]) Mã này thiết lập ứng dụng Flask và xác định tuyến đường để xử lý các yêu cầu GET đến điểm cuối . Khi điểm cuối này được truy cập, nó sẽ tạo dữ liệu giả cho một tác giả có ID được cung cấp và truy xuất danh sách các bài đăng cho tác giả đó từ dịch vụ bài đăng riêng biệt. Sau đó, nó chạy ứng dụng Flask, lắng nghe tên máy chủ và cổng được chỉ định trong các biến môi trường tương ứng. Lưu ý rằng logic trên phụ thuộc vào , và gói. Để giải thích cho điều này, tôi sẽ thêm chúng vào dịch vụ của tác giả tập tin, như sau: /authors/{author_id} flask requests Faker requirements.txt flask == 2 . 2 . 2 requests == 2 . 28 . 1 Faker == 15 . 3 . 4 Lưu ý rằng không có yêu cầu cụ thể về phiên bản gói cho bất kỳ thành phần phụ thuộc nào được tham chiếu trong hướng dẫn này. Các phiên bản được sử dụng là phiên bản mới nhất có sẵn tại thời điểm viết. Cho , trông như sau: posts_service app.py app = flask.Flask(__name__) posts = [ { } ] app.run( ) import os import uuid from random import randint import flask from faker import Faker @app.route( '/posts/<string:author_id>' , methods=[ 'GET' ] ) def get_posts_by_author_id ( author_id: str ): "id:" : str (uuid.uuid4()), "author_id" : author_id, "title" : Faker().sentence(), "body" : Faker().paragraph() for _ in range (randint( 1 , 5 )) return flask.jsonify(posts) if __name__ == '__main__' : host=os.environ[ 'SERVICE_HOST' ], port= int (os.environ[ 'SERVICE_PORT' ]) Trong mã này, khi một khách hàng (tức là ) gửi yêu cầu GET đến tuyến đường , chức năng được gọi với chỉ định như một tham số. Hàm tạo dữ liệu giả cho từ 1 đến 5 bài đăng do tác giả viết bằng thư viện Faker và trả về danh sách các bài đăng dưới dạng phản hồi JSON cho ứng dụng khách. authors_service /posts/{author_id} get_posts_by_author_id author_id Tôi cũng sẽ cần thêm các gói jar và Faker vào dịch vụ đăng bài tập tin, như sau: requirements.txt flask == 2 . 2 . 2 Faker == 15 . 3 . 4 Trước khi chứa các dịch vụ này, chúng ta hãy xem xét một ví dụ về lý do tại sao tôi muốn đóng gói và chạy chúng tách biệt với nhau ngay từ đầu. Cả hai dịch vụ đều sử dụng các biến môi trường và để xác định ổ cắm mà máy chủ Flask sẽ được khởi chạy. Trong khi không phải là vấn đề (nhiều dịch vụ có thể nghe trên cùng một máy chủ), có thể gây ra vấn đề. Nếu tôi cài đặt tất cả các phụ thuộc trong môi trường Python cục bộ và chạy cả hai dịch vụ, thì dịch vụ đầu tiên bắt đầu sẽ sử dụng cổng đã chỉ định, khiến dịch vụ thứ hai gặp sự cố vì không thể sử dụng cùng một cổng. Một giải pháp đơn giản là sử dụng các biến môi trường riêng biệt (ví dụ: và ) thay thế. Tuy nhiên, việc sửa đổi mã nguồn để thích ứng với các ràng buộc về môi trường có thể trở nên phức tạp khi mở rộng quy mô. SERVICE_HOST SERVICE_PORT SERVICE_HOST SERVICE_PORT AUTHORS_SERVICE_PORT POSTS_SERVICE_PORT Quá trình container hóa giúp tránh các sự cố như thế này bằng cách . Trong trường hợp này, tôi có thể đặt biến môi trường thành một giá trị khác cho từng dịch vụ và mỗi dịch vụ sẽ có thể sử dụng cổng riêng của mình mà không bị các dịch vụ khác can thiệp. Để chứa các dịch vụ, tôi sẽ tạo một tệp mới có tên trong mỗi thư mục của dịch vụ. Nội dung của tệp này (cho cả hai dịch vụ) như sau: thiết lập môi trường phù hợp với ứng dụng, thay vì ngược lại SERVICE_PORT Dockerfile WORKDIR /app COPY . /app/ FROM python: 3.8 RUN mkdir /app COPY requi rements.txt /app/ RUN pip install -r requi rements.txt CMD [ "python" , "app.py" ] Cái này xây dựng từ Python 3.8 và thiết lập thư mục cho ứng dụng trong vùng chứa. Sau đó, nó sao chép tệp từ máy chủ sang vùng chứa và cài đặt các phụ thuộc được liệt kê trong tệp đó. Cuối cùng, nó sao chép phần còn lại của mã ứng dụng từ máy chủ sang bộ chứa và chạy tập lệnh ứng dụng chính khi bộ chứa được khởi động. Dockerfile hình ảnh gốc requirements.txt Tiếp theo, tôi sẽ tạo một tệp có tên trong thư mục dự án gốc. Như đã đề cập ngắn gọn ở trên, tệp này được sử dụng để xác định và chạy các ứng dụng Docker đa vùng chứa. bên trong tệp, tôi có thể xác định các dịch vụ tạo nên ứng dụng, chỉ định các phụ thuộc giữa chúng và định cấu hình cách chúng sẽ được xây dựng và chạy. Trong trường hợp này, nó trông như sau: docker-compose.yml docker-compose.yml --- # Specify the version of the Docker Compose file format version: '3.9' services: # Define the authors_service service authors_service: # This service relies on, and is therefor dependent on, the below `posts_service` service depends_on: - posts_service # Specify the path to the Dockerfile for this service build: context: ./authors_service dockerfile: Dockerfile # Define environment variables for this service environment: - SERVICE_HOST=0.0.0.0 - PYTHONPATH=/app - SERVICE_PORT=5000 - POSTS_SERVICE_URL=http://posts_service:6000/posts # Map port 5000 on the host machine to port 5000 on the container ports: - "5000:5000" # Mount the authors_service source code directory on the host to the working directory on the container volumes: - ./authors_service:/app # Define the posts_service service posts_service: # Specify the path to the Dockerfile for this service build: context: ./posts_service dockerfile: Dockerfile # Define environment variables for this service environment: - PYTHONPATH=/app - SERVICE_HOST=0.0.0.0 - SERVICE_PORT=6000 # Mount the posts_service source code directory on the host to the working directory on the container volumes: - ./posts_service:/app Chạy ứng dụng Các thùng chứa có thể được bắt đầu với chỉ huy. Lần đầu tiên chạy, hình ảnh docker sẽ tự động được tạo. docker-compose up Điều này đáp ứng yêu cầu cốt lõi đầu tiên ở trên của "Run". triển khai lại Lưu ý rằng trong tệp, ổ đĩa được gắn kết được sử dụng để chia sẻ các thư mục mã nguồn cho và dịch vụ giữa máy chủ và các thùng chứa. Điều này cho phép mã được chỉnh sửa trên máy chủ với các thay đổi được phản ánh tự động trong các vùng chứa (và ngược lại). docker-compose.yml authors_service posts_service Ví dụ: dòng sau gắn kết thư mục trên máy chủ đến thư mục trong thùng đựng hàng: ./authors_service /app authors_service volumes: - . /authors_service:/ app Các thay đổi được thực hiện trên máy chủ sẽ có sẵn ngay lập tức trên bộ chứa và các thay đổi được thực hiện trong bộ chứa sẽ ngay lập tức được lưu vào thư mục mã nguồn của máy chủ. Điều này cho phép nhanh chóng triển khai lại các thay đổi bằng cách khởi động lại vùng chứa có liên quan xây dựng lại hình ảnh, đáp ứng hiệu quả yêu cầu cốt lõi thứ hai là "Triển khai". mà không cần gỡ lỗi Đây là nơi nó được tham gia nhiều hơn một chút. Trình gỡ lỗi trong Python sử dụng các công cụ gỡ lỗi do trình thông dịch cung cấp để tạm dừng việc thực thi chương trình và kiểm tra trạng thái của chương trình tại một số điểm nhất định. Điều này bao gồm thiết lập chức năng theo dõi với tại mỗi dòng mã và kiểm tra các điểm ngắt, cũng như sử dụng các tính năng như ngăn xếp cuộc gọi và kiểm tra biến. Gỡ lỗi trình thông dịch Python chạy bên trong vùng chứa có khả năng tăng thêm độ phức tạp so với gỡ lỗi trình thông dịch Python chạy trên máy chủ. Điều này là do môi trường vùng chứa bị cô lập khỏi máy chủ. sys.settrace() Để khắc phục điều này, có thể thực hiện một trong hai cách chung sau: Có thể gỡ lỗi mã từ bên trong chính bộ chứa hoặc mã có thể được gỡ lỗi bằng cách sử dụng máy chủ gỡ lỗi từ xa. Đầu tiên, tôi sẽ sử dụng làm trình soạn thảo lựa chọn để trình bày cách thực hiện điều này. Sau đó, tôi sẽ giải thích cách hoạt động tương tự với . VSCode JetBrains PyCharm Gỡ lỗi mã từ bên trong vùng chứa Để phát triển và gỡ lỗi mã từ bên trong bộ chứa docker đang chạy bằng VSCode, tôi sẽ: 1. Đảm bảo đã cài đặt và bật cho VSCode. tiện ích mở rộng Docker 2. Đảm bảo vùng chứa mà tôi muốn đính kèm đang hoạt động. 3. Mở chế độ xem thám hiểm của tiện ích mở rộng Docker bằng cách nhấp vào biểu tượng Docker ở thanh bên trái. 4. Trong chế độ xem trình khám phá, hãy mở rộng phần "Vùng chứa đang chạy" và chọn vùng chứa mà tôi muốn đính kèm. 5. Nhấp chuột phải vào vùng chứa và chọn tùy chọn "Đính kèm Mã Visual Studio" từ menu ngữ cảnh. Điều này sẽ đính kèm Visual Studio Code vào vùng chứa đã chọn và mở một cửa sổ VSCode mới trong vùng chứa. Trong cửa sổ mới này, tôi có thể viết, chạy và gỡ lỗi mã như bình thường trên môi trường cục bộ. Để tránh phải cài đặt các tiện ích mở rộng VSCode, chẳng hạn như mỗi khi bộ chứa khởi động lại, tôi có thể gắn một ổ đĩa bên trong bộ chứa lưu trữ các tiện ích mở rộng VSCode. Bằng cách này, khi vùng chứa được khởi động lại, các tiện ích mở rộng sẽ vẫn khả dụng vì chúng được lưu trữ trên máy chủ. Để làm điều này bằng cách sử dụng docker soạn thảo trong dự án demo này, tập tin có thể được sửa đổi như sau: Python docker-compose.yml --- # Specify the version of the Docker Compose file format version: '3.9' services: # Define the authors_service service authors_service: ... # Mount the authors_service source code directory on the host to the working directory on the container volumes: - ./authors_service:/app # Mount the vscode extension directory on the host to the vscode extension directory on the container - /path/to/host/extensions:/root/.vscode/extensions # Define the posts_service service posts_service: ... Lưu ý rằng các tiện ích mở rộng VSCode thường có thể được tìm thấy tại trên Linux và macOS, hoặc trên Windows. ~/.vscode/extensions %USERPROFILE%\.vscode\extensions Sử dụng máy chủ gỡ lỗi Python từ xa Phương pháp gỡ lỗi ở trên hoạt động tốt đối với các tập lệnh độc lập hoặc để viết, chạy và kiểm tra gỡ lỗi. Tuy nhiên, việc gỡ lỗi một luồng logic liên quan đến nhiều dịch vụ đang chạy trong các vùng chứa khác nhau sẽ phức tạp hơn. Khi một vùng chứa được khởi động, dịch vụ chứa trong đó thường được khởi chạy ngay lập tức. Trong trường hợp này, máy chủ Flask trên cả hai dịch vụ đã chạy vào thời điểm VSCode được đính kèm, do đó, việc nhấp vào "Chạy và gỡ lỗi" và khởi chạy bản khác của máy chủ Flask là không thực tế vì nó sẽ dẫn đến nhiều phiên bản của cùng một dịch vụ đang chạy trên cùng một vùng chứa và cạnh tranh với nhau, đây thường không phải là quy trình gỡ lỗi đáng tin cậy. Điều này đưa tôi đến tùy chọn số hai; sử dụng máy chủ gỡ lỗi Python từ xa. Máy chủ gỡ lỗi Python từ xa là trình thông dịch Python đang chạy trên máy chủ từ xa và được định cấu hình để chấp nhận kết nối từ trình gỡ lỗi. Điều này cho phép sử dụng trình gỡ lỗi đang chạy cục bộ để kiểm tra và kiểm soát quy trình Python đang chạy trên môi trường từ xa. một phiên Điều quan trọng cần lưu ý là thuật ngữ "từ xa" không nhất thiết đề cập đến một máy từ xa vật lý hoặc thậm chí là một môi trường cục bộ nhưng bị cô lập, chẳng hạn như bộ chứa Docker chạy trên máy chủ. Máy chủ gỡ lỗi từ xa Python cũng có thể hữu ích để gỡ lỗi quy trình Python đang chạy trong cùng môi trường với trình gỡ lỗi. Trong ngữ cảnh này, tôi sẽ sử dụng một máy chủ gỡ lỗi từ xa đang chạy trong cùng vùng chứa với quá trình tôi đang gỡ lỗi. Sự khác biệt chính giữa phương pháp này và tùy chọn đầu tiên để gỡ lỗi mà chúng tôi đề cập là tôi sẽ đính kèm vào một quy trình có sẵn thay vì tạo một quy trình mới mỗi khi tôi muốn chạy và gỡ lỗi mã. Để bắt đầu, bước đầu tiên là thêm gói vào tập tin cho cả hai dịch vụ. debugpy là trình gỡ lỗi Python mã nguồn mở cấp cao có thể được sử dụng để gỡ lỗi các chương trình Python cục bộ hoặc từ xa. Tôi sẽ thêm dòng sau vào cả hai các tập tin: debugpy requirements.txt requirements.txt debugpy == 1 . 6 . 4 Bây giờ tôi cần xây dựng lại hình ảnh để cài đặt gỡ lỗi trên hình ảnh Docker cho từng dịch vụ. tôi sẽ chạy lệnh để làm điều này. Sau đó tôi sẽ chạy để khởi động các container. docker-compose build docker-compose up Tiếp theo, tôi sẽ đính kèm VSCode vào bộ chứa đang chạy có chứa quy trình mà tôi muốn gỡ lỗi, như tôi đã làm ở trên. Để đính kèm trình gỡ lỗi vào ứng dụng python đang chạy, tôi cần thêm đoạn mã sau vào mã tại điểm mà tôi muốn bắt đầu gỡ lỗi: import debugpy; debugpy.listen( 5678 ) Đoạn mã này nhập mô-đun gỡ lỗi và gọi bắt đầu một máy chủ gỡ lỗi lắng nghe các kết nối từ trình gỡ lỗi trên số cổng đã chỉ định (trong trường hợp này là 5678). listen Nếu tôi muốn gỡ lỗi , tôi có thể đặt đoạn mã trên ngay trước khai báo hàm trong tập tin - như sau: authors_service get_author_by_id app.py app = flask.Flask(__name__) ... import os import flask import requests from faker import Faker import debugpy; debugpy.listen( 5678 ) @app.route( "/authors/<string:author_id>" , methods=[ "GET" ] ) def get_author_by_id ( author_id: str ): Điều này sẽ khởi động một máy chủ gỡ lỗi khi khởi động ứng dụng vì tập lệnh được thực thi. app.py Bước tiếp theo là tạo cấu hình khởi chạy VSCode để gỡ lỗi ứng dụng. Trong thư mục gốc của dịch vụ chứa bộ chứa mà tôi đã đính kèm (và trên đó tôi đang chạy cửa sổ VSCode), tôi sẽ tạo một thư mục có tên . Sau đó, trong thư mục này, tôi sẽ tạo một tệp có tên , với nội dung như sau: .vscode launch.json { } } ] } { "version" : "0.2.0" , "configurations" : [ "name" : "Python: Remote Attach" , "type" : "python" , "request" : "attach" , "connect" : { "host" : "localhost" , "port" : 5678 Cấu hình này chỉ định rằng VSCode sẽ đính kèm với trình gỡ lỗi Python chạy trên máy cục bộ (tức là vùng chứa hiện tại) trên cổng 5678 - điều quan trọng là cổng được chỉ định khi gọi hàm chức năng trên. debugpy.listen Sau đó tôi sẽ lưu tất cả các thay đổi. Trong chế độ xem trình khám phá của tiện ích mở rộng Docker, tôi sẽ nhấp chuột phải vào vùng chứa mà tôi hiện đang đính kèm và chọn "Khởi động lại vùng chứa" từ menu ngữ cảnh (được thực hiện trên phiên bản VSCode cục bộ). Sau khi khởi động lại bộ chứa, cửa sổ VSCode trong bộ chứa sẽ hiển thị hộp thoại hỏi tôi có muốn tải lại cửa sổ không - câu trả lời đúng là có. Bây giờ tất cả những gì còn lại là xem nó hoạt động!Để bắt đầu gỡ lỗi, trong phiên bản VSCode đang chạy trên bộ chứa, tôi sẽ mở tập lệnh mà tôi muốn gỡ lỗi và nhấn F5 để bắt đầu trình gỡ lỗi. Trình gỡ lỗi sẽ đính kèm vào tập lệnh và tạm dừng thực thi tại dòng mà chức năng được gọi. Giờ đây, các điều khiển trình gỡ lỗi trong tab Gỡ lỗi có thể được sử dụng để duyệt qua mã, đặt điểm dừng và kiểm tra các biến. debugpy.listen Điều này đáp ứng yêu cầu "Gỡ lỗi" ở trên. Phát triển và gỡ lỗi từ xa với Jetbrains Pycharm IDE Theo , có hai cách để giải quyết vấn đề này khi sử dụng PyCharm: Có thể truy xuất trình thông dịch từ hình ảnh Docker bằng tính năng và/hoặc . Lưu ý rằng hai tùy chọn này không loại trừ lẫn nhau. Cá nhân tôi chủ yếu dựa vào tính năng phiên dịch từ xa để phát triển và sử dụng cấu hình máy chủ gỡ lỗi từ xa nếu và khi cần thiết. tài liệu chính thức trình thông dịch từ xa cấu hình máy chủ gỡ lỗi từ xa Thiết lập trình thông dịch từ xa Để thiết lập trình thông dịch từ xa trên PyCharm, tôi sẽ: 1. Nhấp vào menu bật lên tab trình thông dịch ở góc dưới cùng bên phải của cửa sổ IDE. 2. Nhấp vào , sau đó chọn từ trình đơn bật lên. Thêm trình thông dịch mới Trên trình soạn thảo docker... 3. Trong cửa sổ bật lên tiếp theo, chọn tệp soạn thảo docker có liên quan, sau đó chọn dịch vụ có liên quan từ danh sách thả xuống. Bây giờ PyCharm sẽ cố gắng kết nối với hình ảnh docker và truy xuất các trình thông dịch python có sẵn. 4. Trong cửa sổ tiếp theo, chọn trình thông dịch python mà tôi muốn sử dụng (ví dụ: ). Khi trình thông dịch đã được chọn, nhấp vào "Tạo". /usr/local/bin/python Sau đó, PyCharm sẽ lập chỉ mục cho trình thông dịch mới, sau đó tôi có thể chạy hoặc gỡ lỗi mã như bình thường - PyCharm sẽ điều phối việc soạn thảo docker phía sau hậu trường cho tôi bất cứ khi nào tôi muốn làm như vậy. Thiết lập cấu hình máy chủ gỡ lỗi từ xa Để thiết lập cấu hình máy chủ gỡ lỗi từ xa, trước tiên tôi cần thêm hai phụ thuộc vào liên quan (các) tệp: và . Các gói này có chức năng tương tự như gói gỡ lỗi đã trình bày ở trên, nhưng, như tên gọi của nó, pydevd_pycharm được thiết kế đặc biệt để gỡ lỗi với PyCharm. Trong ngữ cảnh của dự án demo này, tôi sẽ thêm hai dòng sau vào cả hai các tập tin: requirements.txt pydevd pydevd_pycharm requirements.txt pydevd ~= 2 . 9 . 1 pydevd -pycharm== 223 . 8214 . 17 Khi điều này được thực hiện và hình ảnh docker đã được xây dựng lại, tôi có thể nhúng đoạn mã sau vào mã để khởi động máy chủ gỡ lỗi pydevd_pycharm tại điểm trong mã mà tôi muốn bắt đầu gỡ lỗi: import pydevd_pycharm; pydevd_pycharm.settrace( 'host.docker.internal' , 5678 ) Lưu ý rằng không giống như gỡ lỗi, ở đây tôi đã chỉ định địa chỉ tên máy chủ có giá trị "host.docker.internal", là tên DNS phân giải thành địa chỉ IP nội bộ của máy chủ từ bên trong bộ chứa Docker. Điều này là do tôi không chạy PyCharm trên vùng chứa; thay vào đó, tôi đang định cấu hình hiệu quả máy chủ gỡ lỗi để nghe trên cổng 5678 . của máy chủ Tùy chọn này cũng tồn tại với tính năng gỡ lỗi, nhưng vì trong trường hợp đó tôi đang chạy một phiên bản VSCode nên nó đã đơn giản hóa mọi thứ để chỉ để địa chỉ tên máy chủ mặc định là "localhost" (tức là giao diện loopback của chính bộ chứa đó, chứ không phải máy chủ). trên chính bộ chứa, Bước cuối cùng là thiết lập cấu hình chạy mà PyCharm có thể sử dụng để kết nối với máy chủ gỡ lỗi từ xa. Để làm điều này, tôi sẽ: 1. Mở hộp thoại Chạy/Gỡ lỗi Cấu hình bằng cách chọn > từ menu chính. 2. Nhấp vào nút ở góc trên cùng bên trái của hộp thoại và chọn từ trình đơn thả xuống. 3. Trong trường , nhập tên cho cấu hình chạy. 4. Trong trường , chỉ định đường dẫn đến tập lệnh mà tôi muốn gỡ lỗi. 5. Trong trường , hãy nhập địa chỉ IP của máy chủ mà máy chủ trình gỡ lỗi sẽ chạy. Trong ví dụ này, đó là "localhost". Chạy Chỉnh sửa Cấu hình + Python Remote Debug Tên Đường dẫn tập lệnh Máy chủ 6. Trong trường , hãy nhập số cổng mà máy chủ trình gỡ lỗi sẽ nghe. Trong ví dụ này, đó là 5678. Cổng 7. Trong phần , tôi có thể chỉ định cách các đường dẫn trên máy chủ ánh xạ tới các đường dẫn bên trong vùng chứa. Điều này hữu ích nếu tôi đang gỡ lỗi mã được gắn vào bộ chứa từ máy chủ, vì các đường dẫn có thể không giống nhau trong cả hai môi trường. Trong ví dụ này, tôi sẽ muốn lập bản đồ trên máy chủ, để trong vùng chứa để gỡ lỗi tác giả_service hoặc đến trên vùng chứa để gỡ lỗi posts_service (đây sẽ cần phải là hai cấu hình chạy riêng biệt). Ánh xạ đường dẫn path/to/project/on/host/authors_service /app path/to/project/on/host/posts_service /app 8. Nhấn để lưu cấu hình chạy. Để bắt đầu gỡ lỗi, tôi sẽ chọn cấu hình chạy ở trên từ menu thả xuống và nhấp vào nút , sau đó quay (các) vùng chứa có liên quan bằng chỉ huy. Trình gỡ lỗi PyCharm sẽ đính kèm vào tập lệnh và tạm dừng thực thi tại dòng nơi tập lệnh chức năng được gọi, cho phép tôi bắt đầu đập những lỗi đó. OK Chạy Gỡ lỗi docker-compose up pydevd_pycharm.settrace Tóm tắt Trong hướng dẫn này, tôi đã đưa ra một cái nhìn tổng quan nhưng thực tế về môi trường phát triển python được container hóa, tại sao chúng lại hữu ích và cách viết, triển khai và gỡ lỗi mã python bằng cách sử dụng chúng. Xin lưu ý rằng đây không phải là hướng dẫn toàn diện để làm việc với các môi trường này. Nó chỉ đơn thuần là một điểm khởi đầu để từ đó mở rộng. Dưới đây là một vài liên kết hữu ích để kết thúc đó: 1. Tổng quan về container hóa bằng redhat 3. Tài liệu Docker chính thức 4. Tài liệu JetBrains PyCharm chính thức để gỡ lỗi từ xa 5. Tài liệu VSCode chính thức để phát triển Python trên vùng chứa dev Tôi hy vọng bạn thấy hướng dẫn này hữu ích - cảm ơn vì đã đọc!