Cách cấu hình môi trường kiểm tra tích hợp liên tục với Docker và Docker Compose trên Ubuntu 16.04
Tích hợp liên tục (CI) đề cập đến thực tiễn trong đó các nhà phát triển tích hợp mã thường xuyên nhất có thể và mọi commit đều được kiểm tra trước và sau khi được hợp nhất vào một repository được chia sẻ bởi một bản dựng tự động .CI tăng tốc quá trình phát triển của bạn và giảm thiểu rủi ro của các vấn đề quan trọng trong production , nhưng nó không phải là tầm thường để cài đặt ; các bản dựng tự động chạy trong môi trường khác, nơi cài đặt phụ thuộc thời gian chạy và cấu hình của các dịch vụ bên ngoài có thể khác với trong môi trường local và môi trường nhà phát triển của bạn.
Docker là một nền tảng container hóa nhằm mục đích đơn giản hóa các vấn đề về tiêu chuẩn hóa môi trường để việc triển khai các ứng dụng cũng có thể được tiêu chuẩn hóa ( tìm hiểu thêm về Docker ). Đối với các nhà phát triển, Docker cho phép bạn mô phỏng môi trường production trên các máy local bằng cách chạy các thành phần ứng dụng trong các containers local . Các containers này có thể dễ dàng tự động hóa bằng Docker Compose , độc lập với ứng dụng và hệ điều hành cơ bản.
Hướng dẫn này sử dụng Docker Compose để chứng minh sự tự động hóa của quy trình làm việc CI.
Ta sẽ tạo một ứng dụng Python loại “Xin chào thế giới” được tài liệu hóa và một tập lệnh thử nghiệm Bash. Ứng dụng Python sẽ yêu cầu hai containers để chạy: một containers cho chính ứng dụng và một containers Redis để lưu trữ được yêu cầu làm phụ thuộc cho ứng dụng.
Sau đó, các kịch bản thử nghiệm sẽ được Dockerized trong container riêng của bạn và toàn bộ môi trường thử nghiệm chuyển đến một file Docker-compose.test.yml vì vậy ta có thể chắc chắn rằng ta đang chạy mỗi thực hiện thử nghiệm trong một môi trường trong lành và áp dụng thống nhất.
Cách tiếp cận này cho thấy cách bạn có thể xây dựng một môi trường thử nghiệm mới, giống hệt nhau cho ứng dụng của bạn , bao gồm cả các phần phụ thuộc của nó, mỗi khi bạn kiểm tra nó.
Do đó, ta tự động hóa các quy trình làm việc CI độc lập với ứng dụng đang được thử nghiệm và cơ sở hạ tầng bên dưới.
Yêu cầu
Trước khi bắt đầu, bạn cần :
- Server Ubuntu 16.04 với user không phải root có quyền sudo . Cài đặt server ban đầu với Ubuntu 16.04 giải thích cách cài đặt điều này.
- Docker , được cài đặt theo các Bước 1 và 2 của Cách cài đặt và sử dụng Docker trên Ubuntu 16.04 .
- Docker Compose , được cài đặt theo Bước 1 từ Cách cài đặt Docker Compose trên Ubuntu 16.04
Bước 1 - Tạo ứng dụng Python “Hello World”
Trong bước này, ta sẽ tạo một ứng dụng Python đơn giản làm ví dụ về loại ứng dụng bạn có thể thử nghiệm với cài đặt này.
Tạo một folder mới cho ứng dụng của ta bằng cách thực hiện:
- cd ~
- mkdir hello_world
- cd hello_world
Chỉnh sửa file mới app.py
bằng nano :
- nano app.py
Thêm nội dung sau:
from flask import Flask from redis import Redis app = Flask(__name__) redis = Redis(host="redis") @app.route("/") def hello(): visits = redis.incr('counter') html = "<h3>Hello World!</h3>" \ "<b>Visits:</b> {visits}" \ "<br/>" return html.format(visits=visits) if __name__ == "__main__": app.run(host="0.0.0.0", port=80)
Khi bạn hoàn tất, hãy lưu và thoát khỏi file .
app.py
là một ứng dụng web dựa trên Flask kết nối với dịch vụ dữ liệu Redis. Dòng visits = redis.incr('counter')
tăng số lượt truy cập và duy trì giá trị này trong Redis. Cuối cùng, một thông báo Hello World
với số lượt truy cập được trả về trong HTML.
Ứng dụng của ta có hai phụ thuộc, Flask
và Redis
, bạn có thể thấy trong hai dòng đầu tiên. Những phụ thuộc này phải được định nghĩa khi ta có thể thực thi ứng dụng.
Mở một file mới:
- nano requirements.txt
Thêm nội dung:
Flask Redis
Khi bạn hoàn tất, hãy lưu và thoát khỏi file . Bây giờ ta đã xác định các yêu cầu của bạn , ta sẽ đưa ra các yêu cầu sau này trong docker-compose.yml
, ta đã sẵn sàng cho bước tiếp theo.
Bước 2 - Tài liệu hóa ứng dụng “Hello World”
Docker sử dụng một file có tên Dockerfile
để chỉ ra các bước cần thiết để xây dựng Docker image cho một ứng dụng nhất định. Chỉnh sửa file mới:
- nano Dockerfile
Thêm các nội dung sau:
FROM python:2.7 WORKDIR /app ADD requirements.txt /app/requirements.txt RUN pip install -r requirements.txt ADD app.py /app/app.py EXPOSE 80 CMD ["python", "app.py"]
Hãy phân tích ý nghĩa của từng dòng:
-
FROM python:2.7
: cho biết rằng hình ảnh ứng dụng “Hello World” của ta được xây dựng từ hình ảnhpython:2.7
chính thức -
WORKDIR /app
: đặt folder làm việc bên trong Docker image thành/app
-
ADD requirements.txt /app/requirements.txt
: thêm filerequirements.txt
để hình ảnh của ta Docker -
RUN pip install -r requirements.txt
: cài đặt các phụ thuộcpip
của ứng dụng -
ADD app.py /app/app.py
: thêm mã nguồn ứng dụng của ta vào Docker image -
EXPOSE 80
: cho biết rằng ứng dụng của ta có thể được truy cập ở cổng 80 (cổng web công cộng tiêu chuẩn) -
CMD ["python", "app.py"]
: lệnh khởi động ứng dụng của ta
Lưu và thoát khỏi file . Dockerfile
này có tất cả thông tin cần thiết để xây dựng thành phần chính của ứng dụng “Hello World” của ta .
Sự phụ thuộc
Bây giờ ta đi đến phần phức tạp hơn của ví dụ. Ứng dụng của ta yêu cầu Redis như một dịch vụ bên ngoài. Đây là kiểu phụ thuộc có thể khó cài đặt theo cách giống hệt nhau mọi lúc trong môi trường Linux truyền thống, nhưng với Docker Compose, ta có thể cài đặt nó theo cách có thể lặp lại mọi lúc.
Hãy tạo file docker-compose.yml
để bắt đầu sử dụng Docker Compose.
Chỉnh sửa file mới:
- nano docker-compose.yml
Thêm các nội dung sau:
web: build: . dockerfile: Dockerfile links: - redis ports: - "80:80" redis: image: redis
Tệp Docker Compose này cho biết cách tạo ứng dụng “Hello World” local trong hai containers Docker.
Nó định nghĩa hai containers , web
và redis
.
web
sử dụng folder hiện tại cho ngữ cảnhbuild
và xây dựng ứng dụng Python của ta từ fileDockerfile
mà ta vừa tạo. Đây là Docker image local mà ta đã tạo chỉ cho ứng dụng Python của bạn . Nó xác định một liên kết đến containersredis
để có quyền truy cập vào IP containersredis
. Nó cũng làm cho cổng 80 có thể truy cập từ Internet bằng IP công cộng của server Ubuntu của bạnredis
được thực thi từ một Docker image công khai tiêu chuẩn, có tên làredis
.
Khi bạn hoàn tất, hãy lưu và thoát khỏi file .
Bước 3 - Triển khai ứng dụng “Hello World”
Trong bước này, ta sẽ triển khai ứng dụng và cuối cùng, nó sẽ có thể truy cập được qua Internet. Đối với mục đích của quy trình triển khai của bạn, bạn có thể coi đây là môi trường nhà phát triển, dàn dựng hoặc production , vì bạn có thể triển khai ứng dụng theo cùng một cách nhiều lần.
Các docker-compose.yml
và Dockerfile
file cho phép bạn tự động hóa việc triển khai các môi trường local bằng cách thực hiện:
- docker-compose -f ~/hello_world/docker-compose.yml build
- docker-compose -f ~/hello_world/docker-compose.yml up -d
Dòng đầu tiên xây dựng hình ảnh ứng dụng local của ta từ file Dockerfile
. Dòng thứ hai chạy web
và redis
container trong chế độ daemon ( -d
), như quy định trong docker-compose.yml
file .
Kiểm tra xem các containers ứng dụng đã được tạo bằng cách thực thi:
- docker ps
Điều này sẽ hiển thị hai containers đang chạy, có tên là helloworld_web_1
và helloworld_redis_1
.
Hãy kiểm tra xem ứng dụng đã hoạt động chưa. Ta có thể lấy IP của containers helloworld_web_1
bằng cách thực thi:
- WEB_APP_IP=$(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' helloworld_web_1)
- echo $WEB_APP_IP
Kiểm tra xem ứng dụng web có trả lại thông báo thích hợp không:
- curl http://${WEB_APP_IP}:80
Kết quả sẽ trả về thông tin như :
<h3>Hello World!</h3><b>Visits:</b> 2<br/>
Số lượt truy cập sẽ tăng lên mỗi khi bạn đạt đến điểm cuối này. Bạn cũng có thể truy cập ứng dụng “Hello World” từ trình duyệt của bạn bằng cách truy cập địa chỉ IP công cộng của server Ubuntu của bạn.
Cách tùy chỉnh cho ứng dụng của bạn
Key để cài đặt ứng dụng của bạn là đặt ứng dụng của bạn vào containers Docker của riêng nó và chạy từng phần phụ thuộc từ containers của chính nó. Sau đó, bạn có thể xác định mối quan hệ giữa các containers với Docker Compose, như được minh họa trong ví dụ. Docker Compose được đề cập chi tiết hơn trong bài viết Docker Compose này .
Để có một ví dụ khác về cách chạy một ứng dụng trên nhiều containers , hãy đọc bài viết này về cách chạy WordPress và phpMyAdmin với Docker Compose .
Bước 4 - Tạo tập lệnh thử nghiệm
Bây giờ ta sẽ tạo một tập lệnh thử nghiệm cho ứng dụng Python của ta . Đây sẽ là một tập lệnh đơn giản để kiểm tra kết quả HTTP của ứng dụng. Tập lệnh là một ví dụ về loại thử nghiệm mà bạn có thể cần chạy như một phần của quá trình triển khai tích hợp liên tục của bạn .
Chỉnh sửa file mới:
- nano test.sh
Thêm các nội dung sau:
sleep 5 if curl web | grep -q '<b>Visits:</b> '; then echo "Tests passed!" exit 0 else echo "Tests failed!" exit 1 fi
test.sh
kiểm tra kết nối web cơ bản của ứng dụng “Hello World” của ta . Nó sử dụng cURL để lấy số lượt truy cập và báo cáo về việc thử nghiệm đã được vượt qua hay chưa.
Bước 5 - Tạo môi trường thử nghiệm
Để kiểm tra ứng dụng của bạn , ta cần triển khai môi trường kiểm thử. Và, ta muốn đảm bảo nó giống với môi trường ứng dụng trực tiếp mà ta đã tạo ở Bước 3 .
Đầu tiên, ta cần Dockerize script thử nghiệm của bạn bằng cách tạo một file Dockerfile mới. Chỉnh sửa file mới:
- nano Dockerfile.test
Thêm các nội dung sau:
FROM ubuntu:xenial RUN apt-get update && apt-get install -yq curl && apt-get clean WORKDIR /app ADD test.sh /app/test.sh CMD ["bash", "test.sh"]
Dockerfile.test
mở rộng ubuntu:xenial
image chính thức để cài đặt phụ thuộc curl
, thêm tests.sh
vào hệ thống file hình ảnh và chỉ ra lệnh CMD
thực thi tập lệnh thử nghiệm với Bash.
Sau khi các thử nghiệm của ta được Dockerized, chúng có thể được thực thi theo cách có thể sao chép và bất khả tri.
Bước tiếp theo là liên kết containers thử nghiệm của ta với ứng dụng “Hello World”. Đây là nơi Docker Compose đến để giải cứu . Chỉnh sửa file mới:
- nano docker-compose.test.yml
Thêm các nội dung sau:
sut: build: . dockerfile: Dockerfile.test links: - web web: build: . dockerfile: Dockerfile links: - redis redis: image: redis
Phần thứ hai của file Docker Soạn triển khai các chính web
ứng dụng và nó redis
phụ thuộc trong cùng một cách như trước docker-compose.yml
file . Đây là phần của file chỉ định containers web
và redis
. Sự khác biệt duy nhất là containers web
không còn hiển thị cổng 80 nữa, vì vậy ứng dụng sẽ không khả dụng trên Internet công cộng trong quá trình thử nghiệm. Vì vậy, bạn có thể thấy rằng ta đang xây dựng ứng dụng và các phụ thuộc của nó giống hệt như cách chúng đang triển khai trực tiếp.
Tệp docker-compose.test.yml
cũng xác định một containers sut
(được đặt tên cho hệ thống đang thử nghiệm ) chịu trách nhiệm thực hiện các thử nghiệm tích hợp của ta . Vùng chứa sut
chỉ định folder hiện tại làm folder build
của ta và chỉ định file Dockerfile.test
của ta . Nó liên kết với containers web
để địa chỉ IP của containers ứng dụng có thể truy cập vào tập lệnh test.sh
của ta .
Cách tùy chỉnh cho ứng dụng của bạn
Lưu ý docker-compose.test.yml
có thể bao gồm hàng chục dịch vụ bên ngoài và nhiều containers thử nghiệm. Docker sẽ có thể chạy tất cả các phụ thuộc này trên một server duy nhất vì mọi containers đều chia sẻ hệ điều hành cơ bản.
Nếu bạn có nhiều thử nghiệm hơn để chạy trên ứng dụng của bạn , bạn có thể tạo các file Dockerfiles bổ sung cho chúng, tương tự như file Dockerfile.test
được hiển thị ở trên.
Sau đó, bạn có thể thêm container bổ sung bên dưới sut
chứa trong docker-compose.test.yml
file , tham khảo Dockerfiles bổ sung.
Bước 6 - Kiểm tra ứng dụng “Hello World”
Cuối cùng, mở rộng các ý tưởng Docker từ môi trường local sang môi trường thử nghiệm, ta có một cách tự động kiểm tra ứng dụng của bạn bằng Docker bằng cách thực thi:
- docker-compose -f ~/hello_world/docker-compose.test.yml -p ci build
Lệnh này xây dựng các hình ảnh local cần thiết bởi docker-compose.test.yml
. Lưu ý ta đang sử dụng -f
để trỏ đến docker-compose.test.yml
và -p
để chỉ ra một tên dự án cụ thể.
Bây giờ hãy tạo ra môi trường thử nghiệm mới của bạn bằng cách thực hiện:
- docker-compose -f ~/hello_world/docker-compose.test.yml -p ci up -d
OutputCreating ci_redis_1 Creating ci_web_1 Creating ci_sut_1
Kiểm tra kết quả của containers sut
bằng cách thực hiện:
- docker logs -f ci_sut_1
% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 42 100 42 0 0 3902 0 --:--:-- --:--:-- --:--:-- 4200 Tests passed!
Và cuối cùng, hãy kiểm tra mã thoát của containers sut
để xác minh xem các bài kiểm tra của bạn đã vượt qua chưa:
- docker wait ci_sut_1
0
Sau khi thực hiện lệnh này, giá trị của $?
sẽ là 0
nếu các bài kiểm tra vượt qua. Nếu không, các thử nghiệm ứng dụng của ta không thành công.
Lưu ý các công cụ CI khác có thể sao chép repository mã của ta và thực hiện một số lệnh này để xác minh xem các thử nghiệm có đang vượt qua với các bit mới nhất của ứng dụng của bạn hay không mà không phải lo lắng về dependencies thời gian chạy hoặc cấu hình dịch vụ bên ngoài.
Đó là nó! Ta đã chạy thử nghiệm thành công trong một môi trường mới được xây dựng giống với môi trường production của ta .
Kết luận
Nhờ Docker và Docker Soạn, ta đã có thể tự động hóa việc xây dựng một ứng dụng ( Dockerfile
), triển khai một môi trường local ( docker-compose.yml
), xây dựng một hình ảnh thử nghiệm ( Dockerfile.test
), và thực hiện (tích hợp) kiểm tra ( docker-compose.test.yml
) cho bất kỳ ứng dụng nào.
Đặc biệt, lợi thế của việc sử dụng file docker-compose.test.yml
để thử nghiệm là quá trình thử nghiệm là:
- Tự động hóa : cách một công cụ thực thi
docker-compose.test.yml
độc lập với ứng dụng đang thử nghiệm - Trọng lượng nhẹ : hàng trăm dịch vụ bên ngoài có thể được triển khai trên một server duy nhất, mô phỏng môi trường thử nghiệm (tích hợp) phức tạp
- Bất khả tri : tránh khóa nhà cung cấp CI và các thử nghiệm của bạn có thể chạy trong bất kỳ cơ sở hạ tầng nào và trên bất kỳ hệ điều hành nào hỗ trợ Docker
- Bất biến : các bài kiểm tra vượt qua trên máy local của bạn sẽ vượt qua trong công cụ CI của bạn
Hướng dẫn này cho thấy một ví dụ về cách kiểm tra một ứng dụng “Hello World” đơn giản.
Bây giờ nó là thời gian để sử dụng profile của bạn , Dockerize kịch bản thử nghiệm ứng dụng của bạn , và tạo riêng của bạn docker-compose.test.yml
để kiểm tra ứng dụng của bạn trong một môi trường trong lành và không thay đổi.
Các tin liên quan
Cách cấu hình môi trường kiểm tra tích hợp liên tục với Docker và Docker Compose trên Ubuntu 14.042016-11-03
Cách cài đặt và sử dụng Docker trên CentOS 7
2016-11-02
Cách gỡ lỗi và khắc phục các sự cố thường gặp của Docker
2016-10-20
Cách cài đặt Prometheus bằng Docker trên CentOS 7
2016-01-15
Cách cài đặt Prometheus bằng Docker trên Ubuntu 14.04
2016-01-12
Cách cài đặt Wordpress và PhpMyAdmin với Docker Compose trên Ubuntu 14.04
2015-11-19
Cách cài đặt và sử dụng Docker Compose trên Ubuntu 14.04
2015-11-19
Cách dọn dẹp môi trường Docker của bạn bằng CloudSlang trên CoreOS Cluster
2015-06-10
Cách quản lý triển khai nhiều node của bạn với Máy Rancher và Docker trên Ubuntu 14.04
2015-04-27
Cách tập trung log Docker của bạn với Fluentd và ElasticSearch trên Ubuntu 14.04
2015-03-30