Add docker-compose support (closes #19)

This commit is contained in:
R. Miles McCain 2020-05-02 10:27:16 -04:00
commit dfb78b3669
No known key found for this signature in database
GPG Key ID: 24F9B6A2588C5408
10 changed files with 197 additions and 5 deletions

View File

@ -30,4 +30,4 @@ USER appuser
EXPOSE 8080 EXPOSE 8080
CMD [ "./webserver.sh" ] ENTRYPOINT [ "./entrypoint.sh" ]

View File

@ -93,7 +93,8 @@ Shynet is pretty simple, but there are a few key terms you need to know in order
## Installation ## Installation
You can find installation instructions in the [Getting Started Guide](GUIDE.md#installation). You can find installation instructions in the [Getting Started Guide](GUIDE.md#installation). Out of the box, we support deploying via a simple
Docker container, docker-compose, or Kubernetes (see [kubernetes](/kubernetes)).
## FAQ ## FAQ

59
TEMPLATE.env Normal file
View File

@ -0,0 +1,59 @@
# This file shows all of the environment variables you can
# set to configure Shynet, as well as information about their
# effects. Make a copy of this file to configure your deployment.
# Whether to perform checks and setup at startup. For most setups,
# the recommended value is True.
PERFORM_CHECKS_AND_SETUP=True
# Database settings (PostgreSQL)
DB_NAME=shynet_db
DB_USER=shynet_db_user
DB_PASSWORD=shynet_db_user_password
DB_HOST=db
DB_PORT=5432
# Email settings (optional)
EMAIL_HOST_USER=example
EMAIL_HOST_PASSWORD=example_password
EMAIL_HOST=smtp.example.com
SERVER_EMAIL=<Shynet> noreply@shynet.example.com
# General Django settings
DJANGO_SECRET_KEY=random_string
# For better security, set this to your deployment's domain. Comma separated.
ALLOWED_HOSTS=*
# Set to True (capitalized) if you want people to be able to sign up for your Shynet instance (not recommended)
SIGNUPS_ENABLED=False
# The timezone of the admin panel. Affects how dates are displayed.
TIME_ZONE=America/New_York
# Set to "False" if you will not be serving content over HTTPS
SCRIPT_USE_HTTPS=True
# How frequently should the monitoring script "phone home" (in ms)?
SCRIPT_HEARTBEAT_FREQUENCY=5000
# Should only superusers (admins) be able to create services? This is helpful
# when you'd like to invite others to your Shynet instance but don't want
# them to be able to create services of their own.
ONLY_SUPERUSERS_CREATE=True
# If PERFORM_CHECKS_AND_SETUP is True, the following values will be set on
# first run. After they are set once, they won't have any effect.
# (Changing these values WILL NOT affect your Shynet instance.)
#
# Your admin user's email. A temporary password will be printed
# to the console on first run.
SHYNET_ADMIN_EMAIL=you@example.com
# The domain on which you'll be hosting Shynet.
SHYNET_HOST=shynet.example.com
# What you'd like to call your Shynet instance.
SHYNET_WHITELABEL=My Shynet Instance

32
docker-compose.yml Normal file
View File

@ -0,0 +1,32 @@
version: '3'
services:
shynet:
image: milesmcc/shynet:latest
restart: unless-stopped
expose:
- 8080
env_file:
# Create a file called '.env' if it doesn't already exist.
# You can use `TEMPLATE.env` as a guide.
- .env
environment:
- DB_HOST=db
networks:
- internal
depends_on:
- db
db:
image: postgres
restart: always
environment:
- "POSTGRES_USER=${DB_USER}"
- "POSTGRES_PASSWORD=${DB_PASSWORD}"
- "POSTGRES_DB=${DB_NAME}"
volumes:
- shynet_db:/var/lib/postgresql/data
networks:
- internal
volumes:
shynet_db:
networks:
internal:

View File

@ -0,0 +1,49 @@
import traceback
import uuid
from django.conf import settings
from django.contrib.sites.models import Site
from django.core.management.base import BaseCommand, CommandError
from django.utils.crypto import get_random_string
from django.db import DEFAULT_DB_ALIAS, connections
from django.db.utils import OperationalError, ConnectionHandler
from django.core.exceptions import ImproperlyConfigured
from core.models import User
class Command(BaseCommand):
help = "Internal command to perform startup sanity checks."
def check_migrations(self):
from django.db.migrations.executor import MigrationExecutor
try:
executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
except OperationalError:
# DB_NAME database not found?
return True
except ImproperlyConfigured:
# No databases are configured (or the dummy one)
return True
if executor.migration_plan(executor.loader.graph.leaf_nodes()):
return True
return False
def handle(self, *args, **options):
migration = self.check_migrations()
admin, hostname, whitelabel = [True] * 3
if not migration:
admin = not User.objects.all().exists()
hostname = not Site.objects.filter(domain__isnull=False).exclude(domain__exact="").exclude(domain__exact="example.com").exists()
whitelabel = not Site.objects.filter(name__isnull=False).exclude(name__exact="").exclude(name__exact="example.com").exists()
self.stdout.write(
self.style.SUCCESS(
f"{migration} {admin} {hostname} {whitelabel}"
)
)

7
shynet/entrypoint.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
if [[ $PERFORM_CHECKS_AND_SETUP == True ]]; then
./startup_checks.sh
fi
./webserver.sh

View File

@ -27,7 +27,7 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = os.getenv("DJANGO_SECRET_KEY", "onlyusethisindev") SECRET_KEY = os.getenv("DJANGO_SECRET_KEY", "onlyusethisindev")
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.getenv("DEBUG", "True") == "True" DEBUG = os.getenv("DEBUG", "False") == "True"
ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "*").split(",") ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "*").split(",")

0
shynet/ssl.webserver.sh Normal file → Executable file
View File

45
shynet/startup_checks.sh Executable file
View File

@ -0,0 +1,45 @@
#!/bin/bash
# Check if setup is necessary, do setup as needed
echo "Performing startup checks..."
sanity_results=( $(./manage.py startup_checks) )
if [[ ${sanity_results[0]} == True ]]; then
echo "Running migrations (setting up DB)..."
{
./manage.py migrate && echo "Migrations complete!"
} || {
echo "Migrations failed, exiting" && exit 1
}
else
echo "Database is ready to go."
fi
if [[ -n $SHYNET_ADMIN_EMAIL && ${sanity_results[1]} == True ]]; then
echo "Creating an admin user..."
{
temppwd=$( ./manage.py registeradmin $SHYNET_ADMIN_EMAIL ) && echo "Admin user ($SHYNET_ADMIN_EMAIL) created! Password: $temppwd"
} || {
echo "Failed to create admin, exiting" & exit 1
}
else
echo "Making no changes to admin user."
fi
if [[ -n $SHYNET_HOST && ${sanity_results[2]} == True ]]; then
echo "Setting hostname..."
{
./manage.py hostname $SHYNET_HOST && echo "Hostname set to $SHYNET_HOST!"
} || {
echo "Failed setting hostname, exiting" & exit 1
}
else
echo "Making no changes to hostname."
fi
if [[ -n $SHYNET_WHITELABEL && ${sanity_results[3]} == True ]]; then
echo "Setting whitelabel..."
{
./manage.py whitelabel $SHYNET_WHITELABEL && echo "Whitelabel set! Whitelabel: $SHYNET_WHITELABEL"
} || {
echo "Failed to set whitelabel, exiting" & exit 1
}
else
echo "Making no changes to whitelabel."
fi
echo "Startup checks complete!"

View File

@ -1,5 +1,4 @@
#!/bin/bash #!/bin/bash
# Start Gunicorn processes # Start Gunicorn processes
echo Launching Shynet web server... echo Launching Shynet web server...
exec gunicorn shynet.wsgi:application \ exec gunicorn shynet.wsgi:application \