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

Adds Docker support #125

Open
wants to merge 2 commits into
base: docker
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -2,6 +2,8 @@
__pycache__/
*.py[cod]
*$py.class
.env
MR.md

# C extensions
*.so
Expand Down
10 changes: 10 additions & 0 deletions README.md
Expand Up @@ -18,6 +18,16 @@
## Installation
Follow these instructions to install Hashview Server on Ubuntu 20.04.3 LTS server. In theory Hashview should be able to run on any *nix system, but the dev's only installed/tested on Debian/Ubuntu.

### NEW ⭐ Docker Install ⭐
We now have a docker image available for Hashview. This is the easiest way to get Hashview up and running.

1. Copy and update the .env.example file from the docker folder to .env in the root of the project. (Leave DB_HOST as 'db' if you are using the included mysql container.)
2. Run `docker compose build --no-cache`
3. Run `docker-compose up` / `docker-compose up -d` to start the Hashview server
4. Navigate to https://localhost:8443 / https://<your-ip>:8443
5. Login with the credentials you set in the .env file.


#### 1) Setup MySQL

```
Expand Down
52 changes: 52 additions & 0 deletions docker-compose.yaml
@@ -0,0 +1,52 @@
services:
hashview:
platform: linux/amd64
build:
context: .
dockerfile: docker/Dockerfile
args:
DB_SERVER: ${DB_SERVER}
DB_USERNAME: ${DB_USERNAME}
DB_PASSWORD: ${DB_PASSWORD}
SMTP_SERVER: ${SMTP_SERVER}
SMTP_SENDER_ADDRESS: ${SMTP_SENDER_ADDRESS}
SMTP_USERNAME: ${SMTP_USERNAME}
SMTP_PASSWORD: ${SMTP_PASSWORD}
SMTP_TLS: ${SMTP_TLS}
CERT_SUBJECT: ${CERT_SUBJECT}
container_name: hashview
working_dir: /app
ports:
- "8443:8443"
depends_on:
- db
env_file:
- .env
networks:
- hashview-network

db:
image: mysql:5.7
container_name: hashview_db
platform: linux/amd64
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
MYSQL_DATABASE: hashview
MYSQL_USER: ${DB_USERNAME}
MYSQL_PASSWORD: ${DB_PASSWORD}
expose:
- "3306"
volumes:
- db_data:/var/lib/mysql
env_file:
- .env
networks:
- hashview-network

volumes:
db_data:

networks:
hashview-network:
name: hashview-network
driver: bridge
13 changes: 13 additions & 0 deletions docker/.env.example
@@ -0,0 +1,13 @@
DB_SERVER=db
DB_USERNAME=hashview
DB_PASSWORD=Password1!
SMTP_SERVER=smtp.example.com
SMTP_SENDER_ADDRESS=hashview@example.com
SMTP_USERNAME=user@example.com
SMTP_PASSWORD=emailpassword
SMTP_TLS=y
ADMIN_EMAIL=admin@example.com
ADMIN_PASSWORD=ChangeMe123!
ADMIN_FIRSTNAME=Admin
ADMIN_LASTNAME=User
CERT_SUBJECT="/C=US/ST=California/L=San Francisco/O=Hashview/OU=Hashview/CN=hashview.example.com"
40 changes: 40 additions & 0 deletions docker/Dockerfile
@@ -0,0 +1,40 @@
FROM --platform=linux/amd64 python:3.8

WORKDIR /app

# Define build-time environment variables
ARG DB_SERVER
ARG DB_USERNAME
ARG DB_PASSWORD
ARG SMTP_SERVER
ARG SMTP_SENDER_ADDRESS
ARG SMTP_USERNAME
ARG SMTP_PASSWORD
ARG SMTP_TLS
ARG CERT_SUBJECT

# Set build-time environment variables as environment variables
ENV DB_SERVER=${DB_SERVER} \
DB_USERNAME=${DB_USERNAME} \
DB_PASSWORD=${DB_PASSWORD} \
SMTP_SERVER=${SMTP_SERVER} \
SMTP_SENDER_ADDRESS=${SMTP_SENDER_ADDRESS} \
SMTP_USERNAME=${SMTP_USERNAME} \
SMTP_PASSWORD=${SMTP_PASSWORD} \
SMTP_TLS=${SMTP_TLS} \
CERT_SUBJECT=${CERT_SUBJECT}

COPY ../ /app
COPY ../docker/waitfor.sh /app
COPY ../docker/setup-docker.py /app

# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# Install netcat to wait for the database to be ready
RUN apt-get update && apt-get install -y netcat-traditional

# Run the setup script
RUN python3 setup-docker.py

ENTRYPOINT ["sh", "-c", "./waitfor.sh db && python3 hashview.py"]
57 changes: 57 additions & 0 deletions docker/setup-docker.py
@@ -0,0 +1,57 @@
#!/usr/bin/python3
import os


# Install dependencies
def install_and_import(package):
import importlib
try:
importlib.import_module(package)
except ImportError:
import pip
pip.main(['install', package])
finally:
globals()[package] = importlib.import_module(package)

# Assuming requirements.txt only contains 'transliterate'
install_and_import('transliterate')

# Configuration from environment variables
db_server = os.environ.get('DB_SERVER', 'db')
db_username = os.environ.get('DB_USERNAME', 'root')
db_password = os.environ.get('DB_PASSWORD', 'password')
smtp_server = os.environ.get('SMTP_SERVER', 'localhost')
smtp_sender_address = os.environ.get('SMTP_SENDER_ADDRESS', 'hashview@example.com')
smtp_username = os.environ.get('SMTP_USERNAME', '')
smtp_password = os.environ.get('SMTP_PASSWORD', '')
smtp_tls = os.environ.get('SMTP_TLS', 'n').lower() in ['y', 'yes', 'true', '1']

# Write config file
with open("hashview/config.conf", "w") as config:
config.write(f"""[database]
host = {db_server}
username = {db_username}
password = {db_password}

[SMTP]
server = {smtp_server}
port = 25
use_tls = {str(smtp_tls)}
username = {smtp_username}
password = {smtp_password}
default_sender = {smtp_sender_address}
""")

print('Writing hashview config at: hashview/config.conf')

# Database and SSL setup commands
# os.system('export FLASK_APP=hashview.py; flask db upgrade')

# get CERT_SUBJECT from os.environ
cert_subject = os.environ.get('CERT_SUBJECT', '/C=US/ST=OHIO/L=WeightRoom/O=Internet Widgits Pty Ltd/OU=/CN=/emailAddress=hans@localhost.local')

print('Generating SSL certificate...')

os.system(f'openssl req -x509 -newkey rsa:4096 -nodes -out ./hashview/ssl/cert.pem -keyout ./hashview/ssl/key.pem -days 365 -subj "{cert_subject}"')

print('Setup complete. You can now start your instance of hashview by running: ./hashview.py')
20 changes: 20 additions & 0 deletions docker/waitfor.sh
@@ -0,0 +1,20 @@
#!/bin/sh
# wait-for-mysql.sh

set -e

host="$1"
shift
cmd="$@"

until nc -z "$host" 3306; do
>&2 echo "MySQL is unavailable - sleeping"
sleep 1
done

# Run database migrations
echo "Running database migrations..."
export FLASK_APP=hashview.py; flask db upgrade

>&2 echo "MySQL is up - executing command"
exec $cmd
18 changes: 18 additions & 0 deletions hashview.py
Expand Up @@ -50,6 +50,24 @@ def ensure_admin_account(db, bcrypt):
if (0 < admin_user_count):
print('✓ Admin user exists in database.')
return



# Check if we have environment variables for the admin account
admin_email, admin_password, admin_firstname, admin_lastname = (
os.environ.get('ADMIN_EMAIL'),
os.environ.get('ADMIN_PASSWORD'),
os.environ.get('ADMIN_FIRSTNAME'),
os.environ.get('ADMIN_LASTNAME'),
)
if admin_email and admin_password and admin_firstname and admin_lastname:
print('\nInitial setup detected. Hashview will now provision an Administrative account using environment variables.\n')
print('Provisioning account in database.')
hashed_password = bcrypt.generate_password_hash(admin_password).decode('utf-8')

user = Users(first_name=admin_firstname, last_name=admin_lastname, email_address=admin_email, password=hashed_password, admin=True)
db.session.add(user)
db.session.commit()

else:
print('\nInitial setup detected. Hashview will now prompt you to setup an Administrative account.\n')
Expand Down
22 changes: 21 additions & 1 deletion hashview/config.py
@@ -1,11 +1,31 @@
import secrets
from configparser import ConfigParser

file_config = ConfigParser()

class Config:

# Read the configuration file
file_config.read('hashview/config.conf')

# Print database configuration
print('Database configuration:')
print('Host:', file_config['database']['host'])
print('Username:', file_config['database']['username'])
print('Password:', file_config['database']['password'])


SECRET_KEY = secrets.token_hex(16)
SQLALCHEMY_DATABASE_URI = 'mysql+mysqlconnector://' + file_config['database']['username'] + ':' + file_config['database']['password'] + '@' + file_config['database']['host'] + '/hashview'
try:
SQLALCHEMY_DATABASE_URI = 'mysql+mysqlconnector://' + file_config['database']['username'] + ':' + file_config['database']['password'] + '@' + file_config['database']['host'] + '/hashview'
except KeyError:
# Print database configuration
print('Database configuration:')
print('Host:', file_config['database']['host'])
print('Username:', file_config['database']['username'])
print('Password:', file_config['database']['password'])
exit(1)


# SMTP Config
MAIL_SERVER = file_config['SMTP']['server']
Expand Down
2 changes: 1 addition & 1 deletion setup.py 100755 → 100644
@@ -1,6 +1,6 @@
#!/usr/bin/python3
import sys
import os
import sys
from getpass import getpass

# Step 1
Expand Down