Docker-Compose Single-Run

Add firstrun checks

Avoids running commands on firstrun
Add Docker-compose file

allows setup in a single docker-compose up command
Updated Readme re: docker-compose

Added stub detailing how to use the compose file.
Update README.md
Changed Entrypoint

Moved sanity checks to their own script, changed entrypoint logic
updated entrypoint
This commit is contained in:
Windyo 2020-04-30 22:59:04 +02:00
parent c896a4c150
commit 6fa67f0531
6 changed files with 164 additions and 4 deletions

View File

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

View File

@ -93,7 +93,11 @@ Shynet is pretty simple, but there are a few key terms you need to know in order
## Installation
You can find installation instructions in the [Getting Started Guide](GUIDE.md#installation).
If you use docker-compose, you can use the docker-compose.yml file to set up shynet and launch it by doing docker-compose up.
Note that the application will generate a password for you on initial run, which will be output to standard docker logs.
Also note that this compose file assumes you use a reverse-proxy in front of it, whether Traefik v2, Nginx-Proxy, or a solution on your host.
You can find further installation instructions in the [Getting Started Guide](GUIDE.md#installation).
## FAQ

64
docker-compose.yml Normal file
View File

@ -0,0 +1,64 @@
version: '3'
services:
shynet:
image: milesmcc/shynet:latest
restart: unless-stopped
expose:
- 8080
environment:
# Database Settings
- DB_NAME=shynet_DBname
- DB_USER=shynet_User
- DB_PASSWORD=shynet_RandomPassword
# Database connection, relies on DB service
- DB_HOST=db
- DB_PORT=5432
# General Django settings
- DJANGO_SECRET_KEY=shynet_OtherRandomPassword
# Don't leak error details to visitors, very important
- DEBUG=False
# Unless you are using an external Celery task queue, make sure this
# is set to True.
- CELERY_TASK_ALWAYS_EAGER=True
# 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
# Change as required
- TIME_ZONE=America/New_York
# Set to "False" if you will not be serving content over HTTPS
- SCRIPT_USE_HTTPS=True
# Email settings
- EMAIL_HOST_USER=youruser@yourhost.example.com
- EMAIL_HOST_PASSWORD=youruser_password
- EMAIL_HOST=host.email.provider
- SERVER_EMAIL=noreply.analytics@shynet.example.com
# Redis and queue settings; not necessary for single-instance deployments
#- REDIS_CACHE_LOCATION=redis://redis.default.svc.cluster.local/0
# If set, make sure CELERY_TASK_ALWAYS_EAGER is False
#- CELERY_BROKER_URL=redis://redis.default.svc.cluster.local/1
# 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
networks:
- internal
depends_on:
- db
db:
image: postgres
restart: always
environment:
- POSTGRES_USER=shynet_User
- POSTGRES_PASSWORD=shynet_RandomPassword
- POSTGRES_DB=shynet_DBname
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 = "Performs sanity checks on the Shynet setup"
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}"
)
)

44
shynet/entrypoint.sh Executable file
View File

@ -0,0 +1,44 @@
#!/bin/bash
# Check if Setup is necessary, do setup as needed
sanity_results=( $(python manage.py sanity_checks) )
if [[ ${sanity_results[0]} == True ]]; then
echo "Running Migrations..."
{
python manage.py migrate && echo "Migrations Done"
} || {
echo "Failed Migrations, exiting" && exit 1
}
else
echo "Migrations Unecessary, skipping"
fi
if [[ ${sanity_results[1]} == True ]]; then
echo "Running CreateAdmin..."
{
temppwd=$( python manage.py registeradmin $SHYNET_EMAIL ) && echo "Admin Created, password $temppwd"
} || {
echo "Failed CreateAdmin, exiting" & exit 1
}
else
echo "CreateAdmin Unecessary, skipping"
fi
if [[ ${sanity_results[2]} == True ]]; then
echo "Setting Hostname..."
{
python manage.py hostname $SHYNET_HOST && echo "Host Set"
} || {
echo "Failed setting Hostname, exiting" & exit 1
}
else
echo "Hostname Unecessary, skipping"
fi
if [[ ${sanity_results[3]} == True ]]; then
echo "Setting Hostname..."
{
python manage.py whitelabel $SHYNET_NAME && echo "WhiteLabel Set"
} || {
echo "Failed Migrations, exiting" & exit 1
}
else
echo "WhiteLabel Unecessary, skipping"
fi
./webserver.sh

View File

@ -1,8 +1,7 @@
#!/bin/bash
# Start Gunicorn processes
echo Launching Shynet web server...
exec gunicorn shynet.wsgi:application \
--bind 0.0.0.0:8080 \
--workers 3 \
--timeout 100
--timeout 100