Tạo chuỗi CI/CD và tự động hóa công việc với Docker

Tôi viết trang web đầu tiên của mình vào cuối những năm 90. Hồi đó việc đưa chúng vào hoạt động rất dễ dàng. Có một máy chủ Apache trên một số dịch vụ lưu trữ được chia sẻ, bạn có thể đăng nhập vào máy chủ này qua FTP bằng cách viết một cái gì đó như ftp://ftp.example.com. Sau đó, bạn phải nhập tên và mật khẩu của mình rồi tải tệp lên máy chủ. Có những thời điểm khác nhau, mọi thứ lúc đó đơn giản hơn bây giờ.

Tạo chuỗi CI/CD và tự động hóa công việc với Docker

Trong hai thập kỷ kể từ đó, mọi thứ đã thay đổi rất nhiều. Các trang web đã trở nên phức tạp hơn; chúng phải được lắp ráp trước khi đưa vào sản xuất. Một máy chủ duy nhất trở thành nhiều máy chủ chạy phía sau bộ cân bằng tải và việc sử dụng hệ thống kiểm soát phiên bản trở nên phổ biến.

Đối với dự án cá nhân của tôi, tôi đã có một cấu hình đặc biệt. Và tôi biết rằng tôi cần khả năng triển khai trang web trong sản xuất bằng cách chỉ thực hiện một hành động: viết mã cho một nhánh master trên GitHub. Ngoài ra, tôi biết rằng để đảm bảo hoạt động của ứng dụng web nhỏ của mình, tôi không muốn quản lý một cụm Kubernetes khổng lồ hoặc sử dụng công nghệ Docker Swarm hoặc duy trì một nhóm máy chủ với các nhóm, đại lý và tất cả các loại khác. sự phức tạp. Để đạt được mục tiêu làm cho công việc trở nên dễ dàng nhất có thể, tôi cần phải làm quen với CI/CD.

Nếu bạn có một dự án nhỏ (trong trường hợp này là dự án Node.js) và bạn muốn biết cách tự động hóa quá trình triển khai dự án này, đồng thời đảm bảo rằng những gì được lưu trữ trong kho khớp chính xác với những gì hoạt động trong sản xuất, thì tôi nghĩ rằng bạn có thể quan tâm đến bài viết này.

Điều kiện tiên quyết

Người đọc bài viết này mong đợi có sự hiểu biết cơ bản về dòng lệnh và cách viết các tập lệnh Bash. Ngoài ra, anh ta sẽ cần các tài khoản Travis C.I. и Trung tâm Docker.

Mục tiêu

Tôi sẽ không nói rằng bài viết này có thể được gọi là “hướng dẫn” một cách vô điều kiện. Đây giống như một tài liệu trong đó tôi nói về những gì tôi đã học được và mô tả quy trình phù hợp với tôi để thử nghiệm và triển khai mã vào sản xuất, được thực hiện trong một lần chuyển tự động.

Đây là kết quả của quy trình làm việc của tôi.

Đối với mã được đăng lên bất kỳ nhánh kho lưu trữ nào ngoại trừ master, các hành động sau được thực hiện:

  • Dự án xây dựng trên Travis CI bắt đầu.
  • Tất cả các bài kiểm tra đơn vị, tích hợp và end-to-end đều được thực hiện.

Chỉ dành cho mã rơi vào master, sau đây được thực hiện:

  • Tất cả mọi thứ được đề cập ở trên, cộng với...
  • Xây dựng hình ảnh Docker dựa trên mã, cài đặt và môi trường hiện tại.
  • Triển khai hình ảnh vào Docker Hub.
  • Kết nối với máy chủ sản xuất.
  • Tải hình ảnh từ Docker Hub lên máy chủ.
  • Dừng vùng chứa hiện tại và bắt đầu vùng chứa mới dựa trên hình ảnh mới.

Nếu bạn hoàn toàn không biết gì về Docker, hình ảnh và vùng chứa, đừng lo lắng. Tôi sẽ kể cho bạn nghe tất cả về nó.

CI/CD là gì?

CI/CD viết tắt là viết tắt của “tích hợp liên tục/triển khai liên tục”.

▍ Tích hợp liên tục

Tích hợp liên tục là một quá trình trong đó các nhà phát triển thực hiện cam kết với kho lưu trữ mã nguồn chính của dự án (thường là một nhánh master). Đồng thời, chất lượng của mã được đảm bảo thông qua kiểm tra tự động.

▍Triển khai liên tục

Triển khai liên tục là việc triển khai mã tự động, thường xuyên vào sản xuất. Phần thứ hai của từ viết tắt CI/CD đôi khi được đánh vần là “phân phối liên tục”. Về cơ bản, điều này giống như “triển khai liên tục”, nhưng “phân phối liên tục” hàm ý cần phải xác nhận các thay đổi theo cách thủ công trước khi bắt đầu quá trình triển khai dự án.

Bắt đầu

Ứng dụng tôi sử dụng để tìm hiểu tất cả những điều này có tên là Ghi chú. Đây là một dự án web tôi đang thực hiện, được thiết kế để ghi chú. Lúc đầu tôi đã cố gắng làm JAMStack-project hoặc chỉ là một ứng dụng front-end không có máy chủ, để tận dụng khả năng lưu trữ và triển khai dự án tiêu chuẩn mà nó cung cấp netlify. Khi độ phức tạp của ứng dụng tăng lên, tôi cần tạo phần máy chủ của nó, điều đó có nghĩa là tôi sẽ cần xây dựng chiến lược của riêng mình để tích hợp tự động và triển khai dự án một cách tự động.

Trong trường hợp của tôi, ứng dụng này là một máy chủ Express chạy trong môi trường Node.js, phục vụ ứng dụng React một trang và hỗ trợ API phía máy chủ an toàn. Kiến trúc này tuân theo chiến lược có thể được tìm thấy trong điều này Hướng dẫn xác thực toàn bộ ngăn xếp.

Tôi đã tư vấn với bạn bè, một chuyên gia tự động hóa, đã hỏi anh ấy những gì tôi cần làm để mọi thứ hoạt động theo cách tôi muốn. Anh ấy đã cho tôi ý tưởng về quy trình làm việc tự động sẽ như thế nào, được nêu trong phần Mục tiêu của bài viết này. Có được những mục tiêu này có nghĩa là tôi cần tìm ra cách sử dụng Docker.

phu bến tàu

Docker là một công cụ, nhờ công nghệ container hóa, cho phép các ứng dụng dễ dàng phân phối, triển khai và chạy trong cùng một môi trường, ngay cả khi bản thân nền tảng Docker chạy trong các môi trường khác nhau. Đầu tiên, tôi cần sử dụng các công cụ dòng lệnh Docker (CLI). hướng dẫn Hướng dẫn cài đặt Docker không thể gọi là rõ ràng và dễ hiểu, nhưng từ đó bạn có thể biết rằng để thực hiện bước cài đặt đầu tiên, bạn cần tải xuống Docker Desktop (dành cho Mac hoặc Windows).

Docker Hub gần giống như GitHub cho kho git hoặc sổ đăng ký NPM cho các gói JavaScript. Đây là kho lưu trữ trực tuyến cho hình ảnh Docker. Đây là những gì Docker Desktop kết nối tới.

Vì vậy, để bắt đầu với Docker, bạn cần làm hai việc:

Sau này, bạn có thể kiểm tra xem Docker CLI có hoạt động hay không bằng cách chạy lệnh sau để kiểm tra phiên bản Docker:

docker -v

Tiếp theo, đăng nhập vào Docker Hub bằng cách nhập tên người dùng và mật khẩu của bạn khi được hỏi:

docker login

Để sử dụng Docker, bạn phải hiểu các khái niệm về image và container.

▍Hình ảnh

Hình ảnh giống như một bản thiết kế chứa hướng dẫn cách lắp ráp thùng chứa. Đây là ảnh chụp nhanh bất biến về hệ thống tệp và cài đặt của ứng dụng. Các nhà phát triển có thể dễ dàng chia sẻ hình ảnh.

# Вывод сведений обо всех образах
docker images

Lệnh này sẽ xuất ra một bảng có tiêu đề sau:

REPOSITORY     TAG     IMAGE ID     CREATED     SIZE
---

Tiếp theo chúng ta sẽ xem xét một số ví dụ về các lệnh có cùng định dạng - đầu tiên là một lệnh có nhận xét, sau đó là ví dụ về những gì nó có thể xuất ra.

▍Container

Vùng chứa là một gói thực thi chứa mọi thứ cần thiết để chạy một ứng dụng. Một ứng dụng theo cách tiếp cận này sẽ luôn hoạt động giống nhau, bất kể cơ sở hạ tầng: trong một môi trường biệt lập và trong cùng một môi trường. Vấn đề là các phiên bản của cùng một hình ảnh được khởi chạy trong các môi trường khác nhau.

# Перечисление всех контейнеров
docker ps -a
CONTAINER ID     IMAGE     COMMAND     CREATED     STATUS     PORTS     NAMES
---

▍Thẻ

Thẻ là dấu hiệu của một phiên bản cụ thể của hình ảnh.

▍Tham khảo nhanh về các lệnh Docker

Dưới đây là tổng quan về một số lệnh Docker thường được sử dụng.

Đội

Bối cảnh

ảnh hưởng

xây dựng docker

Hình ảnh

Xây dựng hình ảnh từ Dockerfile

thẻ docker

Hình ảnh

Gắn thẻ hình ảnh

ảnh dok

Hình ảnh

Liệt kê hình ảnh

bến tàu chạy

thùng chứa

Chạy vùng chứa dựa trên hình ảnh

đẩy docker

Hình ảnh

Tải hình ảnh lên sổ đăng ký

kéo docker

Hình ảnh

Đang tải hình ảnh từ sổ đăng ký

docker ps

thùng chứa

Liệt kê vùng chứa

hệ thống docker

Hình ảnh/Vùng chứa

Xóa các vùng chứa và hình ảnh không sử dụng

▍Tệp Docker

Tôi biết cách chạy một ứng dụng sản xuất cục bộ. Tôi có cấu hình Webpack được thiết kế để xây dựng ứng dụng React làm sẵn. Tiếp theo, tôi có lệnh khởi động máy chủ dựa trên Node.js trên cổng 5000. Nó trông như thế này:

npm i         # установка зависимостей
npm run build # сборка React-приложения
npm run start # запуск Node-сервера

Cần lưu ý rằng tôi không có ứng dụng mẫu cho tài liệu này. Nhưng ở đây, đối với các thử nghiệm, bất kỳ ứng dụng Node đơn giản nào cũng có thể thực hiện được.

Để sử dụng container, bạn sẽ cần đưa ra hướng dẫn cho Docker. Việc này được thực hiện thông qua một tập tin có tên Dockerfile, nằm trong thư mục gốc của dự án. Tập tin này, lúc đầu, có vẻ khá khó hiểu.

Nhưng những gì nó chứa chỉ mô tả, với các lệnh đặc biệt, một cái gì đó tương tự như việc thiết lập một môi trường làm việc. Dưới đây là một số lệnh sau:

  • TỪ - Lệnh này bắt đầu một tập tin. Nó chỉ định hình ảnh cơ sở mà vùng chứa được xây dựng trên đó.
  • COPY — Sao chép tập tin từ nguồn cục bộ sang vùng chứa.
  • HƯỚNG DẪN LÀM VIỆC — Thiết lập thư mục làm việc cho các lệnh sau.
  • CHẠY - Chạy lệnh.
  • PHƠI RA - Cài đặt cổng.
  • ĐIỂM VÀO - Chỉ thị lệnh sẽ được thực hiện.

Dockerfile có thể trông giống như thế này:

# Загрузить базовый образ
FROM node:12-alpine

# Скопировать файлы из текущей директории в директорию app/
COPY . app/

# Использовать app/ в роли рабочей директории
WORKDIR app/

# Установить зависимости (команда npm ci похожа npm i, но используется для автоматизированных сборок)
RUN npm ci --only-production

# Собрать клиентское React-приложение для продакшна
RUN npm run build

# Прослушивать указанный порт
EXPOSE 5000

# Запустить Node-сервер
ENTRYPOINT npm run start

Tùy thuộc vào hình ảnh cơ sở bạn chọn, bạn có thể cần cài đặt thêm các phần phụ thuộc. Thực tế là một số image cơ bản (như Node Alpine Linux) được tạo ra với mục tiêu làm cho chúng nhỏ gọn nhất có thể. Kết quả là họ có thể không có một số chương trình mà bạn mong đợi.

▍Xây dựng, gắn thẻ và chạy vùng chứa

Việc lắp ráp và hạ thủy container tại địa phương diễn ra sau khi chúng tôi có Dockerfile, các nhiệm vụ khá đơn giản. Trước khi đẩy hình ảnh lên Docker Hub, bạn cần kiểm tra nó cục bộ.

▍Lắp ráp

Đầu tiên bạn cần thu thập một hình ảnh, chỉ định tên và tùy chọn thẻ (nếu không chỉ định thẻ, hệ thống sẽ tự động gán thẻ cho hình ảnh latest).

# Сборка образа
docker build -t <image>:<tag> .

Sau khi chạy lệnh này, bạn có thể xem Docker xây dựng hình ảnh.

Sending build context to Docker daemon   2.88MB
Step 1/9 : FROM node:12-alpine
 ---> ...выполнение этапов сборки...
Successfully built 123456789123
Successfully tagged <image>:<tag>

Quá trình xây dựng có thể mất vài phút - tất cả phụ thuộc vào số lượng phụ thuộc mà bạn có. Khi quá trình xây dựng hoàn tất, bạn có thể chạy lệnh docker images và xem mô tả về hình ảnh mới của bạn.

REPOSITORY          TAG               IMAGE ID            CREATED              SIZE
<image>             latest            123456789123        About a minute ago   x.xxGB

▍Khởi động

Hình ảnh đã được tạo. Điều này có nghĩa là bạn có thể chạy một vùng chứa dựa trên nó. Bởi vì tôi muốn có thể truy cập ứng dụng đang chạy trong container tại localhost:5000, tôi, ở phía bên trái của cặp 5000:5000 trong lệnh tiếp theo được cài đặt 5000. Bên phải là cảng container.

# Запуск с использованием локального порта 5000 и порта контейнера 5000
docker run -p 5000:5000 <image>:<tag>

Bây giờ vùng chứa đã được tạo và chạy, bạn có thể sử dụng lệnh docker ps để xem thông tin về vùng chứa này (hoặc bạn có thể sử dụng lệnh docker ps -a, hiển thị thông tin về tất cả các vùng chứa, không chỉ các vùng chứa đang chạy).

CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                      PORTS                    NAMES
987654321234        <image>             "/bin/sh -c 'npm run…"   6 seconds ago        Up 6 seconds                0.0.0.0:5000->5000/tcp   stoic_darwin

Nếu bây giờ bạn đi đến địa chỉ localhost:5000 — bạn có thể thấy trang của ứng dụng đang chạy trông giống hệt trang của ứng dụng đang chạy trong môi trường sản xuất.

▍Gắn thẻ và xuất bản

Để sử dụng một trong những image đã tạo trên máy chủ sản xuất, chúng ta cần có thể tải xuống image này từ Docker Hub. Điều này có nghĩa là trước tiên bạn cần tạo kho lưu trữ cho dự án trên Docker Hub. Sau này, chúng ta sẽ có một nơi để gửi hình ảnh. Hình ảnh cần được đổi tên để tên của nó bắt đầu bằng tên người dùng Docker Hub của chúng tôi. Tiếp theo là tên của kho lưu trữ. Bất kỳ thẻ nào cũng có thể được đặt ở cuối tên. Dưới đây là một ví dụ về cách đặt tên hình ảnh bằng cách sử dụng sơ đồ này.

Bây giờ bạn có thể xây dựng hình ảnh với tên mới và chạy lệnh docker push để đẩy nó vào kho lưu trữ Docker Hub.

docker build -t <username>/<repository>:<tag> .
docker tag <username>/<repository>:<tag> <username>/<repository>:latest
docker push <username>/<repository>:<tag>

# На практике это может выглядеть, например, так:
docker build -t user/app:v1.0.0 .
docker tag user/app:v1.0.0 user/app:latest
docker push user/app:v1.0.0

Nếu mọi việc suôn sẻ, image sẽ có sẵn trên Docker Hub và có thể dễ dàng tải lên máy chủ hoặc chuyển cho nhà phát triển khác.

Bước tiếp theo

Đến bây giờ, chúng tôi đã xác minh rằng ứng dụng, ở dạng vùng chứa Docker, đang chạy cục bộ. Chúng tôi đã tải vùng chứa lên Docker Hub. Tất cả điều này có nghĩa là chúng tôi đã đạt được tiến bộ rất tốt hướng tới mục tiêu của mình. Bây giờ chúng ta cần giải quyết thêm hai câu hỏi nữa:

  • Thiết lập công cụ CI để kiểm tra và triển khai mã.
  • Thiết lập máy chủ sản xuất để nó có thể tải xuống và chạy mã của chúng tôi.

Trong trường hợp của chúng tôi, chúng tôi sử dụng Travis C.I.. Là một máy chủ - DitigalĐại Dương.

Cần lưu ý rằng ở đây bạn có thể sử dụng một sự kết hợp dịch vụ khác. Ví dụ: thay vì Travis CI, bạn có thể sử dụng CircleCI hoặc Github Actions. Và thay vì DigitalOcean - AWS hoặc Linode.

Chúng tôi quyết định hợp tác với Travis CI và tôi đã định cấu hình một số thứ trong dịch vụ này. Vì vậy, bây giờ tôi sẽ nói ngắn gọn về cách chuẩn bị cho công việc.

Travis C.I.

Travis CI là một công cụ để thử nghiệm và triển khai mã. Tôi không muốn đi sâu vào sự phức tạp của việc thiết lập Travis CI, vì mỗi dự án là duy nhất và điều này sẽ không mang lại nhiều lợi ích. Nhưng tôi sẽ trình bày những điều cơ bản để giúp bạn bắt đầu nếu bạn quyết định sử dụng Travis CI. Cho dù bạn chọn Travis CI, CircleCI, Jenkins hay thứ gì khác, các phương pháp cấu hình tương tự sẽ được sử dụng ở mọi nơi.

Để bắt đầu với Travis CI, hãy truy cập địa điểm dự án và tạo một tài khoản. Sau đó tích hợp Travis CI với tài khoản GitHub của bạn. Khi thiết lập hệ thống, bạn sẽ cần chỉ định kho lưu trữ mà bạn muốn tự động hóa công việc và cho phép truy cập vào nó. (Tôi sử dụng GitHub, nhưng tôi chắc chắn rằng Travis CI có thể tích hợp với BitBucket, GitLab và các dịch vụ tương tự khác).

Mỗi khi Travis CI được khởi động, máy chủ sẽ được khởi chạy, thực thi các lệnh được chỉ định trong tệp cấu hình, bao gồm cả việc triển khai các nhánh kho lưu trữ tương ứng.

▍Vòng đời công việc

Tệp cấu hình Travis CI được gọi .travis.yml và được lưu trữ trong thư mục gốc của dự án, hỗ trợ khái niệm về sự kiện vòng đời nhiệm vụ. Những sự kiện này được liệt kê theo thứ tự chúng xảy ra:

  • apt addons
  • cache components
  • before_install
  • install
  • before_script
  • script
  • before_cache
  • after_success или after_failure
  • before_deploy
  • deploy
  • after_deploy
  • after_script

▍Thử nghiệm

Trong tệp cấu hình, tôi sẽ định cấu hình máy chủ Travis CI cục bộ. Tôi đã chọn Node 12 làm ngôn ngữ và yêu cầu hệ thống cài đặt các phần phụ thuộc cần thiết để sử dụng Docker.

Tất cả mọi thứ được liệt kê trong .travis.yml, sẽ được thực thi khi tất cả các yêu cầu kéo được thực hiện tới tất cả các nhánh của kho lưu trữ, trừ khi có quy định khác. Đây là một tính năng hữu ích vì nó có nghĩa là chúng tôi có thể kiểm tra tất cả mã được đưa vào kho lưu trữ. Điều này cho bạn biết liệu mã đã sẵn sàng để được ghi vào chi nhánh hay chưa. mastervà liệu nó có phá vỡ quá trình xây dựng dự án hay không. Trong cấu hình toàn cầu này, tôi cài đặt mọi thứ cục bộ, chạy máy chủ phát triển Webpack ở chế độ nền (đây là một tính năng trong quy trình làm việc của tôi) và chạy thử nghiệm.

Nếu bạn muốn kho lưu trữ của mình hiển thị các huy hiệu cho biết phạm vi kiểm tra, đây Bạn có thể tìm thấy hướng dẫn ngắn về cách sử dụng Jest, Travis CI và Quần yếm để thu thập và hiển thị thông tin này.

Vì vậy, đây là nội dung của tập tin .travis.yml:

# Установить язык
language: node_js

# Установить версию Node.js
node_js:
  - '12'

services:
  # Использовать командную строку Docker
  - docker

install:
  # Установить зависимости для тестов
  - npm ci

before_script:
  # Запустить сервер и клиент для тестов
  - npm run dev &

script:
  # Запустить тесты
  - npm run test

Đây là nơi kết thúc các hành động được thực hiện cho tất cả các nhánh của kho lưu trữ và cho các yêu cầu kéo.

▍Triển khai

Dựa trên giả định rằng tất cả các thử nghiệm tự động đã hoàn thành thành công, chúng tôi có thể, tùy chọn, triển khai mã đến máy chủ sản xuất. Vì chúng tôi chỉ muốn làm điều này với mã từ chi nhánh master, chúng tôi sẽ cung cấp cho hệ thống các hướng dẫn thích hợp trong cài đặt triển khai. Trước khi bạn thử sử dụng mã mà chúng ta sẽ xem xét tiếp theo trong dự án của bạn, tôi muốn cảnh báo bạn rằng bạn phải có một tập lệnh thực tế được yêu cầu triển khai.

deploy:
  # Собрать Docker-контейнер и отправить его на Docker Hub
  provider: script
  script: bash deploy.sh
  on:
    branch: master

Kịch bản triển khai giải quyết hai vấn đề:

  • Xây dựng, gắn thẻ và gửi hình ảnh đến Docker Hub bằng công cụ CI (trong trường hợp của chúng tôi là Travis CI).
  • Đang tải hình ảnh trên máy chủ, dừng vùng chứa cũ và bắt đầu một vùng chứa mới (trong trường hợp của chúng tôi, máy chủ chạy trên nền tảng DigitalOcean).

Trước tiên, bạn cần thiết lập quy trình tự động để xây dựng, gắn thẻ và đẩy image lên Docker Hub. Tất cả điều này rất giống với những gì chúng tôi đã thực hiện thủ công, ngoại trừ việc chúng tôi cần một chiến lược gán thẻ duy nhất cho hình ảnh và tự động hóa thông tin đăng nhập. Tôi gặp khó khăn với một số chi tiết của tập lệnh triển khai, chẳng hạn như chiến lược gắn thẻ, đăng nhập, mã hóa khóa SSH, thiết lập kết nối SSH. Nhưng may mắn là bạn trai tôi rất giỏi bash cũng như nhiều thứ khác. Anh ấy đã giúp tôi viết kịch bản này.

Vì vậy, phần đầu tiên của tập lệnh là tải hình ảnh lên Docker Hub. Điều này khá dễ thực hiện. Lược đồ gắn thẻ mà tôi đã sử dụng bao gồm việc kết hợp hàm băm git và thẻ git, nếu có. Điều này đảm bảo rằng thẻ là duy nhất và giúp dễ dàng xác định tổ hợp mà nó dựa vào. DOCKER_USERNAME и DOCKER_PASSWORD là các biến môi trường người dùng có thể được đặt bằng giao diện Travis CI. Travis CI sẽ tự động xử lý dữ liệu nhạy cảm để không rơi vào tay kẻ xấu.

Đây là phần đầu tiên của kịch bản deploy.sh.

#!/bin/sh
set -e # Остановить скрипт при наличии ошибок

IMAGE="<username>/<repository>"                             # Образ Docker
GIT_VERSION=$(git describe --always --abbrev --tags --long) # Git-хэш и теги

# Сборка и тегирование образа
docker build -t ${IMAGE}:${GIT_VERSION} .
docker tag ${IMAGE}:${GIT_VERSION} ${IMAGE}:latest

# Вход в Docker Hub и выгрузка образа
echo "${DOCKER_PASSWORD}" | docker login -u "${DOCKER_USERNAME}" --password-stdin
docker push ${IMAGE}:${GIT_VERSION}

Phần thứ hai của tập lệnh sẽ phụ thuộc hoàn toàn vào máy chủ bạn đang sử dụng và cách tổ chức kết nối với nó. Trong trường hợp của tôi, vì tôi sử dụng Digital Ocean nên tôi sử dụng các lệnh để kết nối với máy chủ doc. Khi làm việc với AWS sẽ sử dụng tiện ích aws, và như thế.

Việc thiết lập máy chủ không đặc biệt khó khăn. Vì vậy, tôi thiết lập một giọt dựa trên hình ảnh cơ sở. Cần lưu ý rằng hệ thống tôi chọn yêu cầu cài đặt Docker thủ công một lần và khởi chạy Docker thủ công một lần. Mình dùng Ubuntu 18.04 để cài Docker nên nếu bạn cũng đang dùng Ubuntu để làm tương tự thì có thể làm theo này hướng dẫn đơn giản.

Ở đây tôi không nói về các lệnh cụ thể cho dịch vụ vì khía cạnh này có thể khác nhau rất nhiều trong các trường hợp khác nhau. Tôi sẽ chỉ đưa ra kế hoạch hành động chung sẽ được thực hiện sau khi kết nối qua SSH với máy chủ nơi dự án sẽ được triển khai:

  • Chúng ta cần tìm container hiện đang chạy và dừng nó lại.
  • Sau đó, bạn cần khởi chạy một vùng chứa mới ở chế độ nền.
  • Bạn sẽ cần đặt cổng cục bộ của máy chủ thành 80 - điều này sẽ cho phép bạn vào trang web tại một địa chỉ như example.com, mà không chỉ định cổng, thay vì sử dụng một địa chỉ như example.com:5000.
  • Cuối cùng, bạn cần xóa tất cả các thùng chứa và hình ảnh cũ.

Đây là phần tiếp theo của kịch bản.

# Найти ID работающего контейнера
CONTAINER_ID=$(docker ps | grep takenote | cut -d" " -f1)

# Остановить старый контейнер, запустить новый, очистить систему
docker stop ${CONTAINER_ID}
docker run --restart unless-stopped -d -p 80:5000 ${IMAGE}:${GIT_VERSION}
docker system prune -a -f

Một số điều cần chú ý

Có thể khi bạn kết nối với máy chủ qua SSH từ Travis CI, bạn sẽ thấy cảnh báo khiến bạn không thể tiếp tục cài đặt vì hệ thống sẽ chờ phản hồi của người dùng.

The authenticity of host '<hostname> (<IP address>)' can't be established.
RSA key fingerprint is <key fingerprint>.
Are you sure you want to continue connecting (yes/no)?

Tôi đã học được rằng khóa chuỗi có thể được mã hóa trong base64 để lưu nó ở dạng mà nó có thể hoạt động thuận tiện và đáng tin cậy. Ở giai đoạn cài đặt, bạn có thể giải mã khóa chung và ghi nó vào một tệp known_hosts để khắc phục lỗi trên.

echo <public key> | base64 # выводит <публичный ключ, закодированный в base64>

Trong thực tế, lệnh này có thể trông giống như sau:

echo "123.45.67.89 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3
Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA
t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En
mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx
NrRFi9wrf+M7Q== [email protected]" | base64

Và đây là những gì nó tạo ra - một chuỗi được mã hóa base64:

MTIzLjQ1LjY3Ljg5IHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQUJJd0FBQVFFQWtsT1Vwa0RIcmZIWTE3U2JybVRJcE5MVEdLOVRqb20vQldEU1UKR1BsK25hZnpsSERUWVc3aGRJNHlaNWV3MThKSDRKVzlqYmhVRnJ2aVF6TTd4bEVMRVZmNGg5bEZYNVFWa2JQcHBTd2cwY2RhMwpQYnY3a09kSi9NVHlCbFdYRkNSK0hBbzNGWFJpdEJxeGlYMW5LaFhwSEFac01jaUxxOFY2UmpzTkFRd2RzZE1GdlNsVksvN1hBCnQzRmFvSm9Bc25jTTFROXg1KzNWMFd3NjgvZUlGbWIxenVVRmxqUUpLcHJyWDg4WHlwTkR2allOYnk2dncvUGIwcndlcnQvRW4KbVorQVc0T1pQblRQSTg5WlBtVk1MdWF5ckQyY0U4NlovaWw4YitndzNyMysxbkthdG1Ja2puMnNvMWQwMVFyYVRsTXFWU3NieApOclJGaTl3cmYrTTdRPT0geW91QGV4YW1wbGUuY29tCg==

Đây là lệnh được đề cập ở trên

install:
  - echo < публичный ключ, закодированный в base64> | base64 -d >> $HOME/.ssh/known_hosts

Cách tiếp cận tương tự có thể được sử dụng với khóa riêng khi thiết lập kết nối, vì bạn có thể cần khóa riêng để truy cập máy chủ. Khi làm việc với khóa, bạn chỉ cần đảm bảo rằng nó được lưu trữ an toàn trong biến môi trường Travis CI và nó không được hiển thị ở bất kỳ đâu.

Một điều khác cần lưu ý là bạn có thể cần chạy toàn bộ tập lệnh triển khai dưới dạng một dòng chẳng hạn - với doctl. Điều này có thể đòi hỏi một số nỗ lực thêm.

doctl compute ssh <droplet> --ssh-command "все команды будут здесь && здесь"

TLS/SSL và cân bằng tải

Sau khi thực hiện mọi thứ được đề cập ở trên, vấn đề cuối cùng tôi gặp phải là máy chủ không có SSL. Vì tôi sử dụng máy chủ Node.js nên để buộc работать proxy ngược Nginx và Let's Encrypt, bạn cần phải mày mò rất nhiều.

Tôi thực sự không muốn thực hiện tất cả cấu hình SSL này theo cách thủ công, vì vậy tôi chỉ tạo một bộ cân bằng tải và ghi lại các chi tiết của nó trong DNS. Ví dụ: trong trường hợp của DigitalOcean, việc tạo chứng chỉ tự ký tự động gia hạn trên bộ cân bằng tải là một thủ tục đơn giản, miễn phí và nhanh chóng. Cách tiếp cận này có thêm lợi ích là nó giúp thiết lập SSL rất dễ dàng trên nhiều máy chủ chạy phía sau bộ cân bằng tải nếu cần. Điều này cho phép bản thân các máy chủ không “nghĩ” đến SSL mà đồng thời sử dụng cổng như bình thường 80. Vì vậy, việc thiết lập SSL trên bộ cân bằng tải dễ dàng và thuận tiện hơn nhiều so với các phương pháp thiết lập SSL thay thế.

Bây giờ bạn có thể đóng tất cả các cổng trên máy chủ chấp nhận kết nối đến - ngoại trừ cổng 80, được sử dụng để liên lạc với bộ cân bằng tải và cổng 22 cho SSH. Do đó, nỗ lực truy cập trực tiếp vào máy chủ trên bất kỳ cổng nào ngoài hai cổng này sẽ không thành công.

Kết quả

Sau khi làm tất cả những gì tôi đã nói trong tài liệu này, cả nền tảng Docker lẫn các khái niệm về chuỗi CI/CD tự động đều không còn khiến tôi sợ hãi nữa. Tôi đã có thể thiết lập một chuỗi tích hợp liên tục, trong đó mã được kiểm tra trước khi đưa vào sản xuất và mã được triển khai tự động trên máy chủ. Tất cả những điều này vẫn còn tương đối mới đối với tôi và tôi chắc chắn rằng có nhiều cách để cải thiện quy trình làm việc tự động của mình và làm cho nó hiệu quả hơn. Vì vậy, nếu bạn có bất kỳ ý tưởng nào về vấn đề này, xin vui lòng cho tôi biết. tôi biết. Tôi hy vọng bài viết này đã giúp bạn trong nỗ lực của bạn. Tôi muốn tin rằng sau khi đọc nó, bạn đã học được nhiều điều như tôi đã học được khi tìm ra mọi điều tôi đã nói trong đó.

PS Trong của chúng tôi thương trường có một hình ảnh phu bến tàu, có thể được cài đặt chỉ bằng một cú nhấp chuột. Bạn có thể kiểm tra hoạt động của container tại VPS. Tất cả khách hàng mới được tặng 3 ngày dùng thử miễn phí.

Gởi bạn đọc! Bạn có sử dụng công nghệ CI/CD trong dự án của mình không?

Tạo chuỗi CI/CD và tự động hóa công việc với Docker

Nguồn: www.habr.com

Thêm một lời nhận xét