Thứ tư, 14/06/2017 | 00:00 GMT+7

Cách cài đặt và cấu hình Drone trên Ubuntu 16.04

Cảnh báo : Phiên bản Drone này không được dùng nữa. Để được trợ giúp cài đặt version Drone mới nhất, hãy truy cập hướng dẫn cài đặt Drone Ubuntu 20.04 của ta .


Drone là một nền tảng phân phối và tích hợp liên tục phổ biến được tích hợp sẵn trong Go. Nó tích hợp với nhiều dịch vụ repository kiểm soát version phổ biến như GitHub, GitLab và Bitbucket để theo dõi các thay đổi mã và tự động xây dựng và kiểm tra các thay đổi khi chúng được commit .

Trong hướng dẫn này, ta sẽ trình bày cách cài đặt môi trường tích hợp liên tục Drone hoàn chỉnh cho cơ sở hạ tầng của bạn. Ta sẽ cài đặt Drone và cấu hình nó để tích hợp với kho mã nguồn của bạn. Trên đường đi, ta sẽ cấu hình Nginx, được bảo vệ bởi Let's Encrypt, làm giao diện user cho Drone. Điều này sẽ mã hóa các yêu cầu đến giao diện web của Drone và cho phép server CI tích hợp an toàn với server mã nguồn.

Yêu cầu

Để bắt đầu, bạn nên cấu hình server Ubuntu 16.04 với user sudo không phải root cho các việc quản trị. Server cũng phải có firewall để lọc các kết nối đến. Bạn có thể tìm hiểu cách cấu hình các mục này theo hướng dẫn cài đặt server ban đầu Ubuntu 16.04 .

Bạn sẽ phải hoàn thành một số bước bổ sung để đáp ứng các yêu cầu khác cho cài đặt của ta . Vì Drone chủ yếu được phân phối dưới dạng Docker image , ta sẽ sử dụng Docker Compose để quản lý các containers server CI. Vì mục đích bảo mật và hiệu suất, ta sẽ gửi yêu cầu ủy quyền tới Drone thông qua một version Nginx được bảo vệ bởi Let's Encrypt. Bạn cần một domain gắn với server CI của bạn để cài đặt đúng cách.

Trước khi bạn bắt đầu, hãy sử dụng các bài viết sau để cài đặt các yêu cầu bổ sung sau:

Khi bạn hoàn thành các hướng dẫn trên, server Drone của bạn sẽ có:

  • User sudo cấu hình cho các việc quản trị
  • Đã bật firewall UFW. Nó sẽ chặn tất cả các kết nối ngoại trừ các yêu cầu SSH, HTTP và HTTPS trên các cổng 22, 80 và 443 tương ứng.
  • Docker và Docker Compose đã được cài đặt.
  • Server Nginx được cấu hình bằng certificate SSL do Let's Encrypt cung cấp

Tiếp tục bên dưới khi đã sẵn sàng bắt đầu.

Thêm ứng dụng vào repository mã nguồn của bạn

Để theo dõi các thay đổi mã nhằm kích hoạt các giai đoạn xây dựng và thử nghiệm, Drone cần quyền truy cập vào kho mã nguồn của bạn. Drone có thể tích hợp với GitHub , GitLab , Gogs , Bitbucket CloudBitbucket Server .

Trong hướng dẫn này, ta sẽ tập trung vào việc tích hợp với repository GitHub, nhưng quá trình này phải tương tự đối với các hệ thống khác. Nếu bạn đang sử dụng một repository mã nguồn khác, hãy nhấp vào liên kết thích hợp ở trên để tìm hiểu về cấu hình phần mềm cụ thể mà bạn cần .

Bắt đầu bằng cách truy cập account GitHub của bạn. Nhấp vào biểu tượng user của bạn ở góc trên bên phải và chọn Cài đặt từ menu thả xuống:

Cài đặt Drone GitHub

Tiếp theo, tìm mục Ứng dụng OAuth trong phần Cài đặt dành cho nhà phát triển ở bên trái màn hình:

Ứng dụng Drone OAuth

Trên trang sau đó, nhấp vào Đăng ký ứng dụng mới :

Drone ứng dụng mới

Tiếp theo, bạn sẽ thấy biểu mẫu đăng ký ứng dụng OAuth:

Drone đăng ký một ứng dụng mới

Bạn cần điền vào các trường sau (các trường này có trên GitHub. Các nhà cung cấp dịch vụ lưu trữ khác có thể có các dấu nhắc khác nhau):

  • Tên ứng dụng : Tên bạn chọn để xác định tích hợp. “Drone” là một lựa chọn tốt nếu bạn không có nhu cầu đặc biệt.
  • URL trang chủ : Tên domain của server Drone của bạn. Sử dụng https:// tại đây vì ta đang sử dụng domain được bảo mật.
  • Mô tả ứng dụng : Mô tả đơn giản về Drone và mục đích của nó.
  • URL gọi lại ủy quyền : Đây phải là công cụ chỉ định giản đồ https:// , theo sau là domain của server Drone của bạn, theo sau là /authorize . Nếu domain của ta là example.com , thì file này sẽ là https:// example.com /authorize .

Khi đã sẵn sàng , hãy nhấp vào Đăng ký ứng dụng .

Trên trang sau, bạn sẽ thấy thông tin chi tiết về ứng dụng mới của bạn . Hai mục ta cần là ID khách hàngBí mật khách hàng :

Thông tin khách hàng Drone

Sao chép hai giá trị này để sử dụng sau. Ta cần những thứ này để kết nối Drone với account GitHub của ta .

Kéo hình ảnh Drone Docker và chuẩn bị cấu hình

Đến đây bạn đã đăng ký server Drone của bạn với nhà cung cấp repository , bạn có thể cài đặt và cấu hình Drone trên server của bạn .

Drone được phân phối dưới dạng containers Docker, vì vậy nó sẽ được tự động download nếu ta sử dụng nó trong file Docker Compose. Tuy nhiên, để tăng tốc quá trình một chút, ta có thể kéo hình ảnh xuống trước:

  • docker pull drone/drone:0.7

Hình ảnh Drone Docker là một containers thống nhất có thể chạy theo một số cách khác nhau. Ta sẽ chạy một containers hoạt động như server Drone, điều phối quyền truy cập repository , lưu trữ giao diện user web và cung cấp API. Sử dụng cùng một hình ảnh với các cài đặt khác nhau, ta sẽ chạy một containers khác với quyền là tác nhân Drone, chịu trách nhiệm xây dựng và thử nghiệm phần mềm từ các kho được cấu hình .

Ta sẽ chạy cả hai containers này trên server Drone bằng Docker Compose. Bắt đầu bằng cách tạo một folder cấu hình để lưu trữ các file ta cần:

  • sudo mkdir /etc/drone

Tiếp theo, ta sẽ tạo một vài file bên trong để cấu hình các dịch vụ của ta .

Tạo file docker composer cho Drone

Đầu tiên, tạo file Docker Compose trong folder cấu hình:

  • sudo nano /etc/drone/docker-compose.yml

Bên trong, ta sẽ đánh dấu định dạng file Docker Compose là version “3”. Sau đó, ta sẽ xác định các dịch vụ cho cả hai dịch vụ mà ta đã mô tả ở trên.

Dịch vụ drone-server sẽ bắt đầu lắng nghe containers server Drone chính trên cổng 8000. Ta sẽ gắn folder /var/lib/drone bên trong containers để Drone có thể duy trì dữ liệu của nó. Ta sẽ cấu hình dịch vụ để khởi động lại tự động và đọc hướng dẫn cấu hình chi tiết hơn dưới dạng các biến môi trường được xác định trong file mà ta sẽ tạo tại /etc/drone/server.env .

Dịch vụ drone-agent sử dụng cùng một hình ảnh, bắt đầu bằng lệnh agent . Nó nhận được hướng dẫn từ version server Drone chính, vì vậy mặc dù nó không cần quyền truy cập mạng chung nhưng nó cần được khởi động sau dịch vụ Drone. Nó cũng cần quyền truy cập vào file socket của Docker để quay các containers nhằm chạy các bước xây dựng và thử nghiệm thực tế. Giống như dịch vụ drone-server , dịch vụ này cũng sẽ tự động khởi động lại và đọc file môi trường tại /etc/drone/agent.env để có cấu hình bổ sung.

Sử dụng file Docker Compose sau đây để cấu hình hai dịch vụ này. Hãy chú ý đến định dạng YAML của file , vì lỗi trong thụt lề hoặc định dạng có thể gây ra lỗi:

/etc/drone/docker-compose.yml
version: '3'  services:   drone-server:     image: drone/drone:0.7     ports:       - 127.0.0.1:8000:8000     volumes:       - /var/lib/drone:/var/lib/drone     restart: always     env_file:       - /etc/drone/server.env    drone-agent:     image: drone/drone:0.7     command: agent     depends_on:       - drone-server     volumes:       - /var/run/docker.sock:/var/run/docker.sock     restart: always     env_file:       - /etc/drone/agent.env 

Khi bạn hoàn tất, hãy lưu file Docker Compose.

Cấu hình file biến môi trường của server Drone

Tiếp theo, ta cần tạo file biến môi trường của server Drone mà ta đã tham chiếu trong file Docker Compose ở trên.

Trước khi mở file , ta nên tạo một khóa mạnh để xác thực các thành phần tác nhân và server . Mặc dù cài đặt của ta sẽ có cả hai thành phần này trên cùng một server , khi cơ sở hạ tầng thử nghiệm của bạn mở rộng, một khóa mạnh là điều cần thiết. Trên dòng lệnh, tạo khóa bằng lệnh :

  • LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 | head -c 65 && echo

Lệnh này tạm thời đặt ngôn ngữ trong shell thành một phạm vi ký tự hạn chế. Sau đó, nó lấy một stream byte ngẫu nhiên từ /dev/urandom và lọc thêm bất kỳ ký tự không phải chữ và số nào. Ta lấy 65 ký tự đầu tiên làm key của ta .

Đầu ra sẽ giống như sau ( Không sao chép giá trị bên dưới! Hãy tạo giá trị của bạn ! ):

Output
ERmA7xubDvTa8i0wYBlljc9yjT1NJPG7xOlZBwAdMAmBYL4RZE4QngxWcCLowk9KN

Sao chép khóa đã tạo để sử dụng trong file môi trường server .

Tạo một file mới tại /etc/drone/server.env và mở nó trong editor của bạn:

  • sudo nano /etc/drone/server.env

Bên trong, ta sẽ xác định các biến môi trường mà Drone sử dụng để kết nối để liên kết bắt đầu dịch vụ, kết nối với nhà cung cấp repository và đặt policy cấp quyền account . Bạn cần các giá trị mà bạn đã sao chép từ nhà cung cấp repository của bạn trước đó để điền các giá trị một cách chính xác.

Để bắt đầu, cài đặt các DRONE_HOSTDRONE_SECRET giá trị. Đặt DRONE_SECRET thành khóa bạn đã tạo trên dòng lệnh. Cài đặt DRONE_HOST thông báo cho Drone về địa chỉ có thể truy cập của nó. Đây phải là domain được bảo vệ Let's Encrypt của bạn, đứng trước trình chỉ định schemas https:// :

/etc/drone/server.env
# Service settings DRONE_SECRET=secret_generated_on_command_line DRONE_HOST=https://example.com 

Tiếp theo, ta sẽ cấu hình tích hợp với nhà cung cấp VCS của ta , trong trường hợp của ta là GitHub. Các cài đặt thích hợp cho dự án của bạn có thể khác nhau tùy thuộc vào nhu cầu của bạn và cách tổ chức nội dung GitHub của bạn.

Ta sẽ khóa cài đặt Drone của bạn và vô hiệu hóa đăng ký đang mở bằng cách đặt DRONE_OPEN thành false . Điều này nghĩa là chỉ những tên account GitHub được chỉ định trong DRONE_ADMIN mới có thể đăng nhập.

Lưu ý : Nếu bạn làm việc với cộng tác viên với quyền là một tổ chức GitHub, tốt hơn nên đặt DRONE_OPEN thành true và thay DRONE_ADMIN bằng DRONE_ORGS . Cài đặt DRONE_ORGS cho phép bạn chỉ định một hoặc nhiều tổ chức GitHub có các thành viên được phép đăng ký. Drone sẽ giới hạn đăng ký cho những user thuộc các group đó.

Đảm bảo rằng DRONE_ADMIN chứa tên account GitHub của bạn.

Sau đó, kích hoạt plugin tích hợp GitHub bằng cách đặt DRONE_GITHUB thành true . Sau đó, ta sẽ đặt DRONE_GITHUB_CLIENTDRONE_GITHUB_SECRET thành các khóa mà ta đã sao chép từ trang ứng dụng GitHub OAuth khi ta đăng ký ứng dụng Drone:

/etc/drone/server.env
# Service settings DRONE_SECRET=secret_generated_on_command_line DRONE_HOST=https://example.com  # Registration settings DRONE_OPEN=false DRONE_ADMIN=sammytheshark  # GitHub Settings DRONE_GITHUB=true DRONE_GITHUB_CLIENT=Client_ID_from_GitHub DRONE_GITHUB_SECRET=Client_Secret_from_GitHub 

Ta đã hoàn tất cấu hình thành phần server . Trước khi rời đi, hãy sao chép giá trị DRONE_SECRET từ file . Ta cần đặt cùng một khóa này trong phần tiếp theo khi ta cấu hình tác nhân. Lưu file khi bạn hoàn tất.

Cấu hình file biến môi trường của tác nhân bay không người lái

Tiếp theo, ta sẽ tạo một file môi trường cho thành phần tác nhân Drone.

Mở một file mới để đặt các biến môi trường tác nhân:

  • sudo nano /etc/drone/agent.env

Bên trong, ta chỉ cần xác định hai giá trị. DRONE_SECRET sẽ trùng với cấu hình trong file sever.env .

Cài đặt DRONE_SERVER sẽ cấu hình cách tác nhân sẽ kết nối với thành phần server Drone. Nó sẽ bắt đầu với một tiền tố giao thức wss:// để cho biết rằng kết nối sẽ sử dụng một socket web được mã hóa theo sau là domain của server Drone với URI /ws/broker nối vào cuối:

/etc/drone/agent.env
DRONE_SECRET=secret_generated_on_command_line DRONE_SERVER=wss://example.com/ws/broker 

Lưu file khi bạn hoàn tất.

Cấu hình file đơn vị Drone Systemd

Bây giờ các file cấu hình của ta đã có sẵn, ta có thể xác định file đơn vị systemd để quản lý dịch vụ Drone.

Mở file .service mới trong folder /etc/systemd/system để cấu hình dịch vụ:

  • sudo nano /etc/systemd/system/drone.service

Bên trong dán các nội dung sau:

/etc/systemd/system/drone.service
[Unit] Description=Drone server After=docker.service nginx.service  [Service] Restart=always ExecStart=/usr/local/bin/docker-compose -f /etc/drone/docker-compose.yml up ExecStop=/usr/local/bin/docker-compose -f /etc/drone/docker-compose.yml stop  [Install] WantedBy=multi-user.target 

Phần đầu tiên yêu cầu systemd khởi động dịch vụ này sau khi có Docker và Nginx. Phần thứ hai yêu cầu hệ thống init tự động khởi động lại dịch vụ trong trường hợp bị lỗi. Sau đó, nó xác định các lệnh để bắt đầu và dừng dịch vụ Drone bằng Docker Compose và file cấu hình mà ta đã tạo trước đó. Cuối cùng, phần cuối cùng xác định cách kích hoạt dịch vụ khởi động khi server khởi động .

Lưu file khi bạn hoàn tất.

Trước khi bắt đầu dịch vụ Drone, ta phải cấu hình Nginx. Tác nhân Drone cần có khả năng kết nối với server Drone và kết nối dựa vào proxy Nginx đang có.

Cấu hình Nginx Để Yêu cầu Proxy để Drone

Tiếp theo, ta cần sửa đổi cấu hình của Nginx thành các yêu cầu proxy tới server Drone của ta .

Bắt đầu bằng cách tìm cấu hình khối server xử lý domain được bảo vệ bằng Let's Encrypt của bạn. Tìm kiếm thuộc tính server_name trong tất cả các khối server đã bật bằng lệnh :

  • grep -R server_name /etc/nginx/sites-enabled
Output
/etc/nginx/sites-enabled/default: server_name example.com; /etc/nginx/sites-enabled/default: return 301 https://$server_name$request_uri; /etc/nginx/sites-enabled/default: server_name example.com; /etc/nginx/sites-enabled/default:# server_name example.com;

Trong kết quả ở trên, domain ( example.com trong trường hợp này) đang được xác định trong file /etc/nginx/sites-enabled/default . Bạn cần chỉnh sửa file (cột đầu tiên) được liên kết với domain của bạn.

Có thể bạn cũng có thể thấy thông tin như thế này:

Output
/etc/nginx/sites-enabled/default: server_name _; /etc/nginx/sites-enabled/default: return 301 https://$server_name$request_uri; /etc/nginx/sites-enabled/default: server_name _; /etc/nginx/sites-enabled/default:# server_name example.com;

Trong kết quả ở trên, server_name _; dòng đại diện cho các khối server nghĩa là hoạt động như cơ chế dự phòng. Mã định danh server “_” là server không hợp lệ, vì vậy nó sẽ không bao giờ tự khớp.

Trong cấu hình, chúng được ghép nối với các chỉ thị listen đặt tùy chọn default_server để khối hoạt động như một mặc định khi server được yêu cầu không trùng với bất kỳ khối server đã xác định nào khác. Nếu bạn không thể tìm thấy định nghĩa server_name phù hợp với domain của bạn , bạn nên sử dụng file xác định các khối dự phòng này để thay thế.

Mở file được liên kết tốt nhất với domain của bạn trong editor của bạn:

  • sudo nano /etc/nginx/sites-enabled/default

Bên trong, ta sẽ bắt đầu bằng cách thêm hai phần bên ngoài các khối server hiện có:

/ etc / nginx / sites-enable / default
upstream drone {     server 127.0.0.1:8000; }  map $http_upgrade $connection_upgrade {     default upgrade;     ''      close; }  server {     . . . 

Khối đầu tiên cấu hình một vị trí ngược dòng được gọi là drone nơi ta có thể yêu cầu proxy. Chỉ thị server xác định cách kết nối với dịch vụ Drone của ta , dịch vụ này sẽ chạy trên cổng 8000.

Các bộ khối thứ hai một biến user định nghĩa gọi là $connection_upgrade dựa trên giá trị của $http_upgrade biến, mà bộ Nginx khi một “Nâng cấp” tiêu đề HTTP được nhận. Nếu nhận được tiêu đề Nâng cấp, Nginx sẽ đặt biến $connection_upgrade connect_upgrade để upgrade . Nếu không, nó sẽ đặt nó để close . Các biến này cho phép ta cài đặt các tiêu đề chính xác khi ủy quyền các yêu cầu WebSocket.

Tiếp theo, tìm khối server có chỉ thị listen 443 bên trong. Thay thế nội dung của location / khối bằng các lệnh sau. Đảm bảo comment hoặc xóa bất kỳ cấu hình hiện có nào khỏi khối đó để tránh xung đột:

/ etc / nginx / sites-enable / default
. . . server {     listen 443 ssl;     . . .     location / {         # try_files $uri $uri/ =404;         proxy_pass http://drone;          include proxy_params;         proxy_set_header Upgrade $http_upgrade;         proxy_set_header Connection $connection_upgrade;          proxy_redirect off;         proxy_http_version 1.1;         proxy_buffering off;         chunked_transfer_encoding off;         proxy_read_timeout 86400;     }     . . . }  

Dòng proxy_pass yêu cầu Nginx chuyển tất cả truy cập được phân phối ra khỏi khối này đến phần upstream mà ta đã xác định trước đó. Tiếp theo, ta bao gồm một số định nghĩa tiêu đề proxy từ file proxy_params và thêm các tiêu đề bổ sung dựa trên cài đặt map của ta trước đó.

Sau đó, ta điều chỉnh một số cài đặt proxy cụ thể khác đảm bảo proxy WebSocket hoạt động chính xác và đảm bảo các thành phần của ta có thể giao tiếp hiệu quả.

Khi bạn hoàn tất, hãy lưu file .

Kiểm tra và khởi động lại Nginx và Drone

Cấu hình của ta hiện đã hoàn tất. Ta chỉ cần khởi động hoặc khởi động lại các dịch vụ của bạn để triển khai cấu hình.

Để bắt đầu, hãy kiểm tra cấu hình Nginx để biết lỗi cú pháp:

  • sudo nginx -t
Output
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

Nếu kết quả cho biết đã có sự cố cấu hình, hãy quay lại và kiểm tra lại cấu hình Nginx.

Khi đã sẵn sàng tiếp tục, hãy khởi động lại Nginx:

  • sudo systemctl restart nginx

Như vậy, Nginx có sẵn cho các yêu cầu proxy giữa tác nhân và server , ta có thể khởi động Drone:

  • sudo systemctl start drone

Kiểm tra đảm bảo dịch vụ có thể khởi động thành công:

  • sudo systemctl status drone
Output
● drone.service - Drone server Loaded: loaded (/etc/systemd/system/drone.service; disabled; vendor preset: enabled) Active: active (running) since Fri 2017-06-09 21:56:33 UTC; 2min 58s ago Main PID: 15225 (docker-compose) Tasks: 5 Memory: 37.7M CPU: 1.544s CGroup: /system.slice/drone.service ├─15225 /usr/local/bin/docker-compose -f /etc/drone/docker-compose.yml up └─15228 /usr/local/bin/docker-compose -f /etc/drone/docker-compose.yml up . . . Jun 09 21:56:35 drone docker-compose[15225]: drone-agent_1 | pipeline: request next execution

Nếu dịch vụ được đánh dấu là active (running) và không có lỗi nào trong log , thì Drone đang hoạt động.

Nếu bạn gặp sự cố, bạn có thể kiểm tra log Nginx bằng lệnh :

  • sudo less /var/log/nginx/error.log

Bạn có thể kiểm tra log Drone bằng lệnh :

  • sudo journalctl -u drone

Nếu mọi thứ đang chạy chính xác, hãy cho phép Drone khởi động khi server khởi động bằng lệnh :

  • sudo systemctl enable drone

Dịch vụ Drone sẽ khởi động sau khi dịch vụ Docker và Nginx khả dụng.

Đăng nhập vào Drone để cấp quyền truy cập vào repository của bạn

Bây giờ Drone đã được cài đặt và chạy, ta có thể đăng nhập vào giao diện web và cho phép ứng dụng sử dụng account GitHub của ta .

Truy cập domain của server trong trình duyệt web để xem giao diện web Drone:

https://example.com 

Trong lần đầu tiên truy cập, bạn sẽ được yêu cầu đăng nhập:

Chuyến thăm đầu tiên của Drone

Nhấp vào đăng nhập để xác thực Drone bằng account GitHub của bạn bằng OAuth. Nếu bạn hiện chưa đăng nhập vào GitHub, trước tiên bạn sẽ được hướng dẫn đăng nhập vào GitHub.

Sau đó, bạn sẽ được yêu cầu cho phép Drone truy cập vào account GitHub của bạn:

Drone cho phép truy cập thông qua GitHub

Sau khi xem xét các quyền được yêu cầu và thực hiện bất kỳ điều chỉnh nào, hãy nhấp vào nút Ủy quyền tên user để ủy quyền cho Drone.

Bạn sẽ được chuyển hướng trở lại server Drone của bạn :

Drone đã đăng nhập

Từ đây, bạn có thể kích hoạt và cấu hình repository của bạn để tự động kiểm tra mã của bạn.

Kết luận

Trong hướng dẫn này, ta cài đặt Drone làm server phân phối và tích hợp liên tục cho các dự án GitHub của ta . Ta đã cấu hình server Drone làm trung tâm trung tâm để ủy quyền công việc, xử lý xác thực và lắng nghe các thay đổi từ kho của ta . Ta cũng đã cấu hình một tác nhân Drone có thể chạy thử nghiệm và quản lý containers . Trước tất cả những điều này, ta đã cấu hình Nginx để hoạt động như một Reverse Proxy an toàn.

Khi đã sẵn sàng cài đặt Drone để tự động chạy thử nghiệm đối với repository của bạn , hãy xem tài liệu Drone để tìm hiểu cách xác định file .drone.yml với các quy trình thử nghiệm của bạn.


Tags:

Các tin liên quan

Cách giám sát cảnh báo Zabbix với Alerta trên Ubuntu 16.04
2017-06-13
Cách cài đặt và cấu hình Zabbix để giám sát an toàn server từ xa trên Ubuntu 16.04
2017-06-08
how-to-config-an-orientdb-cluster-on-ubuntu-16-04
2017-06-02
Cách cài đặt và cấu hình OpenLDAP và phpLDAPadmin trên Ubuntu 16.04
2017-06-01
Cách bật SFTP mà không cần truy cập Shell trên Ubuntu 16.04
2017-05-31
Cách tạo Go Executables cho nhiều nền tảng trên Ubuntu 16.04
2017-05-30
Cách cài đặt Concourse CI trên Ubuntu 16.04
2017-05-26
Cách giám sát server và dịch vụ bằng Icinga trên Ubuntu 16.04
2017-05-05
Cách thiết lập đồng bộ hóa thời gian trên Ubuntu 16.04
2017-04-28
Cách quản lý log với Graylog 2 trên Ubuntu 16.04
2017-04-25