19/09/2018, 09:49

Làm thế nào để triển khai một ứng dụng PHP nâng cao bằng cách sử dụng Ansible trên Ubuntu 14.04

Giới thiệu Hướng dẫn này là bài viết thứ hai trong loạt bài về triển khai các ứng dụng PHP sử dụng Ansible trên Ubuntu 14.04. Các hướng dẫn đầu tiên bao gồm các bước cơ bản để triển khai một ứng dụng và là điểm bắt đầu cho các bước được nêu trong hướng dẫn này. Trong hướng dẫn này, chúng tôi sẽ ...

Giới thiệu

Hướng dẫn này là bài viết thứ hai trong loạt bài về triển khai các ứng dụng PHP sử dụng Ansible trên Ubuntu 14.04. Các hướng dẫn đầu tiên bao gồm các bước cơ bản để triển khai một ứng dụng và là điểm bắt đầu cho các bước được nêu trong hướng dẫn này.

Trong hướng dẫn này, chúng tôi sẽ giới thiệu các khóa SSH để hỗ trợ các công cụ triển khai / xuất bản mã, cấu hình tường lửa hệ thống, cung cấp và cấu hình cơ sở dữ liệu (bao gồm cả mật khẩu!), Và thiết lập các trình lên lịch nhiệm vụ (crons) và các trình tiện ích xếp hàng. Mục tiêu ở cuối hướng dẫn này là để bạn có một máy chủ ứng dụng PHP hoạt động đầy đủ với cấu hình nâng cao nói trên.

Giống như hướng dẫn cuối cùng, chúng tôi sẽ sử dụng Khuôn khổ Laravel như ứng dụng PHP ví dụ của chúng tôi. Tuy nhiên, các hướng dẫn này có thể dễ dàng sửa đổi để hỗ trợ các khung công tác và ứng dụng khác nếu bạn đã có các hướng dẫn của riêng mình.

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

Hướng dẫn này sau đây trực tiếp từ cuối hướng dẫn đầu tiên trong loạt bàivà tất cả cấu hình và tệp được tạo cho hướng dẫn đó là bắt buộc. Nếu bạn chưa hoàn thành hướng dẫn đó, trước tiên hãy làm như vậy trước khi tiếp tục với hướng dẫn này.

Bước 1 - Chuyển kho lưu trữ ứng dụng

Trong bước này, chúng tôi sẽ cập nhật kho lưu trữ Git thành một kho lưu trữ ví dụ được tùy chỉnh một chút.

Vì cài đặt Laravel mặc định không yêu cầu các tính năng nâng cao mà chúng ta sẽ thiết lập trong hướng dẫn này, chúng ta sẽ chuyển kho lưu trữ hiện có từ kho lưu trữ tiêu chuẩn sang kho lưu trữ ví dụ với một số mã được thêm vào, chỉ để hiển thị khi mọi thứ đang hoạt động . Kho lưu trữ chúng tôi sẽ sử dụng được đặt tại https://github.com/do-community/do-ansible-adv-php.

Nếu bạn chưa làm như vậy, hãy thay đổi thư mục thành ansible-php từ hướng dẫn trước.

cd ~/ansible-php/

Mở sách playbook hiện tại của chúng tôi để chỉnh sửa.

nano php.yml

Tìm và cập nhật tác vụ "Clone git repository", vì vậy nó trông như thế này.

Updated Ansible task

- name: Clone git repository
  git: >
    dest=/var/www/laravel
    repo=https://github.com/do-community/do-ansible-adv-php
    update=yes
    version=example
  sudo: yes
  sudo_user: www-data
  register: cloned

Lưu và chạy playbook.

ansible-playbook php.yml --ask-sudo-pass

Khi nó đã chạy xong, hãy truy cập vào máy chủ của bạn trong trình duyệt web của bạn (ví dụ: http://your_server_ip/). Bạn sẽ thấy một thông báo cho biết "không thể tìm thấy trình điều khiển".

Điều này có nghĩa là chúng ta đã trao đổi thành công kho lưu trữ mặc định cho kho lưu trữ ví dụ của chúng ta, nhưng ứng dụng không thể kết nối với cơ sở dữ liệu. Đây là những gì chúng tôi mong đợi để xem ở đây, và chúng tôi sẽ cài đặt và thiết lập cơ sở dữ liệu sau trong hướng dẫn.

Bước 2 - Thiết lập Khóa SSH cho Triển khai

Trong bước này, chúng ta sẽ thiết lập các khóa SSH có thể được sử dụng cho các kịch bản triển khai mã ứng dụng.

Trong khi Ansible là tuyệt vời cho việc duy trì cấu hình và thiết lập máy chủ và ứng dụng, các công cụ như Envoy và Rocketeer thường được sử dụng để đẩy các thay đổi mã vào máy chủ của bạn và chạy các lệnh ứng dụng từ xa. Hầu hết các công cụ này yêu cầu kết nối SSH có thể truy cập trực tiếp vào cài đặt ứng dụng. Trong trường hợp của chúng tôi, điều này có nghĩa là chúng tôi cần phải định cấu hình các khóa SSH cho www-data người dùng.

Chúng tôi sẽ cần tệp khóa công khai cho người dùng bạn muốn đẩy mã của mình. Tệp này thường được tìm thấy tại ~/.ssh/id_rsa.pub. Sao chép tệp đó vào ansible-php danh mục.

cp ~/.ssh/id_rsa.pub ~/ansible-php/deploykey.pub

Chúng ta có thể sử dụng Ansible authorized_key để cài đặt khóa công khai của chúng tôi trong /var/www/.ssh/authorized_keys, cho phép các công cụ triển khai kết nối và truy cập vào ứng dụng của chúng tôi. Cấu hình chỉ cần biết khóa ở đâu, sử dụng tra cứu và người dùng cần phải cài đặt khóa cho (www-data trong trường hợp của chúng ta).

New Ansible task

- name: Copy public key into /var/www
  authorized_key: user=www-data key="{{ lookup('file', 'deploykey.pub') }}"

Chúng ta cũng cần thiết lập www-data shell của người dùng, vì vậy chúng tôi có thể thực sự đăng nhập. Nếu không, SSH sẽ cho phép kết nối, nhưng sẽ không có trình bao nào được hiển thị cho người dùng. Điều này có thể được thực hiện bằng cách sử dụng user mô-đun và đặt trình bao thành /bin/bash (hoặc vỏ ưa thích của bạn).

New Ansible task

- name: Set www-data user shell
  user: name=www-data shell=/bin/bash

Bây giờ, hãy mở cuốn sách để chỉnh sửa để thêm vào các tác vụ mới.

nano php.yml

Thêm các tác vụ trên vào php.yml playbook; phần cuối của tệp phải khớp với phần sau. Các bổ sung được đánh dấu màu đỏ.

Updated php.yml

. . .

  - name: Configure nginx
    template: src=nginx.conf dest=/etc/nginx/sites-available/default
    notify:
      - restart php5-fpm
      - restart nginx

  - name: Copy public key into /var/www
    authorized_key: user=www-data key="{{ lookup('file', 'deploykey.pub') }}"

  - name: Set www-data user shell
    user: name=www-data shell=/bin/bash

  handlers:

. . .

Lưu và chạy playbook.

ansible-playbook php.yml --ask-sudo-pass

Khi Ansible kết thúc, bạn sẽ có thể SSH bằng cách sử dụng www-data người dùng.

ssh www-data@your_server_ip

Nếu bạn đăng nhập thành công, nó hoạt động! Bây giờ bạn có thể đăng xuất trở lại bằng cách nhập logout hoặc nhấn CTRL + D.

Chúng tôi sẽ không cần sử dụng kết nối đó cho bất kỳ bước nào khác trong hướng dẫn này, nhưng sẽ hữu ích nếu bạn đang thiết lập các công cụ khác, như đã đề cập ở trên, hoặc để gỡ lỗi chung và bảo trì ứng dụng theo yêu cầu.

Bước 3 - Cấu hình tường lửa

Trong bước này, chúng ta sẽ cấu hình tường lửa trên máy chủ để chỉ cho phép các kết nối cho HTTP và SSH.

Ubuntu 14.04 đi kèm với UFW (Tường lửa không biến chứng) được cài đặt theo mặc định và Ansible hỗ trợ nó với ufw mô-đun. Nó có một số tính năng mạnh mẽ và được thiết kế đơn giản nhất có thể. Nó hoàn toàn phù hợp cho các máy chủ web độc lập chỉ cần một vài cổng mở. Trong trường hợp của chúng tôi, chúng tôi muốn cổng 80 (HTTP) và cổng 22 (SSH) mở. Bạn cũng có thể muốn cổng 443 cho HTTPS.

Các ufw module có một số tùy chọn khác nhau thực hiện các tác vụ khác nhau. Các tác vụ khác nhau mà chúng tôi cần thực hiện là:

  1. Bật UFW và từ chối tất cả lưu lượng truy cập đến theo mặc định.

  2. Mở cổng SSH nhưng tốc độ giới hạn nó để ngăn chặn các cuộc tấn công bạo lực.

  3. Mở cổng HTTP.

Điều này có thể được thực hiện với các tác vụ sau, tương ứng.

New Ansible tasks

- name: Enable UFW
  ufw: direction=incoming policy=deny state=enabled

- name: UFW limit SSH
  ufw: rule=limit port=ssh

- name: UFW open HTTP
  ufw: rule=allow port=http

Như trước đây, hãy mở php.yml tệp để chỉnh sửa.

nano php.yml

Thêm các nhiệm vụ trên vào sổ tay chơi; phần cuối của tệp phải khớp với phần sau.

Updated php.yml

. . .

  - name: Copy public key into /var/www
    authorized_key: user=www-data key="{{ lookup('file', 'deploykey.pub') }}"

  - name: Set www-data user shell
    user: name=www-data shell=/bin/bash

  - name: Enable UFW
    ufw: direction=incoming policy=deny state=enabled

  - name: UFW limit SSH
    ufw: rule=limit port=ssh

  - name: UFW open HTTP
    ufw: rule=allow port=http

  handlers:

. . .

Lưu và chạy playbook.

ansible-playbook php.yml --ask-sudo-pass

Khi đã hoàn tất thành công, bạn vẫn có thể kết nối qua SSH (sử dụng Ansible) hoặc HTTP tới máy chủ của bạn; các cổng khác sẽ bị chặn.

Bạn có thể xác minh trạng thái của UFW bất cứ lúc nào bằng cách chạy lệnh này:

ansible php --sudo --ask-sudo-pass -m shell -a "ufw status verbose"

Phá vỡ lệnh Ansible ở trên:

  • ansible: Chạy một tác vụ Ansible thô, không có sách hướng dẫn.
  • php: Chạy tác vụ đối với các máy chủ trong nhóm này.
  • --sudo: Chạy lệnh dưới dạng sudo.
  • --ask-sudo-pass: Nhắc cho sudo mật khẩu.
  • -m shell: Chạy shell mô-đun.
  • -a "ufw status verbose": Các tùy chọn được chuyển vào mô-đun. Bởi vì nó là một shell lệnh, chúng ta truyền lệnh thô (tức là ufw status verbose) thẳng vào mà không cần bất kỳ key=value tùy chọn.

Nó sẽ trả lại một cái gì đó như thế này.

UFW status output

your_server_ip | success | rc=0 >>
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22                         LIMIT IN    Anywhere
80                         ALLOW IN    Anywhere
22 (v6)                    LIMIT IN    Anywhere (v6)
80 (v6)                    ALLOW IN    Anywhere (v6)

Bước 4 - Cài đặt các gói MySQL

Trong bước này, chúng tôi sẽ thiết lập một cơ sở dữ liệu MySQL cho ứng dụng của chúng tôi để sử dụng.

Bước đầu tiên là đảm bảo rằng MySQL được cài đặt trên máy chủ của chúng tôi bằng cách đơn giản thêm các gói cần thiết vào nhiệm vụ cài đặt gói ở đầu sách của chúng tôi. Các gói chúng tôi cần là mysql-server, mysql-clientvà php5-mysql. Chúng tôi cũng sẽ cần python-mysqldb vì vậy Ansible có thể giao tiếp với MySQL.

Vì chúng tôi đang thêm gói, chúng tôi cần phải khởi động lại nginx và php5-fpm để đảm bảo các gói mới có thể sử dụng được bởi ứng dụng. Trong trường hợp này, chúng ta cần MySQL để có sẵn cho PHP, vì vậy nó có thể kết nối với cơ sở dữ liệu.

Một trong những điều tuyệt vời về Ansible là bạn có thể sửa đổi bất kỳ nhiệm vụ nào và chạy lại playbook của bạn và những thay đổi sẽ được áp dụng. Điều này bao gồm danh sách các tùy chọn, như chúng tôi có với apt bài tập.

Như trước đây, hãy mở php.yml tệp để chỉnh sửa.

nano php.yml

Tìm install packages nhiệm vụ và cập nhật nó để bao gồm các gói ở trên:

Updated php.yml

. . .

- name: install packages
  apt: name={{ item }} update_cache=yes state=latest
  with_items:
    - git
    - mcrypt
    - nginx
    - php5-cli
    - php5-curl
    - php5-fpm
    - php5-intl
    - php5-json
    - php5-mcrypt
    - php5-sqlite
    - sqlite3
    - mysql-server
    - mysql-client
    - php5-mysql
    - python-mysqldb
  notify:
    - restart php5-fpm
    - restart nginx

. . .

Lưu và chạy playbook:

ansible-playbook php.yml --ask-sudo-pass

Bước 5 - Thiết lập cơ sở dữ liệu MySQL

Trong bước này, chúng ta sẽ tạo một cơ sở dữ liệu MySQL cho ứng dụng của chúng ta.

Ansible có thể nói chuyện trực tiếp với MySQL bằng cách sử dụng mysql_-những mô-đun được thay thế (ví dụ mysql_db, mysql_user). Các mysql_db module cung cấp một cách để đảm bảo một cơ sở dữ liệu với một tên cụ thể tồn tại, vì vậy chúng ta có thể sử dụng một nhiệm vụ như thế này để tạo ra cơ sở dữ liệu.

New Ansible task

- name: Create MySQL DB
  mysql_db: name=laravel state=present

Chúng tôi cũng cần một tài khoản người dùng hợp lệ với mật khẩu đã biết để cho phép ứng dụng của chúng tôi kết nối với cơ sở dữ liệu. Một cách tiếp cận cho điều này là tạo mật khẩu cục bộ và lưu nó trong Playbook Ansible của chúng tôi, nhưng điều đó không an toàn và có cách tốt hơn.

Chúng tôi sẽ tạo mật khẩu bằng cách sử dụng Ansible trên chính máy chủ và sử dụng nó trực tiếp khi cần. Để tạo mật khẩu, chúng tôi sẽ sử dụng makepasswd công cụ dòng lệnh và yêu cầu mật khẩu 32 ký tự. Bởi vì makepasswd không phải là mặc định trên Ubuntu, chúng ta cũng cần thêm nó vào danh sách các gói.

Chúng ta cũng sẽ bảo Ansible nhớ đầu ra của lệnh (tức là mật khẩu), vì vậy chúng ta có thể sử dụng nó sau này trong playbook của chúng ta. Tuy nhiên, vì Ansible không biết nếu nó đã chạy shell lệnh, chúng tôi cũng sẽ tạo một tệp khi chúng tôi chạy lệnh đó. Ansible sẽ kiểm tra xem tệp có tồn tại hay không và nếu có, nó sẽ cho rằng lệnh đã được chạy và sẽ không chạy lại.

Nhiệm vụ trông như thế này:

New Ansible task

- name: Generate DB password
  shell: makepasswd --chars=32
  args:
    creates: /var/www/laravel/.dbpw
  register: dbpwd

Tiếp theo, chúng ta cần tạo người dùng cơ sở dữ liệu MySQL thực tế với mật khẩu mà chúng tôi đã chỉ định. Điều này được thực hiện bằng cách sử dụng mysql_user và chúng tôi có thể sử dụng stdout tùy chọn trên biến mà chúng tôi đã xác định trong tác vụ tạo mật khẩu để có được đầu ra thô của lệnh shell, như sau: dbpwd.stdout.

Các mysql_user lệnh chấp nhận tên người dùng và các đặc quyền được yêu cầu. Trong trường hợp của chúng tôi, chúng tôi muốn tạo một người dùng được gọi là laravel và cung cấp cho họ toàn bộ đặc quyền trên laravel bàn. Chúng ta cũng cần nói nhiệm vụ chỉ chạy khi dbpwd biến có đã thay đổi, sẽ chỉ khi tác vụ tạo mật khẩu được chạy.

Nhiệm vụ sẽ trông như thế này:

New Ansible task

- name: Create MySQL User
  mysql_user: name=laravel password={{ dbpwd.stdout }} priv=laravel.*:ALL state=present
  when: dbpwd.changed

Đặt điều này lại với nhau, mở php.yml tệp để chỉnh sửa, vì vậy chúng tôi có thể thêm vào các tác vụ trên.

nano php.yml

Thứ nhất, tìm install packages nhiệm vụ và cập nhật nó để bao gồm makepasswd gói.

Updated php.yml

. . .

- name: install packages
  apt: name={{ item }} update_cache=yes state=latest
  with_items:
    - git
    - mcrypt
    - nginx
    - php5-cli
    - php5-curl
    - php5-fpm
    - php5-intl
    - php5-json
    - php5-mcrypt
    - php5-sqlite
    - sqlite3
    - mysql-server
    - mysql-client
    - php5-mysql
    - python-mysqldb
    - makepasswd
  notify:
    - restart php5-fpm
    - restart nginx

. . .

Sau đó, thêm tạo mật khẩu, tạo cơ sở dữ liệu MySQL và các tác vụ tạo người dùng ở dưới cùng.

Updated php.yml

. . .

  - name: UFW limit SSH
    ufw: rule=limit port=ssh

  - name: UFW open HTTP
    ufw: rule=allow port=http

  - name: Create MySQL DB
    mysql_db: name=laravel state=present

  - name: Generate DB password
    shell: makepasswd --chars=32
    args:
      creates: /var/www/laravel/.dbpw
    register: dbpwd

  - name: Create MySQL User
    mysql_user: name=laravel password={{ dbpwd.stdout }} priv=laravel.*:ALL state=present
    when: dbpwd.changed

  handlers:

. . .

Không chạy playbook được! Bạn có thể nhận thấy rằng mặc dù chúng tôi đã tạo ra người dùng MySQL và cơ sở dữ liệu, chúng tôi đã không làm bất cứ điều gì với mật khẩu. Chúng tôi sẽ đề cập đến điều đó trong bước tiếp theo. Khi đang sử dụng shell các nhiệm vụ trong Ansible, điều quan trọng cần nhớ là phải hoàn thành toàn bộ quy trình làm việc với kết quả đầu ra / kết quả của tác vụ trước khi chạy nó để tránh phải đăng nhập và đặt lại trạng thái theo cách thủ công.

Bước 6 - Cấu hình ứng dụng PHP cho cơ sở dữ liệu

Trong bước này, chúng tôi sẽ lưu mật khẩu cơ sở dữ liệu MySQL vào .env tệp cho ứng dụng.

Như chúng tôi đã làm trong hướng dẫn trước, chúng tôi sẽ cập nhật .env tệp để bao gồm thông tin đăng nhập cơ sở dữ liệu mới được tạo của chúng tôi. Theo mặc định của Laravel .env tập tin chứa các dòng này:

Laravel .env file

DB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

Chúng ta có thể rời khỏi DB_HOST dòng là-is, nhưng sẽ cập nhật ba phần còn lại bằng cách sử dụng các tác vụ sau, rất giống với các tác vụ chúng tôi đã sử dụng trong hướng dẫn trước để đặt APP_ENV và APP_DEBUG.

New Ansible tasks

- name: set DB_DATABASE
  lineinfile: dest=/var/www/laravel/.env regexp='^DB_DATABASE=' line=DB_DATABASE=laravel

- name: set DB_USERNAME
  lineinfile: dest=/var/www/laravel/.env regexp='^DB_USERNAME=' line=DB_USERNAME=laravel

- name: set DB_PASSWORD
  lineinfile: dest=/var/www/laravel/.env regexp='^DB_PASSWORD=' line=DB_PASSWORD={{ dbpwd.stdout }}
  when: dbpwd.changed

Như chúng ta đã làm với tác vụ tạo người dùng MySQL, chúng tôi đã sử dụng biến mật khẩu được tạo (dbpwd.stdout) để điền tệp bằng mật khẩu và đã thêm when tùy chọn để đảm bảo nó chỉ chạy khi dbpwd đã thay đổi.

Bây giờ, bởi vì .env tệp đã tồn tại trước khi chúng tôi thêm tác vụ tạo mật khẩu của mình, chúng tôi sẽ cần lưu mật khẩu vào một tệp khác. Tác vụ tạo thế hệ có thể tìm kiếm sự tồn tại của tệp đó (mà chúng ta đã thiết lập trong tác vụ). Chúng tôi cũng sẽ sử dụng sudo và sudo_user tùy chọn để báo cho Ansible tạo tệp như www-data người dùng.

New Ansible task

- name: Save dbpw file
  lineinfile: dest=/var/www/laravel/.dbpw line="{{ dbpwd.stdout }}" create=yes state=present
  sudo: yes
  sudo_user: www-data
  when: dbpwd.changed

Mở php.yml tệp để chỉnh sửa.

nano php.yml

Thêm các nhiệm vụ trên vào sổ tay chơi; phần cuối của tệp phải khớp với phần sau.

Updated php.yml

. . .

  - name: Create MySQL User
    mysql_user: name=laravel password={{ dbpwd.stdout }} priv=laravel.*:ALL state=present
    when: dbpwd.changed

  - name: set DB_DATABASE
    lineinfile: dest=/var/www/laravel/.env regexp='^DB_DATABASE=' line=DB_DATABASE=laravel

  - name: set DB_USERNAME
    lineinfile: dest=/var/www/laravel/.env regexp='^DB_USERNAME=' line=DB_USERNAME=laravel

  - name: set DB_PASSWORD
    lineinfile: dest=/var/www/laravel/.env regexp='^DB_PASSWORD=' line=DB_PASSWORD={{ dbpwd.stdout }}
    when: dbpwd.changed

  - name: Save dbpw file
    lineinfile: dest=/var/www/laravel/.dbpw line="{{ dbpwd.stdout }}" create=yes state=present
    sudo: yes
    sudo_user: www-data
    when: dbpwd.changed

  handlers:

. . .

Một lần nữa, không chạy playbook được nêu ra! Chúng tôi còn một bước nữa để hoàn thành trước khi chúng tôi có thể chạy sách.

Bước 7 - Di chuyển cơ sở dữ liệu

Trong bước này, chúng tôi sẽ chạy các cơ sở dữ liệu di chuyển để thiết lập các bảng cơ sở dữ liệu.

Trong Laravel, điều này được thực hiện bằng cách chạy migrate lệnh (tức là php artisan migrate --force) trong thư mục Laravel. Lưu ý rằng chúng tôi đã thêm --force gắn cờ vì production môi trường đòi hỏi nó.

Tác vụ Ansible để thực hiện việc này trông giống như thế này.

New Ansible task

  - name: Run artisan migrate
    shell: php /var/www/laravel/artisan migrate --force
    sudo: yes
    sudo_user: www-data
    when: dbpwd.changed

Bây giờ là lúc cập nhật playbook của chúng tôi. Mở php.yml tệp để chỉnh sửa.

nano php.yml

Thêm các nhiệm vụ trên vào sổ tay chơi; phần cuối của tệp phải khớp với phần sau.

Updated php.yml

. . .

  - name: Save dbpw file
    lineinfile: dest=/var/www/laravel/.dbpw line="{{ dbpwd.stdout }}" create=yes   state=present
    sudo: yes
    sudo_user: www-data
    when: dbpwd.changed

  - name: Run artisan migrate
    shell: php /var/www/laravel/artisan migrate --force
    sudo: yes
    sudo_user: www-data
    when: dbpwd.changed

  handlers:

. . .

Cuối cùng, chúng ta có thể lưu và chạy playbook.

ansible-playbook php.yml --ask-sudo-pass

Khi kết thúc việc thực thi, hãy làm mới trang trong trình duyệt của bạn và bạn sẽ thấy thông báo cho biết:

your_server_ip/'>http://your_server_ip/

Queue: NO
Cron: NO

Điều này có nghĩa là cơ sở dữ liệu được thiết lập chính xác và hoạt động như mong đợi, nhưng chúng tôi vẫn chưa thiết lập các tác vụ cron hoặc daemon xếp hàng.

Bước 8 - Cấu hình cron Tasks

Trong bước này, chúng ta sẽ thiết lập bất kỳ nhiệm vụ cron nào cần được cấu hình.

Các tác vụ Cron là các lệnh chạy trên một lịch biểu đã định và có thể được sử dụng để thực hiện bất kỳ số nhiệm vụ nào cho ứng dụng của bạn, như thực hiện các tác vụ bảo trì hoặc gửi các cập nhật hoạt động email - về cơ bản mọi thứ cần được thực hiện định kỳ mà không cần sự can thiệp của người dùng thủ công. Các tác vụ Cron có thể chạy thường xuyên theo từng phút hoặc ít khi bạn yêu cầu.

Laravel đi kèm với lệnh Artisan gọi là schedule:run theo mặc định, được thiết kế để chạy mỗi phút và thực hiện các tác vụ được lập lịch đã định nghĩa trong ứng dụng. Điều này có nghĩa là chúng ta chỉ cần thêm một tác vụ cron duy nhất, nếu ứng dụng của chúng ta tận dụng lợi thế của tính năng này.

Ansible có một cron mô-đun với một số tùy chọn khác nhau dịch trực tiếp sang các tùy chọn khác nhau mà bạn có thể định cấu hình qua cron:

  • job: Lệnh để thực hiện. Bắt buộc nếu state = present.
  • minute, hour, day, monthvà weekday: Phút, giờ, ngày, tháng hoặc ngày trong tuần khi công việc sẽ chạy, tương ứng.
  • special_time (reboot, yearly, annually, monthly, weekly, daily, hourly): Biệt hiệu đặc tả thời gian đặc biệt.

Theo mặc định, nó sẽ tạo ra một nhiệm vụ chạy mỗi phút, đó là những gì chúng ta muốn. Điều này có nghĩa là nhiệm vụ chúng tôi muốn trông như thế này:

New Ansible task

- name: Laravel Scheduler
  cron: >
    job="run-one php /var/www/laravel/artisan schedule:run 1>> /dev/null 2>&1"
    state=present
    user=www-data
    name="php artisan schedule:run"

Các run-one lệnh là một trợ giúp nhỏ trong Ubuntu đảm bảo lệnh chỉ được chạy một lần. Điều này có nghĩa là nếu trước đó schedule:run lệnh vẫn chạy, nó sẽ không chạy lại. Điều này rất hữu ích để tránh tình huống trong đó một tác vụ cron bị khóa trong một vòng lặp, và theo thời gian, ngày càng nhiều trường hợp của cùng một tác vụ được bắt đầu cho đến khi máy chủ hết tài nguyên.

Như trước đây, hãy mở php.yml tệp để chỉnh sửa.

nano php.yml

Thêm nhiệm vụ trên vào playbook; phần cuối của tệp phải khớp với phần sau.

Updated php.yml

. . .

  - name: Run artisan migrate
    shell: php /var/www/laravel/artisan migrate --force
    sudo: yes
    sudo_user: www-data
    when: dbpwd.changed

  - name: Laravel Scheduler
    cron: >
      job="run-one php /var/www/laravel/artisan schedule:run 1>> /dev/null 2>&1"
      state=present
      user=www-data
      name="php artisan schedule:run"

  handlers:

. . .

Lưu và chạy playbook:

ansible-playbook php.yml --ask-sudo-pass

Bây giờ, hãy làm mới trang trong trình duyệt của bạn. Trong một phút, nó sẽ cập nhật để trông như thế này.

your_server_ip/'>http://your_server_ip/

Queue: NO
Cron: YES

Điều này có nghĩa là cron đang hoạt động chính xác. Là một phần của ứng dụng ví dụ, có một công việc định kỳ đang chạy từng phút cập nhật một mục trạng thái trong cơ sở dữ liệu để ứng dụng biết nó đang chạy.

Bước 9 - Cấu hình Daemon Queue

Giống như schedule:run Lệnh Artisan từ bước 8, Laravel cũng đi kèm với một công nhân xếp hàng có thể được bắt đầu bằng queue:work --daemon Lệnh Artisan. Trong bước này, chúng ta sẽ cấu hình công việc xếp hàng daemon cho Laravel.

Công nhân xếp hàng tương tự như các công việc cron trong đó họ chạy các tác vụ trong nền. Sự khác biệt là ứng dụng đẩy các công việc vào hàng đợi, hoặc thông qua các hành động được thực hiện bởi người dùng hoặc từ các tác vụ được lên lịch thông qua một công việc định kỳ. Nhiệm vụ xếp hàng được thực hiện bởi một nhân viên tại một thời điểm và sẽ được xử lý theo yêu cầu khi chúng được tìm thấy trong hàng đợi. Nhiệm vụ xếp hàng thường được sử dụng cho công việc cần có thời gian để thực thi, chẳng hạn như gửi email hoặc thực hiện cuộc gọi API tới các dịch vụ bên ngoài.

Không giống như schedule:run lệnh, đây không phải là lệnh cần chạy mỗi phút. Thay vào đó, nó cần phải chạy như một daemon trong nền liên tục. Cách phổ biến để thực hiện việc này là sử dụng gói của bên thứ ba như người giám sát, nhưng phương pháp đó đòi hỏi phải hiểu cách cấu hình và quản lý hệ thống đã nói. Có một cách đơn giản hơn nhiều để thực hiện nó bằng cron và run-one chỉ huy.

Chúng ta sẽ tạo một mục cron để khởi động trình nền công nhân hàng đợi và sử dụng run-one để chạy nó. Điều này có nghĩa là cron sẽ bắt đầu quá trình trong lần chạy đầu tiên và mọi lần chạy cron tiếp theo sẽ bị bỏ qua run-one trong khi nhân viên đang chạy. Ngay khi nhân viên dừng lại, run-one sẽ cho phép lệnh chạy lại và nhân viên hàng đợi sẽ bắt đầu lại. Nó là một phương pháp cực kỳ đơn giản và dễ sử dụng giúp bạn tiết kiệm từ việc cần phải học cách cấu hình và sử dụng một công cụ khác.

Với tất cả ý nghĩ đó, chúng ta sẽ tạo một tác vụ cron khác để chạy công nhân xếp hàng của chúng ta.

New Ansible task

- name: Laravel Queue Worker
  cron: >
    job="run-one php /var/www/laravel/artisan queue:work --daemon --sleep=30 --delay=60 --tries=3 1>> /dev/null 2>&1"
    state=present
    user=www-data
    name="Laravel Queue Worker"

Như trước đây, hãy mở php.yml tệp để chỉnh sửa.

nano php.yml

Thêm nhiệm vụ trên vào playbook; cuối tệp phải khớp với các phần sau:

Updated php.yml

. . .

  - name: Laravel Scheduler
    cron: >
      job="run-one php /var/www/laravel/artisan schedule:run 1>> /dev/null 2>&1"
      state=present
      user=www-data
      name="php artisan schedule:run"

  - name: Laravel Queue Worker
    cron: >
      job="run-one php /var/www/laravel/artisan queue:work --daemon --sleep=30 --delay=60 --tries=3 1>> /dev/null 2>&1"
      state=present
      user=www-data
      name="Laravel Queue Worker"

  handlers:
. . .

Lưu và chạy playbook:

ansible-playbook php.yml --ask-sudo-pass

Như trước đây, hãy làm mới trang trong trình duyệt của bạn. Sau một phút, nó sẽ cập nhật để trông như thế này:

your_server_ip/'>http://your_server_ip/

Queue: YES
Cron: YES

Điều này có nghĩa là công nhân hàng đợi đang hoạt động chính xác. Công việc cron mà chúng tôi đã bắt đầu ở bước cuối cùng đẩy một công việc lên hàng đợi. Công việc này cập nhật cơ sở dữ liệu khi nó được chạy để cho thấy rằng nó đang hoạt động.

Bây giờ chúng ta có một ứng dụng ví dụ làm việc Laravel bao gồm các công việc cron và các công nhân xếp hàng.

Phần kết luận

Hướng dẫn này trình bày một số chủ đề nâng cao hơn khi sử dụng Ansible để triển khai các ứng dụng PHP. Tất cả các tác vụ được sử dụng có thể dễ dàng sửa đổi cho phù hợp với hầu hết các ứng dụng PHP (tùy thuộc vào yêu cầu cụ thể của chúng), và nó sẽ cho bạn một điểm khởi đầu tốt để thiết lập playbook của riêng bạn cho các ứng dụng của bạn.

Chúng tôi đã không sử dụng một lệnh SSH như một phần của hướng dẫn này (ngoài việc kiểm tra www-data đăng nhập người dùng) và mọi thứ - bao gồm cả mật khẩu người dùng MySQL - đã được thiết lập tự động. Sau khi làm theo hướng dẫn này, ứng dụng của bạn đã sẵn sàng để đi và hỗ trợ các công cụ để đẩy các bản cập nhật mã.

0