Dự án mongodb bình python

Ở bài trước mình đã hướng dẫn các bạn cách dockerize một ứng dụng NodeJS, đồng thời với đó là một số khái niệm và câu hỏi liên quan trong bài

Ở bài này chúng ta sẽ tiếp tục series bằng cách thực hiện dockerize một ứng dụng Python Flask nhé.

Dự án mongodb bình python

"ĐỪNG DỪNG KHÔNG, TIẾP THEO, TIẾP THEO, chuyển bài ông ơiiiii. Tôi dev NodeJS PHP chứ không phải Python đâu mà quan tâm"

Dự án mongodb bình python
Dự án mongodb bình python

Mục đích của series này là mình sẽ hướng dẫn các bạn học Docker, trong bài này mình nghĩ các bạn hoàn toàn có thể hiểu được dù mình chưa bao giờ code Python. Do đó mình hi vọng rằng các bạn vẫn sẽ theo dõi được series này, từng bài từng bài, vì trong mỗi bài sẽ có những vấn đề liên quan đến Docker mình muốn gửi cho các bạn

Bắt tay vào làm thôi nào

Tiền cài đặt

Nhớ kiểm tra xem bạn đã cài đặt Docker và Docker-compose chưa nhé. Nếu chưa thì nhớ xem lại phần cuối bài viết trước của mình để biết cách cài đặt nhé

Cài đặt

Các bạn clone mã nguồn ở đây về nhé

Ở bài này ta sẽ chỉ quan tâm tới thư mục docker-python sau khi clone nhé

Dự án mongodb bình python
. Ở đó mình đã setup cho các bạn một ứng dụng Python sử dụng Flask framework nhé (bạn nào dev PHP có thể coi nó như Laravel của PHP vậy
Dự án mongodb bình python
)

Nếu các bạn đã cài đặt Python trên máy thì có thể chạy command sau để chạy project nhé.

pip install -r requirements.txt
python app.py

Mở trình duyệt tại địa chỉ localhost. 5000 and you will see line Hello World

Còn nếu máy bạn không có Python thì vẫn tuyệt vời ô liệt kê nhé. Chỉ cần các bạn đã cài Docker và Docker soạn, những thứ khác có hay không có, không quan trọng

Dự án mongodb bình python
Dự án mongodb bình python

Xây dựng hình ảnh Docker

Vẫn như ở bài trước, đầu tiên ta cần tạo file cấu hình Dockerfile và định nghĩa môi trường chúng ta mong muốn, sau đó ta sẽ build image và chạy nhé

Dự án mongodb bình python

Cấu hình Dockerfile

At the docker-python docker-python do các bạn tạo tên file là Dockerfile, bên trong có nội dung như sau

FROM python:3.6-alpine

WORKDIR /app

COPY . .

RUN pip install -r requirements.txt

CMD ["python", "app.py"]

Giải thích

  • Dòng đầu tiên FROM. ta bắt đầu từ 1 Hình ảnh có môi trường Alpint và đã cài sẵn Python phiên bản 3. 6. Xem danh sách Image Python ở đâu, các bạn check ở link chính thức này nhé
  • Lí do sao lại chọn Alpine mà không phải Ubuntu hay Debian, CentOS,. Thì ở mình đã phân tích rồi nhé. Đồng thời xuyên suốt loạt bài này mình sẽ luôn sử dụng môi trường hệ điều hành Alpine Linux nhé
  • Tiếp theo trong file Dockerfile ta có WORKDIR. ý là ta sẽ chuyển đến đường dẫn là /app bên trong Hình ảnh, nếu đường dẫn này không tồn tại thì sẽ tự động được tạo luôn nhé
  • Tiếp theo ta COPY toàn bộ file từ thư mục ở môi trường gốc (bên ngoài - thư mục docker-python) và đưa vào đường dẫn /app bên trong Image
  • Tiếp theo là ta cài đặt phụ thuộc, cần cài đặt thứ gì thì ta đề cập sẵn ở tệp yêu cầu. txt rồi (câu lệnh này các bạn có thể xem nó xêm xêm như npm install trong NodeJS nhé)
  • Cuối cùng là ta sử dụng CMD để chỉ lệnh mặc định khi một vùng chứa được khởi tạo từ Image. ở đây ta sẽ khởi động file app. py

Xây dựng hình ảnh Docker

Sau khi cấu hình nhiễn thì ngon rồi,bước tiếp theo là ta build Image thôi. Các bạn chạy lệnh sau để build Image nhé

docker build -t learning-docker/python:v1 .

Ở mình đã giải thích cho các bạn lệnh trên làm gì rồi các bạn có thể xem lại nhé

Giải thích nhanh. command on will build 1 image name is learning-docker/python with tag is v1, both name and tag ta đều có thể tùy chọn tùy ý, nếu ta không để tag thì sẽ tự động được lấy là mới nhất. Dấu "chấm" ở cuối ghi chú Docker là "tìm file Dockerfile ở thư mục hiện tại và build" nhé

Dự án mongodb bình python

Sau khi quá trình build Image thành công, các bạn có thể kiểm tra bằng lệnh

docker images

Will see display as after nhé

Dự án mongodb bình python
.

Vẫn ở thư mục docker-python, bạn đã tạo tệp docker-compose. yml, with the content as after

version: "3.7"

services:
  app:
    image: learning-docker/python:v1
    ports:
      - "5000:5000"
    restart: unless-stopped

Ở mình đã giải thích cho các bạn những thứ bên trên. Nếu các bạn chưa đọc thì nên xem qua nhé

Dự án mongodb bình python
.

Giải thích nhanh

  • Ta định nghĩa 1 tên dịch vụ là ứng dụng, dịch vụ này khi chạy sẽ tạo ra 1 vùng chứa tương ứng, vùng chứa được tạo từ hình ảnh với tên chúng ta đã chọn
  • Ta ánh xạ cổng từ cổng 5000 ở máy gốc (bên ngoài) vào cổng 5000 bên trong container, vì dự án của chúng ta được chạy ở cổng 5000 (default of Flask)

Nói nôm na là cách setup chả khác cho bài trước làm với NodeJS là mấy nhỉ

Dự án mongodb bình python
.

To start project you run command after

docker-compose up

Sau đó các bạn sẽ thấy ở terminal được hiển thị như sau

Dự án mongodb bình python

Dự án mongodb bình python
Dự án mongodb bình python

Cố gắng xem lại mã xem nhé

  • ứng dụng tệp. py menu khá đơn giản, không có gì đáng gờm
  • Đã có command run app at file Dockerfile
  • Port also map at file docker-compose. yml

Vấn đề là ở đâu nhỉ??

Rõ ràng nếu mình chạy trực tiếp từ môi trường bên ngoài, máy gốc của mình (nếu ở máy gốc các bạn có cài Python), không dùng Docker nữa thì mọi thứ vẫn oke mà nhỉ.

Dự án mongodb bình python
Dự án mongodb bình python

Cố gắng xem lại tài liệu của Flask ở đây, và chúng ta đã tìm ra chân lý, chúng ta dành cho mục Máy chủ có thể nhìn thấy bên ngoài. Mình sẽ dịch luôn cho các bạn

Nếu bạn chạy ứng dụng lên thì bạn sẽ để ý thấy rằng ứng dụng của bạn chỉ có thể truy cập được trong phạm vi máy của bạn (localhost), điều này được cài đặt mặc định

Do đó khi chạy project của chúng ta trong container thì chỉ môi trường trong container mới truy cập được vào project, project của chúng ta coi môi trường đó mới là localhost, còn từ môi trường gốc (bên ngoài) truy vấn thì sẽ không được

Ghi chú. các bạn lưu ý điều này vì sau này khi dockerize project Nuxt cũng sẽ tương tự

Do that to fix this thing ta doing as after

Các bạn đã sửa lại ứng dụng tệp. py một chút như sau nhé

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def hello():
    return render_template('index.html', title='Docker Python', name='James')

if __name__ == "__main__":
    app.run(host="0.0.0.0")

At on ta only add to duy nhất host=0. 0. 0. 0 để nói với dự án chúng ta là "chấp nhận cho tất cả mọi IP truy cập"

Ổn rồi đó chúng ta build lại ảnh nhé

docker build -t learning-docker/python:v1 .

Sau khi build xong ta cần khởi động lại project nhé, các bạn chạy lệnh sau

docker-compose down
docker-compose up

Và cuối cùng là mở trình duyệt và kiểm tra thôi nào

Dự án mongodb bình python
Dự án mongodb bình python

Môi trường biến đổi (ENV)

Bài trước và bài các bạn có thể thấy là project khi chạy đều được fix phần cứng 1 cổng (bài trước là 3000, bài này là 5000), thế nếu ta muốn container chạy ở cổng khác thì ta lại phải sửa code hay sao?

Lúc đó ta sẽ nghĩ đến biến môi trường (environment variable), trong quá trình dev và khi chạy thực tế sử dụng biến môi trường sẽ giúp ta rất nhiều trong việc giảm tối thiểu công việc phải chỉnh sửa code

Biến môi trường tại Dockerfile

Đầu tiên là ta sẽ thử dùng biến môi trường khai báo ở Dockerfile để thiết lập Port(cổng) cho project chạy trong container nhé (ý là container sẽ không chạy ở port 5000 nữa)

Ở ứng dụng tệp. py ta sửa lại như sau

FROM python:3.6-alpine

WORKDIR /app

COPY . .

RUN pip install -r requirements.txt

CMD ["python", "app.py"]
0

Sau đó ở file Dockerfile ta sửa lại như sau

FROM python:3.6-alpine

WORKDIR /app

COPY . .

RUN pip install -r requirements.txt

CMD ["python", "app.py"]
1

Tại tệp docker-compose. yml ta sửa lại một chút như sau nhé

FROM python:3.6-alpine

WORKDIR /app

COPY . .

RUN pip install -r requirements.txt

CMD ["python", "app.py"]
2

Các bạn lưu ý ở trên khi ta map port ta chỉ chuyển từng cảnh bên phải, cảnh bên phải là cổng của dự án đang chạy trong container nhé, cảnh bên trái là cổng ở môi trường gốc (bên ngoài, ta có thể tùy chọn ý

Tiếp tục theo ta process build back image nhé

docker build -t learning-docker/python:v1 .

And start up project

docker-compose down
docker-compose up

Mở trình duyệt tại địa chỉ localhost. 5000 (vẫn như cũ), các bạn sẽ thấy mọi thứ chạy bình thường, nhưng nhìn qua Terminal thì sẽ thấy như sau

Dự án mongodb bình python

Thế nếu bây giờ ta muốn đổi port của project trong container thành 6666 thì sao, ta lại phải build lại Image?

Với những dạng môi trường biến mà dễ thay đổi thì ta có sự lựa chọn khác đơn giản hơn đó là khai báo ở file docker-compose. yml nhé

Biến môi trường tại docker-compose

Để không phải build lại image mỗi lần ta đổi port, ta sẽ khai báo biến môi trường tại docker-compose. yml nhé. in sao

  • Biến môi trường tại file Dockerfile sẽ được khai báo khi ta build image
  • Biến môi trường tại file docker-compose. yml will be started when container is started, tức là khi ta chạy docker-compose up. Làm vậy để thay đổi môi trường biến môi trường ta chỉ cần down và up là xong
    Dự án mongodb bình python

Thử nghiệm thôi nào

Tại file Dockerfile ta xóa dòng ENV PORT 5555 đi nhé

Sau đó ở file docker-compose. yml ta sửa lại như sau

FROM python:3.6-alpine

WORKDIR /app

COPY . .

RUN pip install -r requirements.txt

CMD ["python", "app.py"]
5

Bây giờ ta vẫn cần build lại image 1 lần để update mới áp dụng được

docker build -t learning-docker/python:v1 .

Sau đó ta khởi động lại project nhé

docker-compose down
docker-compose up

Sau đó F5 lại trình duyệt để đảm bảo mọi thứ vẫn ổn và xem ở terminal

Dự án mongodb bình python
)

Cách tốt hơn để tạo môi trường biến

Ở ví dụ trên nếu ta muốn đổi PORT thành 7777 chẳng hạn, ta phải sửa ở 2 chỗ trong file docker-compose. yml, vậy nếu biến đó được sử dụng ở vị trí 100 trong tệp docker-compose. yml thì sao?

docker-compose support ta a way đơn giản hơn, tiện lợi hơn để khởi động môi trường biến, that is set at file. env (giống y như Laravel

Dự án mongodb bình python
, cũng đồng nghĩa với việc nếu ta dockerize project Laravel thì ta chỉ cần duy nhất 1 file chung là. vi). Khi chạy project thì docker-compose sẽ tự tìm file có. env or not and load the variable in that.

Cùng thử nhé

Dự án mongodb bình python

Tại thư mục docker-python ta tạo file. env with rest as after

FROM python:3.6-alpine

WORKDIR /app

COPY . .

RUN pip install -r requirements.txt

CMD ["python", "app.py"]
8

Giải thích

  • PORT biến. chỉ port của project đang chạy bên trong container
  • biến PUBLIC_PORT. only port that "external world" used to access to project
    Dự án mongodb bình python
    (ý là port ta gọi ở trình duyệt)

Ta sửa lại file docker-compose. yml as after

FROM python:3.6-alpine

WORKDIR /app

COPY . .

RUN pip install -r requirements.txt

CMD ["python", "app.py"]
9

Sau đó ta khởi động lại project nhé

docker-compose down
docker-compose up

Kiểm tra ở terminal ta sẽ thấy

Dự án mongodb bình python
)

Đẩy hình ảnh lên sổ đăng ký

Ở bài trước dài quá mình chưa nói thêm vào ảnh đã đưa lên sổ đăng ký và làm cho người khác có thể chạy dự án của bạn từ ảnh như thế nào. Ở bài này thì ta có đất diễn rồi

Dự án mongodb bình python

Docker build chạy ngon nghẻ ở máy của ta rồi thì thử đưa cho người khác xem họ chạy thế nào chứ nhỉ

Dự án mongodb bình python

registry là nơi ta lưu Docker image (giống như github để lưu code, còn đây là lưu Docker image), có rất nhiều registry, có public có private

Ở trong series này ta sẽ dùng Gitlab để lưu code và cả lưu image vào registry của mình nhé. Gitlab cho ta Unlimited image ở private registry cho từng kho lưu trữ (quá tuyệt vời mà free back but private)

Tạo tài khoản và kho lưu trữ trên Gitlab

Đầu tiên các bạn cần tạo 1 tài khoản trên Gitlab. com (if not have). Sau đó ta tạo một kho tên là learning-docker cho toàn bộ series này nhé

Dự án mongodb bình python

Sau đó bấm chọn kho ta vừa tạo, để ghi chú ở phần sidebar bên trái, di chuột vào Packages, sau đó bấm chọn Container Registry, đây chính là nơi ta sẽ dùng để lưu trữ ảnh nhé

Dự án mongodb bình python

Các bạn sẽ thấy được hiển thị như sau

Dự án mongodb bình python

Đầu tiên là ở hình trên, ta cần đăng nhập vào sổ đăng ký của Gitlab trước (vì sổ đăng ký này là riêng tư mà

Dự án mongodb bình python
). Ta run command after to login.

docker build -t learning-docker/python:v1 .
1

Ta sẽ thấy ở terminal hỏi email và mật khẩu tài khoản gitlab, các bạn nhập thông số của các bạn vào nhé

Sau đó bước tiếp theo như ở hình trên ta cần dựng hình. Nhưng vì image ta đã có sẵn ở local rồi nên ta không cần build lại nữa

"Ok vậy là tôi có thể luôn luôn lên Gitlab rồi đó là gì?"

Dự án mongodb bình python

Khi đưa hình ảnh lên sổ đăng ký của gitlab, ta cần phải đặt tên hình ảnh theo tiêu chuẩn của họ, thẻ có thể đặt tùy chọn nhưng tên phải đúng, theo định dạng sau