Chào mọi người. Chúng tôi tiếp tục loạt bài về cách viết dự án của bạn.
Sắp xếp các nhánh
Điều quan trọng là, để không bị lạc giữa các nhánh và thứ tự của chúng trong kho lưu trữ, tôi quyết định đổi tên chúng bằng cách thêm tiền tố STEP_{number} . Ví dụ: chúng tôi có ba nhánh ngoài nhánh chính:- JRTB-0
- JRTB-2
- JRTB-3
- STEP_1_JRTB-0 - bước đầu tiên
- STEP_2_JRTB-2 - bước thứ hai
- STEP_3_JRTB-3 - bước thứ ba
Một chút về Docker
Docker là gì? Tóm lại, nó là một công cụ giúp bạn có thể triển khai (triển khai) ứng dụng một cách nhanh chóng và an toàn, tạo cho chúng một cơ sở hạ tầng khép kín chỉ cần thiết cho chúng. Nó vẫn còn khó khăn, tôi hiểu. Nhìn chung, Docker có thể được hiểu là một nền tảng phát triển nơi bạn có thể làm việc nhanh chóng và hiệu quả. Docker có thể hiểu là một chương trình chạy trên máy chủ. Chương trình này có khả năng lưu trữ các container với các ứng dụng. Thùng chứa là gì? Đây là một cơ sở hạ tầng riêng biệt mà bạn có thể thêm mọi thứ bạn cần vào. Ví dụ: đối với một ứng dụng Java, chúng ta cần JRE để chạy ứng dụng, container sẽ có cái này, chúng ta sẽ cần một số phần mềm khác - chúng ta có thể thêm cái này. Hoặc có thể chúng ta cần Linux và bộ chứa servlet Tomcat. Điều này cũng có thể được thực hiện. Các vùng chứa được tạo dựa trên hình ảnh: nghĩa là đây là một mẫu cụ thể chứa mọi thứ cần thiết để tạo vùng chứa Docker. Làm thế nào để tạo ra hình ảnh này? Trong trường hợp của chúng tôi, chúng tôi sẽ cần tạo một Dockerfile ở thư mục gốc của dự án mô tả những gì sẽ có trong vùng chứa. Vì chúng tôi không muốn để lộ mã thông báo của bot ở bất kỳ đâu nên chúng tôi sẽ phải chuyển mã thông báo này mỗi lần chúng tôi muốn triển khai ứng dụng. Bạn có thể đọc thêm về chủ đề này ở đây và ở đây .Chúng tôi viết JRTB-13
Chúng ta cần thiết lập quy trình triển khai nhanh chóng và dễ dàng cho ứng dụng của mình lên máy chủ. Tức là đối với một cỗ máy hoạt động 24/7. Hãy lấy Docker làm cơ sở. Nhưng không có nhiệm vụ nào trong danh sách của chúng tôi chịu trách nhiệm thêm chức năng này. Bằng cách nào đó tôi đã bỏ lỡ nó khi tạo ra nó. Không vấn đề gì, hãy tạo nó ngay bây giờ. Chúng ta đi tới tab tạo vấn đề trên GitHub và chọn Yêu cầu tính năng: Thêm mô tả về nhiệm vụ, tiêu chí để chấp nhận nó, đặt vấn đề này thuộc về dự án nào và bạn có thể tạo một vấn đề mới: Bây giờ, để cho thấy rằng nhiệm vụ đã được thực hiện được chấp nhận cho công việc, hãy thay đổi trạng thái của nhiệm vụ từ Đang thực hiện: Đây sẽ là một bài viết khó. Nếu có vấn đề gì hãy viết bình luận: Mình sẽ theo dõi và giải đáp trong khả năng của mình. Đây sẽ là một Hỗ trợ khách hàng nhỏ :DTạo một Dockerfile
Dockerfile là gì? Đối với Docker, đây là tập lệnh (hướng dẫn từng bước) về cách tạo hình ảnh cho vùng chứa Docker. Để ứng dụng của chúng tôi hoạt động, chúng tôi cần JDK, phiên bản 11. Tức là chúng ta cần tìm hình ảnh docker JDK 11 và thêm nó vào hình ảnh của mình. Điều này tương tự như cách chúng ta thêm phần phụ thuộc vào bộ nhớ. Docker có DockerHub cho mục đích này . Để tải hình ảnh xuống cục bộ, bạn cần phải đăng ký ở đó. Sau khi đăng ký, chúng ta hãy đi tìm JDK11. Từ những gì tôi tìm thấy, đây là vùng chứa: Adoptopenjdk/openjdk11 . Mô tả của vùng chứa này có những gì cần thiết cho dockerfile:FROM adoptopenjdk/openjdk11:ubi
RUN mkdir /opt/app
COPY japp.jar /opt/app
CMD ["java", "-jar", "/opt/app/japp.jar"]
Hãy sửa thư mục mà chúng ta lấy tệp jar. Chúng tôi có nó trong thư mục đích sau khi chạy tác vụ maven gói mvn. Trước khi thực hiện tất cả những điều này, dựa trên nhánh chính đã cập nhật, chúng tôi tạo một nhánh mới cho nhiệm vụ của mình: STEP_4_JRTB-13 . Bây giờ bạn có thể làm việc. Trong thư mục gốc của dự án, tạo một tệp không có phần mở rộng Dockerfile và thêm phần sau vào bên trong:
FROM adoptopenjdk/openjdk11:ubi
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
Dòng đầu tiên là nội dung của hình ảnh - Adoptopenjdk/openjdk11. Dòng thứ hai là thêm đối số vào hình ảnh có tên JAR_FILE, nằm trong thư mục đích. Hơn nữa, thư mục hiện tại được xác định bởi vị trí của Dockerfile. Dòng thứ ba - sao chép jar của dự án của chúng tôi vào hình ảnh docker. Dòng cuối cùng về cơ bản chứa một mảng được tạo từ lệnh trong terminal, được phân tách bằng dấu cách. Nghĩa là, cuối cùng, lệnh sau sẽ được thực thi: “java -jar /app.jar” Để giữ bí mật mã thông báo bot, khi khởi động vùng chứa, chúng ta sẽ cần chuyển hai biến - tên của bot và mã thông báo của nó. Để làm điều này, chúng ta sẽ viết một truy vấn để khởi chạy dự án của chúng ta với các biến. Và làm thế nào để làm điều đó? Bạn cần phải tra Google: đây là liên kết đầu tiên có mô tả thông thường. chúng ta muốn làm cái gì? Chúng tôi có hai biến trong tệp application.properties mà chúng tôi xác định ở đó:
- bot.tên người dùng
- bot.token
- Hãy chạy tập lệnh bash.
- Tập lệnh bash chạy docker-compose.
- Docker-compose khởi chạy một container docker với ứng dụng của chúng tôi.
- Bộ chứa Docker chạy ứng dụng của chúng tôi.
FROM adoptopenjdk/openjdk11:ubi
ARG JAR_FILE=target/*.jar
ENV BOT_NAME=test.javarush_community_bot
ENV BOT_TOKEN=1375780501:AAE4A6Rz0BSnIGzeu896OjQnjzsMEG6_uso
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-Dbot.username=${BOT_NAME}", "-Dbot.token=${BOT_TOKEN}", "-jar", "/app.jar"]
Bạn có thể thấy rằng chúng tôi đã thêm hai dòng và cập nhật ENTRYPOINT. Dòng:
ENV BOT_NAME=test.javarush_community_bot
ENV BOT_TOKEN=1375780501:AAE4A6Rz0BSnIGzeu896OjQnjzsMEG6_uso
khai báo các biến bên trong tệp mã hóa. Theo mặc định, chúng có một giá trị được chỉ định. Nếu khi tạo một hình ảnh từ dockerfile này, các biến môi trường có tên như vậy được truyền vào thì các giá trị sẽ khác. Và trong ENTRYPOINT, chúng tôi đã thêm một số phần tử nữa sẽ đọc các biến môi trường này:
"-Dbot.username=${BOT_NAME}", "-Dbot.token=${BOT_TOKEN}"
Ở đây bạn có thể thấy rằng bên trong dòng, sử dụng cấu trúc ${}, các giá trị của BOT_NAME và BOT_TOKEN sẽ được chuyển. Tiếp theo, chúng ta cần dạy cách nhận và chuyển các biến này sang docker-compose.
Tạo docker-compose.yml
Sẽ rất tốt nếu bạn đọc riêng về định dạng YAML, nếu không, bài viết đã phát triển nhảy vọt. Đối với chúng tôi, đây chỉ là một mô tả khác về các biến thuộc loại .properties. Chỉ trong thuộc tính, nó được viết bằng dấu chấm, nhưng trong YAML, điều này được thực hiện đẹp hơn một chút. Ví dụ như thế này. Hai biến trong .properties: javarush.telegram.bot.name=ivan javarush.telegram.bot.token=pupkin Nhưng trong .yaml (giống như .yml), nó sẽ như thế này:javarush:
telegram:
bot:
name: ivan
token: pupkin
Lựa chọn thứ hai đẹp hơn và dễ hiểu hơn. Các khoảng trống phải chính xác như được chỉ ra ở trên. Hãy dịch application.properties và application.yml của chúng ta bằng cách nào đó. Đầu tiên bạn cần tạo nó. Trong thư mục gốc của dự án, tạo một tệp docker-compose.yml và viết nội dung sau vào đó:
version: '3.1'
services:
jrtb:
build:
context: .
environment:
- BOT_NAME=${BOT_NAME}
- BOT_TOKEN=${BOT_TOKEN}
restart: always
Dòng đầu tiên là phiên bản docker-compose. dịch vụ: cho biết rằng tất cả các dòng sau dòng này (sẽ được thay đổi) đề cập đến các dịch vụ mà chúng tôi đang định cấu hình. Cho đến nay chúng tôi chỉ có một trong số này - một ứng dụng java có tên jrtb . Và bên dưới nó sẽ là tất cả các cài đặt của nó. Ví dụ: build: context: . nói rằng chúng tôi sẽ tìm Dockerfile trong cùng thư mục với docker-compose.yml. Nhưng phần môi trường: sẽ chịu trách nhiệm đảm bảo rằng chúng ta chuyển các biến môi trường cần thiết cho Dockerfile. Đúng thứ chúng ta cần. Vì vậy, chúng tôi chuyển các biến bên dưới. Docker-compose sẽ tìm kiếm chúng trong các biến môi trường vận hành máy chủ. Hãy thêm chúng vào tập lệnh bash.
Tạo tập lệnh bash
Bước cuối cùng là tạo một tập lệnh bash. Tạo một tệp có tên start.sh trong thư mục gốc của dự án và viết nội dung sau vào đó:#!/bin/bash
# Pull new changes
git pull
# Prepare Jar
mvn clean
mvn package
# Ensure, that docker-compose stopped
docker-compose stop
# Add environment variables
export BOT_NAME=$1
export BOT_TOKEN=$2
# Start new deployment
docker-compose up --build -d
Dòng đầu tiên là cần thiết cho tất cả các tập lệnh bash: nó sẽ không hoạt động nếu không có nó. Và sau đó - chỉ là một tập hợp các lệnh trong terminal cần được thực thi. Tôi đã thêm nhận xét vào mỗi lệnh để nó rõ ràng. Điều duy nhất tôi muốn giải thích là $1 và $2 nghĩa là gì. Đây là hai biến sẽ được chuyển khi tập lệnh bash được khởi chạy. Sử dụng lệnh xuất, chúng sẽ được thêm vào các biến máy chủ và đọc trong docker-compose. Điều này hoạt động với Ubuntu, có thể không dành cho Windows, nhưng tôi không chắc. Bây giờ bạn cần thêm tập lệnh stop.sh, tập lệnh này sẽ dừng công việc. Nó sẽ chứa một số dòng:
#!/bin/bash
# Ensure, that docker-compose stopped
docker-compose stop
# Ensure, that the old application won't be deployed again.
mvn clean
Ở đây chúng tôi dừng docker-compose và dọn dẹp jarnik của dự án, vốn đã tồn tại kể từ lần xây dựng cuối cùng. Chúng tôi làm điều này để đảm bảo rằng dự án của chúng tôi được xây dựng lại một cách chính xác. Đã có tiền lệ, đó là lý do tại sao tôi thêm) Kết quả là chúng tôi có 4 tệp mới:
- Dockerfile - một tệp để tạo hình ảnh ứng dụng của chúng tôi;
- docker-compose.yml - một tệp có cài đặt về cách chúng tôi sẽ khởi chạy vùng chứa của mình;
- start.sh - tập lệnh bash để triển khai ứng dụng của chúng tôi;
- stop.sh là tập lệnh bash để dừng ứng dụng của chúng tôi.
# Ghi chú phát hành ## 0.3.0-SNAPSHOT * JRTB-13: đã thêm quy trình triển khai vào dự án ## 0.2.0-SNAPSHOT * JRTB-3: đã triển khai Mẫu lệnh để xử lý các lệnh Telegram Bot ## 0.1.0-SNAPSHOT * JRTB -2: đã thêm bot telegram sơ khai * JRTB-0: đã thêm dự án khung SpringBoot
Và trong README, chúng tôi sẽ thêm một đoạn mới mô tả cách triển khai ứng dụng của mình:
## Triển khai Quá trình triển khai dễ dàng nhất có thể: Phần mềm bắt buộc: - terminal để chạy tập lệnh bash - docker - docker-compose để triển khai ứng dụng, chuyển sang nhánh cần thiết và chạy tập lệnh bash: $ bash start.sh ${bot_username} ${bot_token } Đó là tất cả.
Tất nhiên, mọi thứ đều được viết bằng tiếng Anh. Như thường lệ, trong nhánh mới được tạo STEP_4_JRTB-13, chúng tôi tạo một cam kết mới với tên: JRTB-13: triển khai quy trình triển khai thông qua docker và đẩy nó. Tôi ngừng đi sâu vào chi tiết về những điều mà tôi đã mô tả trong các bài viết trước. Tôi không thấy có ích gì khi lặp lại điều tương tự. Ngoài ra, những người đã tìm ra và tự mình làm sẽ không còn thắc mắc gì nữa. Đây là tôi đang nói về cách tạo một nhánh mới, cách tạo một cam kết, cách đẩy một cam kết vào kho lưu trữ.
GO TO FULL VERSION