There will be a short maintenance break on Wed 27.10. at 12:00. Estimated time 30 minutes.

Commit 1f7357b8 authored by Ossi Laine's avatar Ossi Laine
Browse files

Dockerized app

parent c433a793
......@@ -19,3 +19,7 @@ config.py
.vscode/
documentation
/deploy/.env.dev
/deploy/dbdata/*
/deploy/log/nginx/access.log
/deploy/log/nginx/error.log
FROM python:3.7-slim
WORKDIR /srv/app
COPY requirements.txt /srv/app
RUN apt-get update && \
apt-get install -y \
build-essential \
make \
gcc \
pkg-config
#ython3-matplotlib
RUN pip install --upgrade pip -r requirements.txt
COPY app/. /srv/app/app
COPY run.py /srv/app
COPY config.py /srv/app
COPY messages.pot /srv/app
RUN mkdir logs
[mysqld]
explicit_defaults_for_timestamp = 1
\ No newline at end of file
/*
SQL initialization script
Run: mysql -u rating -p -D rating_db < create_rating_db.sql
This will create user 'admin' with password 'password'.
*/
CREATE DATABASE IF NOT EXISTS rating_db;
USE rating_db;
GRANT ALL PRIVILEGES ON rating_db.* TO 'rating'@'%' WITH GRANT OPTION;
/* Drop all tables (cascade removes foreign keys also) */
DROP TABLE IF EXISTS background_question_answer;
DROP TABLE IF EXISTS background_question_option;
DROP TABLE IF EXISTS background_question;
DROP TABLE IF EXISTS forced_id;
DROP TABLE IF EXISTS user;
DROP TABLE IF EXISTS trial_randomization;
DROP TABLE IF EXISTS embody_answer;
DROP TABLE IF EXISTS embody_question;
DROP TABLE IF EXISTS answer;
DROP TABLE IF EXISTS answer_set;
DROP TABLE IF EXISTS question;
DROP TABLE IF EXISTS page;
DROP TABLE IF EXISTS experiment;
/* Experiment set */
CREATE TABLE experiment (
idexperiment INTEGER NOT NULL AUTO_INCREMENT,
name VARCHAR(120),
instruction TEXT,
directoryname VARCHAR(120),
language VARCHAR(120),
status VARCHAR(120),
randomization VARCHAR(120),
short_instruction TEXT,
single_sentence_instruction TEXT,
is_archived VARCHAR(120),
creator_name VARCHAR(120),
research_notification_filename VARCHAR(120),
creation_time DATETIME,
stimulus_size VARCHAR(120),
consent_text TEXT,
use_forced_id VARCHAR(120),
PRIMARY KEY (idexperiment)
);
/* Answer set holds session information about users experiment */
CREATE TABLE answer_set (
idanswer_set INTEGER NOT NULL AUTO_INCREMENT,
experiment_idexperiment INTEGER,
session VARCHAR(120),
agreement VARCHAR(120),
answer_counter INTEGER,
registration_time DATETIME,
last_answer_time DATETIME,
PRIMARY KEY (idanswer_set),
FOREIGN KEY(experiment_idexperiment) REFERENCES experiment (idexperiment)
);
/* Background questions are asked before the experiment begins */
CREATE TABLE background_question (
idbackground_question INTEGER NOT NULL AUTO_INCREMENT,
background_question VARCHAR(120),
experiment_idexperiment INTEGER,
PRIMARY KEY (idbackground_question)
);
CREATE TABLE background_question_option (
idbackground_question_option INTEGER NOT NULL AUTO_INCREMENT,
background_question_idbackground_question INTEGER,
`option` VARCHAR(120),
PRIMARY KEY (idbackground_question_option),
FOREIGN KEY(background_question_idbackground_question) REFERENCES background_question (idbackground_question)
);
CREATE TABLE background_question_answer (
idbackground_question_answer INTEGER NOT NULL AUTO_INCREMENT,
answer_set_idanswer_set INTEGER,
answer VARCHAR(120),
background_question_idbackground_question INTEGER,
PRIMARY KEY (idbackground_question_answer),
FOREIGN KEY(answer_set_idanswer_set) REFERENCES answer_set (idanswer_set),
FOREIGN KEY(background_question_idbackground_question) REFERENCES background_question (idbackground_question)
);
/* Randomize experiment page order */
CREATE TABLE trial_randomization (
idtrial_randomization INTEGER NOT NULL AUTO_INCREMENT,
page_idpage INTEGER,
randomized_idpage INTEGER,
answer_set_idanswer_set INTEGER,
experiment_idexperiment INTEGER,
PRIMARY KEY (idtrial_randomization)
);
CREATE TABLE user (
id INTEGER NOT NULL AUTO_INCREMENT,
username VARCHAR(64),
email VARCHAR(120),
password_hash VARCHAR(128),
PRIMARY KEY (id)
);
/* By using forced ID login subjects can only participate to a rating task by logging in with a pregenerated ID */
CREATE TABLE forced_id (
idforced_id INTEGER NOT NULL AUTO_INCREMENT,
experiment_idexperiment INTEGER,
pregenerated_id VARCHAR(120),
PRIMARY KEY (idforced_id),
FOREIGN KEY(experiment_idexperiment) REFERENCES experiment (idexperiment)
);
/* Information about stimulus type and content on a page */
CREATE TABLE page (
idpage INTEGER NOT NULL AUTO_INCREMENT,
experiment_idexperiment INTEGER,
type VARCHAR(120),
text VARCHAR(120),
media VARCHAR(120),
PRIMARY KEY (idpage),
FOREIGN KEY(experiment_idexperiment) REFERENCES experiment (idexperiment)
);
/* Slider question */
CREATE TABLE question (
idquestion INTEGER NOT NULL AUTO_INCREMENT,
experiment_idexperiment INTEGER,
question VARCHAR(120),
`left` VARCHAR(120),
`right` VARCHAR(120),
PRIMARY KEY (idquestion),
FOREIGN KEY(experiment_idexperiment) REFERENCES experiment (idexperiment)
);
/* Slider answer */
CREATE TABLE answer (
idanswer INTEGER NOT NULL AUTO_INCREMENT,
question_idquestion INTEGER,
answer_set_idanswer_set INTEGER,
answer VARCHAR(120),
page_idpage INTEGER,
PRIMARY KEY (idanswer),
FOREIGN KEY(answer_set_idanswer_set) REFERENCES answer_set (idanswer_set),
FOREIGN KEY(page_idpage) REFERENCES page (idpage),
FOREIGN KEY(question_idquestion) REFERENCES question (idquestion)
);
/* Create indexes for faster operations */
CREATE INDEX ix_experiment_consent_text ON experiment (consent_text(255));
CREATE INDEX ix_experiment_creation_time ON experiment (creation_time);
CREATE UNIQUE INDEX ix_experiment_directoryname ON experiment (directoryname);
CREATE INDEX ix_experiment_instruction ON experiment (instruction(255));
CREATE INDEX ix_experiment_name ON experiment (name);
CREATE INDEX ix_experiment_short_instruction ON experiment (short_instruction(255));
CREATE INDEX ix_experiment_single_sentence_instruction ON experiment (single_sentence_instruction(255));
CREATE UNIQUE INDEX ix_user_email ON user (email);
CREATE UNIQUE INDEX ix_user_username ON user (username);
CREATE INDEX ix_answer_set_last_answer_time ON answer_set (last_answer_time);
CREATE INDEX ix_answer_set_registration_time ON answer_set (registration_time);
CREATE INDEX ix_page_media ON page (media);
CREATE INDEX ix_page_text ON page (text);
CREATE INDEX ix_page_type ON page (type);
/* New fields for updating embody tool to onni.utu.fi */
/* Embody picture/question information */
CREATE TABLE embody_question (
idembody INTEGER NOT NULL AUTO_INCREMENT,
experiment_idexperiment INTEGER,
picture TEXT,
question TEXT,
PRIMARY KEY (idembody),
FOREIGN KEY(experiment_idexperiment) REFERENCES experiment (idexperiment)
);
/* Embody answer (coordinates). Answer is saved as a json object:
{x:[1,2,100,..], y:[3,4,101,..], r:[13,13,8,...]} */
CREATE TABLE embody_answer (
idanswer INTEGER NOT NULL AUTO_INCREMENT,
answer_set_idanswer_set INTEGER,
page_idpage INTEGER,
embody_question_idembody INTEGER DEFAULT 0,
coordinates TEXT,
PRIMARY KEY (idanswer),
FOREIGN KEY(answer_set_idanswer_set) REFERENCES answer_set (idanswer_set),
FOREIGN KEY(page_idpage) REFERENCES page (idpage) ,
FOREIGN KEY(embody_question_idembody) REFERENCES embody_question (idembody)
);
/* Set flag if embody tool is enabled -> this is not the most modular solution, but works for now */
ALTER TABLE experiment ADD COLUMN (embody_enabled BOOLEAN DEFAULT 0);
/* Set current answer type (embody/slider/etc..) so returning users are routed to correct question */
ALTER TABLE answer_set ADD COLUMN (answer_type VARCHAR(120));
INSERT INTO user VALUES(1,'admin',NULL,'pbkdf2:sha256:50000$6Cc6Mjmo$3fe413a88db1bacfc4d617f7c1547bd1ea4cbd6c5d675a58e78332201f6befc6');
/* eyelabs */
INSERT INTO user VALUES(2,'eyelabs',NULL,'pbkdf2:sha256:50000$sdBu3Rjm$7ab97c6d2686460b85a2a20517b7012c15ffb341ba3fef5b0f17ed8354fc38d9');
CREATE TABLE research_group (
id INTEGER NOT NULL AUTO_INCREMENT,
name TEXT,
tag TEXT,
description TEXT,
PRIMARY KEY (id)
);
INSERT INTO research_group(id, name, tag, description) VALUES(1, 'Human Emotion Systems', 'emotion', 'Welcome to the Human Emotion Systems -laboratory`s Onni-net laboratory! The experiments that are currently underway are listed below - you can participate for as many experiments you want.');
INSERT INTO research_group(id, name, tag, description) VALUES(2, 'Turku Eye-tracking', 'eyelabs', 'Welcome to the Turku Eyelabs -laboratory`s Onni-net laboratory! The experiments that are currently underway are listed below - you can participate for as many experiments you want.');
CREATE TABLE user_in_group (
idgroup INTEGER,
iduser INTEGER,
role TEXT,
FOREIGN KEY(idgroup) REFERENCES research_group (id),
FOREIGN KEY(iduser) REFERENCES user (id)
);
INSERT INTO user_in_group VALUES (1,1, 'admin');
INSERT INTO user_in_group VALUES (2,1, 'admin');
ALTER TABLE experiment ADD COLUMN (group_id INTEGER), ADD FOREIGN KEY(group_id) REFERENCES research_group(id);
upstream flask_app {
server gunicorn:8000 fail_timeout=5s max_fails=5;
}
server {
# NON-SSL
listen 80;
# SSL
#listen 443 ssl http2;
#listen [::]:443 ssl http2;
#ssl_certificate "/etc/nginx/tls/onni.utu.fi-rsa+chain.pem";
#ssl_certificate_key "/etc/nginx/tls/private/onni.utu.fi-rsa.key";
#ssl_protocols TLSv1.2;
#ssl_session_cache shared:SSL:1m;
#ssl_session_timeout 10m;
#ssl_ciphers HIGH:!aNULL:!MD5;
#ssl_prefer_server_ciphers on;
#server_name _;
client_max_body_size 0;
location / {
proxy_pass http://flask_app;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_read_timeout 30s;
}
location /create_embody {
#location /socket.io {
proxy_pass http://flask_app/socket.io;
proxy_http_version 1.1;
proxy_redirect off;
proxy_buffering off;
proxy_connect_timeout 1d;
proxy_send_timeout 1d;
proxy_read_timeout 1d;
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 Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
version: "3.3"
services:
nginx:
#image: nginx:latest
build: ./nginx
restart: always
ports:
- "80:80"
#- "443:443"
volumes:
#- ./tls:/etc/nginx/tls
#- ./config/nginx/rating.conf:/etc/nginx/conf.d/rating.conf
- ./log/nginx:/var/log/nginx
depends_on:
- gunicorn
gunicorn:
image: rating_app:latest
restart: always
ports:
- 8000:8000
env_file:
- ./.env.dev
depends_on:
- db
command: sh -c "gunicorn run:app -b 0.0.0.0:8000 -k gevent --worker-connections=1000 --workers=1 --log-level debug -t 180"
#volumes: FOR DEV
#- ./application:/srv/app
db:
image: mysql
ports:
- "3200:3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: rating_db
MYSQL_USER: rating
MYSQL_PASSWORD: rating_passwd
volumes:
- ./config/mysql/rating.cnf:/etc/mysql/conf.d/rating.cnf
- ./config/mysql/schema.sql:/docker-entrypoint-initdb.d/1.sql
- ./dbdata:/var/lib/mysql
FROM nginx:1.19.0-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d
\ No newline at end of file
upstream flask_app {
server gunicorn:8000 fail_timeout=5s max_fails=5;
}
server {
# NON-SSL
listen 80;
# SSL
#listen 443 ssl http2;
#listen [::]:443 ssl http2;
#ssl_certificate "/etc/nginx/tls/onni.utu.fi-rsa+chain.pem";
#ssl_certificate_key "/etc/nginx/tls/private/onni.utu.fi-rsa.key";
#ssl_protocols TLSv1.2;
#ssl_session_cache shared:SSL:1m;
#ssl_session_timeout 10m;
#ssl_ciphers HIGH:!aNULL:!MD5;
#ssl_prefer_server_ciphers on;
#server_name _;
client_max_body_size 0;
location / {
proxy_pass http://flask_app;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_read_timeout 30s;
}
location /create_embody {
#location /socket.io {
proxy_pass http://flask_app/socket.io;
proxy_http_version 1.1;
proxy_redirect off;
proxy_buffering off;
proxy_connect_timeout 1d;
proxy_send_timeout 1d;
proxy_read_timeout 1d;
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 Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
......@@ -31,3 +31,4 @@ uuid==1.30
Werkzeug==0.14.1
WTForms==2.2.1
WTForms-SQLAlchemy==0.1
cryptography
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment