├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── docker-compose.yml ├── shell.sh ├── start.sh ├── upgrade-site.py └── uwsgi.ini /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | MAINTAINER igor.katson@gmail.com 3 | 4 | ENV RB_VERSION 3.0.17 5 | RUN apt-get update -y && \ 6 | apt-get install --no-install-recommends -y \ 7 | build-essential python-dev libffi-dev libssl-dev patch \ 8 | python-pip python-setuptools python-wheel python-virtualenv \ 9 | uwsgi uwsgi-plugin-python \ 10 | postgresql-client \ 11 | python-psycopg2 python-ldap \ 12 | git-core mercurial subversion python-svn && \ 13 | rm -rf /var/lib/apt/lists/* 14 | 15 | RUN set -ex; \ 16 | if [ "${RB_VERSION}" ]; then RB_VERSION="==${RB_VERSION}"; fi; \ 17 | python -m virtualenv --system-site-packages /opt/venv; \ 18 | . /opt/venv/bin/activate; \ 19 | pip install "ReviewBoard${RB_VERSION}" django-storages==1.1.8 oauthlib==1.0.1 semver; \ 20 | rm -rf /root/.cache 21 | 22 | ENV PATH="/opt/venv/bin:${PATH}" 23 | 24 | ADD start.sh /start.sh 25 | ADD uwsgi.ini /uwsgi.ini 26 | ADD shell.sh /shell.sh 27 | ADD upgrade-site.py /upgrade-site.py 28 | 29 | RUN chmod +x /start.sh /shell.sh /upgrade-site.py 30 | 31 | VOLUME /var/www/ 32 | 33 | EXPOSE 8000 34 | 35 | CMD /start.sh 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Igor Katson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | DOCKER_TAG ?= ikatson/reviewboard 2 | RB_VERSION ?= $(shell git rev-parse --abbrev-ref HEAD) 3 | 4 | all: build 5 | 6 | build: 7 | docker build --pull --build-arg "RB_VERSION=$(RB_VERSION)" -t "$(DOCKER_TAG)" -t "$(DOCKER_TAG):$(RB_VERSION)" . 8 | 9 | clean: 10 | docker-compose down 11 | 12 | run: 13 | docker-compose up --build 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # docker-reviewboard 2 | 3 | Dockerized reviewboard. This container follows Docker's best practices, and DOES NOT include sshd, supervisor, apache2, or any other services except the reviewboard itself which is run with ```uwsgi```. 4 | 5 | The requirements are PostgreSQL and memcached, you can use either dockersized versions of them, or external ones, e.g. installed on the host machine, or even third-party machines. 6 | 7 | ### Disclaimer 8 | I'm neither a user nor maintainer of reviewboard itself. 9 | I created this repo a few years back to test reviewboard out, and did not use it since then. Seems like a lot of people find it useful, so in my spare time I try to fix whatever people are complaining about. Luckily it wasn't too bad so far in terms of support volume, so I'm ok with that. 10 | But if you are missing some features, or having trouble, please file a PR as I'm usually too busy to respond promptly. 11 | 12 | ## Quickstart. Run dockerized reviewboard with all dockerized dependencies, and persistent data in docker containers. 13 | 14 | ### Using Makefile 15 | make build # if you want to build the image yourself 16 | make run 17 | 18 | ### Using docker-compose 19 | docker-compose up 20 | 21 | Then go to http://127.0.0.1:8000/ (or your docker host) and login as admin:admin 22 | 23 | Alternatively, here are the commands to do the same manually. 24 | 25 | # Install postgres 26 | docker run -d --name rb-postgres -e POSTGRES_USER=reviewboard postgres:alpine 27 | 28 | # Install memcached 29 | docker run --name rb-memcached -d -p 11211 memcached:alpine 30 | 31 | # Run reviewboard with a named volume to hold your site's data 32 | docker run -it -v reviewboard-site:/var/www/ --link rb-postgres:pg --link rb-memcached:memcached -p 8000:8000 ikatson/reviewboard 33 | 34 | After that, go the url, e.g. ```http://localhost:8000/```, login as ```admin:admin```, change the admin password, and change the location of your SMTP server so that the reviewboard can send emails. You are all set! 35 | 36 | For details, read below. 37 | 38 | ## Build yourself if you want. 39 | 40 | If you want to build this yourself, just run this: 41 | 42 | docker build -t 'ikatson/reviewboard' git://github.com/ikatson/docker-reviewboard.git 43 | 44 | ## Dependencies 45 | 46 | ### Install PostgreSQL 47 | 48 | You can install postgres either into a docker container, or whereever else. 49 | 50 | 1. Example: install postgres into a docker container, and create a database for reviewboard. 51 | 52 | docker run -d --name rb-postgres -e POSTGRES_USER=reviewboard postgres:alpine 53 | 54 | 2. Example: install postgres into the host machine, example given for a Debian/Ubuntu based distribution. 55 | 56 | apt-get install postgresql-server 57 | 58 | # Uncomment this to make postgres listen on all addresses. 59 | # echo "listen_addresses = '*'" >> /etc/postgresql/VERSION/postgresql.conf 60 | # invoke-rc.d postgresql restart 61 | sudo -u postgres createuser reviewboard 62 | sudo -u postgres createdb reviewboard -O reviewboard 63 | sudo -u postgres psql -c "alter user reviewboard set password to 'SOME_PASSWORD'" 64 | 65 | ### Install memcached 66 | 67 | 1. Example: install into a docker container 68 | 69 | docker run --name memcached -d -p 11211 memcached:alpine 70 | 71 | 1. Example: install locally on Debian/Ubuntu. 72 | 73 | apt-get install memcached 74 | 75 | Don't forget to make it listen on needed addresses by editing /etc/memcached.conf, but be careful not to open memcached for the whole world. 76 | 77 | ## Run reviewboard 78 | 79 | This container has one volume mount-point: 80 | 81 | - `/var/www/` - The path where the reviewboard site resides, this includes it's ssh keys and uploaded media. 82 | 83 | The container accepts the following environment variables: 84 | 85 | - ```PGHOST``` - the postgres host. Defaults to the value of ```PG_PORT_5432_TCP_ADDR```, provided by the ```pg``` linked container. 86 | - ```PGPORT``` - the postgres port. Defaults to the value of ```PG_PORT_5432_TCP_PORT```, provided by the ```pg``` linked container, or 5432, if it's empty. 87 | - ```PGUSER``` - the postgres user. Defaults to ```reviewboard```. 88 | - ```PGDB``` - the postgres database. Defaults to ```reviewboard```. 89 | - ```PGPASSWORD``` - the postgres password. Defaults to ```reviewboard```. 90 | - ```MEMCACHED``` - memcache address in format ```host:port```. Defaults to the value from linked ```memcached``` container. 91 | - ```DOMAIN``` - defaults to ```localhost```. 92 | - ```DEBUG``` - if set, the django server will be launched in debug mode. 93 | - ```SITE_ROOT``` - the path of the site, relative to the domain. This should start and end with a ```/```. For example, ```/reviews/```. Defaults to ```/```. 94 | 95 | Also, uwsgi accepts environment prefixed with ```UWSGI_``` for it's configuration 96 | E.g. ```-e UWSGI_PROCESSES=10``` will create 10 reviewboard processes. 97 | 98 | ### Example. Run with dockerized postgres and memcached from above, expose on port 8000: 99 | 100 | docker run -it -v reviewboard-site:/var/www/ --link rb-postgres:pg --link memcached:memcached -p 8000:8000 ikatson/reviewboard 101 | 102 | ### Example. Run with postgres and memcached installed on the host machine. 103 | 104 | DOCKER_HOST_IP=$( ip addr | grep 'inet 172.1' | awk '{print $2}' | sed 's/\/.*//') 105 | 106 | docker run -it -v reviewboard-site:/var/www/ -p 8000:8080 -e PGHOST="$DOCKER_HOST_IP" -e PGPASSWORD=123 -e PGUSER=reviewboard -e MEMCACHED="$DOCKER_HOST_IP":11211 ikatson/reviewboard 107 | 108 | Now, go to the url, e.g. ```http://localhost:8000/```, login as ```admin:admin``` and change the password. The reviewboard is almost ready to use! 109 | 110 | ### Container SMTP settings. 111 | 112 | You should also change SMTP settings, so that the reviewboard can send emails. A good way to go is to set this to docker host's internal IP address, usually, ```172.17.42.1```). 113 | 114 | Don't forget to setup you mail agent to accept emails from docker. 115 | 116 | For example, if you use ```postfix```, you should change ```/etc/postfix/main.cf``` to contain something like the lines below: 117 | 118 | mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 172.17.0.0/16 119 | inet_interfaces = 127.0.0.1,172.17.42.1 120 | 121 | ## Upgrading 122 | 123 | Upgrading to a new ReviewBoard version is as simple as pulling and running the latest image (or use a specific tag). 124 | The upgrade will be detected at runtime and `rb-site upgrade` will be executed. See: https://www.reviewboard.org/docs/manual/dev/admin/upgrading/upgrading-sites 125 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | postgres: 4 | image: postgres:alpine 5 | environment: 6 | - POSTGRES_USER=reviewboard 7 | - POSTGRES_PASSWORD=reviewboard 8 | memcached: 9 | image: memcached:alpine 10 | reviewboard: 11 | build: ./ 12 | restart: always 13 | volumes: 14 | - /var/www/ 15 | depends_on: 16 | - postgres 17 | - memcached 18 | environment: 19 | - PGHOST=postgres 20 | - PGPASSWORD=reviewboard 21 | - MEMCACHED=memcached:11211 22 | - WAIT_FOR_POSTGRES=true 23 | ports: 24 | - 8000:8000 25 | -------------------------------------------------------------------------------- /shell.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd /var/www/reviewboard/conf 4 | 5 | export PYTHONPATH=./ 6 | export DJANGO_SETTINGS_MODULE=reviewboard.settings 7 | exec django-admin.py shell 8 | -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PGUSER="${PGUSER:-reviewboard}" 3 | PGPASSWORD="${PGPASSWORD:-reviewboard}" 4 | PGDB="${PGDB:-reviewboard}" 5 | 6 | # Get these variables either from PGPORT and PGHOST, or from 7 | # linked "pg" container. 8 | PGPORT="${PGPORT:-$( echo "${PG_PORT_5432_TCP_PORT:-5432}" )}" 9 | PGHOST="${PGHOST:-$( echo "${PG_PORT_5432_TCP_ADDR:-127.0.0.1}" )}" 10 | 11 | # Get these variable either from MEMCACHED env var, or from 12 | # linked "memcached" container. 13 | MEMCACHED_LINKED_NOTCP="${MEMCACHED_PORT#tcp://}" 14 | MEMCACHED="${MEMCACHED:-$( echo "${MEMCACHED_LINKED_NOTCP:-127.0.0.1}" )}" 15 | 16 | DOMAIN="${DOMAIN:localhost}" 17 | 18 | if [[ "${WAIT_FOR_POSTGRES}" = "true" ]]; then 19 | 20 | echo "Waiting for Postgres readiness..." 21 | export PGUSER PGHOST PGPORT PGPASSWORD 22 | 23 | until psql "${PGDB}"; do 24 | echo "Postgres is unavailable - sleeping" 25 | sleep 1 26 | done 27 | echo "Postgres is up!" 28 | 29 | fi 30 | 31 | if [[ "${SITE_ROOT}" ]]; then 32 | if [[ "${SITE_ROOT}" != "/" ]]; then 33 | # Add trailing and leading slashes to SITE_ROOT if it's not there. 34 | SITE_ROOT="${SITE_ROOT#/}" 35 | SITE_ROOT="/${SITE_ROOT%/}/" 36 | fi 37 | else 38 | SITE_ROOT=/ 39 | fi 40 | 41 | mkdir -p /var/www/ 42 | 43 | CONFFILE=/var/www/reviewboard/conf/settings_local.py 44 | 45 | if [[ ! -d /var/www/reviewboard ]]; then 46 | rb-site install --noinput \ 47 | --domain-name="$DOMAIN" \ 48 | --site-root="$SITE_ROOT" \ 49 | --static-url=static/ --media-url=media/ \ 50 | --db-type=postgresql \ 51 | --db-name="$PGDB" \ 52 | --db-host="$PGHOST" \ 53 | --db-user="$PGUSER" \ 54 | --db-pass="$PGPASSWORD" \ 55 | --cache-type=memcached --cache-info="$MEMCACHED" \ 56 | --web-server-type=lighttpd --web-server-port=8000 \ 57 | --admin-user=admin --admin-password=admin --admin-email=admin@example.com \ 58 | /var/www/reviewboard/ 59 | fi 60 | 61 | /upgrade-site.py /var/www/reviewboard/rb-version /var/www/reviewboard 62 | 63 | if [[ "${DEBUG}" ]]; then 64 | sed -i 's/DEBUG *= *False/DEBUG=True/' "$CONFFILE" 65 | cat "${CONFFILE}" 66 | fi 67 | 68 | export SITE_ROOT 69 | 70 | exec uwsgi --ini /uwsgi.ini 71 | -------------------------------------------------------------------------------- /upgrade-site.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import subprocess 5 | import semver 6 | import reviewboard 7 | 8 | 9 | def main(version_file, site_folder): 10 | running_version = reviewboard.get_version_string() 11 | 12 | try: 13 | with open(version_file) as f: 14 | previous_version = f.readline().strip() 15 | except IOError: 16 | previous_version = "0.0.0" 17 | 18 | if semver.compare(running_version, previous_version) == 1: 19 | print("ReviewBoard upgrade detected, performing rb-site upgrade") 20 | subprocess.check_call(["rb-site", "upgrade", site_folder]) 21 | with open(version_file, 'w') as f: 22 | f.write(running_version) 23 | 24 | 25 | if __name__ == "__main__": 26 | main(*sys.argv[1:]) 27 | -------------------------------------------------------------------------------- /uwsgi.ini: -------------------------------------------------------------------------------- 1 | [uwsgi] 2 | plugin=python,http 3 | home=/opt/venv/ 4 | die-on-term= 5 | env=DJANGO_SETTINGS_MODULE=reviewboard.settings 6 | pymodule-alias=settings_local=/var/www/reviewboard/conf/settings_local.py 7 | module = django.core.handlers.wsgi:WSGIHandler() 8 | master=true 9 | http=:8000 10 | static-map=$(SITE_ROOT)static=/var/www/reviewboard/htdocs/static 11 | static-map=$(SITE_ROOT)media=/var/www/reviewboard/htdocs/media 12 | static-map=$(SITE_ROOT)errordocs=/var/www/reviewboard/htdocs/errordocs 13 | static-safe=/opt/venv/lib/python2.7/site-packages/ 14 | enable-threads=true 15 | processes=%k 16 | buffer-size=8192 17 | --------------------------------------------------------------------------------