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.