diff --git a/backend/Dockerfile b/backend/Dockerfile index 4ede12b..99f27b6 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -12,15 +12,28 @@ RUN set -ex \ && apk add --no-cache --virtual .build-deps \ gcc \ musl-dev \ + linux-headers \ postgresql-dev \ python3-dev \ && apk add --no-cache \ libpq \ - && pip install -r /requirements.txt \ + && pip install --no-cache-dir uwsgi==2.0.19.1 \ + && pip install --no-cache-dir -r /requirements.txt \ && rm -rf requirements.txt \ && apk del .build-deps COPY . /code -CMD sh /code/entrypoint.sh +ARG APP_USER=app +RUN addgroup -S ${APP_USER} && adduser -S ${APP_USER} -G ${APP_USER} + +EXPOSE 8000 +ENV DJANGO_SETTINGS_MODULE=backend.settings +ENV UWSGI_WSGI_FILE=backend/wsgi.py +ENV UWSGI_HTTP=:8000 UWSGI_MASTER=1 UWSGI_HTTP_AUTO_CHUNKED=1 UWSGI_HTTP_KEEPALIVE=1 UWSGI_LAZY_APPS=1 UWSGI_WSGI_ENV_BEHAVIOR=holy +ENV UWSGI_WORKERS=2 UWSGI_THREADS=4 +ENV UWSGI_STATIC_MAP="/static/=/code/static/" UWSGI_STATIC_EXPIRES_URI="/static/.*\.[a-f0-9]{12,}\.(css|js|png|jpg|jpeg|gif|ico|woff|ttf|otf|svg|scss|map|txt) 315360000" + +USER ${APP_USER}:${APP_USER} +ENTRYPOINT ["sh", "/code/prod-entrypoint.sh"] diff --git a/backend/Dockerfile.dev b/backend/Dockerfile.dev new file mode 100644 index 0000000..4ede12b --- /dev/null +++ b/backend/Dockerfile.dev @@ -0,0 +1,26 @@ +FROM python:3.9.1-alpine3.13 + +MAINTAINER "Ameya Shenoy " + +ENV PYTHONUNBUFFERED=1 + +WORKDIR /code + +COPY requirements.txt / + +RUN set -ex \ + && apk add --no-cache --virtual .build-deps \ + gcc \ + musl-dev \ + postgresql-dev \ + python3-dev \ + && apk add --no-cache \ + libpq \ + && pip install -r /requirements.txt \ + && rm -rf requirements.txt \ + && apk del .build-deps + +COPY . /code + +CMD sh /code/entrypoint.sh + diff --git a/backend/app/utils.py b/backend/app/utils.py index c3b7b49..4ab87a7 100644 --- a/backend/app/utils.py +++ b/backend/app/utils.py @@ -41,9 +41,8 @@ def fetch_bhav_copy_equity_data(curr_date=None): with ZipFile(BytesIO(resp.content)) as bhavcopy_zf: csv_file = bhavcopy_zf.namelist()[0] with bhavcopy_zf.open(csv_file, 'r') as infile: - data = list(csv.reader(TextIOWrapper(infile, 'utf-8'))) # TODO: potentially remove list + data = list(csv.reader(TextIOWrapper(infile, 'utf-8'))) return data - # schedule again in 5 minutes return None @@ -96,8 +95,8 @@ def populate_bhav_copy_data(): tdcloindi=stock[13], ) except: - # potential code for alerting if needed goes here - # Repeat job after 10 mins if fails at 6 pm + # Potentially add code for alerting if needed + # Repeat job after 10 mins if job fails scheduler = django_rq.get_scheduler('default') scheduler.schedule( scheduled_time=datetime.datetime.now()+datetime.timedelta(minutes=10), diff --git a/backend/app/views.py b/backend/app/views.py index ad7ae7d..823c97e 100644 --- a/backend/app/views.py +++ b/backend/app/views.py @@ -42,6 +42,7 @@ class EmptyRespoinseView(generics.RetrieveAPIView): class BhavCopyEquityCustomRedisView(generics.RetrieveAPIView): def get(self, request, *args, **kwargs): + # TODO: try stringified json pipe = cache.pipeline() stocks = cache.lrange("stocks", 0, -1) if len(stocks) == 0: diff --git a/backend/backend/settings.py b/backend/backend/settings.py index 79f9759..3452b2f 100644 --- a/backend/backend/settings.py +++ b/backend/backend/settings.py @@ -22,13 +22,14 @@ BASE_DIR = Path(__file__).resolve().parent.parent # TODO: remove this key # SECURITY WARNING: keep the secret key used in production secret! -# SECRET_KEY = 'eo$1gb^g#gx25$b$(9hp#i^av^t0e8ge#kjcr$g(=yimc#j1-l' SECRET_KEY = os.environ.get('SECRET_KEY') # SECURITY WARNING: don't run with debug turned on in production! DEBUG = bool(os.environ.get('DEBUG')) -ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS').split(',') +ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS') +if ALLOWED_HOSTS: + ALLOWED_HOSTS = ALLOWED_HOSTS.split(',') # Application definition @@ -143,7 +144,9 @@ USE_L10N = True USE_TZ = True # TODO: fix hardcoded cross allowed origins -CORS_ALLOWED_ORIGINS = os.environ.get('CORS_ALLOWED_ORIGINS').split(',') +CORS_ALLOWED_ORIGINS = os.environ.get('CORS_ALLOWED_ORIGINS') +if CORS_ALLOWED_ORIGINS: + CORS_ALLOWED_ORIGINS = CORS_ALLOWED_ORIGINS.split(',') RQ_QUEUES = { 'default': { diff --git a/backend/prod-entrypoint.sh b/backend/prod-entrypoint.sh new file mode 100644 index 0000000..4bf6624 --- /dev/null +++ b/backend/prod-entrypoint.sh @@ -0,0 +1,11 @@ +#!/bin/sh + + +# Apply database migrations +echo "Apply database migrations" +python manage.py migrate collectstatic --noinput + +# Start server +echo "Starting server" +uwsgi --show-config + diff --git a/docker-compose.yml b/docker-compose.yml index ff7aaa5..410325c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,9 +4,10 @@ version: '3.8' services: backend: - image: codingcoffee/bullish-backend + image: codingcoffee/bullish-backend-dev build: context: ./backend + dockerfile: Dockerfile.dev volumes: - ./backend:/code env_file: @@ -20,9 +21,10 @@ services: - 8000:8000 frontend: - image: codingcoffee/bullish-frontend + image: codingcoffee/bullish-frontend-dev build: context: ./frontend + dockerfile: Dockerfile.dev volumes: - ./frontend:/code ports: @@ -34,9 +36,10 @@ services: # - 6379:6379 rqworker: - image: codingcoffee/bullish-backend + image: codingcoffee/bullish-backend-dev build: context: ./backend + dockerfile: Dockerfile.dev env_file: - dev.env volumes: @@ -46,9 +49,10 @@ services: - redis rqscheduler: - image: codingcoffee/bullish-backend + image: codingcoffee/bullish-backend-dev build: context: ./backend + dockerfile: Dockerfile.dev env_file: - dev.env volumes: @@ -62,7 +66,6 @@ services: restart: unless-stopped volumes: - bullish-db-data:/var/lib/postgresql/data/pgdata - # TODO: remove pass env_file: - dev.env # ports: diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 0000000..e0a57b2 --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1,2 @@ +**/node_modules +**/dist diff --git a/frontend/.vuerc b/frontend/.vuerc new file mode 100644 index 0000000..31c91b7 --- /dev/null +++ b/frontend/.vuerc @@ -0,0 +1,4 @@ +{ + "packageManager": "npm", + "useTaobaoRegistry": false +} diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 27afb42..04a6a6d 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,11 +1,19 @@ -FROM node:15.8.0-alpine3.10 +FROM node:15.8.0-alpine3.10 as builder MAINTAINER "Ameya Shenoy " WORKDIR /code +COPY package.json package-lock.json /code/ +COPY .vuerc /root/ RUN set -ex \ - npm i -g npm \ - npm i + && npm i -g npm@7.5.3 @vue/cli \ + && npm i + +COPY src /code/src +RUN NODE_ENV=production npm run build + +FROM nginx:1.19.6-alpine +COPY --from=builder /code/dist/ /usr/share/nginx/html +COPY nginx.conf /etc/nginx/nginx.conf -ENTRYPOINT sh /code/entrypoint.sh diff --git a/frontend/Dockerfile.dev b/frontend/Dockerfile.dev new file mode 100644 index 0000000..07652b0 --- /dev/null +++ b/frontend/Dockerfile.dev @@ -0,0 +1,12 @@ +FROM node:15.8.0-alpine3.10 + +MAINTAINER "Ameya Shenoy " + +WORKDIR /code + +RUN set -ex \ + && npm i -g npm \ + && npm i + +ENTRYPOINT sh /code/entrypoint.sh + diff --git a/frontend/nginx.conf b/frontend/nginx.conf new file mode 100644 index 0000000..6f35c0e --- /dev/null +++ b/frontend/nginx.conf @@ -0,0 +1,43 @@ + +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; + keepalive_timeout 65; + + server { + listen 80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html; + try_files $uri $uri/ /index.html; + } + + error_page 500 502 503 504 /50x.html; + + location = /50x.html { + root /usr/share/nginx/html; + } + + } +} + diff --git a/prod-build.sh b/prod-build.sh new file mode 100755 index 0000000..3edca6c --- /dev/null +++ b/prod-build.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +cd "$DIR/backend" +docker build -t codingcoffee/bullish-backend . + +cd "$DIR/frontend" +docker build -t codingcoffee/bullish-frontend . +