Merge branch 'develop'. Version 0.1.0

master
androiddrew 6 years ago
commit 306df93923

@ -18,14 +18,14 @@ To test the build locally on your laptop:
`docker run -it --name datasketch_cms -e DB_HOST="host.docker.internal" -p 8888:8000 androiddrew/datasketch:latest` `docker run -it --name datasketch_cms -e DB_HOST="host.docker.internal" -p 8888:8000 androiddrew/datasketch:latest`
If using the postgres.app on Mac OS you will need to update both the postgresql.conf and pg_hba.conf files If using the postgres.app on Mac OS you will need to update both the `postgresql.conf` and `pg_hba.conf` files
/Users/<user_name>/Library/Application Support/Postgres/var-10/postgresql.conf /Users/user_name/Library/Application Support/Postgres/var-10/postgresql.conf
``` ```
listen_addresses = '*' listen_addresses = '*'
``` ```
/Users/<user_name>/Library/Application Support/Postgres/var-10/pg_hba.conf /Users/user_name/Library/Application Support/Postgres/var-10/pg_hba.conf
``` ```
# TYPE DATABASE USER ADDRESS METHOD # TYPE DATABASE USER ADDRESS METHOD
@ -46,8 +46,14 @@ host datasketch datasketch host.docker.internal trust
## Trouble shooting ## Trouble shooting
You can run the following command to get the logs for a task, running or not. You can run the following commands to get the logs for a task, running or not.
``` ```
docker logs $(docker inspect --format "{{.Status.ContainerStatus.ContainerID}}" <task_id>) docker logs -f $(docker inspect --format "{{.Status.ContainerStatus.ContainerID}}" <task_id>)
```
or
```
docker service logs -f <service name or TaskID >
``` ```

@ -3,27 +3,45 @@ version: '3.6'
services: services:
cms: cms:
image: androiddrew/datasketch:latest image: androiddrew/datasketch:0.1.3
command: gunicorn cms.wsgi:application --bind 0.0.0.0:5000 --workers 3
deploy: deploy:
replicas: 1 replicas: 1
restart_policy: restart_policy:
condition: on-failure condition: on-failure
ports:
- 8000:8000
secrets: secrets:
- datasketch_key - datasketch_key
- pg_passwd_datasketch - pg_passwd_datasketch
environment: environment:
- DJANGO_SETTINGS_MODULE=cms.settings.production - DJANGO_SETTINGS_MODULE=cms.settings.production
- DB_HOST=db - DB_HOST=db
- DB_PORT=5432
- DB_USER=datasketch - DB_USER=datasketch
volumes: volumes:
- datasketch-media-vol:/code/media - datasketch-media-vol:/code/media
- datasketch-static-vol:/code/staticout
depends_on: depends_on:
- db - db
networks: networks:
- datasketch_net - datasketch_net
nginx:
image: androiddrew/datasketch_nginx:0.1.0
deploy:
replicas: 1
restart_policy:
condition: on-failure
ports:
- 8000:80
depends_on:
- cms
networks:
- datasketch_net
volumes:
- datasketch-media-vol:/var/www/datasketch/media
- datasketch-static-vol:/var/www/datasketch/static
db: db:
image: postgres:10.5-alpine image: postgres:10.5-alpine
deploy: deploy:
@ -62,6 +80,13 @@ volumes:
type: nfs type: nfs
o: addr=nas1.androiddrew.com,rw o: addr=nas1.androiddrew.com,rw
device: ":/volume1/expanse/datasketch_media" device: ":/volume1/expanse/datasketch_media"
datasketch-static-vol:
driver: local
driver_opts:
type: nfs
o: addr=nas1.androiddrew.com,rw
device: ":/volume1/expanse/datasketch_static"
secrets: secrets:
pg_passwd_datasketch: pg_passwd_datasketch:

@ -1,21 +1,38 @@
#FROM python:3.7-alpine
FROM python:3.7 FROM python:3.7
LABEL maintainer="drew@androiddrew.comw" LABEL maintainer="drew@androiddrew.comw"
# Set environmental variables
ENV PYTHONUNBUFFERED 1 ENV PYTHONUNBUFFERED 1
ENV DJANGO_ENV production ENV PYTHONDONTWRITEBYTECODE 1
# Set Working Directory
WORKDIR /code
# install psycopg2
#RUN apk update \
# && apk add --virtual build-deps gcc python3-dev musl-dev \
# && apk add postgresql-dev \
# && pip install psycopg2 \
# && apk del build-deps
# Install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt /code/requirements.txt COPY ./requirements.txt /code/requirements.txt
RUN pip install -r /code/requirements.txt RUN pip install -r /code/requirements.txt
RUN pip install gunicorn
# Copy entrypoint.sh
COPY ./entrypoint.sh /code/entrypoint.sh
# Copy code to image
COPY . /code/ COPY . /code/
WORKDIR /code/
RUN python manage.py collectstatic RUN useradd wagtail && chown -R wagtail /code
RUN apt update && apt -y install netcat
RUN useradd wagtail
RUN chown -R wagtail /code
USER wagtail USER wagtail
EXPOSE 8000 # run entrypoint.sh
CMD exec gunicorn cms.wsgi:application --bind 0.0.0.0:8000 --workers 3 ENTRYPOINT ["/code/entrypoint.sh"]

@ -2,17 +2,13 @@
This service is built using the [Wagtail](http://docs.wagtail.io/en/v2.3/) framework. This service is built using the [Wagtail](http://docs.wagtail.io/en/v2.3/) framework.
## Middleware
Since this application is being deployed to a Docker swarm it utilizes [Whitenoise](http://whitenoise.evans.io/en/stable/) and the Django specific whitenoise middleware to deliver static content. This solution is suitable for serving low traffic static content. To improve performance an Nginx reverse proxy could leverage HTTP caching or could be configured to serve all static content directly.
## Environmental Variables ## Environmental Variables
The follow environment variables must be set for development. Note that the DB_PASSWD for production must be a docker secret. The follow environment variables must be set for development. Note that the DB_PASSWD for production must be a docker secret.
``` ```
DB_HOST=<hostname for database> DB_HOST=<hostname for database>
DB_PASSWD=ec<Password for datasketch user> DB_PASSWD=<Password for datasketch user>
``` ```
In production you must set the `DJANGO_SETTINGS_MODULE` to the appropriate module: In production you must set the `DJANGO_SETTINGS_MODULE` to the appropriate module:
@ -21,6 +17,5 @@ In production you must set the `DJANGO_SETTINGS_MODULE` to the appropriate modul
DJANGO_SETTINGS_MODULE=cms.settings.production DJANGO_SETTINGS_MODULE=cms.settings.production
``` ```
## Migrations ## Migrations and collectstatic
Migrations and the collection of static content is managed through the `entrypoint.sh` script. On start up the cms container will check for the availability of the Postgres server, then run the migration and static file collection processes. The static files in production will be written to a persistent location on a NAS device. An Nginx service will mount that same static location and serve content.
The `manage.py` file is used to upgrade the backend database. You will need to log into the container on the appropriate host and execute the command `python manage.py migrate` manually.

@ -48,7 +48,6 @@ INSTALLED_APPS = [
] ]
MIDDLEWARE = [ MIDDLEWARE = [
"whitenoise.middleware.WhiteNoiseMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware", "django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware", "django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware", "django.middleware.csrf.CsrfViewMiddleware",
@ -134,7 +133,7 @@ STATICFILES_DIRS = [os.path.join(PROJECT_DIR, "static")]
# See https://docs.djangoproject.com/en/2.1/ref/contrib/staticfiles/#manifeststaticfilesstorage # See https://docs.djangoproject.com/en/2.1/ref/contrib/staticfiles/#manifeststaticfilesstorage
STATICFILES_STORAGE = "django.contrib.staticfiles.storage.ManifestStaticFilesStorage" STATICFILES_STORAGE = "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
STATIC_ROOT = os.path.join(BASE_DIR, "static") STATIC_ROOT = os.path.join(BASE_DIR, "staticout")
STATIC_URL = "/static/" STATIC_URL = "/static/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media") MEDIA_ROOT = os.path.join(BASE_DIR, "media")

@ -18,12 +18,15 @@ DATABASES = {
"USER": "datasketch", "USER": "datasketch",
"PASSWORD": PG_PASSWD, "PASSWORD": PG_PASSWD,
"HOST": os.environ.get("DB_HOST") if os.environ.get("DB_HOST") else "127.0.0.1", "HOST": os.environ.get("DB_HOST") if os.environ.get("DB_HOST") else "127.0.0.1",
"PORT": "5432", "PORT": os.environ.get("DB_PORT") if os.environ.get("DB_PORT") else "5432",
} }
} }
# Set as the volume map for media on the nas STATIC_ROOT = os.path.join(BASE_DIR, "staticout")
MEDIA_URL = "/code/media/" STATIC_URL = "/static/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"
LOGGING = { LOGGING = {
"version": 1, "version": 1,

@ -0,0 +1,17 @@
#!/bin/sh
echo "Waiting for PostgreSQL"
while ! nc -z $DB_HOST $DB_PORT; do
sleep 0.1
done
echo "PostgreSQL started"
python manage.py flush --no-input
python manage.py migrate
python manage.py collectstatic --no-input
echo "Migratation and static file collection Successful"
exec "$@"

@ -1,4 +1,4 @@
Django>=2.1,<2.2 Django>=2.1,<2.2
wagtail>=2.3,<2.4 wagtail>=2.3,<2.4
psycopg2>=2.7.5 psycopg2==2.7.5
whitenoise>=4.1 gunicorn==19.9.0

@ -0,0 +1,4 @@
FROM nginx:1.15.0-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY prod.conf /etc/nginx/conf.d

@ -0,0 +1,26 @@
upstream wagtail_app {
server cms:5000;
}
server {
listen 80;
location / {
proxy_pass http://wagtail_app;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
location /media/ {
alias /var/www/datasketch/media/;
}
location /static/ {
alias /var/www/datasketch/static/;
}
}
Loading…
Cancel
Save