Skip to content

Commit b479bb3

Browse files
authored
Merge pull request #1530 from getredash/docker_workflow
Docker based developer workflow
2 parents 8b74de7 + 5ee5b5a commit b479bb3

28 files changed

+359
-202
lines changed

.dockerignore

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
client/.tmp/
2-
client/node_modules/
2+
node_modules/
3+
.tmp/
34
.git/
4-
.vagrant/

.gitignore

-3
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ venv
2020

2121
dump.rdb
2222

23-
# Docker related
24-
docker-compose.yml
25-
2623
node_modules
2724
.tmp
2825
.sass-cache

Dockerfile

+7-48
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,10 @@
1-
FROM ubuntu:trusty
1+
FROM redash/base:latest
22

3-
# Ubuntu packages
4-
RUN apt-get update && \
5-
apt-get install -y python-pip python-dev curl build-essential pwgen libffi-dev sudo git-core wget \
6-
# Postgres client
7-
libpq-dev \
8-
# Additional packages required for data sources:
9-
libssl-dev libmysqlclient-dev freetds-dev libsasl2-dev && \
10-
apt-get clean && \
11-
rm -rf /var/lib/apt/lists/*
3+
# We first copy only the requirements file, to avoid rebuilding on every file
4+
# change.
5+
COPY requirements.txt requirements_dev.txt requirements_all_ds.txt ./
6+
RUN pip install -r requirements.txt -r requirements_dev.txt -r requirements_all_ds.txt
127

13-
# Users creation
14-
RUN useradd --system --comment " " --create-home redash
8+
COPY . ./
159

16-
# Pip requirements for all data source types
17-
RUN pip install -U setuptools==23.1.0 && \
18-
pip install supervisor==3.1.2
19-
20-
COPY . /opt/redash/current
21-
RUN chown -R redash /opt/redash/current
22-
23-
# Setting working directory
24-
WORKDIR /opt/redash/current
25-
26-
# Install project specific dependencies
27-
RUN pip install -r requirements_all_ds.txt && \
28-
pip install -r requirements.txt
29-
30-
RUN curl https://deb.nodesource.com/setup_4.x | bash - && \
31-
apt-get install -y nodejs && \
32-
sudo -u redash -H make deps && \
33-
rm -rf node_modules client/node_modules /home/redash/.npm /home/redash/.cache && \
34-
apt-get purge -y nodejs && \
35-
apt-get clean && \
36-
rm -rf /var/lib/apt/lists/*
37-
38-
# Setup supervisord
39-
RUN mkdir -p /opt/redash/supervisord && \
40-
mkdir -p /opt/redash/logs && \
41-
cp /opt/redash/current/setup/docker/supervisord/supervisord.conf /opt/redash/supervisord/supervisord.conf
42-
43-
# Fix permissions
44-
RUN chown -R redash /opt/redash
45-
46-
# Expose ports
47-
EXPOSE 5000
48-
EXPOSE 9001
49-
50-
# Startup script
51-
CMD ["supervisord", "-c", "/opt/redash/supervisord/supervisord.conf"]
10+
ENTRYPOINT ["/app/bin/docker-entrypoint"]

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ deps:
1111

1212
pack:
1313
sed -ri "s/^__version__ = '([0-9.]*)'/__version__ = '$(FULL_VERSION)'/" redash/__init__.py
14-
tar -zcv -f $(FILENAME) --exclude="optipng*" --exclude=".git*" --exclude="*.pyc" --exclude="*.pyo" --exclude="venv" --exclude="node_modules" --exclude="client/app" *
14+
tar -zcv -f $(FILENAME) --exclude="optipng*" --exclude=".git*" --exclude="*.pyc" --exclude="*.pyo" --exclude="venv" --exclude="node_modules" *
1515

1616
upload:
1717
python bin/release_manager.py $(CIRCLE_SHA1) $(BASE_VERSION) $(FILENAME)

Procfile.dev

-2
This file was deleted.

Vagrantfile

-15
This file was deleted.

bin/docker-entrypoint

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/bin/bash
2+
set -e
3+
4+
worker() {
5+
WORKERS_COUNT=${WORKERS_COUNT:-2}
6+
QUEUES=${QUEUES:-queries,scheduled_queries,celery}
7+
8+
echo "Starting $WORKERS_COUNT workers for queues: $QUEUES..."
9+
exec sudo -E -u redash /usr/local/bin/celery worker --app=redash.worker -c$WORKERS_COUNT -Q$QUEUES -linfo --maxtasksperchild=10 -Ofair
10+
}
11+
12+
scheduler() {
13+
WORKERS_COUNT=${WORKERS_COUNT:-1}
14+
QUEUES=${QUEUES:-celery}
15+
16+
echo "Starting scheduler and $WORKERS_COUNT workers for queues: $QUEUES..."
17+
18+
exec sudo -E -u redash /usr/local/bin/celery worker --app=redash.worker --beat -c$WORKERS_COUNT -Q$QUEUES -linfo --maxtasksperchild=10 -Ofair
19+
}
20+
21+
server() {
22+
exec sudo -E -u redash /usr/local/bin/gunicorn -b 0.0.0.0:5000 --name redash -w4 redash:app
23+
}
24+
25+
help() {
26+
echo "Redash Docker."
27+
echo ""
28+
echo "Usage:"
29+
echo ""
30+
31+
echo "server -- start Redash server (with gunicorn)"
32+
echo "worker -- start Celery worker"
33+
echo "scheduler -- start Celery worker with a beat (scheduler) process"
34+
echo ""
35+
echo "shell -- open shell"
36+
echo "dev_server -- start Flask development server with debugger and auto reload"
37+
echo "create_db -- create database tables"
38+
}
39+
40+
tests() {
41+
export REDASH_DATABASE_URL="postgresql://postgres@postgres/tests"
42+
exec sudo -E -u redash make test
43+
}
44+
45+
case "$1" in
46+
worker)
47+
shift
48+
worker
49+
;;
50+
server)
51+
shift
52+
server
53+
;;
54+
scheduler)
55+
shift
56+
scheduler
57+
;;
58+
dev_server)
59+
exec sudo -E -u redash /app/manage.py runserver --debugger --reload -h 0.0.0.0
60+
;;
61+
shell)
62+
exec sudo -E -u redash /app/manage.py shell
63+
;;
64+
create_db)
65+
exec sudo -E -u redash /app/manage.py database create_tables
66+
;;
67+
tests)
68+
tests
69+
;;
70+
*)
71+
help
72+
;;
73+
esac

bin/vagrant_ctl.sh

-21
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.menu-search {
2+
margin-top: 3px;
3+
}
4+
5+
.menu-search input[type="text"] {
6+
height: 30px;
7+
}

client/app/components/app-header/app-header.html

+4-2
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@
3737
</li>
3838
</ul>
3939
<form class="navbar-form navbar-left" role="search" ng-submit="$ctrl.searchQueries()">
40-
<div class="form-group">
40+
<div class="input-group menu-search">
4141
<input type="text" ng-model="$ctrl.term" class="form-control" placeholder="Search queries...">
42+
<span class="input-group-btn">
43+
<button type="submit" class="btn btn-default"><span class="zmdi zmdi-search"></span></button>
44+
</span>
4245
</div>
43-
<button type="submit" class="btn btn-default"><span class="zmdi zmdi-search"></span></button>
4446
</form>
4547
<ul class="nav navbar-nav navbar-right">
4648
<li ng-show="$ctrl.currentUser.isAdmin">

client/app/components/app-header/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import debug from 'debug';
22

33
import template from './app-header.html';
44
import logoUrl from '../../assets/images/redash_icon_small.png';
5+
import './app-header.css';
56

67
const logger = debug('redash:appHeader');
78

client/app/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ ngModule.config(($routeProvider, $locationProvider, $compileProvider,
107107
});
108108

109109
// Update ui-select's template to use Font-Awesome instead of glyphicon.
110-
ngModule.run(($templateCache) => {
110+
ngModule.run(($templateCache, OfflineListener) => { // eslint-disable-line no-unused-vars
111111
const templateName = 'bootstrap/match.tpl.html';
112112
let template = $templateCache.get(templateName);
113113
template = template.replace('glyphicon glyphicon-remove', 'fa fa-remove');

client/app/services/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ export { default as DataSource } from './data-source';
1212
export { default as QuerySnippet } from './query-snippet';
1313
export { default as Notifications } from './notifications';
1414
export { default as KeyboardShortcuts } from './keyboard-shortcuts';
15+
export { default as OfflineListener } from './offline-listener';
1516
export { default as AlertDialog } from './alert-dialog';
1617
export { default as Auth } from './auth';
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
function OfflineListener(toastr) {
2+
function addOnlineListener(toast) {
3+
function onlineStateHandler() {
4+
toastr.remove(toast.toastId);
5+
window.removeEventListener('online', onlineStateHandler);
6+
}
7+
window.addEventListener('online', onlineStateHandler);
8+
}
9+
10+
window.addEventListener('offline', () => {
11+
const toast = toastr.warning('<div>Please check your Internet connection.</div>', '', {
12+
allowHtml: true,
13+
autoDismiss: false,
14+
timeOut: false,
15+
tapToDismiss: true,
16+
});
17+
addOnlineListener(toast);
18+
});
19+
}
20+
21+
export default function (ngModule) {
22+
ngModule.service('OfflineListener', OfflineListener);
23+
}

docker-compose-example.yml

-24
This file was deleted.

docker-compose.production.yml

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# This is an example configuration for Docker Compose. Make sure to atleast update
2+
# the cookie secret & postgres database password.
3+
#
4+
# Some other recommendations:
5+
# 1. To persist Postgres data, assign it a volume host location.
6+
# 2. Split the worker service to adhoc workers and scheduled queries workers.
7+
version: '2'
8+
services:
9+
server:
10+
build: .
11+
command: server
12+
depends_on:
13+
- postgres
14+
- redis
15+
ports:
16+
- "5000:5000"
17+
environment:
18+
PYTHONUNBUFFERED: 0
19+
REDASH_LOG_LEVEL: "INFO"
20+
REDASH_REDIS_URL: "redis://redis:6379/0"
21+
REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
22+
REDASH_COOKIE_SECRET: veryverysecret
23+
worker:
24+
build: .
25+
command: scheduler
26+
environment:
27+
PYTHONUNBUFFERED: 0
28+
REDASH_LOG_LEVEL: "INFO"
29+
REDASH_REDIS_URL: "redis://redis:6379/0"
30+
REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
31+
QUEUES: "queries,scheduled_queries,celery"
32+
WORKERS_COUNT: 2
33+
redis:
34+
image: redis:2.8
35+
postgres:
36+
image: postgres:9.3
37+
# volumes:
38+
# - /opt/postgres-data:/var/lib/postgresql/data
39+
nginx:
40+
image: redash/nginx:latest
41+
ports:
42+
- "80:80"
43+
depends_on:
44+
- server

docker-compose.yml

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# This configuration file is for **development** setup. For production, refer to
2+
# docker-compose.production.yml.
3+
version: '2'
4+
services:
5+
server:
6+
build: .
7+
command: dev_server
8+
depends_on:
9+
- postgres
10+
- redis
11+
ports:
12+
- "5000:5000"
13+
volumes:
14+
- ".:/app"
15+
environment:
16+
PYTHONUNBUFFERED: 0
17+
REDASH_LOG_LEVEL: "INFO"
18+
REDASH_REDIS_URL: "redis://redis:6379/0"
19+
REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
20+
worker:
21+
build: .
22+
command: scheduler
23+
volumes_from:
24+
- server
25+
depends_on:
26+
- server
27+
environment:
28+
PYTHONUNBUFFERED: 0
29+
REDASH_LOG_LEVEL: "INFO"
30+
REDASH_REDIS_URL: "redis://redis:6379/0"
31+
REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
32+
QUEUES: "queries,scheduled_queries,celery"
33+
WORKERS_COUNT: 2
34+
redis:
35+
image: redis:2.8
36+
postgres:
37+
image: postgres:9.3
38+
# The following turns the DB into less durable, but gains significant performance improvements for the tests run (x3
39+
# improvement on my personal machine). We should consider moving this into a dedicated Docker Compose configuration for
40+
# tests.
41+
command: "postgres -c fsync=off -c full_page_writes=off -c synchronous_commit=OFF"

redash/__init__.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@ def setup_logging():
2525
handler.setFormatter(formatter)
2626
logging.getLogger().addHandler(handler)
2727
logging.getLogger().setLevel(settings.LOG_LEVEL)
28-
logging.getLogger("passlib").setLevel("ERROR")
28+
29+
# Make noisy libraries less noisy
30+
if settings.LOG_LEVEL != "DEBUG":
31+
logging.getLogger("passlib").setLevel("ERROR")
32+
logging.getLogger("requests.packages.urllib3").setLevel("ERROR")
33+
logging.getLogger("snowflake.connector").setLevel("ERROR")
2934

3035

3136
def create_redis_connection():

0 commit comments

Comments
 (0)