SoFunction
Updated on 2024-11-14

Remote Deployment Tool Fabric Explained (Python3 Support)

preamble

If you search around for the keyword "Fabric", you'll find that 90% of the information is outdated because Fabric now supports Python3, but it's not compatible with older versions of Fabric. so it simply won't run if you follow those tutorials.

If you haven't used Fabric yet, this article is to help you get started with Fabric. Whether you use it now or not, you'll need it later.

Normally our development process looks like this, after months of fighting, the project is finally developed and tested OK, we submit the code to a hosting platform like GitHub and prepare to deploy to the official environment. You carefully log in to the official server, go to the project directory, pull the code down from the remote repository, and start the program. Every time a new feature is released or even a small bug is fixed, you have to do the same thing over and over again, logging into the server, switching to a specific directory, pulling the code, and restarting the service.

Fabric is a remote deployment tool that allows you to execute commands locally on a remote server.

How do I do it? It's simple, just a few steps.

Installing Fabric

$ pip install fabric --upgrade

Note that if you installed an old version of Fabric, then the new version of Fabric is not compatible with the old version. Currently, there are three versions of Fabric, Fabric1 is the previous version of Fabric, which only supports Python2 and is no longer recommended, and Fabric2 is the current version of Fabric, which supports Python2 and Python3, and is also highly recommended. Fabric2 is the current version of Fabric, which supports both Python2 and Python3, and is highly recommended. There is also Fabric3, which is an unofficial version cloned from the old Fabric1, but is compatible with Fabric1 and supports Python2 and Python3.

The latest fabric does not need files, nor does it need the fab command, and almost all tutorials and materials on the web are still based on fabric1, so be careful when you read those tutorials. The new fabric provides a very simple API.

Run command

As an example, here's a deployment script

# 
# 1. Create a remote connection
# 2. Access to designated directories
# 3. Execute the reboot command under the specified directory

from fabric import Connection

def main():
  # ip, I just filled it in.
  # If your computer is equipped with ssh password-free login, you don't need connect_kwargs to specify a password.
  c = Connection("[email protected]", connect_kwargs={"password": "youpassword"})

  with ('/var/www/youproject'):
    ("git pull origin master")
    ("/usr/bin/supervisorctl -c ../supervisor/ restart youproject")

if __name__ == '__main__':
  main()

fulfillment

python 

After the completion of the implementation, the latest code has been deployed to the formal environment and restarted the service, is not very convenient, mom no longer worry about me in the formal environment knocking the wrong command to delete the database to run away.

Fabric not only supports Linux, but also runs well on Windows platforms. In small and medium-sized projects, it is a very good operation and maintenance tool, and with Frabic, managing hundreds of servers is not a problem.

Build Connections

class Connection(Context):
  host = None
  user = None
  port = None
  ssh_config = None
  connect_timeout = None
  connect_kwargs = None
  ...

There are different ways to build the Connection object, for example you can write host as "[email protected]:22" or as 3 separate parameters. The connect_kwargs is a dictionary object, usually filled with the server's login password or key.

Uploading files
The run method is used to execute a command, cd to enter a specified directory, and the put method is used to upload a file, for example:

from fabric import Connection
c = Connection('web1')
('', '/opt/mydata')
('tar -C /opt/mydata -xzvf /opt/mydata/')

Multiple servers

If you are trying to run commands on multiple servers, the easy way to do this is to use iteration and execute the commands server by server:

# web1,web2,mac1 are all server names, you can also use ip instead.
>>> from fabric import Connection
>>> for host in ('web1', 'web2', 'mac1'):
>>>   result = Connection(host).run('uname -s')
...   print("{}: {}".format(host, ()))
...
web1: Linux
web2: Linux
mac1: Darwin

Or use the SerialGroup

from fabric import SerialGroup as Group
pool = Group('web1', 'web2', 'web3', connect_kwargs={"password": "youpassword"} )
('', '/opt/mydata')
('tar -C /opt/mydata -xzvf /opt/mydata/')

Group(*hosts, **kwargs) Parameter Description:

  • *hosts: multiple hostnames or IPs can be passed in
  • **kwargs receives the same parameters as Connection and can specify a password.

This article is over, did you get it?

This is the entire content of this article.