Cuối tuần vừa rồi đọc được cuốn sách khá hay nên tranh thủ viết vài dòng review về cuốn sách này. Một cuốn sách viết về UX nhưng không đề cập đến các kỹ thuật UI/UX mà trình bày về chiến lược phân tích và triển khai sản phẩm. Đó là cuốn “Think First: My No-Nonsense Approach to Creating Successful Products, Memorable User Experiences + Very Happy Customers” của Joe Natoli.
Thế là đã hết tuần đầu tiên của 2017, mọi người đã học được gì mới chưa? Giờ rãnh rỗi mới dành chút thời gian viết về Typescript, một thứ “ngôn ngữ” mới đã tranh thủ học được trong mấy ngày qua và chia sẻ một số góc nhìn cá nhân về Typescript. Đây cũng là bài khai trương năm 2017, hy vọng cả năm thăng hoa với nghiệp code và tổ nghiệp phù hộ làm ăn phát đạt.
Thế là đã hết năm 2016, một năm được coi là có quá nhiều sự kiện lớn, thăng trầm đều có đủ. Trước khi đi sang những mục tiêu của năm mới, việc nhìn lại năm cũ cũng thật cần thiết.
2016 – Đầy thăng trầm
2016 là năm dành nhiều thời gian nhất cho gia đình, có thể là nhiều nhất kể từ khi mình vào Sài Gòn từ 2004. Đầu năm bắt đầu bằng một sự kiện rất vui là dẫn được cả gia đình cha mẹ, vợ con đi chơi Thái Lan, một chuyến đi đáng nhớ cho tất cả mọi người. Đây là khoảng khắc bắt đầu những mối quan tâm của mình về gia đình.
Vậy là đã sang năm 2016, nhìn lại năm 2015 thì đúng là còn sóng gió và thú vị hơn cả năm 2014. Và đã có những bài học và kinh nghiệm khó quên trong cuộc đời và sự nghiệp của mình.
2015 – Một năm thú vị
Nếu như năm 2014 được đánh giá là năm “Thích nghi” của mình, thì sau 1 năm nhìn lại thì 2015 mình chỉ có thể dùng 1 từ là “Sinh tồn” (survive). Như một số bạn cũng biết mình mở công ty từ năm 2014 và đồng hành với việc thích nghi khi mở một công ty, thuê 10 nhân viên thì vốn đầu tư từ angel vẫn còn và sử dụng khá thoải mái.
Hôm qua bạn đi làm về lúc mấy giờ? Chắc quá 5pm? Vậy thì bạn nên dành chút thời gian để đọc bài blog nhỏ này. Mình viết bài này dành cho những người anh em, bạn bè đang là người trả lương hoặc được trả lương nhằm chia sẻ góc nhìn về việc đi làm về trễ. Có bao giờ bạn tự hỏi là nếu mình về trễ hơn 5pm hoặc cho anh em (nhân viên) của mình về trễ hơn 5pm thì mình có nợ nần gì cuộc đời không?
Nợ chính cái tôi của bạn
Một ngày trung bình bạn ngủ 8 tiếng, vậy còn 16 tiếng để thức. Vậy bạn dành 16 tiếng này để làm gì? Làm việc 12 tiếng, vui chơi nghỉ ngơi 4 tiếng hay đi làm 8 tiếng, 8 tiếng còn lại cho mình một cuộc sống thú vị. Bạn cần nhiều thời gian hơn cho việc tập luyện thể thao, ăn uống, đọc sách, du lịch đây đó, học một kỹ năng nào đó hoặc đơn giản hơn là không làm gì cả để cho tâm được tĩnh và thư giản sau những giờ phút căng thẳng.
Nợ cha mẹ bạn
Cha mẹ bạn luôn là người mong muốn bạn có một cuộc sống khỏe mạnh và hạnh phúc, cũng như có một cuộc sống cân bằng, vui vẻ. Nếu may mắn bạn được sống chung với cha mẹ thì tại sao phải về trễ để cha mẹ chờ cơm và cha mẹ luôn là những người lo lắng cho bạn khi bạn không ở nhà.
Nợ người bạn đời của bạn
Hầu hết ai cũng sẽ có người tâm giao (vợ, chồng,…) và đó là những người bên cạnh và chờ đợi bạn đi làm về để cùng sum vầy bên gia đình cũng như thưởng thức những bữa tối cùng nhau. Hà cớ gì mà bạn phải để những người thương của mình phải chờ đợi bạn dài cổ mỗi khi chiều về và đến tận 7,8pm mới được gặp nhau.
Nợ những đứa con của bạn
Hơn ai hết, con cái chúng ta rất mong chúng ta về nhà và cùng vui vầy với nhau mỗi khi chiều xuống. Bạn có biết là con cái chúng ta lớn nhanh đến thế nào không, đến khi hết tất bật nhìn lại thì chúng đã lớn khôn mất rồi và những ký ức và khoảng thời gian này sẽ khó mà trở lại.
Nợ những đồng nghiệp của bạn
Bạn tự chọn cho mình về sau 5pm để hoàn thành công việc mà lẽ ra công việc của bạn phải hoàn thành sớm hơn. Đôi khi công việc của bạn lại liên quan đến công việc của một người nào đó, và hệ lụy của nó là đồng nghiệp của bạn phải chịu trận chung với mình và khiến họ gánh những món nợ ân tình mà đáng ra họ không nên có.
…và bạn sẽ còn nợ rất nhiều thứ khác nếu bạn phải hoặc bị ép ở lại sau 5pm.
Với những món nợ to lớn thế nào, thật không thể nào dám để anh em cùng chiến tuyến của mình về sau 5pm và may mắn là văn hóa 9am-5pm vẫn duy trì tốt từ khi thành lập công ty cho đến bây giờ vì mình hiểu, ai cũng có gia đình và ai cũng có nhu cầu về đúng giờ để dành thời gian cho gia đình, người thương và cân bằng cuộc sống.
Lựa chọn IaaS nào luôn là trăn trở của công ty cung cấp dịch vụ cloud-based (SaaS) như mình vì vấn đề cân đối giữa giá và performance hệ thống, người dùng luôn được cân nhắc. Vừa chuyển về cloud của Việt Nam (VCCloud, không có quảng cáo, cái nào tốt thì xài) thấy giá không như xưa, có thể nói là ngang ngửa giá với cloud thuộc dạng rẻ nhất của nước ngoài (Linode, mình sử dụng Linode vì chính sách giá cũng như support khá tốt, và có data center ở Singapore), nếu biết tweak có thể có một số cấu hình rẻ hơn nước ngoài về memory. Được cái cloud ở VN thì performance là tốt nhất so với nước ngoài vì độ trễ thấp hơn nhiều (trừ những lúc mấy ông nội VN cấu hình sao đó mà truy cập site ở VN mà chậm hơn ở Sing ^^!). Sau khi đo đạc, nghiên cứu thì sau 10 ngày, tức là hôm nay thì data center của Teamcrop đã về với đất mẹ.
Nội dung bài viết chia sẻ một số cách tiếp cận của mình khi phân tích performance và quyết định dời nhà hệ thống về Việt Nam.
Về giá cả
Trước đây, khi quyết định chuẩn bị một hệ thống scale thì đã quyết định không sử dụng bare metal server mà xem xét nâng cấp lên cloud server để scale cho dễ. Thời điểm cách đây nửa năm các dịch vụ cloud ở Việt Nam còn khá mơ hồ về chất lượng và giá cả, còn về mảng dịch vụ VPS hoặc Dedicated server thì chi phí khá cao.
Mình đã quyết định chuyển toàn bộ hệ thống sang Singapore và sử dụng dịch vụ server của Linode. Linode là một trong những nhà cung cấp có tiếng trên thế giới về hạ tầng Cloud server và giá thì rất cạnh tranh so với Amazon Web Service (AWS), vì dùng AWS tính toàn giá trên trời và giá của Linode cũng rẻ gần như bằng 1 nửa so với các server cùng cấu hình ở VN.
Về performance
Khi chuyển Data center ra ngoài Việt Nam thì một trong những vấn đề performance lớn nhất là tốc độ kết nối, kéo theo khá nhiều thứ bị chậm lại theo. Do hệ thống sử dụng HTTPS và đặc thù của HTTPS là cần 3 RTT (round-trip time) nên nếu 1 RTT chậm thì sẽ kéo theo https sẽ rất chậm. Còn về performance của server thì hầu như không có sự khác biệt về CPU, Memory, HDD.
Mình có cung cấp 1 số thông tin mình test và quyết định chuyển hệ thống về Việt Nam bên dưới.
Về kiến trúc ứng dụng
Do đặc thù định hướng xây dựng theo kiến trúc Microservices và Single Page App (SPA) nên một trang trong tương lai sẽ gọi khá nhiều web service và đồng thời mở ra các web service cho 3rd-party khiến cho việc di chuyển về VN sẽ có nhiều lợi thế về tốc độ hơn, kẻo đã chậm lại càng thêm chậm khi chuyển sang kiến trúc mới.
Khảo sát & so sánh
Một số kết quả khảo sát của mình thực hiện trước khi ra quyết định chuyển về dùng Cloud ở Việt Nam. Thời điểm khảo sát là ngày 29/9/2015 và thực hiện tại TPHCM. Mình có benchmark kết nối với Redis server vì hệ thống mình dùng chủ yếu là Redis cho layer cache.
1. VCCloud – SAS – 1CPU, 2G RAM
– iperf3 giữa 2 server là ~380Mbits/sec. Metric này khá quan trọng nếu bạn xây dựng microservice vì tốc độ giữa 2 server nội mạng là cực kỳ quan trọng vì các server sẽ request lẫn nhau khá nhiều. Do data center trong nước chưa đầu tư các đường truyền hoành tráng nên có vẻ metric này khá thấp so với data center của quốc tế.
– PING RTT giữa 2 server là: 0.578ms
– PING RTT từ Client Viettel đến server: 50.913
– PING RTT từ Client FPT đến server: 26.558ms
– PING RTT từ Client VNPT đến server: 31.834ms
– PING RTT từ Client 3G Mobifone đến server: 105ms
– Redis benchmark
Without pipeline:
./redis-benchmark -h redis.server.lan.ip -n 100000 -t get,set -q
SET: ~ 44K requests per second
GET: ~ 48K requests per second
With pipeline -P 1000
./redis-benchmark -h redis.server.lan.ip -n 100000 -t get,set -q -P 1000
SET: ~ 550K – 610k requests per second
GET: ~ 560K – 610k requests per second
2. Linode – SSD – 2CPU, 2G Ram
– iperf giữa 2 server là 5.78Gbits/sec
– PING RTT giữa 2 server là: 0.508ms
– PING RTT từ Client Viettel đến server: 49.015
– PING RTT từ Client FPT đến server: 160.753ms
– PING RTT từ Client VNPT đến server: 306.097 ms
– PING RTT từ Client 3G Mobifone đến server: 311ms
– Redis benchmark
Without pipeline:
./redis-benchmark -h redis.server.lan.ip -n 100000 -t get,set -q
SET: ~ 33K requests per second
GET: ~ 32K requests per second
With pipeline -P 1000
./redis-benchmark -h redis.server.lan.ip -n 100000 -t get,set -q -P 1000
SET: ~ 790k – 950K requests per second
GET: ~ 1100K requests per second
—
Một số lưu ý là Cloud server ở Việt Nam nếu bạn dùng nhiều ổ cứng, SSD thì giá sẽ khá cao nên cần tối ưu giữa sử dụng nhiều ở cứng hay không vì mình không dùng nhiều ổ cứng mà dùng nhiều memory, nên một số server cache memory thì cứ để memory mong muốn, hdd và cpu ở mức chạy được là sẽ tiết kiệm hơn khá nhiều so với cloud ở quốc tế.
Hy vọng một số chia sẻ ở đây sẽ giúp các bạn có một số góc nhìn về hệ thống cũng như hạ tầng cloud và ra quyết định sao cho có lợi cho sản phẩm của mình trong quá trình triển khai và scale phục vụ nhiều người dùng.
Docker registry là nơi chứa các image trong quá trình khởi động các container. Hầu hết mọi người đang sử dụng các image có sẵn và nếu chưa biết thì nó được host tại Docker hub chính thức. Tuy nhiên, có một số hạn chế khi sử dụng docker hub như sau:
– Server đặt ở nước ngoài (khác VN)
– Tính phí cho các private image. Bạn không thể nào public các image nội bộ nên bạn chỉ có lựa chọn private image. Nếu bạn có một vài project thì chi phí không cao. Nhưng nếu bạn phát triển theo hướng microservice như mình thì sẽ có vài chục đến vài trăm private image, nếu thuê theo gói thì hoàn toàn không kinh tế lắm.
Với 2 hạn chế trên thì hầu hết các công ty tự triển khai các registry cho riêng mình vì registry cũng là open source. Bạn thuê / mua một con server, vps và start cái image registry 2.0 là xong, và có rất nhiều hướng dẫn trên mạng chỉ bạn cách dựng một private registry như vậy. Tuy nhiên, registry bạn dựng lên hầu như không thực tế và chỉ để test mà thôi.
Nội dung bài viết này mình hướng đến một cài đặt registry production tức là chạy thực sự chứ không phải để test đòi hỏi một số yêu cầu như tên miền riêng, ngắn, hỗ trợ https, có backup và có hỗ trợ ACL (Access Control List).
1. Tên miền và SSL Certificate
Tên miền
Bạn cần chọn một tên miền cho registry của mình. Lời khuyên của mình là chọn một tên miền khác với tên miền đang dùng và dự kiến là sẽ không public tên miền này ở port 80, 443, có nghĩa là không dùng tên miền này để chạy web server. Ví dụ mình chọn tên miền docker2.com là registry của mình.
Bạn có thể mua tên miền và tạo A record trở đến IP của VPS/Server của bạn.
SSL Certificate
Vì private registry mặc định hỗ trợ https nên bạn cần phải có SSL Certificate cho domain của mình. Cách đăng ký mua SSL Certificate thì có rất nhiều bài hướng dẫn, chịu khó google là ra. Ở đây mình ví dụ là mua ở sslcertificate.com.
Quy trình tiếp theo của mua SSL Certificate là kích hoạt và nhập CSR của bạn. CSR (Certificate Signing Request) là một chuỗi có được trong quá trình tạo ra private key. Nó chứa các thông tin cần thiết trong quá trình tạo ra SSL Certificate của bạn. Bạn phải cung cấp CSR thì mới có được SSL Certificate.
Có thể dễ dạng tạo ra cặp CSR và private key thông qua openssl, ví dụ trong hình là mình tạo csr và private key.
Lưu ý là “common name” thường là domain hoặc subdomain dùng để đăng ký SSL Certificate. Vì loại SSL Certificate rẻ nhất chỉ áp dụng cho 1 domain hoặc subdomain. Còn loại Wildcard SSL Certificate thì áp dụng cho toàn bộ subdomain của 1 domain nên giá của wildcard khá chát.
Bạn copy nội dung của file CSR bỏ vào phần thông tin yêu cầu CSR của nhà cung cấp.
Màn hình confirm các thông tin CSR và thông tin sẽ submit để lấy SSL Certificate
Sau đó, bạn làm theo chỉ dẫn của nhà cung cấp để có các file cần thiết của Certificate. Bạn sẽ nhận được 1 file Certificate hoặc nội dung email chứa certificate của bạn. Thường thì với certificate này là có thể cấu hình ssl được. Tuy nhiên, hầu hết các nhà cung cấp SSL đều có một (một số) key gọi là intermediate certificate (cũng là file crt). Khi tạo file crt cuối cùng thường nối thêm các file intermediate certificate này nữa. Có thể nối thông qua câu lệnh CAT.
Ví dụ trong trường hợp mua SSL của COMODO, ngoài file CRT của domain, họ còn cung cấp 1 số intermediate crt, có thể gom các crt và tạo ra bundle các certificate bằng câu lệnh sau:
Bạn sẽ dùng file crt bundle này và file .key (generate ở bước tạo csr) là có thể cấu hình được https.
Để thuận tiện cho các bước chạy các container, đổi tên file bundle crt thành file “domain.crt” và file .key thành “domain.key”. Tiến hành đến bước khởi tạo private registry.
Trong thư mục này thì 2 file “domain.crt” và “domain.key” là 2 file đã được đề cập ở phần 1.
Nội dung file “docker-compose.yml” sẽ là chỉ dẫn để khởi tạo 2 container từ 2 image có sẵn “registry” để tạo container chạy registry 2.0 và image “cesanta/docker_auth” để sử dụng cơ chế token authentication. Trong file docker-composer.yml cũng tạo các volume mount đến các thư mục cần sử dụng như là “certs”, “data”, “log”…Lưu ý là thư mục “certs” sẽ được mount thành thư mục gốc “/certs” trong các container, điều này giải thích vì sao các đường dẫn của certificate bạn thấy là “/certs/domain.crt” và “/certs/domain.key” thay vì sử dụng đường dẫn khác.
Nội dung file “auth_config.yml” chính là config cho hệ thống phân quyền và config trỏ đến đường dẫn của 2 file certificate sau khi mount tại “/certs”. Bạn có thể tham khảo thêm chi tiết về image này tại project https://github.com/cesanta/docker_auth. Dưới đây là ví dụ file cấu hình của mình.
Lưu ý là phần password được tạo bên ngoài và copy vào file config. Password được tạo bằng “htpasswd -n -B yourusername” thì sẽ hiển thị password cho bạn. Ví dụ:
Thư mục “log” dùng để lưu lại các log trong quá trình chứng thực private registry. Thư mục “data” là thư mục quan trọng, chứa toàn bộ dữ liệu của registry. Bạn có thể stop và remove container và khi start lại có thể mount lại volume trên thư mục “data” là có thể sử dụng được dữ liệu của registry. Bạn có thể backup thư mục “data” này để backup cho toàn bộ registry.
Sau khi các file và thư mục đã chuẩn bị sẵn sàng, bạn có thể sử dụng docker composer để nhanh chóng khởi động private registry của mình thông qua câu lệnh:
docker-composer up -d
Bạn có thể verify bằng cách thực hiện docker login, ví dụ: “docker login yourdomain:5000” và nhập “username” và “password” như đã cài đặt trong file “auth_config.yml”.
Cấu hình port 443 (HTTPS)
Trong một số trường hợp, mình muốn chạy domain của registry không cần port 5000, vậy thì mình phải config để có thể forward từ port 443 sang port 5000.
Hầu hết các request của mình đều thông qua Haproxy nên mình có thể điều hướng trong haproxy. Khi có request https đến từ port 443 thì forward sang port 5000 đang chạy registry service.
Bởi vì bản thân registry service đang chạy port 5000 hỗ trợ SSL nên mình cấu hình haproxy sẽ đơn giản hơn, bởi vì mình không terminate SSL tại haproxy mà service registry đang chạy trên port 5000 đã terminate SSL rồi. Do đó, cấu hình SSL ở Haproxy chỉ đơn giản là pass-through sang service đang chạy port 5000.
Ví dụ của file /etc/haproxy/haproxy.cfg:
Sau khi chỉnh sửa file config thì tiến hành reload haproxy để apply. Như vậy bạn có thể sử dụng yourdomain.com thay vì yourdomain.com:5000 như thông thường.
Lưu ý là làm cách này thì bạn không thể cung cấp được website bình thường (https) vì registry đã sử dụng port này rồi, nên domain để chạy registry thường không được sử dụng để truy cập trực tiếp nếu bạn muốn dùng https trên domain.
—
Hy vọng bài viết này sẽ giúp các bạn triển khai được một private registry ngon lành cho công ty của mình.
Chắc hẳn là lập trình web thì mọi người đã từng một lần kết nối đến một hệ thống khác thông qua Web Service, có thể là SOAP, RESTful…Nội dung bài viết này mình sẽ chia sẻ với mọi người một số vấn đề và giải pháp mà mình đang gặp phải khi triển khai các Restful service.
Restful Documentation
Trong quá trình thiết kế Restful API, documentation (docs) cho API là một trong những thứ cực kỳ cần thiết để giúp bạn cũng như công ty, khách hàng dễ dàng làm việc trên API mà bạn thiết kế.
Docs API đơn giản có thể là các ghi chú, word, excel hoặc các SaaS base service để giúp tạo API nhanh chóng và tiện lợi hơn cũng như hỗ trợ làm việc nhóm hiệu quả hơn.
Đã thử dùng rất nhiều công cụ và nhiều phương tiện khác nhưng không có cái nào phù hợp nhu cầu nên đành tự phát triển một công cụ tạo docs API riêng cho mình, đơn giản và linh hoạt hơn, đó là Apitoy.com.
Cũng như hầu hết các công cụ SaaS based khác để làm Restful API Docs, Apitoy.com cũng cho phép tạo nhiều dự án, mỗi dự án sẽ có nhiều nhóm request (group). Mỗi request sẽ có quy định loại request (GET, POST, PUT..), tham số đầu vào, định dạng cũng như các thông tin request / response của một request.
Một số hình ảnh của Apitoy:
Danh sách Zone (Project)Danh sách các Request của một zone.Chỉnh sửa chi tiết một RequestChi tiết một Request Docs
Mock Server
Cũng như các lập trình viên thiết kế Restful API khác, việc dựng một Mock server từ một API Docs là một nhu cầu cực kỳ cần thiết để việc test cũng như tách biệt giữa web service consumer & service producer trong quá trình phát triển ứng dụng. Nhờ có Mock server mà phía frontend có thể có data giả (fake data) nhưng có cấu trúc đúng với cấu trúc của API thiết kế và sẽ không lệ thuộc vào backend phải hoàn thành API trước khi thử.
Apitoy có một tính năng rất thú vị và độc đáo là cho phép tự tạo một mock service dựa vào một request mà bạn đã thiết kế và response data (fake data) sẽ được auto-generate khi có request vào đúng mô tả request của bạn như đúng HTTP Method (GET, POST< PUT…), đúng URL…
Lưu ý là để mock service có thể chạy thì bạn bắt buộc phải tạo ít nhất 1 response cho request. Các snippet động “{{…}}” sẽ được bỏ khi xem docs và được thay thế khi có request để lấy mock data.
Apitoy hỗ trợ một số hình thức generate dữ liệu động sau:
Kiểu dữ liệu chuẩn
Nếu các giá trị có dạng “Integer”, “Float”, “String” thì sẽ được thay thế bằng các dữ liệu ngẫu nhiên tương ứng với kiếu giá trị như “100”, “3.14”, “Hello world”…
String{{phoneNumber}}: Thay thế bằng số điện thoại ngẫu nhiên
String{{email}}: thay thế bằng email ngẫu nhiên
Integer{{randomNumber}}: thay thế bằng một số ngẫu nhiên
Integer{{randomNumber:5}}: thay thế bằng một số ngẫu nhiên có 5 chữ số
…
Bạn có thể tham khảo website https://github.com/fzaninotto/Faker để biết tất cả các Snippet hỗ trợ trong Apitoy để generate các dữ liệu “giống thật” hơn.
Apitoy Snippet
Bên cạnh các snippet hỗ trợ từ thư viên Faker, apitoy còn cung cấp 2 snippet khác là “enum” và “repeat”.
– String{{enum:option1:option2:option3}}: chọn ngẫu nhiên một giá trị trong danh sách option. Ví dụ: Integer{{enum:0:1}}, String{{enum:”Yes”:”No”}}…
– {{repeat:repeat_id:repeat_count:repeat_seperator}}…{{/repeat:repeat_id}}: lặp lại một đoạn code được đánh dấu. Trong đó: “repeat_id” để đánh dấu đoạn code cần lặp, không có 2 đoạn repeat có cùng “repeat_id”. “repeat_count” số lần lặp lại của đoạn code bạn đánh dấu. “repeat_separator” ký tự phân cách giữa các lần lặp, mặc định là dấu phẩy “,”.
Hiện nay, Python là một trong những ngôn ngữ lập trình đang được chú ý bởi tính đa dạng về ứng dụng, thư viện phong phú và cộng đồng đông đảo.
Đã làm việc với PHP 10 năm, và có những tác vụ mà PHP khó mà thực hiện tối ưu được, khiến mình phải tiếp cận với Python trong giai đoạn này.
Cuốn sách nhỏ này được viết trong quá trình mình bắt đầu học Python và giải quyết các bài toán cơ bản theo nhu cầu của mình.
Hy vọng những ghi chép của mình cũng sẽ giúp ích cho những ai đang quan tâm đến việc ứng dụng Python vào công việc và xử lý hiện tại.
Mục lục
Sách được chia làm 15 chương, mỗi chương sẽ trình bày 1 khía cạnh của Python mà mình sẽ gặp phải và sẽ hữu ích khi biết các kiến thức này trong việc áp dụng Python vào công việc trong tương lai.
Hy vọng mọi người thấy cuốn sách nhỏ này hữu ích và sẽ không ngại học ngôn ngữ Python vì tương lai Python sẽ là một ngôn ngữ rất hot. Và cũng đừng quên tham gia và đóng góp nhiều hơn cho cộng đồng open source.
Bạn thường deploy code bằng cách nào? Sử dụng FTP để drag & drop file từ máy lên server? Hôm nay mình sẽ chia sẻ cho mọi người một cách deploy code bài bản hơn một chút nhờ sử dụng Jenkins. Ngoài ra, Bài viết cũng tập trung cho các dự án code bằng PHP và có sử dụng một số đồ chơi để phân tích code PHP khi build. Nối tiếp chuỗi bài viết về Docker, bài viết này cũng sẽ hướng dẫn chạy Jenkins trên môi trường Docker.
Jenkins là gì
Nếu như các bạn có quan tâm đến các kỹ thuật CI/CD thì sẽ không thể không biết đến “anh đại” Jenkins. Jenkins là một bộ phần mềm viết bằng Java và hỗ trợ rất mạnh mẽ việc build và deploy code trong quá trình triển khai code lên các môi trường mà bạn đang làm việc như test, beta, production…
Trước đây, để cài đặt một server Jenkins thì đỏi hỏi khá nhiều công sức và khá rắc rối khiến cho nhiều anh chị em bỏ cuộc nữa chừng, khiến cho việc tiếp cận với các đồ chơi của Jenkins bị hạn chế. Và trước đây mình cũng nhiều lần cài đặt Jenkins và cũng vọc nhưng cũng không thấy mặn mà lắm vì mỗi lần cài đặt, setup khá vất vả.
Tuy nhiên, nhờ sự trợ giúp của Docker, ngày nay, việc cài đặt Jenkins là một trải nghiệm “sung sướng”. Chỉ cần pull image chính thức của Jenkins và làm theo một số chỉ dẫn tại https://hub.docker.com/_/jenkins/ là đã nhanh chóng dựng được Jenkins để trải nghiệm quá trình build và deploy code nhanh chóng.
Jenkins và PHP
Mục tiêu của phần này giới thiệu đến mọi người một Jenkins Docker image mà mình xây dựng riêng cho các dự án hằng ngày là tích hợp sắn các phần mềm và plugin kèm theo trong jenkins cho PHP. Image này mình có public trên docker hub, có tên là “voduytuan/jenkins-php-docker”.
Một số đồ chơi PHP cài thêm cho server này là:
– Toàn bộ đồ chơi tại http://jenkins-php.org (loại trừ phpdox mình không xài nên không cài)
– Xdebug extension để generate code coverage report
– Jenkins Git plugin để pull code từ repo Github hoặc Bitbucket..
– Jenkins Push Over SSH plugin để deploy code lên server
– Docker bên trong jenkins (^^!) để build các image và push lên private registry cho các dự án microservice
Các bạn có thể tham khảo Dockerfile để biết thêm các đồ chơi mình cài cũng như có thể tạo riêng cho mình một image với các đồ chơi theo nhu cầu của bạn.
Bạn có thể start Jenkins bằng câu lệnh sau: ~ > docker run -d --name jenkins -p 9090:8080 -v /data/jenkins/jenkins-php-docker:/var/jenkins_home:rw voduytuan/jenkins-php-docker
Hướng dẫn tham số:
– “-v /data/jenkins/jenkins-php-docker:/var/jenkins_home:rw”: Một tham số cần lưu ý là mount volume thư mục data của jenkins (/var/jenkins_home). Đây là toàn bộ dữ liệu của Jenkins trong quá trình sử dụng. Ở đây mình mount vào thư mục /data/jenkins/jenkins-php-docker trên máy. Bạn có thể để thư mục “jenkins-php-docker” là rỗng hoặc clone từ repo của mình (https://github.com/voduytuan/jenkins-php-docker) để có sẵn một template tên là “php-template” để sau này khi tạo project thì sử dụng template để tạo nhanh các cấu hình build dự án. Lưu ý việc phân quyền user cho thư mục bạn mount volume. Đơn giản nhất là cứ quyền 0777.
Sau khi chạy docker run, chờ một thời gian (một vài phút tùy server) để Jenkins khởi động và bạn có thể truy cập đến Jenkins thông qua IP của server và port bạn khai báo (vd: 9090). Nếu thành công, bạn sẽ thấy màn hình như bên dưới:
Dashboard của Jenkins
Khởi tạo Jenkins
Khi chạy Jenkins lần đầu thì Jenkins hoàn toàn không có một cơ chế bảo mật nào hết và cho phép truy cập ẩn danh. Bạn có thể làm theo 1 số thao tác đơn giản sau để tạo tài khoản Admin và phân quyền lại cho an toàn hệ thống.
Manage Jenkins
Vào Manage Jenkins > Configure Global Security và chỉnh như hình bên dưới để cho phép tạo tài khoản:
Configure Global Security
Sau khi cấu hình, nhấn lưu thì góc trên bên phải sẽ hiện link đăng ký, và đăng nhập. Tiến hành đăng ký tài khoản đầu tiên.
Jenkins create new user
Sau khi tạo tài khoản và đăng nhập vào, bạn quay lại trang “Configure Global Security” để cấu hình như bên dưới. Configure Global Security
(Nội dung thay đổi là bỏ cho phép đăng ký và chọn hình thức Authorization là Matrix-based security và add user bạn vừa tạo vào bảng phân quyền, đồng thời chọn hết các quyền cho user này, sau đó nhấn Apply và Save để hoàn tất quá trình thay đổi.
Ngoài ra, cũng trong trang này, phần “Markup Formatter” chọn là “Raw HTML” để trong trang dự án hiển thị HTML được trong phần “Description”.
Với tài khoản hiện tại, bạn có thể tạo tài khoản cho các thành viên khác có nhu cầu sử dụng hệ thống và phân quyền theo nhu cầu của bạn. Bài viết sẽ không đi sâu vào hướng dẫn phân quyền, bạn có thể tham khảo trên google hoặc trên trang web chính thức của Jenkins.
Sau khi quyền hạn và cài đặt đã xong, bạn tiến hành tạo project để thực hiện CI/CD cho dự án của mình.
Tạo project và tiến hành build
– Tạo một project mới và đặt tên tùy ý và với template mẫu là “php-template” (nếu bạn thư mục mount có project đã clone từ repo của mình hướng dẫn). (Xem hình) Create new project in Jenkins
Nhấn OK để tạo và đến trang cấu hình của dự án này. Trang cấu hình là trang quan trọng nhất của dự án bởi nó sẽ giúp bạn cài đặt các thao tác cho dự án này.
Project Configuration
Có 3 bước cơ bản (quan trọng) trong trang cấu hình bạn cần biết là:
1. SCM: Bạn cần link đến repo source code của bạn. Mặc định Jenkins ko hỗ trợ Git, nhưng bản Docker image của mình đã cài Git plugin nên bạn có thể cấu hình liên kết đến các Git repo (github, bitbucket…). Ví dụ cấu hình Git: Git SCM
2. Build: dùng để cấu hình, chọn các cách thức build dự án. Ở template “php-template” thì mình build bằng Apache Ant (thông qua file build.xml tại thư mục gốc của sourcecode – mình sẽ share file build.xml mẫu cho một dự án php ở cuối bài).
3. Post-build action: là các thao tác được thực hiện. Đó có thể là phân tích các file output (xml, json..) từ bước build tạo ra và tạo các report, hoặc là SSH vào remote server để deploy code, thực hiện một câu lệnh nào đó hoặc build một docker image mới rồi push lên repo sau khi build success. Có rất nhiều plugin của Jenkins hỗ trợ nhiều khía cạnh build khác nhau. Có thể tham khảo thêm trên Jenkins plugin. Hình chụp một số Post-build action trong dự án của mình: Post build Action vẽ biểu đồ
Post build action Push Over SSH
Một số kết quả generate từ các post-build action theo template mẫu “php-template”:
Bạn có thể tìm hiểu thêm tại http://jenkins-php.org/ để hiểu rõ về cách đọc các report về ứng dụng PHP của bạn.
Hy vọng những chia sẻ về Jenkins này sẽ giúp bạn nhanh chóng và dễ dàng triển khai Jenkins cho hệ thống của mình để quá trình build và deploy code được tự động, nhanh chóng và an toàn hơn.
—
Cấu trúc thư mục của dự án Apitoy để mọi người hiểu hơn về các đường dẫn trong file config.
File sample build.xml dùng cho Ant cho dự án của mình, chia sẻ để mọi người tham khảo.
Trong file build.xml có sử dụng 2 file xml khác cho phpmd và phpunit. 2 file này cũng được chia sẻ bên dưới.