|
| 1 | +================================================================================ |
| 2 | + Serving Static Datatracker Files via a CDN |
| 3 | +================================================================================ |
| 4 | + |
| 5 | +Intro |
| 6 | +===== |
| 7 | + |
| 8 | +With release 6.4.0, the way that the static files used by the datatracker are |
| 9 | +handled changes substantially. Static files were previously versioned under a |
| 10 | +top-level ``static/`` directory, but this is not the case any more. External |
| 11 | +files (such as for instance ``jquery.min.js``) are now placed under |
| 12 | +``ietf/externals/static/`` and updated using a tool called bower_, while |
| 13 | +datatracker-specific files (images, css, js, etc.) are located under |
| 14 | +``ietf/static/ietf/`` and ``ietf/secr/static/secr/`` respectively. |
| 15 | + |
| 16 | +The following sections provide more details about handling of internals, |
| 17 | +externals, and how deployment is done. |
| 18 | + |
| 19 | + |
| 20 | +Serving Static Files via CDN |
| 21 | +============================ |
| 22 | + |
| 23 | +Production Mode |
| 24 | +--------------- |
| 25 | + |
| 26 | +If resources served over a CDN and/or with a high max-age don't have different |
| 27 | +URLs for different versions, then any component upgrade which is accompanied |
| 28 | +by a change in template functionality will have a long transition time |
| 29 | +during which the new pages are served with old components, with possible |
| 30 | +breakage. We want to avoid this. |
| 31 | + |
| 32 | +The intention is that after a release has been checked out, but before it is |
| 33 | +deployed, the standard django 'collectstatic' management command will be |
| 34 | +run, resulting in all static files being collected from their working |
| 35 | +directory location and placed in an appropiate location for serving via CDN. |
| 36 | +This location will have the datatracker release version as part of its URL, |
| 37 | +so that after the deployment of a new release, the CDN will be forced to fetch |
| 38 | +the appropriate static files for that release. |
| 39 | + |
| 40 | +An important part of this is to set up the ``STATIC_ROOT`` and ``STATIC_URL`` |
| 41 | +settings appropriately. In 6.4.0, the setting is as follows in production |
| 42 | +mode:: |
| 43 | + |
| 44 | + STATIC_URL = "https://www.ietf.org/lib/dt/%s/"%__version__ |
| 45 | + STATIC_ROOT = CDN_ROOT + "/a/www/www6s/lib/dt/%s/"%__version__ |
| 46 | + |
| 47 | +The result is that all static files collected via the ``collectstatic`` |
| 48 | +command will be placed in a location served via CDN, with the release |
| 49 | +version being part of the URL. |
| 50 | + |
| 51 | +Development Mode |
| 52 | +---------------- |
| 53 | + |
| 54 | +In development mode, ``STATIC_URL`` is set to ``/static/``, and Django's |
| 55 | +``staticfiles`` infrastructure makes the static files available under that |
| 56 | +local URL root (unless you set |
| 57 | +``settings.SERVE_CDN_FILES_LOCALLY_IN_DEV_MODE`` to ``False``). It is not |
| 58 | +necessary to actually populate the ``static/`` directory by running |
| 59 | +``collectstatic`` in order for static files to be served when running |
| 60 | +``ietf/manage.py runserver`` -- the ``runserver`` command has extra support |
| 61 | +for finding and serving static files without running collectstatic. |
| 62 | + |
| 63 | +In order to work backwards from a file served in development mode to the |
| 64 | +location from which it is served, the mapping is as follows:: |
| 65 | + |
| 66 | + ============================== ============================== |
| 67 | + Development URL Working copy location |
| 68 | + ============================== ============================== |
| 69 | + localhost:8000/static/ietf/* ietf/static/ietf/* |
| 70 | + localhost:8000/static/secr/* ietf/secr/static/secr/* |
| 71 | + localhost:8000/static/* ietf/externals/static/* |
| 72 | + ============================== ============================== |
| 73 | + |
| 74 | +Handling of External Javascript and CSS Components |
| 75 | +================================================== |
| 76 | + |
| 77 | +In order to make it easy to keep track of and upgrade external components, |
| 78 | +these are now handled by a tool called ``bower``, via a new management |
| 79 | +command ``bower_install``. Each external component is listed in a file |
| 80 | +``ietf/bower.json``. In order to update the version of a component listed in |
| 81 | +``ietf/bower.json``, or add a new one, you should edit ``bower.json``, and |
| 82 | +then run the management command:: |
| 83 | + |
| 84 | + $ ietf/manage.py bower_install |
| 85 | + |
| 86 | +(Not surprisingly, you need to have bower_ installed in order to use this |
| 87 | +management command.) |
| 88 | + |
| 89 | +That command will fetch the required version of each external component listed |
| 90 | +in ``bower.json`` (actually, it will do this for *all* ``bower.json`` files |
| 91 | +found in the ``static/`` directories of all ``INSTALLED_APPS`` and the |
| 92 | +directories in ``settings.STATICFILES_DIRS``), saving them temporarily under |
| 93 | +``.tmp/bower_components/``; it will then extract the relevant production |
| 94 | +``js`` and ``css`` files and place them in an appropriately named directory |
| 95 | +under ``ietf/externals/static/``. The latter location is taken from |
| 96 | +``COMPONENT_ROOT`` in ``settings.py``. |
| 97 | + |
| 98 | +Managing external components via bower has the additional benefit of |
| 99 | +managing dependencies -- components that have dependencies will pull in |
| 100 | +these, so that they also are placed under ``ietf/externals/static/``. |
| 101 | +You still have to manually add the necessary stylesheet and/or javascript |
| 102 | +references to your templates, though. |
| 103 | + |
| 104 | +The ``bower_install`` command is not run automatically by ``bin/mkrelease``, |
| 105 | +since it needs an updated ``bower.json`` in order to do anything interesting. |
| 106 | +So when you're intending to update an external web asset to a newer version, |
| 107 | +you need to edit the ``bower.json`` file, run ``manage.py bower_install``, |
| 108 | +verify that the new version doesn't break things, and then commit the new |
| 109 | +files under ``ietf/externals/static/`` and the updated ``bower.json``. |
| 110 | + |
| 111 | +.. _bower: http://bower.io/ |
| 112 | + |
| 113 | +The ``ietf/externals/static/`` Directory |
| 114 | +----------------------------------------- |
| 115 | + |
| 116 | +The directory ``ietf/externals/static/`` holds a number of subdirectories |
| 117 | +which hold distribution files for external client-side components, collected |
| 118 | +by ``bower_install`` as described above. Currently |
| 119 | +(01 Aug 2015) this means ``js`` and ``css`` components and fonts. |
| 120 | + |
| 121 | +These components each reside in their own subdirectory, which is named with |
| 122 | +the component name:: |
| 123 | + |
| 124 | + henrik@zinfandel $ ls -l ietf/externals/static/ |
| 125 | + total 40 |
| 126 | + drwxr-xr-x 6 henrik henrik 4096 Jul 25 15:25 bootstrap |
| 127 | + drwxr-xr-x 4 henrik henrik 4096 Jul 25 15:25 bootstrap-datepicker |
| 128 | + drwxr-xr-x 4 henrik henrik 4096 Jul 25 15:25 font-awesome |
| 129 | + drwxr-xr-x 2 henrik henrik 4096 Jul 25 15:25 jquery |
| 130 | + drwxr-xr-x 2 henrik henrik 4096 Jul 25 15:25 jquery.cookie |
| 131 | + drwxr-xr-x 2 henrik henrik 4096 Jul 25 15:24 ptmono |
| 132 | + drwxr-xr-x 2 henrik henrik 4096 Jul 25 15:24 ptsans |
| 133 | + drwxr-xr-x 2 henrik henrik 4096 Jul 25 15:24 ptserif |
| 134 | + drwxr-xr-x 2 henrik henrik 4096 Jul 25 15:25 select2 |
| 135 | + drwxr-xr-x 2 henrik henrik 4096 Jul 25 15:25 select2-bootstrap-css |
| 136 | + |
| 137 | +The ``pt*`` fonts are an exception, in that there is no bower component |
| 138 | +available for these fonts, so they have been put in place manually. |
| 139 | + |
| 140 | + |
| 141 | +Handling of Internal Static Files |
| 142 | +================================= |
| 143 | + |
| 144 | +Previous to this release, internal static files were located under |
| 145 | +``static/``, mixed together with the external components. They are now |
| 146 | +located under ``ietf/static/ietf/`` and ``ietf/secr/static/secr``, and will be |
| 147 | +collected for serving via CDN by the ``collectstatic`` command. Any static |
| 148 | +files associated with a particular app will be handled the same way (which |
| 149 | +means that all ``admin/`` static files automatically will be handled correctly, too). |
| 150 | + |
| 151 | +Handling of Customised Bootstrap Files |
| 152 | +====================================== |
| 153 | + |
| 154 | +We are using a customised version of Bootstrap_, which is handled specially, |
| 155 | +by a SVN externals definition in ``ietf/static/ietf``. That pulls the content |
| 156 | +of the ``bootstrap/dist/`` directory (which is generated by running ``grunt`` |
| 157 | +in the ``bootstrap/`` directory) into ``ietf/static/ietf/bootstrap``, from |
| 158 | +where it is collected by ``collectstatic``. |
| 159 | + |
| 160 | +Changes to Template Files |
| 161 | +========================= |
| 162 | + |
| 163 | +In order to make the template files refer to the correct versioned CDN URL |
| 164 | +(as given by the STATIC_URL root) all references to static files in the |
| 165 | +templates have been updated to use the ``static`` template tag when referring |
| 166 | +to static files. This will automatically result in both serving static files |
| 167 | +from the right place in development mode, and referring to the correct |
| 168 | +versioned URL in production mode and the simpler ``/static/`` urls in |
| 169 | +development mode. |
| 170 | + |
| 171 | +.. _bootstrap: http://getbootstrap.com/ |
| 172 | + |
| 173 | +Deployment |
| 174 | +========== |
| 175 | + |
| 176 | +During deployment, it is now necessary to run the management command:: |
| 177 | + |
| 178 | + $ ietf/manage.py collectstatic |
| 179 | + |
| 180 | +before activating a new release. |
| 181 | + |
| 182 | +The deployment ``README`` file at ``/a/www/ietf-datatracker/README`` has been |
| 183 | +updated accordingly. |
0 commit comments