diff --git a/.docker/destroy.sh b/.docker/destroy.sh new file mode 100755 index 0000000..3fe2b2b --- /dev/null +++ b/.docker/destroy.sh @@ -0,0 +1,34 @@ +#!/bin/bash +COMPONENTS=$* +if [ -z "$COMPONENTS" ]; then + echo "Usage: $0 [components]" + exit 1 +fi +for CMP in $COMPONENTS; do + if [ "$CMP" = "postgres" -o "$CMP" = "all" ]; then + echo "destroying postgres" + docker kill snipt-pg + docker rm snipt-pg + fi + if [ "$CMP" = "elasticsearch" -o "$CMP" = "all" ]; then + echo "destroying elasticsearch" + docker kill snipt-es + docker rm snipt-es + fi + + if [ "$CMP" = "app" -o "$CMP" = "all" ]; then + echo "destroying app" + docker kill snipt-app + docker rm snipt-app + fi + + if [ "$CMP" = "proxy" -o "$CMP" = "all" ]; then + echo "destroying proxy" + docker kill snipt-proxy + docker rm snipt-proxy + fi + if [ "$CMP" = "all" ]; then + docker kill snipt-net + docker rm snipt-net + fi +done diff --git a/.docker/nginx.conf b/.docker/nginx.conf new file mode 100644 index 0000000..fade215 --- /dev/null +++ b/.docker/nginx.conf @@ -0,0 +1,54 @@ +user nginx; +worker_processes 1; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + upstream backend_snipt { + server 127.0.0.1:8000; + } + server { + listen 80 default_server; + + access_log off; + error_log /var/log/nginx/snipt.log; + + location ~* /favicon.ico { + root /app/snipt/static/images/; + expires max; + } + + location / { + proxy_pass http://backend_snipt; + proxy_set_header Host $host; + } + + location /static/ { + alias /app/snipt/static/; + expires max; + } + } + +} diff --git a/.docker/run.sh b/.docker/run.sh new file mode 100755 index 0000000..3a704a1 --- /dev/null +++ b/.docker/run.sh @@ -0,0 +1,16 @@ +#!/bin/bash +APP_ROOT=/app +APP_DIR=$APP_ROOT/snipt +COOKIE_DOMAIN=${SESSION_COOKIE_DOMAIN:-.snipt.net} +SECRET_KEY=${SECRET_KEY:-changeme} +cp $APP_DIR/settings_local-template.py $APP_DIR/settings_local.py +# replace SESSION_COOKIE_DOMAIN +sed -i "s/^SESSION_COOKIE_DOMAIN.*/SESSION_COOKIE_DOMAIN = '$COOKIE_DOMAIN'/g" $APP_DIR/settings_local.py +sed -i "s/^SECRET_KEY.*/SECRET_KEY = '$SECRET_KEY'/g" $APP_DIR/settings_local.py +pushd $APP_DIR +python manage.py syncdb --noinput +python manage.py migrate --noinput +popd + +pushd $APP_DIR +python manage.py run_gunicorn -c $APP_DIR/gunicorn.conf.server.py diff --git a/.docker/start.sh b/.docker/start.sh new file mode 100755 index 0000000..85e977a --- /dev/null +++ b/.docker/start.sh @@ -0,0 +1,44 @@ +#!/bin/bash +COMPONENTS=$* +if [ -z "$COMPONENTS" ]; then + echo "Usage: $0 [components]" + exit 1 +fi + +for CMP in $COMPONENTS; do + if [ "$CMP" = "all" ]; then + # start net container + docker run -it -p 8000:80 --name snipt-net -d debian:jessie bash + sleep 1 + fi + if [ "$CMP" = "postgres" -o "$CMP" = "all" ]; then + echo "starting postgres" + docker run -it -d --name snipt-pg --net container:snipt-net postgres:9.1 + # wait for PG to start + sleep 5 + fi + + if [ "$CMP" = "elasticsearch" -o "$CMP" = "all" ]; then + echo "starting elasticsearch" + docker run -it -d --name snipt-es --net container:snipt-net arcus/elasticsearch + sleep 1 + fi + + if [ "$CMP" = "app" -o "$CMP" = "all" ]; then + echo "starting app" + # migrate + docker run -it --rm -e DB_USER=postgres -e DB_NAME=postgres --net container:snipt-net snipt/snipt python manage.py syncdb --noinput + docker run -it --rm -e DB_USER=postgres -e DB_NAME=postgres --net container:snipt-net snipt/snipt python manage.py migrate --noinput + # collect static + docker run -it --rm -v $(pwd)/static:/app/snipt/static --net container:snipt-net snipt/snipt python manage.py collectstatic --noinput + # run app + docker run -it --name snipt-app -d -e DB_USER=postgres -e DB_NAME=postgres -e DEBUG=false --net container:snipt-net snipt/snipt + sleep 1 + fi + + if [ "$CMP" = "proxy" -o "$CMP" = "all" ]; then + echo "starting proxy" + docker run -d --name snipt-proxy -it -v $(pwd)/.docker/nginx.conf:/etc/nginx/nginx.conf -v $(pwd)/static:/app/snipt/static --net container:snipt-net nginx nginx -g 'daemon off;' -c /etc/nginx/nginx.conf + fi + +done diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6fc3eb5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +FROM debian:jessie +ENV DEBIAN_FRONTEND noninteractive +RUN apt-get update && apt-get install -y \ + build-essential \ + python \ + python-dev \ + python-setuptools \ + git-core \ + mercurial \ + libxml2-dev \ + libxslt-dev \ + libpq-dev +RUN easy_install pip +COPY . /app/snipt +RUN pip install -r /app/snipt/requirements.txt +RUN pip install --index-url https://code.stripe.com --upgrade stripe +ADD .docker/run.sh /docker-run +RUN mkdir -p /tmp/app +WORKDIR /app/snipt +EXPOSE 8000 +CMD ["/docker-run"] diff --git a/fig.yml b/fig.yml new file mode 100644 index 0000000..635c3f7 --- /dev/null +++ b/fig.yml @@ -0,0 +1,32 @@ +postgres: + image: postgres:9.1 + expose: + - "5432" + +elasticsearch: + image: arcus/elasticsearch + expose: + - "9200" + - "9300" +app: + build: . + links: + - postgres:db + - elasticsearch:es + ports: + - "8000:80" + expose: + - "8000" + environment: + - DB_NAME=postgres + - DB_USER=postgres + +proxy: + image: nginx + ports: + - "80" + volumes: + - .docker/nginx.conf:/etc/nginx.conf + - static:/app/snipt/static + net: "container:snipt_app_1" + diff --git a/gunicorn.conf.server.py b/gunicorn.conf.server.py index 025deab..f48c9fb 100644 --- a/gunicorn.conf.server.py +++ b/gunicorn.conf.server.py @@ -1,4 +1,4 @@ -bind = "unix:/tmp/gunicorn.snipt.sock" +bind = "0.0.0.0:8000" daemon = False # Whether work in the background debug = False # Some extra logging logfile = ".gunicorn.log" # Name of the log file diff --git a/requirements.txt b/requirements.txt index 679ad17..296b197 100644 --- a/requirements.txt +++ b/requirements.txt @@ -24,6 +24,7 @@ psycopg2==2.5.1 py-bcrypt==0.4 pycrypto==2.6.1 pyelasticsearch==0.3 +elasticsearch==1.2.0 python-dateutil==2.2 python-memcached==1.53 python-mimeparse==0.1.4 diff --git a/settings.py b/settings.py index cd3831a..16b2fab 100644 --- a/settings.py +++ b/settings.py @@ -15,11 +15,11 @@ MANAGERS = ADMINS DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'snipt', - 'USER': '', - 'PASSWORD': '', - 'HOST': 'localhost', - 'PORT': '', + 'NAME': os.environ.get('DB_NAME', 'snipt'), + 'USER': os.environ.get('DB_USER', ''), + 'PASSWORD': os.environ.get('DB_PASS', ''), + 'HOST': os.environ.get('DB_PORT_5432_TCP_ADDR', 'localhost'), + 'PORT': os.environ.get('DB_PORT_5432_TCP_PORT', ''), } } diff --git a/settings_local-template.py b/settings_local-template.py index ba87a26..bab4930 100644 --- a/settings_local-template.py +++ b/settings_local-template.py @@ -2,6 +2,8 @@ import os from settings import INSTALLED_APPS, MIDDLEWARE_CLASSES DEBUG = True +if os.environ.get('DEBUG', '').lower() == 'false': + DEBUG = False TEMPLATE_DEBUG = DEBUG @@ -18,14 +20,15 @@ MANAGERS = ADMINS DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'snipt', - 'USER': '', - 'PASSWORD': '', - 'HOST': 'localhost', - 'PORT': '', + 'NAME': os.environ.get('DB_NAME', 'snipt'), + 'USER': os.environ.get('DB_USER', ''), + 'PASSWORD': os.environ.get('DB_PASS', ''), + 'HOST': os.environ.get('DB_PORT_5432_TCP_ADDR', 'localhost'), + 'PORT': os.environ.get('DB_PORT_5432_TCP_PORT', ''), } } + TIME_ZONE = 'America/New_York' LANGUAGE_CODE = 'en-us' @@ -34,7 +37,7 @@ MEDIA_ROOT = os.path.join(BASE_PATH, 'media/uploads') MEDIA_URL = '/media/uploads/' -STATIC_URL = '/media/' +STATIC_URL = '/static/' SECRET_KEY = '' @@ -58,10 +61,13 @@ CSRF_COOKIE_SECURE = False SESSION_COOKIE_DOMAIN = '.snipt.net' ALLOWED_HOSTS = ['*'] +ES_HOST = os.environ.get('ES_PORT_9200_TCP_ADDR', '127.0.0.1') +ES_PORT = os.environ.get('ES_PORT_9200_TCP_PORT', '9200') + HAYSTACK_CONNECTIONS = { 'default': { 'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine', - 'URL': 'http://127.0.0.1:9200/', + 'URL': 'http://{}:{}/'.format(ES_HOST, ES_PORT), 'INDEX_NAME': 'haystack', }, }