如何在Ubuntu 14.04上使用Ansible部署高级PHP应用程序

介绍

在本教程中,我们将介绍如何设置SSH密钥以支持代码部署/发布工具,配置系统防火墙,配置和配置数据库(包括密码!),以及设置任务调度程序(crons)和队列守护进程。本教程结束时的目标是让您拥有一个具有上述高级配置的完全可用的PHP应用程序服务器。

与上一个教程一样,我们将使用Laravel框架作为示例PHP应用程序。但是,如果您已拥有自己的框架和应用程序,则可以轻松修改这些说明以支持其他框架和应用程序。

先决条件

在本教程中,我们将使用Ansible在Ubuntu 14.04 Droplet上安装和配置Nginx,PHP和其他服务。本教程以Ansible的基本知识为基础。

要学习本教程,您需要:

  • 我们将用于配置和部署我们的PHP应用程序的任何大小的Ubuntu 14.04 腾讯云CVM。整个教程将引用本机的your_server_ipIP地址。
  • 一个Ubuntu 14.04 CVM将用于Ansible。这是您将在本教程的整个过程中登录的CVM。
  • 为两个CVM配置的有sodo权限的非root用户。(一台已经设置好可以使用sudo命令的非root账号的Ubuntu服务器,并且已开启防火墙。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器。)
  • Ansible CVM的SSH密钥授权在PHP部署CVM上登录。

第1步 - 切换应用程序存储库

在此步骤中,我们将Git存储库更新为稍微自定义的示例存储库。

由于默认的Laravel安装不需要我们将在本教程中设置的高级功能,因此我们将现有存储库从标准存储库切换到添加了一些调试代码的示例存储库,只是为了显示何时工作正常。我们将使用的存储库位于https://github.com/do-community/do-ansible-adv-php

如果您还没有这样做,请将目录更改为ansible-php

cd ~/ansible-php/

打开我们现有的剧本进行编辑。

nano php.yml

查找并更新“Clone git repository”任务,看起来像这样。

- 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

保存并运行剧本。

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

运行完毕后,请在Web浏览器中访问您的服务器(即http://your_server_ip/)。您应该看到一条消息“无法找到驱动程序”

这意味着我们已成功换出示例存储库的默认存储库,但应用程序无法连接到数据库。这是我们期望在这里看到的,我们将在本教程的后面安装和设置数据库。

步骤2 - 设置SSH密钥以进行部署

在此步骤中,我们将设置可用于应用程序代码部署脚本的SSH密钥。

虽然Ansible非常适合维护配置和设置服务器和应用程序,但EnvoyRocketeer等工具通常用于将代码更改推送到服务器并远程运行应用程序命令。大多数这些工具都需要SSH连接才能直接访问应用程序安装。在我们的例子中,这意味着我们需要为www-data用户配置SSH密钥。

我们将需要您希望从中推送代码的用户的公钥文件。此文件通常位于~/.ssh/id_rsa.pub。将该文件复制到该ansible-php目录中。

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

我们可以使用Ansible authorized_key模块在其中安装我们的公钥/var/www/.ssh/authorized_keys,这将允许部署工具连接和访问我们的应用程序。配置只需要知道密钥的位置,使用查找,以及需要安装密钥的用户(www-data在我们的例子中)。

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

我们还需要设置www-data用户的shell,因此我们实际上可以登录。否则,SSH将允许连接,但不会向用户显示shell。这可以使用user模块完成,并将shell设置为/bin/bash(或您首选的shell)。

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

现在,打开剧本进行编辑以添加新任务。

nano php.yml

将上述任务添加到您的php.yml剧本中; 文件的末尾应与以下内容匹配。添加内容为后2段以“-”开头的文字。

. . .
​
  - 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:
​
. . .

保存并运行剧本。

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

当Ansible完成时,您应该能够使用该www-data用户来SSH 。

ssh www-data@your_server_ip

如果您成功登录,它正在运行!您现在可以通过输入logout或按CTRL + D进行注销。

我们不需要将该连接用于本教程中的任何其他步骤,但是如果您正在设置其他工具(如上所述)或者根据需要进行常规调试和应用程序维护,它将非常有用。

第3步 - 配置防火墙

在此步骤中,我们将在服务器上配置防火墙,以仅允许HTTP和SSH连接。

Ubuntu 14.04 默认安装了UFW(Uncomplicated Firewall),Ansible支持该ufw模块。它具有许多强大的功能,并且设计得尽可能简单。它非常适合只需要打开几个端口的自包含Web服务器。在我们的例子中,我们希望打开端口80(HTTP)和端口22(SSH)。您可能还需要端口443用于HTTPS。

ufw模块具有许多不同的选项,可执行不同的任务。我们需要执行的不同任务是:

  1. 默认情况下启用UFW并拒绝所有传入流量。
  2. 打开SSH端口,但速率限制它以防止暴力攻击。
  3. 打开HTTP端口。

这可以分别通过以下任务完成。

新的Ansible任务

- 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

和以前一样,打开php.yml文件进行编辑。

nano 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:
​
. . .

保存并运行剧本。

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

成功完成后,您仍然可以通过SSH(使用Ansible)或HTTP连接到您的服务器; 其他端口现在将被阻止。

您可以通过运行此命令随时验证UFW的状态:

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

分解上面的Ansible命令:

  • ansible:运行原始的Ansible任务,没有剧本。
  • php:针对此组中的主机运行任务。
  • --sudo:运行命令为sudo
  • --ask-sudo-pass:提示输入sudo密码。
  • -m shell:运行shell模块。
  • -a "ufw status verbose":要传递给模块的选项。因为它是一个shell命令,我们直接传递原始命令(即ufw status verbose)而没有任何key=value选项。

它应该返回这样的东西。

UFW状态输出

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)

第4步 - 安装MySQL包

在这一步中,我们将为我们的应用程序设置一个MySQL数据库。

(自建服务器难免会遇到这样的问题,配置SSL很麻烦,虽然对一部分人来说这也是一种乐趣,但是如果您在生产环境使用,我还是建议您直接使用云关系型数据库,云关系型数据库让您在云中轻松部署、管理和扩展的关系型数据库,提供安全可靠、伸缩灵活的按需云数据库服务。腾讯云关系型数据库提供 MySQL、SQL Server、MariaDB、PostgreSQL 数据库引擎,并针对数据库引擎的性能进行了优化。云关系型数据库是一种高度可用的托管服务,提供容灾、备份、恢复、监控、迁移等数据库运维全套解决方案,可将您从耗时的数据库管理任务中解放出来,让您有更多时间专注于您的应用和业务。)

第一步是确保在我们的服务器上安装MySQL,只需将所需的包添加到我们的playbook顶部的安装包任务即可。我们需要的包有mysql-servermysql-clientphp5-mysql。我们还需要python-mysqldbAnsible可以与MySQL通信。

在我们添加软件包时,我们需要重新启动nginxphp5-fpm确保应用程序可以使用新软件包。在这种情况下,我们需要MySQL可用于PHP,因此它可以连接到数据库。

Ansible的一个奇妙之处在于您可以修改任何任务并重新运行您的剧本,并且将应用更改。这包括选项列表,就像我们对apt任务一样。

和以前一样,打开php.yml文件进行编辑。

nano php.yml

找到install packages任务,并更新它以包含上面的包:

. . .
​
- 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
​
. . .

保存并运行剧本:

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

第5步 - 设置MySQL数据库

在这一步中,我们将为我们的应用程序创建一个MySQL数据库。

Ansible可以通过直接与MySQL mysql_-prefaced模块(例如mysql_dbmysql_user)。该mysql_db模块提供了一种确保具有特定名称的数据库的方法,因此我们可以使用这样的任务来创建数据库。

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

我们还需要一个具有已知密码的有效用户帐户,以允许我们的应用程序连接到数据库。一种方法是在本地生成密码并将其保存在我们的Ansible playbook中,但这是不安全的,并且有更好的方法。

我们将在服务器上使用Ansible生成密码,并在需要的地方直接使用。要生成密码,我们将使用makepasswd命令行工具,并要求输入32个字符的密码。因为makepasswd在Ubuntu上不是默认的,我们还需要将它添加到包列表中。

我们还会告诉Ansible记住命令的输出(即密码),以便我们稍后可以在我们的剧本中使用它。但是,因为Ansible不知道它是否已经运行了shell命令,所以我们还会在运行该命令时创建一个文件。Ansible将检查文件是否存在,如果存在,它将假定该命令已经运行并且不会再次运行它。

任务看起来像这样:

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

接下来,我们需要使用我们指定的密码创建实际的MySQL数据库用户。这是使用mysql_user模块完成的,我们可以使用stdout我们在密码生成任务中定义的变量选项来获取shell命令的原始输出,如下所示:dbpwd.stdout

mysql_user命令接受用户的名称和所需的权限。在我们的例子中,我们想要创建一个被调用的用户,laravel并为他们提供laravel表的完全权限。我们还需要告诉任务仅在dbpwd变量发生变化时才运行,这只会在密码生成任务运行时运行。

任务应如下所示:

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

把它们放在一起,打开php.yml文件进行编辑,这样我们就可以添加上述任务了。

nano php.yml

首先,找到install packages任务,并更新它以包含该makepasswd包。

. . .
​
- 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
​
. . .

然后,在底部添加密码生成,MySQL数据库创建和用户创建任务。

. . .
​
  - 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:
​
. . .

不要运行剧本了!您可能已经注意到虽然我们已经创建了MySQL用户和数据库,但我们还没有对密码做任何事情。我们将在下一步中介绍它。shell在Ansible中使用任务时,记住在运行任务之前完成处理任务输出/结果的整个工作流程以避免必须手动登录和重置状态,这一点非常重要。

第6步 - 为数据库配置PHP应用程序

在此步骤中,我们将MySQL数据库密码保存到.env应用程序的文件中。

就像我们在上一个教程中所做的那样,我们将更新.env文件以包含我们新创建的数据库凭据。默认情况下,Laravel的.env文件包含以下行:

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

我们可以按DB_HOST原样保留该行,但是将使用以下任务更新其他三行:

- 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

正如我们对MySQL用户创建任务所做的那样,我们使用生成的密码变量(dbpwd.stdout)来使用密码填充文件,并添加了when选项以确保它仅在dbpwd更改时运行。

现在,因为在我们添加密码生成任务之前.env文件已经存在,我们需要将密码保存到另一个文件。生成任务可以查找该文件的存在(我们已在任务中设置)。我们还将使用sudosudo_user选项告诉Ansible以www-data用户身份创建文件。

- 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

打开php.yml文件进行编辑。

nano 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:

. . .

再次,不要运行剧本了!在我们运行剧本之前,我们还有一个步骤要完成。

第7步 - 迁移数据库

在此步骤中,我们将运行数据库迁移以设置数据库表。

在Laravel中,这是通过在Laravel目录中运行migrate命令(即php artisan migrate --force)来完成的。请注意,我们添加了--force标志,因为production环境需要它。

执行此操作的Ansible任务如下所示。

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

现在是时候更新我们的剧本了。打开php.yml文件进行编辑。

nano 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:

. . .

最后,我们可以保存并运行剧本。

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

完成执行后,在浏览器中刷新页面,您会看到一条消息:

Queue: NO
Cron: NO

这意味着数据库已正确设置并按预期工作,但我们尚未设置cron任务或队列守护程序。

第8步 - 配置cron任务

在此步骤中,我们将设置需要配置的任何cron任务。

Cron任务是在设定的时间表上运行的命令,可用于为您的应用程序执行任意数量的任务,例如执行维护任务或发送电子邮件活动更新 - 基本上任何需要定期完成而无需手动用户干预的任务。Cron任务可以像每分钟一样频繁地运行,也可以根据需要不频繁地运行。

Laravel附带默认调用的名为schedule:run的Artisan命令,该命令旨在每分钟运行并在应用程序中执行定义的计划任务。这意味着如果我们的应用程序利用此功能,我们只需要添加一个cron任务。

Ansible有一个cron包含许多不同选项的模块,可直接转换为您可以通过cron配置的不同选项:

  • job:要执行的命令。如果state = present则需要。
  • minutehourdaymonth,和weekday:在分钟,小时,天,月,或当作业应当运行,分别是星期几。
  • special_timerebootyearlyannuallymonthlyweeklydailyhourly):特殊时间规范的绰号。

默认情况下,它将创建一个每分钟运行的任务,这正是我们想要的。这意味着我们想要的任务看起来像这样:

- 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"

run-one命令是Ubuntu中的一个小帮助程序,可确保命令仅运行一次。这意味着如果先前的schedule:run命令仍在运行,则不会再次运行。这有助于避免cron任务在循环中被锁定的情况,并且随着时间的推移,在服务器资源耗尽之前,会启动相同任务的越来越多的实例。

和以前一样,打开php.yml文件进行编辑。

nano 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:

. . .

保存并运行剧本:

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

现在,在浏览器中刷新页面。在一分钟内,它将更新为这样。

Queue: NO
Cron: YES

这意味着cron正在后台正常工作。作为示例应用程序的一部分,有一个cron作业每分钟运行一次,更新数据库中的状态条目,以便应用程序知道它正在运行。

步骤9 - 配置队列守护程序

与步骤8中的名为schedule:run的Artisan命令一样,Laravel还带有一个可以使用queue:work --daemonArtisan命令启动的队列工作程序。在此步骤中,我们将为Laravel配置队列守护程序worker。

队列工作者与cron作业类似,因为他们在后台运行任务。不同之处在于应用程序通过用户执行的操作或通过cron作业调度的任务将作业推送到队列中。队列任务由工作者一次执行一次,并且当在队列中找到它们时将按需处理。队列任务通常用于需要时间执行的工作,例如发送电子邮件或对外部服务进行API调用。

schedule:run命令不同,这不是每分钟都需要运行的命令。相反,它需要不断在后台运行作为守护进程。一种常见的方法是使用像supervisord这样的第三方软件包,但该方法需要了解如何配置和管理所述系统。使用cron和run-one命令实现它的方法要简单得多。

我们将创建一个cron条目来启动队列工作守护程序,并用run-one它来运行它。这意味着cron将在第一次运行时启动该进程,并且当工作程序运行时,任何后续的cron运行都将被忽略run-one。一旦工作程序停止,run-one将允许该命令再次运行,并且队列工作程序将再次启动。这是一种非常简单易用的方法,使您无需学习如何配置和使用其他工具。

考虑到所有这些,我们将创建另一个cron任务来运行我们的队列工作者。

- 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"

和以前一样,打开php.yml文件进行编辑。

nano 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:
. . .

保存并运行剧本:

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

像以前一样,在浏览器中刷新页面。一分钟后,它将更新为如下所示:

Queue: YES
Cron: YES

这意味着队列工作者正在后台正常工作。我们在上一步中启动的cron作业将作业推送到队列中。此作业在运行时更新数据库以显示其正在运行。

我们现在有一个工作示例Laravel应用程序,其中包括正常运行的cron作业和队列工作程序。

结论

本教程介绍了使用Ansible部署PHP应用程序时的一些更高级的主题。所有使用的任务都可以轻松修改,以适应大多数PHP应用程序(取决于他们的具体要求),它应该为您的应用程序设置自己的Playbooks提供一个很好的起点。

我们没有使用单个SSH命令作为本教程的一部分(除了检查www-data用户登录之外),并且所有内容(包括MySQL用户密码)都已自动设置。完成本教程后,您的应用程序已准备就绪,并支持推送代码更新的工具。

更多Ubuntu教程请前往腾讯云+社区学习更多知识。

参考文献:《How To Deploy an Advanced PHP Application Using Ansible on Ubuntu 14.04》

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏游戏杂谈

Node.js + Express 构建的订餐系统

Express的版本 – v3.3.3  (安装 $ npm install -g express)

1553
来自专栏Python研发

django-celery定时任务以及异步任务and服务器部署并且运行全部过程

应用Celery之前,我想大家都已经了解了,什么是Celery,Celery可以做什么,等等一些关于Celery的问题,在这里我就不一一解释了。

8942
来自专栏Nian糕的私人厨房

WebPack 模块化打包工具(上)

本篇博文的内容根据 入门 Webpack,看这篇就够了 该篇文章总结而来,其代码、模块示例、功能拓展部分均有所删减,若是想了解更多关于 WebPack 的详细内...

1125
来自专栏Golang语言社区

Linux常用命令速查备忘

PS:备忘而已,详细的命令参数说明自己man 一. 启动,关机,登入,登出相关命令 [login] 登录 [logout] 登出 [exit] 登出 [shut...

3839
来自专栏青玉伏案

Git知识总览(二) git常用命令概览

上篇博客我们从 git clone 和 git status 两个命令开始,引出了一系列的git操作命令, 请参见:《Git知识总览(一) 从 git clon...

2988
来自专栏古时的风筝

使用 github 做代码管理,知道这些就够了

只要掌握了下面的常用命令,基本上用使用 github 就没有问题。github 有两种认证方式,一种是通过 ssh 私钥的方式,一种通过 https 的账号名...

3618
来自专栏IT技术精选文摘

Nginx内容缓存

介绍 当启用缓存时,NGINX Plus将响应保存在磁盘缓存中,并使用它们来响应客户端,而不必每次都为同一内容代理请求。 启用响应缓存 要启用缓存,请在...

3329
来自专栏编程直播室

Angular 2 库

2105
来自专栏程序猿

搭建微信小程序教程:基于CentOS 7.6的教程

一个域名、一个SSL证书、一个程序账号、一台CentOS服务器。 然后主要的步骤就是: 1、解析域名; 2、部署服务器; 3、上传SSL证书; 4、填写小程序...

7517
来自专栏LinXunFeng的专栏

一份Cocoapods支持多个target

1123

扫码关注云+社区

领取腾讯云代金券