Mejorado el deploy por docker

Ahora se usan archivos .env para la configuracion en vez del archivo en
la instancia

Tambien se paso a usar docker-compose para tambien crear la base de
datos

Se tienen volumenes separados para la carpeta de uploads y para la base
de datos

Cambie los comandos para que sea solo uno poble la base de datos con
todo lo que implica

Se paso a mysql tambien
This commit is contained in:
Daniel Cortes
2019-03-14 00:40:42 -03:00
parent db27dff960
commit 02d27c3868
10 changed files with 84 additions and 74 deletions

3
.gitignore vendored
View File

@@ -1,4 +1,3 @@
# Created by https://www.gitignore.io/api/flask
# Edit at https://www.gitignore.io/?templates=flask
@@ -127,3 +126,5 @@ dmypy.json
# End of https://www.gitignore.io/api/flask
uploads/
db.env
web.env

View File

@@ -1,13 +1,13 @@
FROM python:alpine
RUN mkdir /app
COPY . /app
COPY requirements.txt gunicorn.conf run.py /app/
COPY files/ /app/files
ENV FLASK_APP=files
WORKDIR /app
RUN apk add mariadb-connector-c-dev gcc musl-dev
RUN pip install --no-cache-dir -r requirements.txt
RUN apk del gcc musl-dev
EXPOSE 8080
EXPOSE 5000
ENV GUNICORN_WORKERS 2
ENV GUNICORN_BIND 0.0.0.0:8080
CMD ["gunicorn", "--config", "gunicorn.conf", "run:app"]

2
db.env.example Normal file
View File

@@ -0,0 +1,2 @@
MYSQL_ROOT_PASSWORD=secret
MYSQL_DATABASE=db

22
docker-compose.yml Normal file
View File

@@ -0,0 +1,22 @@
version: '3'
services:
web:
build: .
ports:
- "8080:8080"
volumes:
- uploads:/app/uploads
depends_on:
- db
env_file:
- web.env
db:
image: mariadb
volumes:
- dbdata:/var/lib/mysql
env_file:
- db.env
volumes:
dbdata:
uploads:

View File

@@ -6,18 +6,15 @@ from werkzeug.wsgi import SharedDataMiddleware
def create_app():
app = Flask(__name__, instance_relative_config=True)
app.config.from_mapping(
SQLALCHEMY_DATABASE_URI="sqlite:///{}".format(
os.path.join(app.instance_path, 'files.sqlite')),
SQLALCHEMY_TRACK_MODIFICATIONS=False,
USERNAME='dev',
PASSWORD='secret',
SECRET_KEY='1337',
UPLOAD_FOLDER='uploads'
SQLALCHEMY_DATABASE_URI=os.environ.get("SQLALCHEMY_DATABASE_URI"),
SQLALCHEMY_TRACK_MODIFICATIONS=os.environ.get("SQLALCHEMY_TRACK_MODIFICATIONS"),
USERNAME=os.environ.get("USERNAME"),
PASSWORD=os.environ.get("PASSWORD"),
SECRET_KEY=os.environ.get("SECRET_KEY"),
UPLOAD_FOLDER=os.environ.get("UPLOAD_FOLDER")
)
app.config.from_pyfile('config.py')
app.wsgi_app = SharedDataMiddleware(
app.wsgi_app, {'/uploads': app.config['UPLOAD_FOLDER']})

View File

@@ -8,30 +8,33 @@ from werkzeug.security import generate_password_hash
from files.models import db, User, Category, File, FileType
def init_db():
db.drop_all()
db.create_all()
def generate_admin():
username = current_app.config['USERNAME']
password = current_app.config['PASSWORD']
user = User(username, generate_password_hash(password))
db.session.add(user)
db.session.commit()
if User.query.filter_by(username=username).first() is None:
password = current_app.config['PASSWORD']
user = User(username, generate_password_hash(password))
db.session.add(user)
db.session.commit()
def add_defaults():
default_category = Category('Default')
default_file_type = FileType('Default')
code_file_type = FileType('Code')
image_file_type = FileType('Image')
db.session.add(default_category)
db.session.add(default_file_type)
db.session.add(code_file_type)
db.session.add(image_file_type)
if Category.query.filter_by(name='Default').first() is None:
default_category = Category('Default')
db.session.add(default_category)
if FileType.query.filter_by(name='Default').first() is None:
default_file_type = FileType('Default')
db.session.add(default_file_type)
if FileType.query.filter_by(name='Code').first() is None:
code_file_type = FileType('Code')
db.session.add(code_file_type)
if FileType.query.filter_by(name='Image').first() is None:
image_file_type = FileType('Image')
db.session.add(image_file_type)
db.session.commit()
@@ -60,42 +63,14 @@ def add_files():
@with_appcontext
def init_db_command():
"""
Creates the db file
Creates and initializes the db with data
If the db was previously created it just keep it and its data
"""
init_db()
@click.command("add-defaults")
@with_appcontext
def add_defaults_command():
"""
Initializes the database with default data
"""
add_defaults()
click.echo("Defaults added")
@click.command('generate-admin')
@with_appcontext
def generate_admin_command():
"""Creates the admin of the system"""
generate_admin()
click.echo('The admin was created')
@click.command('add-files')
@with_appcontext
def add_files_command():
"""
Generates the rows in the database for the files currently uploaded
They all will have default privacy, so, public
"""
added_size = add_files()
click.echo(f'added {added_size} files')
add_defaults()
add_files()
def init_app(app):
app.cli.add_command(init_db_command)
app.cli.add_command(add_defaults_command)
app.cli.add_command(generate_admin_command)
app.cli.add_command(add_files_command)

View File

@@ -140,7 +140,7 @@ def preview_file(file_id):
if file.type.name == 'Code':
try:
content = open(_get_path_in_upload(file.filename), 'r').read()
except IOError:
except UnicodeDecodeError:
flash('Error: file is binary, can\'t be displayed')
content = 'Error'

View File

@@ -8,8 +8,8 @@ db = SQLAlchemy()
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String, unique=True, nullable=False)
password = db.Column(db.String, nullable=False)
username = db.Column(db.String(255), unique=True, nullable=False)
password = db.Column(db.String(255), nullable=False)
def __init__(self, username=None, password=None):
self.username = username
@@ -22,8 +22,8 @@ class User(db.Model):
class Message(db.Model):
__tablename__ = 'messages'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
email = db.Column(db.String, nullable=False)
name = db.Column(db.String(255), nullable=False)
email = db.Column(db.String(255), nullable=False)
message = db.Column(db.Text, nullable=False)
sended = db.Column(db.DateTime, default=datetime.utcnow())
@@ -39,7 +39,7 @@ class Message(db.Model):
class File(db.Model):
__tablename__ = 'files'
id = db.Column(db.Integer, primary_key=True)
filename = db.Column(db.String, nullable=False)
filename = db.Column(db.String(255), nullable=False)
private = db.Column(db.Integer, nullable=False)
category_id = db.Column(
db.Integer,
@@ -68,7 +68,7 @@ class File(db.Model):
class Category(db.Model):
__tablename__ = 'categories'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
name = db.Column(db.String(255), nullable=False)
files = db.relationship('File', backref='category', lazy=True)
def __init__(self, name=None):
@@ -81,7 +81,7 @@ class Category(db.Model):
class FileType(db.Model):
__tablename__ = 'file_types'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
name = db.Column(db.String(255), nullable=False)
files = db.relationship('File', backref='type', lazy=True)
def __init__(self, name=None):

View File

@@ -1,3 +1,4 @@
Flask==1.0.2
Flask-SQLAlchemy==2.3.2
gunicorn==19.9.0
Flask
Flask-SQLAlchemy
mysqlclient
gunicorn

12
web.env.example Normal file
View File

@@ -0,0 +1,12 @@
SQLALCHEMY_DATABASE_URI=mysql://root:secret@localhost:3306/db
SQLALCHEMY_TRACK_MODIFICATIONS=False
USERNAME=admin
PASSWORD=secret
SECRET_KEY=1337
UPLOAD_FOLDER=uploads
GUNICORN_WORKERS=2
GUNICORN_BIND=0.0.0.0:8080