git 应用程序本身更新_如何使用Git通过SFTP正确部署Web应用程序

git 应用程序本身更新

This article was peer reviewed by Haydar KÜLEKCİ and Wern Ancheta. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!

本文由HaydarKÜLEKCİWern Ancheta进行同行评审。 感谢所有SitePoint的同行评审人员使SitePoint内容达到最佳状态!



Uploading files is an integral aspect of any deployment process, and the underlying implementation can vary depending on the type of your server.

上载文件是任何部署过程不可或缺的一部分,其基础实现可能会因服务器的类型而异。

You can easily upload your files to an SFTP server using an open source desktop client like Filezilla. Those who have used this are aware that this process is cumbersome and irritating as it doesn’t let us automate our deployment process, and we always need to upload the whole project, even if we have modified only a part of the files of our codebase.

您可以使用诸如Filezilla的开源桌面客户端轻松地将文件上传到SFTP服务器。 那些使用过此方法的人都知道,此过程很麻烦且烦人,因为它不允许我们自动化部署过程,而且即使只修改了部分代码库文件,我们也始终需要上传整个项目。 。

Abstract image symbolizing upload - a cloud shape made from glowing teal pixels, and in front of it, or inside it, an arrow pointing upwards

The PHPSECLIB (PHP Secure Communications Library) package has an awesome API for routine SFTP tasks: it uses some optional PHP extensions if they’re available, and falls back on an internal PHP implementation otherwise. You don’t need any additional PHP extension to use this package, the default extensions that are packaged with PHP will do. In this article, we will first cover various features of PHPSECLIB – SFTP, including but not limited to uploading or deleting files. Then, we will take a look at how we can use Git in combination with this library to automate our SFTP deployment process.

PHPSECLIB (PHP 小号 ecureÇommunications 郭宝宏)封装,具有日常任务SFTP一个真棒API:它使用了一些可选PHP扩展,如果他们是可用的,并且倒在内部PHP执行,否则。 您不需要任何其他PHP扩展即可使用此程序包,PHP打包的默认扩展程序可以使用。 在本文中,我们将首先介绍PHPSECLIB – SFTP的各种功能,包括但不限于上载或删除文件。 然后,我们将研究如何结合使用Git和该库来自动化SFTP部署过程。

PhpSecLib安装 (PhpSecLib Installation)

composer require phpseclib/phpseclib

This will install the most recent stable version of the library via Composer.

这将通过Composer安装该库的最新稳定版本。

认证方式 (Authentication)

By default, password authentication is used to connect to your SFTP server. A cryptographic key-pair is more secure because a private key takes the place of a password, which is generally much more difficult to brute-force. Using phpseclib, you can connect to your SFTP server with any of the following authentication methods:

默认情况下,密码验证用于连接到SFTP服务器。 加密密钥对更安全,因为私钥代替了密码,而密码通常很难破解 。 使用phpseclib ,可以使用以下任何一种身份验证方法连接到SFTP服务器:

  1. RSA key

    RSA密钥
  2. Password Protected RSA key

    受密码保护的RSA密钥
  3. Username and Password (Not recommended)

    用户名和密码( 不推荐 )

RSA密钥 (RSA Key)

We will assume that you have a secure RSA key already generated. If you are not familiar with generating a secure RSA key pair, you can go through this article. For a video explanation, you can refer to Creating and Using SSH Keys from Servers For Hackers.

我们将假定您已经生成了一个安全的RSA密钥。 如果您不熟悉生成安全的RSA密钥对,则可以阅读本文 。 有关视频的说明,请参阅从“黑客服务器” 创建和使用SSH密钥

To log in to a remote server using RSA key authentication:

要使用RSA密钥认证登录到远程服务器:

namespace App;

use phpseclib\Crypt\RSA;
use phpseclib\Net\SFTP;

$key = new RSA();
$key->loadKey(file_get_contents('privatekey'));

//Remote server's ip address or hostname
$sftp = new SFTP('192.168.0.1');

if (!$sftp->login('username', $key)) {
    exit('Login Failed');
}

受密码保护的RSA密钥 (Password Protected RSA Key)

If your RSA keys are password protected, do not worry. PHPSECLIB takes care of this particular use case:

如果您的RSA密钥受密码保护,请不要担心。 PHPSECLIB处理这个特殊的用例:

namespace App;

use phpseclib\Crypt\RSA;
use phpseclib\Net\SFTP;

$key = new RSA();
$key->setPassword('your-secure-password');
$key->loadKey(file_get_contents('privatekey'));

//Remote server's ip address or hostname
$sftp = new SFTP('192.168.0.1');

if (!$sftp->login('username', $key)) {
    exit('Login Failed');
}

用户名和密码 (Username and Password)

Alternatively, to log in to your remote server using a username and password (we don’t recommend this practice):

或者,要使用用户名和密码登录到远程服务器(我们不建议您这样做):

namespace App;

use phpseclib\Net\SFTP;

//Remote server's ip address or hostname
$sftp = new SFTP('192.168.0.1');

if (!$sftp->login('username', 'password')) {
    exit('Login Failed');
}

For other options such as No Authentication or Multi-Factor authentication please refer to the documentation.

有关其他选项,例如“无身份验证”或“多重身份验证”,请参阅文档

上传和删除文件 (Uploading and Deleting Files)

A large part of the deployment process includes uploading files to a server. Uploading files essentially means transferring the contents of a local file to a remote file. The example below creates an index.php file on the server with the contents This is a dummy file:

部署过程的很大一部分包括将文件上传到服务器。 上载文件实质上意味着将本地文件的内容传输到远程文件。 下面的示例在服务器上创建一个index.php文件,内容如下: 这是一个虚拟文件

namespace App;

use phpseclib\Crypt\RSA;
use phpseclib\Net\SFTP;

$key = new RSA();
$key->loadKey(file_get_contents('privatekey'));

//Remote server's ip address or hostname
$sftp = new SFTP('192.168.0.1');

if (!$sftp->login('username', $key)) {
    exit('Login Failed');
}

$sftp->put('index.php', 'This is a dummy file');

By default, put does not read from the local filesystem. The contents are dumped straight into the remote file. In a real world scenario, you need to fetch the contents of local files and dump them into the remote file:

默认情况下, put不从本地文件系统读取。 内容直接转储到远程文件中。 在现实世界中,您需要获取本地文件的内容并将其转储到远程文件中:

$contents = file_get_content('path/to/local/file');
$sftp->put('index.php', $contents);

During our deployment process, we need to add one more step of deleting files and directories which are no longer required by the application. You can easily delete a single file or recursively delete all the files and directories from a specific directory.

在部署过程中,我们需要再增加一个步骤,即删除应用程序不再需要的文件和目录。 您可以轻松地删除单个文件,也可以从特定目录中递归删除所有文件和目录。

//Deleting a single file. This does not delete directories.
$sftp->delete('index.php');

//Deleting directories and files recursively
$sftp->delete('dir_name', true);

使用Git自动化部署 (Automating Deployment with Git)

Git is widely accepted as the industry standard of versioning tools. Using the power of Git, we can save some time and bandwidth by uploading only those files that changed since the last upload. Using the SFTP API of PHPSECLIB, we will try to deploy our files to our SFTP server.

Git被广泛接受为版本控制工具的行业标准。 利用Git的功能,我们可以仅上传自上次上传以来已更改的文件,从而节省一些时间和带宽。 使用PHPSECLIB的SFTP API,我们将尝试将文件部署到SFTP服务器。

I have divided the whole deployment process into a few steps below to better explain each. Once we go through all the steps, we will bring it all together.

我将整个部署过程分为以下几个步骤,以更好地解释每个步骤。 一旦完成所有步骤,我们将把所有这些整合在一起。

一些Git基础知识 (Some Git basics)

First, we need to understand some specific Git commands which will assist us in our deployment process. We will create a class which will help us execute Git related tasks. Git commands are executed from the command line – we will use the Process component for that. The component provides an abstraction layer for executing shell commands and takes care of the subtle differences between the different platforms. You can refer to its documentation for more information. For now, we will write code specific to fetching the files added, modified or deleted between two given commits.

首先,我们需要了解一些特定的Git命令,这些命令将有助于我们进行部署。 我们将创建一个类来帮助我们执行与Git相关的任务。 Git命令是从命令行执行的–我们将使用Process组件。 该组件提供了一个用于执行Shell命令的抽象层,并照顾了不同平台之间的细微差别。 您可以参考其文档以获取更多信息。 现在,我们将编写特定于获取两次给定提交之间添加,修改或删除的文件的代码。

<?php

namespace App;

use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;

class Git 
{
    public function diffFiles($start_commit, $end_commit)
        {
        //Get new and modified files
        $process = new Process("git diff --name-only --diff-filter=AM $start_commit $end_commit");

        $process->setTimeout(3600);
        $process->setWorkingDirectory('/path/to/local/repository');
        $process->run();

        if (!$process->isSuccessful()) {
            throw new ProcessFailedException($process);
        }

    //Extract all file paths from the process output
        $files["added"] = array_unique(
        array_merge($files["added"], 
        array_filter(explode("\n", $process->getOutput()), 'strlen'))
    );

    //Get deleted files
        $process = new Process("git diff-tree --diff-filter=D --name-only -t $start_commit $end_commit");

        $process->setTimeout(3600);
        $process->setWorkingDirectory('/path/to/local/repository');
        $process->run();

        if (!$process->isSuccessful()) {
            throw new ProcessFailedException($process);
        }

        $files["deleted"] = array_filter(explode("\n", $process->getOutput()), 'strlen');

        return $files;
    }
}

在特定提交时获取文件的内容 (Get contents of a file at a specific commit)

Git stores the historical data regarding a given repository in the hidden .git folder. To move forward with our deployment process, we need to fetch the contents of files recorded by Git in the specified commit. We will add another method to the Git class:

Git将有关给定存储库的历史数据存储在隐藏的.git文件夹中。 为了继续进行我们的部署过程,我们需要获取Git在指定提交中记录的文件的内容。 我们将向Git类添加另一个方法:

public function getContent($commit, $file)
{
    //Get contents of a file at a specific commit
    $process = new Process("git show \"$commit:$file\"");

    $process->setTimeout(3600);
    $process->setWorkingDirectory('path/to/repository');
    $process->run();

    if (!$process->isSuccessful()) {
        throw new ProcessFailedException($process);
    }

    return $process->getOutput();
}

部署文件 (Deploying files)

Next, we need to write a piece of code which will take care of executing the deployment process. Let us first list the important steps we need to take care of:

接下来,我们需要编写一段代码来执行部署过程。 让我们首先列出我们需要注意的重要步骤:

  1. Fetch added, modified, and deleted files between the two commits

    在两次提交之间获取添加,修改和删除的文件
  2. Transfer new and modified files to SFTP server

    将新的和修改的文件传输到SFTP服务器
  3. Delete the files which were removed between the two commits

    删除两次提交之间删除的文件

Now that we are clear on what we need to achieve, let’s put that into code:

现在我们已经清楚了需要实现的目标,现在将其放入代码中:

$files = $git->diffFiles($start_commit, $end_commit);

if(count($files['added']) > 0) {
    foreach($files['added'] as $file) {
        $content = $git->getContent($end_commit, $file);

        //Ensure a directory exists - if it doesn't create it recursively.
        if (!$sftp->file_exists(dirname($file))) {
            $sftp->mkdir(dirname($path), -1, true);
        }

        $sftp->put('/path/to/remote/file', $content);
    }
}

if(count($files['deleted']) > 0) {
    foreach($files['deleted'] as $file) {

        if ($sftp->file_exists($file)) {
            $sftp->delete($file, true);
        }

    }
}

The above code will transfer all the updated files and delete the files removed between the two specified commits. It also takes care of automatic directory creation. If the directories are not present, the above code will ensure that those directories are created in the process.

上面的代码将传输所有更新的文件,并删除两次指定的提交之间删除的文件。 它还负责自动目录创建。 如果目录不存在,则上面的代码将确保在该过程中创建这些目录。

执行远程命令 (Executing remote commands)

You can execute any shell commands on the remote server before or after your deployment is completed with the exec method.

您可以在使用exec方法完成部署之前或之后在远程服务器上执行任何Shell命令。

$sftp->exec("your-remote-command-here");

Just like with SSH, a call to the exec method does not carry state forward to the next exec call. To execute multiple commands without losing state:

就像使用SSH一样 ,对exec方法的调用不会将状态转移到下一个exec调用。 要执行多个命令而不丢失状态:

$sftp->exec(
    "php artisan up" . PHP_EOL
    "composer dump-autoload -o" . PHP_EOL
    "php artisan optimize"
);

The phpseclib\Net\SFTP class extends the phpseclib\Net\SSH class. You can utilize the full API of the SSH class to execute remote commands or gather output. For an in-depth implementation of SSH, see our previous tutorial.

phpseclib\Net\SFTP类扩展了phpseclib\Net\SSH类。 您可以利用SSH类的完整API来执行远程命令或收集输出。 有关SSH的深入实现,请参阅我们以前的教程

管理权限 (Managing Permissions)

Permissions are the basic defense system of a file. We need to assign some specific rights to users or groups of users for files on the server to prevent potential attacks.

权限是文件的基本防御系统。 我们需要为服务器上的文件的用户或用户组分配一些特定的权限,以防止潜在的攻击。

Setting permissions on a single file returns the new file permissions on success or false on error:

在单个文件上设置权限,成功则返回新文件权限,错误则返回false:

$sftp->chmod(0777, 'path/to/remote/file');

Alternatively, you can set the permissions for all files in a directory recursively:

另外,您可以递归设置目录中所有文件的权限:

$sftp->chmod(0777, 'path/to/remote/file', true);

Below is the summary of the most important methods regarding file permissions in the SFTP class:

下面是有关SFTP类中文件权限的最重要方法的摘要:

MethodUse case
chgrp($filename, $gid, $recursive = false)Changes file or directory group.
chown($filename, $uid, $recursive = false)Changes file or directory owner.
truncate($filename, $new_size)Truncates a file to a given length.
touch($filename, $time = null, $atime = null)Sets access and modification time of file. If the file does not exist, it will be created.
方法 用例
chgrp($filename, $gid, $recursive = false) 更改文件或目录组。
chown($filename, $uid, $recursive = false) 更改文件或目录的所有者。
truncate($filename, $new_size) 将文件截断为给定的长度。
touch($filename, $time = null, $atime = null) 设置文件的访问和修改时间。 如果文件不存在,将创建它。

下载档案 (Downloading files)

Using PHPSECLIB, we can also download things like backup files or user uploaded media from a server:

使用PHPSECLIB ,我们还可以从服务器下载备份文件或用户上传的媒体之类的内容:

//Gets the remote file's contents
$content = $sftp->get('path/to/remote/file');

//Downloads and saves to the local file
$sftp->get('path/to/remote/file', 'path/to/local/file');

If the file is not present locally, it will be created automatically for you.

如果该文件不在本地,则将自动为您创建。

备择方案 (Alternatives)

  1. git-deploy-php – a simple PHP based tool which deploys your changed files to your SFTP servers. It will transfer files automatically for you for the specified commits.

    git-deploy-php –一个简单的基于PHP的工具,它将更改后的文件部署到SFTP服务器。 对于指定的提交,它将自动为您传输文件。

  2. PHPloy – another PHP based deployment tool to transfer files to SFTP servers. It has more features like rollbacks, support for multiple servers and submodules, and more. The downside is too much involvement in manual configuration for triggering a deployment.

    PHPloy –另一个基于PHP的部署工具,用于将文件传输到SFTP服务器。 它具有更多功能,例如回滚,对多个服务器和子模块的支持等等。 缺点是过多地参与了手动配置以触发部署。

  3. Deploy-Tantra – automatically deploys your repositories to SFTP servers once you push to the specified branch. The upside is a more managed workflow. The downside is it being commercial.

    Deploy-Tantra –推送到指定分支后,将存储库自动部署到SFTP服务器。 好处是工作流程更易于管理。 不利之处在于它是商业性的。

结论 (Conclusion)

In this article, we introduced a particular way to help automate the deployment process for SFTP servers, and we have covered the configuration options necessary to get started.

在本文中,我们介绍了一种特殊的方法来帮助自动化SFTP服务器的部署过程,并且介绍了入门所需的配置选项。

How do you deploy to your SFTP servers? Can you think of some advanced ways of deploying? What are they? Let us know in the comments!

如何部署到SFTP服务器? 您能想到一些高级部署方式吗? 这些是什么? 让我们在评论中知道!

翻译自: https://www.sitepoint.com/how-to-properly-deploy-web-apps-via-sftp-with-git/

git 应用程序本身更新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值