Skip to content

Commit

Permalink
Fix #130: Add docker based setup for Fabrik (#344)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ram81 authored and deshraj committed May 2, 2018
1 parent f5a69bb commit b2e461d
Show file tree
Hide file tree
Showing 16 changed files with 376 additions and 65 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ env/
# Django stuff:
*.log
*.sqlite3
settings/dev.py

# Sphinx documentation
docs/build/
Expand Down
34 changes: 29 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,26 @@ Fabrik is an online collaborative platform to build, visualize and train deep le

This app is presently under active development and we welcome contributions. Please check out our [issues thread](https://github.com/Cloud-CV/IDE/issues) to find things to work on, or ping us on [Gitter](https://gitter.im/Cloud-CV/IDE).

### How to setup

## Installation Instructions

Setting up Fabrik on your local machine is really easy. You can setup Fabrik using two methods:

### Using Docker

1. Get the source code on to your machine via git.

```shell
git clone https://github.com/Cloud-CV/Fabrik.git && cd Fabrik
```

2. Build and run the Docker containers. This might take a while. You should be able to access Fabrik at `0.0.0.0:8000`.

```
docker-compose up --build
```

### Using Virtual Environment
1. First set up a virtualenv
```
sudo apt-get install python-pip python-dev python-virtualenv
Expand All @@ -22,8 +41,13 @@ This app is presently under active development and we welcome contributions. Ple
```
git clone --recursive https://github.com/Cloud-CV/Fabrik.git
```

3. Rename settings/dev.sample.py as settings/dev.py and change credential in settings/dev.py
```
cp settings/dev.sample.py settings/dev.py
```

3. If you have Caffe, Keras and Tensorflow already installed on your computer, skip this step
4. If you have Caffe, Keras and Tensorflow already installed on your computer, skip this step
* For Linux users
```
cd Fabrik/requirements
Expand All @@ -42,7 +66,7 @@ This app is presently under active development and we welcome contributions. Ple
* [Install Caffe](http://caffe.berkeleyvision.org/install_osx.html)
* [Install Tensorflow](https://www.tensorflow.org/install/install_mac)
* [Install Keras](https://keras.io/#installation)
4. Install dependencies
5. Install dependencies
* For developers:
```
pip install -r requirements/dev.txt
Expand All @@ -51,7 +75,7 @@ This app is presently under active development and we welcome contributions. Ple
```
pip install -r requirements/common.txt
```
5. [Install postgres >= 9.5](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-16-04)
6. [Install postgres >= 9.5](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-16-04)
* Setup postgres database
* Start postgresql by typing ```sudo service postgresql start```
* Now login as user postgres by running ```sudo -u postgres psql``` and type the commands below
Expand All @@ -71,7 +95,7 @@ This app is presently under active development and we welcome contributions. Ple
python manage.py makemigrations caffe_app
python manage.py migrate
```
6. Install node modules
7. Install node modules
```
npm install
sudo npm install -g webpack
Expand Down
49 changes: 49 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
version: '2'

services:
db:
hostname: db
image: postgres
ports:
- "5432:5432"
networks:
- fabrik

reactjs:
container_name: reactjs
hostname: reactjs
build:
context: ./
dockerfile: docker/dev/reactjs/Dockerfile
environment:
NODE_ENV: development
volumes:
- .:/code
- /code/node_modules
networks:
- fabrik

django:
restart: always
container_name: django
hostname: django
env_file:
- docker/dev.env
links:
- reactjs
build:
context: ./
dockerfile: docker/dev/django/Dockerfile
ports:
- "8000:8000"
command: ["./docker/wait-for-it.sh", "db:5432", "--", "sh", "/code/docker/dev/django/container-start.sh"]
depends_on:
- db
- reactjs
volumes:
- .:/code
networks:
- fabrik

networks:
fabrik:
9 changes: 9 additions & 0 deletions docker/dev.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
DEBUG=True

POSTGRES_NAME=postgres
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_HOST=db
POSTGRES_PORT=5432

DJANGO_SERVER=django
54 changes: 54 additions & 0 deletions docker/dev/django/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
FROM ubuntu:16.04
MAINTAINER CloudCV Team

RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
cmake \
git \
wget \
libatlas-base-dev \
libboost-all-dev \
libgflags-dev \
libgoogle-glog-dev \
libhdf5-serial-dev \
libleveldb-dev \
liblmdb-dev \
libopencv-dev \
libprotobuf-dev \
libsnappy-dev \
protobuf-compiler \
python-dev \
python-numpy \
python-pip \
python-setuptools \
python-scipy && \
rm -rf /var/lib/apt/lists/*

ENV CAFFE_ROOT=$HOME/caffe

WORKDIR $CAFFE_ROOT

ENV CLONE_TAG=1.0

RUN pip install --upgrade pip

RUN git clone -b ${CLONE_TAG} --depth 1 https://github.com/BVLC/caffe.git . && \
cd python && for req in $(cat requirements.txt) pydot; do pip install $req; done && cd .. && \
mkdir build && cd build && \
cmake -DCPU_ONLY=1 .. && \
make -j"$(nproc)"

ENV PYCAFFE_ROOT $CAFFE_ROOT/python
ENV PYTHONPATH $PYCAFFE_ROOT:$PYTHONPATH
ENV PATH $CAFFE_ROOT/build/tools:$PYCAFFE_ROOT:$PATH
RUN echo "$CAFFE_ROOT/build/lib" >> /etc/ld.so.conf.d/caffe.conf && ldconfig

WORKDIR /code

ADD . /code

COPY settings/dev.sample.py settings/dev.py

RUN pip install -r requirements/dev.txt

EXPOSE 8000
4 changes: 4 additions & 0 deletions docker/dev/django/container-start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
cd /code && \
python manage.py migrate --noinput && \
KERAS_BACKEND=theano python manage.py runserver 0.0.0.0:8000
2 changes: 2 additions & 0 deletions docker/dev/reactjs/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
npm-debug.log
29 changes: 29 additions & 0 deletions docker/dev/reactjs/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FROM ubuntu:16.04

MAINTAINER CloudCV Team

RUN apt-get update -qq && apt-get install -y build-essential git curl libfontconfig

RUN apt-get install nodejs-legacy -y

RUN apt-get install npm -y

RUN apt-get install -y ruby-dev

RUN gem install sass -v 3.2.19

WORKDIR /code

ADD . /code

RUN npm link gulp

RUN npm cache clean -f
RUN npm install -g n
RUN n stable

RUN npm install

RUN npm install -g [email protected]

CMD ["webpack", "--progress", "--watch", "--colors"]
161 changes: 161 additions & 0 deletions docker/wait-for-it.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#!/usr/bin/env bash
# Use this script to test if a given TCP host/port are available

cmdname=$(basename $0)

echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }

usage()
{
cat << USAGE >&2
Usage:
$cmdname host:port [-s] [-t timeout] [-- command args]
-h HOST | --host=HOST Host or IP under test
-p PORT | --port=PORT TCP port under test
Alternatively, you specify the host and port as host:port
-s | --strict Only execute subcommand if the test succeeds
-q | --quiet Don't output any status messages
-t TIMEOUT | --timeout=TIMEOUT
Timeout in seconds, zero for no timeout
-- COMMAND ARGS Execute command with args after the test finishes
USAGE
exit 1
}

wait_for()
{
if [[ $TIMEOUT -gt 0 ]]; then
echoerr "$cmdname: waiting $TIMEOUT seconds for $HOST:$PORT"
else
echoerr "$cmdname: waiting for $HOST:$PORT without a timeout"
fi
start_ts=$(date +%s)
while :
do
(echo > /dev/tcp/$HOST/$PORT) >/dev/null 2>&1
result=$?
if [[ $result -eq 0 ]]; then
end_ts=$(date +%s)
echoerr "$cmdname: $HOST:$PORT is available after $((end_ts - start_ts)) seconds"
break
fi
sleep 1
done
return $result
}

wait_for_wrapper()
{
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
if [[ $QUIET -eq 1 ]]; then
timeout $TIMEOUT $0 --quiet --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &
else
timeout $TIMEOUT $0 --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &
fi
PID=$!
trap "kill -INT -$PID" INT
wait $PID
RESULT=$?
if [[ $RESULT -ne 0 ]]; then
echoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $HOST:$PORT"
fi
return $RESULT
}

# process arguments
while [[ $# -gt 0 ]]
do
case "$1" in
*:* )
hostport=(${1//:/ })
HOST=${hostport[0]}
PORT=${hostport[1]}
shift 1
;;
--child)
CHILD=1
shift 1
;;
-q | --quiet)
QUIET=1
shift 1
;;
-s | --strict)
STRICT=1
shift 1
;;
-h)
HOST="$2"
if [[ $HOST == "" ]]; then break; fi
shift 2
;;
--host=*)
HOST="${1#*=}"
shift 1
;;
-p)
PORT="$2"
if [[ $PORT == "" ]]; then break; fi
shift 2
;;
--port=*)
PORT="${1#*=}"
shift 1
;;
-t)
TIMEOUT="$2"
if [[ $TIMEOUT == "" ]]; then break; fi
shift 2
;;
--timeout=*)
TIMEOUT="${1#*=}"
shift 1
;;
--)
shift
CLI="$@"
break
;;
--help)
usage
;;
*)
echoerr "Unknown argument: $1"
usage
;;
esac
done

if [[ "$HOST" == "" || "$PORT" == "" ]]; then
echoerr "Error: you need to provide a host and port to test."
usage
fi

TIMEOUT=${TIMEOUT:-15}
STRICT=${STRICT:-0}
CHILD=${CHILD:-0}
QUIET=${QUIET:-0}

if [[ $CHILD -gt 0 ]]; then
wait_for
RESULT=$?
exit $RESULT
else
if [[ $TIMEOUT -gt 0 ]]; then
wait_for_wrapper
RESULT=$?
else
wait_for
RESULT=$?
fi
fi

if [[ $CLI != "" ]]; then
if [[ $RESULT -ne 0 && $STRICT -eq 1 ]]; then
echoerr "$cmdname: strict mode, refusing to execute subprocess"
exit $RESULT
fi
exec $CLI
else
exit $RESULT
fi
Loading

0 comments on commit b2e461d

Please sign in to comment.