Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #45 docker #46

Open
wants to merge 22 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
REQUIREMENTS=requirements.txt

ALLOWED_CANVAS_DOMAINS = example.edu
API_URL=http://example.edu/api/v1/
API_KEY=changeme
SECRET_KEY=changeme
LTI_TOOL_ID=changeme
DB_URI=mysql://qe_user:qe_pass@db/quizextensions
GOOGLE_ANALYTICS=GA-00000
REDIS_URL=redis://redis:6379
CONSUMER_KEY=key
SHARED_SECRET=secret

MYSQL_ROOT_PASSWORD=root
MYSQL_DATABASE=quizextensions
MYSQL_USER=qe_user
MYSQL_PASSWORD=qe_pass
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
.coverage
.DS_Store
.python-version
config.py
/venv*
/env*
/htmlcov
/logs
.env
14 changes: 14 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM tiangolo/uwsgi-nginx-flask:python3.7
ARG REQUIREMENTS
RUN apt-get update && apt-get install -y ca-certificates
RUN apt-get update && apt-get -y install libffi-dev gcc python3-dev libffi-dev libssl-dev libxml2-dev libxmlsec1-dev libxmlsec1-openssl
RUN pip install --upgrade pip
WORKDIR /app
COPY requirements.txt /app/
COPY devops/nginx.conf /app/
COPY devops/uwsgi.ini /app/

COPY $REQUIREMENTS /app/
RUN echo $REQUIREMENTS
RUN pip install -r $REQUIREMENTS
COPY . /app/
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,53 @@ all quizzes at once.

# Installation

## Docker

## Development

First you will need to clone the repo, and create the environment file from the template.


```sh
git clone [email protected]:ucfopen/quiz-extensions.git
cd quiz-extensions
cp .env.template .env

```
You will then want to edit the .env environment variabels file to match your Canvas domain, api url, and api key.

After Docker builds and starts the services, you will run the migration commands to create the database.

```sh
docker-compose build
docker-compose up -d
ssilverm marked this conversation as resolved.
Show resolved Hide resolved
docker-compose exec lti bash
python
from views import db, app
with app.app_context():
db.create_all()
ssilverm marked this conversation as resolved.
Show resolved Hide resolved
```

Quiz Extensions will now be available at: http://127.0.0.1:9001 and the XML available at http://127.0.0.1:9001/lti.xml

## Production

In a production setting, we expect that there is an external Redis server running as well as a DB server available for Quiz Extensions.

Once you have edited the .env file, you will want to run `docker-compose -f docker-compose.production.yml up -d` to bring up the services.

If you have not created your database yet, you can do so with these commands:

```sh
docker-compose exec lti bash
python
from views import db, app
with app.app_context():
db.create_all()

```


## Development Installation

```sh
Expand Down
26 changes: 9 additions & 17 deletions config.py.template → config.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import os

# Canvas API URL (e.g. 'http://example.com/api/v1/')
API_URL = "http://example.com/api/v1/"
API_URL = os.environ.get("API_URL")
# Canvas API Key
API_KEY = "CHANGEME"
API_KEY = os.environ.get("API_KEY")

# A list of domains that are allowed to use the tool.
# (e.g. ['example.com', 'example.edu'])
ALLOWED_CANVAS_DOMAINS = ["example.edu"]
ALLOWED_CANVAS_DOMAINS = [os.environ.get("ALLOWED_CANVAS_DOMAINS")]

# The default number of objects the Canvas API will return per page (usually 10)
DEFAULT_PER_PAGE = 10
Expand All @@ -16,18 +16,18 @@

# A secret key used by Flask for signing. KEEP THIS SECRET!
# (e.g. 'Ro0ibrkb4Z4bZmz1f5g1+/16K19GH/pa')
SECRET_KEY = "CHANGEME"
SECRET_KEY = os.environ.get("SECRET_KEY")

LTI_TOOL_ID = "CHANGEME" # A unique ID for the tool
LTI_TOOL_ID = os.environ.get("LTI_TOOL_ID") # A unique ID for the tool

# URI for database. (e.g. 'mysql://root:root@localhost/quiz_extensions')
SQLALCHEMY_DATABASE_URI = ""
SQLALCHEMY_DATABASE_URI = os.environ.get("DB_URI")
SQLALCHEMY_TRACK_MODIFICATIONS = False

GOOGLE_ANALYTICS = "" # The Google Analytics ID to use.
GOOGLE_ANALYTICS = os.environ.get("GOOGLE_ANALYTICS") # The Google Analytics ID to use.

# URL for the redis server (e.g. 'redis://localhost:6379')
REDIS_URL = "redis://localhost:6379"
REDIS_URL = os.environ.get("REDIS_URL")

LOGGING_CONFIG = {
"version": 1,
Expand All @@ -44,17 +44,9 @@
"formatter": "standard",
"class": "logging.StreamHandler",
},
"file": {
"level": "INFO",
"formatter": "standard",
"class": "logging.handlers.RotatingFileHandler",
"filename": "logs/quiz_ext.log",
"maxBytes": 1024 * 1024 * 5, # 5 MB
"backupCount": 5,
},
ssilverm marked this conversation as resolved.
Show resolved Hide resolved
},
"loggers": {
"app": {"handlers": ["console", "file"], "level": "DEBUG", "propagate": True}
"app": {"handlers": ["console"], "level": "DEBUG", "propagate": True}
},
}

Expand Down
43 changes: 43 additions & 0 deletions devops/nginx.conf
Original file line number Diff line number Diff line change
@@ -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;
#include /etc/nginx/conf.d/*.conf;
ssilverm marked this conversation as resolved.
Show resolved Hide resolved

server {
listen 80;
location / {
try_files $uri @app;
}

location @app {
include uwsgi_params;
uwsgi_pass unix:///tmp/uwsgi.sock;
uwsgi_param SCRIPT_NAME /;
uwsgi_modifier1 30;
uwsgi_read_timeout 300;
uwsgi_connect_timeout 300;
uwsgi_send_timeout 300;
proxy_redirect off;

}

location /static {
alias /app/static;
}
}

}
daemon off;
5 changes: 5 additions & 0 deletions devops/uwsgi.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[uwsgi]
module = views
callable = app
route-run = fixpathinfo:
buffer-size=32768%
48 changes: 48 additions & 0 deletions docker-compose.production.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
version: '3.1'

services:
lti:
build:
context: .
args:
- "REQUIREMENTS=${REQUIREMENTS}"
volumes:
- .:/app
- $PWD/devops/nginx.conf:/app/nginx.conf
- $PWD/devops/uwsgi.ini:/app/uwsgi.ini
ports:
- "80:80"
env_file:
- .env
environment:
- MODULE_NAME=app

worker:
build:
context: .
args:
- "REQUIREMENTS=${REQUIREMENTS}"
volumes:
- .:/app
command: rq worker -c config quizext
env_file:
- .env


# db:
# image: mariadb
# volumes:
# - quizext_db_data:/var/lib/mysql
# restart: always
# env_file: .env
# ports:
# - 3306:3306

# redis:
# image: redis
# restart: always
# ports:
# - 6379:6379

# volumes:
# quizext_db_data: {}
ssilverm marked this conversation as resolved.
Show resolved Hide resolved
54 changes: 54 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
version: '3.1'

services:
lti:
build:
context: .
args:
- "REQUIREMENTS=${REQUIREMENTS}"
volumes:
- .:/app
- $PWD/devops/nginx.conf:/app/nginx.conf
- $PWD/devops/uwsgi.ini:/app/uwsgi.ini
depends_on:
- db
- redis
ports:
- "9001:80"
env_file:
- .env
environment:
- MODULE_NAME=app

worker:
build:
context: .
args:
- "REQUIREMENTS=${REQUIREMENTS}"
volumes:
- .:/app
command: rq worker -c config quizext
depends_on:
- db
- redis
env_file:
- .env


db:
image: mariadb
volumes:
- quizext_db_data:/var/lib/mysql
restart: always
env_file: .env
ports:
- 3306:3306

redis:
image: redis
restart: always
ports:
- 6379:6379

volumes:
quizext_db_data: {}