[#8028] use virtualenv in docker, and more:

* use a helper script to run commands after shared volumes are all up and running
* move npm stuff into helper script, so web's command is not overriden and has no extra delay at that point
* refactor a 'base' container in docker-compose.yml to share the environment & volume settings
diff --git a/Allura/docs/getting_started/installation.rst b/Allura/docs/getting_started/installation.rst
index e180ac3..ce7014b 100644
--- a/Allura/docs/getting_started/installation.rst
+++ b/Allura/docs/getting_started/installation.rst
@@ -256,17 +256,11 @@
 
     docker-compose build
 
-Install requirements (and first containers started):
+Python and JS package setup (and first containers started):
 
 .. code-block:: bash
 
-    docker-compose run web pip install -r requirements.txt
-
-Install Allura packages:
-
-.. code-block:: bash
-
-    docker-compose run web ./rebuild-all.bash
+    docker-compose run web scripts/init-docker-dev.sh
 
 Initialize database with test data:
 
diff --git a/Dockerfile b/Dockerfile
index f91dd98..82860f6 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -36,7 +36,7 @@
 RUN curl --silent --location https://deb.nodesource.com/setup_4.x | sudo bash - && \
     apt-get install --yes nodejs
 
-# only do the global installation here.  All local packages are installed in the docker-compose.yml command, since they need the shared mount
+# only do the global installation here.  All local packages are installed in init-docker-dev.sh, since they need the shared mount
 RUN npm install -g broccoli-cli
 
 # Snapshot generation for SVN (and maybe other SCMs) might fail without this
diff --git a/docker-compose.yml b/docker-compose.yml
index 5eaaf4c..770bf63 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -17,29 +17,14 @@
 
 web:
   build: .
-  # specialized command to run broccoli
-  # since it depends on files from the shared volume, it can't be run as part of the Dockerfile build :(
-  # and --no-bin-links necessary when Virtualbox is used since shared mount can't handle symlinks
-  command: >
-    sh -c '
-    if [ ! -e Allura/allura/public/nf/js/build/transpiled.js ]; then
-      npm install --no-bin-links --loglevel http &&
-      npm run build;
-    fi;
-    gunicorn --paste Allura/docker-dev.ini --reload;
-    '
+  environment: &env
+    # PATH=/allura-data/virtualenv/bin:$PATH doesn't work; see https://github.com/docker/compose/issues/650
+    - PATH=/allura-data/virtualenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
   ports:
     - "8080:8080"
   volumes:
-    - .:/allura
-    # mount env to allow update and sharing with taskd container
-    - /allura-data/env-docker/python:/usr/local/lib/python2.7
-    - /allura-data/env-docker/bin:/usr/local/bin
-    # mounting it separatelly to create git, svn, hg directories automatically
-    - /allura-data/scm/git:/allura-data/scm/git
-    - /allura-data/scm/hg:/allura-data/scm/hg
-    - /allura-data/scm/svn:/allura-data/scm/svn
-    - /allura-data/scm/snapshots:/allura-data/scm/snapshots
+    - .:/allura  # Allura source code from local host
+    - /allura-data:/allura-data  # for virtualenv, scm repos, etc
   links:
     - mongo
     - solr
@@ -48,6 +33,7 @@
 taskd:
   image: allura_web
   working_dir: /allura/Allura
+  environment: *env
   command: paster taskd docker-dev.ini
   volumes_from:
     - web
@@ -82,6 +68,7 @@
 inmail:
   image: allura_web
   working_dir: /allura/Allura
+  environment: *env
   command: paster smtp_server docker-dev.ini
   volumes_from:
     - web
diff --git a/scripts/init-docker-dev.sh b/scripts/init-docker-dev.sh
new file mode 100755
index 0000000..2353419
--- /dev/null
+++ b/scripts/init-docker-dev.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+#       Licensed to the Apache Software Foundation (ASF) under one
+#       or more contributor license agreements.  See the NOTICE file
+#       distributed with this work for additional information
+#       regarding copyright ownership.  The ASF licenses this file
+#       to you under the Apache License, Version 2.0 (the
+#       "License"); you may not use this file except in compliance
+#       with the License.  You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#       Unless required by applicable law or agreed to in writing,
+#       software distributed under the License is distributed on an
+#       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#       KIND, either express or implied.  See the License for the
+#       specific language governing permissions and limitations
+#       under the License.
+
+
+# Various commands needed to set up the Docker environment, but that use shared volumes, so can't be run as part of a Dockerfile image
+
+set -e  # exit if any command fails
+
+echo -e "\nRunning scripts/init-docker-dev.sh\n"
+
+echo -e "Creating SCM directories\n"
+mkdir -p /allura-data/scm/{git,hg,svn,snapshots}
+
+# share venv to allow update and sharing across containers
+if [ ! -e /allura-data/virtualenv ]; then
+    echo -e "Creating virtualenv\n"
+    pip install virtualenv
+    virtualenv /allura-data/virtualenv
+    ln -s /usr/lib/python2.7/dist-packages/pysvn /allura-data/virtualenv/lib/python2.7/site-packages/
+    echo # just a new line
+fi
+source /allura-data/virtualenv/bin/activate
+
+echo -e "Installing python packages\n"
+pip install -q -r requirements.txt
+
+/allura/rebuild-all.bash
+echo
+
+if [ ! -e /allura/Allura/allura/public/nf/js/build/transpiled.js ]; then
+  echo -e "Installing npm packages"
+  # --no-bin-links is necessary when Virtualbox is used since shared mount can't handle symlinks
+  npm install --no-bin-links  # if we want more progress displayed:  --loglevel http
+
+  echo -e "\nCompiling JS"
+  npm run build
+fi
+
+echo "Done"
\ No newline at end of file