April 26, 2016

Bower caching proxy

If you’re using bower for some of your projects and may happen to build this not only locally but also in some sort of CI, you might want to have a bower caching proxy in your network.

Installation

I suggest to add a specific user for this:

useradd -m -d /var/cache/bower -s /bin/false bower

Some neccessary packages:

apt-get install git python-virtualenv

Now we install the cache according to the README.

sudo -u bower-cache /bin/bash
cd
virtualenv .
. bin/activate
pip install -U pip setuptools
pip install bower-cache

Configuration

sudo -u bower-cache /bin/bash
cd
bower-cache-init /var/cache/bower/cache
cd cache
python manage.py changepassword admin

We also need to adjust some variables which gets served to the clients.

In cache/bowercachesite/settings.py, we need to set the REPO_URL to a value, where the files being served by git daemon are accessible later for all clients, e.g ```REPO_URL = ‘git://bower-cache.example.com:6789/‘````.

Startup

/etc/systemd/system/bower-gunicorn.service

[Unit]
Description=bower caching proxy (gunicorn)
After=network.target
After=syslog.target

[Service]
User=bower
Group=bower
RuntimeDirectory=bower
PIDFile=/var/run/bower/bower-gunicorn.pid
WorkingDirectory=/var/cache/bower/cache
ExecStart=/var/cache/bower/bin/gunicorn --bind 0.0.0.0:8000 --pid /var/run/bower/bower-gunicorn.pid --chdir /var/cache/bower/cache bowercachesite.wsgi
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID

[Install]
WantedBy=multi-user.target

/etc/systemd/system/bower-worker.service

[Unit]
Description=bower caching proxy celery worker service
After=network.target

[Service]
Type=forking
User=bower
Group=bower
RuntimeDirectory=bower
WorkingDirectory=/var/cache/bower/cache
ExecStart=/var/cache/bower/bin/python manage.py celery worker --detach --pidfile=/var/run/bower/celery.pid -c 1 -B

[Install]
WantedBy=multi-user.target

/etc/systemd/system/bower-git-daemon.service

[Unit]
Description=bower caching proxy git repositories server daemon
After=network.target

[Service]
User=bower
Group=bower
RuntimeDirectory=bower
PIDFile=/var/run/bower/bower-git-daemon.pid
ExecStart=/usr/lib/git-core/git-daemon --port=6789 --base-path=/var/cache/bower/cache/cache --export-all --pid-file=/var/run/bower/git-daemon.pid --verbose

[Install]
WantedBy=multi-user.target

Client usage

In your package, add this to .bowerrc:

{
  ...
  "registry": "http://bower-cache.example.com:8000",
  ...
}

During my tests, the first run timed out on some packages due to the worker being busy fetching the remote repos. Just watch a tool like top or htop until the git processes settles, then try again.