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 all 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
142 changes: 142 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
.git
Dockerfile
.DS_Store
.gitignore
.dockerignore

/credentials
/cache
/store

/node_modules

# https://github.com/github/gitignore/blob/master/Global/macOS.gitignore

# General
*.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon


# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

# https://raw.githubusercontent.com/github/gitignore/master/Python.gitignore

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
18 changes: 18 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# For production switch to requirements.txt
REQUIREMENTS=test_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
22 changes: 13 additions & 9 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.7, 3.8, 3.9]
python-version: [3.8, 3.9]

steps:
- uses: actions/checkout@v2
Expand All @@ -26,10 +26,9 @@ jobs:
python -m pip install --upgrade pip
pip install -r test_requirements.txt
pip list
- name: Create config and log files
- name: Create env file
run: |
cp config.py.template config.py
mkdir logs; touch logs/quiz_ext.log
cp .env.template .env
- name: Lint with flake8
run: flake8
- name: Check formatting
Expand All @@ -39,8 +38,13 @@ jobs:
- name: Lint markdown files
uses: bewuethr/mdl-action@v1
- name: Run tests
run: coverage run -m unittest discover
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
fail_ci_if_error: true
run: |
docker compose run lti coverage run -m unittest discover
docker compose run lti coverage xml
- name: list files
run: |
ls -lah
# - name: Upload coverage to Codecov
# uses: codecov/codecov-action@v2
# with:
# fail_ci_if_error: true
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
.coverage
.DS_Store
.python-version
config.py
/venv*
/env*
/htmlcov
/logs
.env
dump.rdb

# ignore docker's copies of these files
nginx.conf
uwsgi.ini
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## [Unreleased]

- Dockerize the application
- Update the README to include instructions for running the application in a Docker container

## [5.0.0] - 2021-10-31

### General
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,4 @@ tags: branches: branches:
v0.0.3 ◄── dev/v0.0.3 ◄── issue/123-fix-broken-links + issue/211
v0.0.2 ◄── dev/v0.0.2 ◄── issue/251-rename-all-the-files + issue/222 + issue/12221
v0.0.1 ◄── dev/v0.0.1 ◄── issue/121-get-logins-working-again
```
```
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.8
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/
52 changes: 50 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,55 @@ all quizzes at once.

# Installation

## Development Installation
## Docker

## Development

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

```sh
git clone git@github.com:ucfopen/quiz-extensions.git
cd quiz-extensions
cp .env.template .env

```

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

Quiz Extensions uses Docker Compose to build and start the services:

```sh
docker compose build
docker compose up -d
```

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

```sh
docker compose exec lti flask db upgrade
```

Quiz Extensions will now be available via SSL at:

<https://127.0.0.1:9002> and the XML available at <http://127.0.0.1:9002/lti.xml>

or via standard HTTP 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 flask db upgrade
```

## Development Installation (Deprecated)

```sh
git clone git@github.com:ucfopen/quiz-extensions.git
Expand Down Expand Up @@ -112,7 +160,7 @@ Ensure RQ Worker is running. If not, start it with
rq worker quizext
```

## Production Installation
## Production Installation (Deprecated)

This is for an Ubuntu 16.xx install but should work for other Debian/ubuntu
based installs using Apache and mod_wsgi.
Expand Down
28 changes: 9 additions & 19 deletions config.py.template → config.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
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 maximum amount of objects the Canvas API will return per page (usually 100)
MAX_PER_PAGE = 100

# 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 @@ -42,18 +42,8 @@
"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}
},
"loggers": {"app": {"handlers": ["console"], "level": "DEBUG", "propagate": True}},
}

TESTING_API_URL = "example.edu" # Used only to run tests
Expand Down
Loading
Loading