diff options
Diffstat (limited to 'app/static/doc/flask-docs/_sources/patterns/fabric.txt')
-rw-r--r-- | app/static/doc/flask-docs/_sources/patterns/fabric.txt | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/app/static/doc/flask-docs/_sources/patterns/fabric.txt b/app/static/doc/flask-docs/_sources/patterns/fabric.txt new file mode 100644 index 0000000..b02ad27 --- /dev/null +++ b/app/static/doc/flask-docs/_sources/patterns/fabric.txt @@ -0,0 +1,196 @@ +.. _fabric-deployment: + +Deploying with Fabric +===================== + +`Fabric`_ is a tool for Python similar to Makefiles but with the ability +to execute commands on a remote server. In combination with a properly +set up Python package (:ref:`larger-applications`) and a good concept for +configurations (:ref:`config`) it is very easy to deploy Flask +applications to external servers. + +Before we get started, here a quick checklist of things we have to ensure +upfront: + +- Fabric 1.0 has to be installed locally. This tutorial assumes the + latest version of Fabric. +- The application already has to be a package and requires a working + `setup.py` file (:ref:`distribute-deployment`). +- In the following example we are using `mod_wsgi` for the remote + servers. You can of course use your own favourite server there, but + for this example we chose Apache + `mod_wsgi` because it's very easy + to setup and has a simple way to reload applications without root + access. + +Creating the first Fabfile +-------------------------- + +A fabfile is what controls what Fabric executes. It is named `fabfile.py` +and executed by the `fab` command. All the functions defined in that file +will show up as `fab` subcommands. They are executed on one or more +hosts. These hosts can be defined either in the fabfile or on the command +line. In this case we will add them to the fabfile. + +This is a basic first example that has the ability to upload the current +sourcecode to the server and install it into a pre-existing +virtual environment:: + + from fabric.api import * + + # the user to use for the remote commands + env.user = 'appuser' + # the servers where the commands are executed + env.hosts = ['server1.example.com', 'server2.example.com'] + + def pack(): + # create a new source distribution as tarball + local('python setup.py sdist --formats=gztar', capture=False) + + def deploy(): + # figure out the release name and version + dist = local('python setup.py --fullname', capture=True).strip() + # upload the source tarball to the temporary folder on the server + put('dist/%s.tar.gz' % dist, '/tmp/yourapplication.tar.gz') + # create a place where we can unzip the tarball, then enter + # that directory and unzip it + run('mkdir /tmp/yourapplication') + with cd('/tmp/yourapplication'): + run('tar xzf /tmp/yourapplication.tar.gz') + # now setup the package with our virtual environment's + # python interpreter + run('/var/www/yourapplication/env/bin/python setup.py install') + # now that all is set up, delete the folder again + run('rm -rf /tmp/yourapplication /tmp/yourapplication.tar.gz') + # and finally touch the .wsgi file so that mod_wsgi triggers + # a reload of the application + run('touch /var/www/yourapplication.wsgi') + +The example above is well documented and should be straightforward. Here +a recap of the most common commands fabric provides: + +- `run` - executes a command on a remote server +- `local` - executes a command on the local machine +- `put` - uploads a file to the remote server +- `cd` - changes the directory on the serverside. This has to be used + in combination with the `with` statement. + +Running Fabfiles +---------------- + +Now how do you execute that fabfile? You use the `fab` command. To +deploy the current version of the code on the remote server you would use +this command:: + + $ fab pack deploy + +However this requires that our server already has the +``/var/www/yourapplication`` folder created and +``/var/www/yourapplication/env`` to be a virtual environment. Furthermore +are we not creating the configuration or `.wsgi` file on the server. So +how do we bootstrap a new server into our infrastructure? + +This now depends on the number of servers we want to set up. If we just +have one application server (which the majority of applications will +have), creating a command in the fabfile for this is overkill. But +obviously you can do that. In that case you would probably call it +`setup` or `bootstrap` and then pass the servername explicitly on the +command line:: + + $ fab -H newserver.example.com bootstrap + +To setup a new server you would roughly do these steps: + +1. Create the directory structure in ``/var/www``:: + + $ mkdir /var/www/yourapplication + $ cd /var/www/yourapplication + $ virtualenv --distribute env + +2. Upload a new `application.wsgi` file to the server and the + configuration file for the application (eg: `application.cfg`) + +3. Create a new Apache config for `yourapplication` and activate it. + Make sure to activate watching for changes of the `.wsgi` file so + that we can automatically reload the application by touching it. + (See :ref:`mod_wsgi-deployment` for more information) + +So now the question is, where do the `application.wsgi` and +`application.cfg` files come from? + +The WSGI File +------------- + +The WSGI file has to import the application and also to set an environment +variable so that the application knows where to look for the config. This +is a short example that does exactly that:: + + import os + os.environ['YOURAPPLICATION_CONFIG'] = '/var/www/yourapplication/application.cfg' + from yourapplication import app + +The application itself then has to initialize itself like this to look for +the config at that environment variable:: + + app = Flask(__name__) + app.config.from_object('yourapplication.default_config') + app.config.from_envvar('YOURAPPLICATION_CONFIG') + +This approach is explained in detail in the :ref:`config` section of the +documentation. + +The Configuration File +---------------------- + +Now as mentioned above, the application will find the correct +configuration file by looking up the `YOURAPPLICATION_CONFIG` environment +variable. So we have to put the configuration in a place where the +application will able to find it. Configuration files have the unfriendly +quality of being different on all computers, so you do not version them +usually. + +A popular approach is to store configuration files for different servers +in a separate version control repository and check them out on all +servers. Then symlink the file that is active for the server into the +location where it's expected (eg: ``/var/www/yourapplication``). + +Either way, in our case here we only expect one or two servers and we can +upload them ahead of time by hand. + +First Deployment +---------------- + +Now we can do our first deployment. We have set up the servers so that +they have their virtual environments and activated apache configs. Now we +can pack up the application and deploy it:: + + $ fab pack deploy + +Fabric will now connect to all servers and run the commands as written +down in the fabfile. First it will execute pack so that we have our +tarball ready and then it will execute deploy and upload the source code +to all servers and install it there. Thanks to the `setup.py` file we +will automatically pull in the required libraries into our virtual +environment. + +Next Steps +---------- + +From that point onwards there is so much that can be done to make +deployment actually fun: + +- Create a `bootstrap` command that initializes new servers. It could + initialize a new virtual environment, setup apache appropriately etc. +- Put configuration files into a separate version control repository + and symlink the active configs into place. +- You could also put your application code into a repository and check + out the latest version on the server and then install. That way you + can also easily go back to older versions. +- hook in testing functionality so that you can deploy to an external + server and run the testsuite. + +Working with Fabric is fun and you will notice that it's quite magical to +type ``fab deploy`` and see your application being deployed automatically +to one or more remote servers. + + +.. _Fabric: http://fabfile.org/ |