init
This commit is contained in:
@@ -0,0 +1,27 @@
|
|||||||
|
# Environment variables for docker-compose.yml
|
||||||
|
|
||||||
|
LOG_LEVEL="DEBUG"
|
||||||
|
NETWORK=web
|
||||||
|
## dashboard configs
|
||||||
|
HOST="furyhawk.lol"
|
||||||
|
# subdomain for dashboard.
|
||||||
|
DASHBOARD_HOST="dashboard.furyhawk.lol"
|
||||||
|
|
||||||
|
# The following are the environment variables for the streamlit app
|
||||||
|
FIN_LOCATION="/fin"
|
||||||
|
STREAMLIT_FIN_SERVER_PORT="8501"
|
||||||
|
BAI_LOCATION="/bai"
|
||||||
|
STREAMLIT_BAI_SERVER_PORT="8502"
|
||||||
|
|
||||||
|
# user/pass
|
||||||
|
DASHBOARD_USER=admin
|
||||||
|
DASHBOARD_PASSWORD=pass
|
||||||
|
|
||||||
|
OSRM_ALGORITHM="mld"
|
||||||
|
OSRM_THREADS=2
|
||||||
|
OSRM_PORT=5000
|
||||||
|
OSRM_PROFILE="/opt/car.lua"
|
||||||
|
OSRM_MAP_NAME=${OSRM_MAP_NAME}
|
||||||
|
OSRM_GEOFABRIK_PATH=${OSRM_GEOFABRIK_PATH}
|
||||||
|
# Notify OSRM Manager to restart without stopping container
|
||||||
|
OSRM_NOTIFY_FILEPATH="/data/osrm_notify.txt"
|
||||||
+165
@@ -0,0 +1,165 @@
|
|||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
|
#poetry.lock
|
||||||
|
|
||||||
|
# pdm
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||||
|
#pdm.lock
|
||||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||||
|
# in version control.
|
||||||
|
# https://pdm.fming.dev/#use-with-ide
|
||||||
|
.pdm.toml
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
# .env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
#.idea/
|
||||||
|
|
||||||
|
# ignores production code for traefik and production yml
|
||||||
|
# compose/traefik/
|
||||||
|
# production.yml
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# Streamlit + Traefik + Docker
|
||||||
|
This simple project uses Traefik as a reverse proxy to a Streamlit application and handles SSL certs with Lets Encrypt.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- Docker Compose
|
||||||
|
- Python 3.9
|
||||||
|
|
||||||
|
## Local Deployment
|
||||||
|
#### Python:
|
||||||
|
1. `cd src`
|
||||||
|
2. `pip install -r requirements.txt`
|
||||||
|
3. `streamlit run app.py`
|
||||||
|
|
||||||
|
#### Docker:
|
||||||
|
1. `sudo docker-compose -f local.yml up --build`
|
||||||
|
|
||||||
|
## Production Deployment
|
||||||
|
1. In `compose/traefik/traefik.yml`, change `example@test.com` to your email.
|
||||||
|
2. In `compose/traefik/traefik.yml`, change `example.com` to your domain.
|
||||||
|
3. `docker compose -f production.yml up --build -d --remove-orphans`
|
||||||
|
|
||||||
|
### Notes:
|
||||||
|
Feel free to make a PR or get in contact with me on Discord at yoyojoe#5510.
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
Vendored
BIN
Binary file not shown.
@@ -0,0 +1,29 @@
|
|||||||
|
# base image
|
||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
#basic build prep
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
curl \
|
||||||
|
software-properties-common \
|
||||||
|
git \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# copy over and install packages
|
||||||
|
COPY ./src/requirements.txt ./requirements.txt
|
||||||
|
RUN pip3 install cython
|
||||||
|
RUN pip3 install -r requirements.txt
|
||||||
|
|
||||||
|
# streamlit-specific commands
|
||||||
|
RUN mkdir -p /root/.streamlit
|
||||||
|
RUN bash -c 'echo -e "\
|
||||||
|
[general]\n\
|
||||||
|
email = \"\"\n\
|
||||||
|
" > /root/.streamlit/credentials.toml'
|
||||||
|
# RUN bash -c 'echo -e "\
|
||||||
|
# [server]\n\
|
||||||
|
# baseUrlPath = \"/fin\"\n\
|
||||||
|
# " > /root/.streamlit/config.toml'
|
||||||
|
|
||||||
|
# copying everything over
|
||||||
|
COPY . .
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
FROM traefik:v2.11
|
||||||
|
RUN mkdir -p /etc/traefik/acme \
|
||||||
|
&& touch /etc/traefik/acme/acme.json \
|
||||||
|
&& chmod 600 /etc/traefik/acme/acme.json
|
||||||
|
COPY ./compose/traefik/traefik.yml /etc/traefik
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
log:
|
||||||
|
level: DEBUG
|
||||||
|
api:
|
||||||
|
# Dashboard
|
||||||
|
dashboard: true
|
||||||
|
# https://docs.traefik.io/master/operations/api/#insecure
|
||||||
|
# insecure: true
|
||||||
|
|
||||||
|
|
||||||
|
entryPoints:
|
||||||
|
web:
|
||||||
|
# http
|
||||||
|
address: ":80"
|
||||||
|
http:
|
||||||
|
# https://docs.traefik.io/routing/entrypoints/#entrypoint
|
||||||
|
redirections:
|
||||||
|
entryPoint:
|
||||||
|
to: web-secure
|
||||||
|
|
||||||
|
web-secure:
|
||||||
|
# https
|
||||||
|
address: ":443"
|
||||||
|
|
||||||
|
# osrm:
|
||||||
|
# address: ":5000"
|
||||||
|
|
||||||
|
certificatesResolvers:
|
||||||
|
letsencrypt:
|
||||||
|
# https://docs.traefik.io/master/https/acme/#lets-encrypt
|
||||||
|
acme:
|
||||||
|
email: "furyx@hotmail.com"
|
||||||
|
storage: /etc/traefik/acme/acme.json
|
||||||
|
# https://docs.traefik.io/master/https/acme/#httpchallenge
|
||||||
|
httpChallenge:
|
||||||
|
entryPoint: web
|
||||||
|
|
||||||
|
http:
|
||||||
|
routers:
|
||||||
|
dashboard:
|
||||||
|
rule: "Host(`dashboard.furyhawk.lol`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
|
||||||
|
service: api@internal
|
||||||
|
middlewares:
|
||||||
|
- auth
|
||||||
|
tls:
|
||||||
|
# https://docs.traefik.io/master/routing/routers/#certresolver
|
||||||
|
certResolver: letsencrypt
|
||||||
|
|
||||||
|
web-secure-router:
|
||||||
|
rule: "Host(`furyhawk.lol`, `www.furyhawk.lol`, `bai.furyhawk.lol`) || PathPrefix(`/bai`)"
|
||||||
|
entryPoints:
|
||||||
|
- web-secure
|
||||||
|
middlewares:
|
||||||
|
- csrf
|
||||||
|
- add-bai
|
||||||
|
service: streamlit_bai_app
|
||||||
|
tls:
|
||||||
|
# https://docs.traefik.io/master/routing/routers/#certresolver
|
||||||
|
certResolver: letsencrypt
|
||||||
|
fin-router:
|
||||||
|
rule: "Host(`fin.furyhawk.lol`)"
|
||||||
|
entryPoints:
|
||||||
|
- web-secure
|
||||||
|
middlewares:
|
||||||
|
- csrf
|
||||||
|
- add-fin
|
||||||
|
service: streamlit_fin_app
|
||||||
|
tls:
|
||||||
|
# https://docs.traefik.io/master/routing/routers/#certresolver
|
||||||
|
certResolver: letsencrypt
|
||||||
|
blog-router:
|
||||||
|
rule: "Host(`blog.furyhawk.lol`)"
|
||||||
|
entryPoints:
|
||||||
|
- web-secure
|
||||||
|
# redirect to external blog
|
||||||
|
middlewares:
|
||||||
|
- redirect-blog
|
||||||
|
|
||||||
|
service: blog
|
||||||
|
tls:
|
||||||
|
# https://docs.traefik.io/master/routing/routers/#certresolver
|
||||||
|
certResolver: letsencrypt
|
||||||
|
|
||||||
|
osrm-router:
|
||||||
|
rule: "Host(`osrm.furyhawk.lol`)"
|
||||||
|
entryPoints:
|
||||||
|
- "web-secure"
|
||||||
|
# - "osrm"
|
||||||
|
middlewares:
|
||||||
|
- csrf
|
||||||
|
service: osrm_service
|
||||||
|
tls:
|
||||||
|
# https://docs.traefik.io/master/routing/routers/#certresolver
|
||||||
|
certResolver: letsencrypt
|
||||||
|
|
||||||
|
middlewares:
|
||||||
|
auth:
|
||||||
|
basicAuth:
|
||||||
|
users:
|
||||||
|
- "test:$apr1$2E4PEW8M$/wEgFNKX71h.YYMywV7WZ/"
|
||||||
|
csrf:
|
||||||
|
# https://doc.traefik.io/traefik/middlewares/http/headers/#hostsproxyheaders
|
||||||
|
# https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
|
||||||
|
headers:
|
||||||
|
hostsProxyHeaders: ["X-CSRFToken"]
|
||||||
|
|
||||||
|
add-bai:
|
||||||
|
addPrefix:
|
||||||
|
prefix: "/bai"
|
||||||
|
|
||||||
|
add-fin:
|
||||||
|
addPrefix:
|
||||||
|
prefix: "/fin"
|
||||||
|
|
||||||
|
redirect-blog:
|
||||||
|
# https://docs.traefik.io/master/middlewares/redirectscheme/
|
||||||
|
redirectregex:
|
||||||
|
regex: "^https://blog.furyhawk.lol/(.*)"
|
||||||
|
replacement: "https://furyhawk.github.io/124c41/${1}"
|
||||||
|
permanent: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
osrm_service:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: http://osrm_backend:{{env "OSRM_PORT"}}
|
||||||
|
streamlit_bai_app:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: http://streamlit_bai_app:8502/bai
|
||||||
|
streamlit_fin_app:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: http://streamlit_fin_app:{{env "STREAMLIT_FIN_SERVER_PORT"}}/{{env "FIN_LOCATION"}}
|
||||||
|
blog:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: https://furyhawk.github.io/124c41/
|
||||||
|
|
||||||
|
providers:
|
||||||
|
# https://docs.traefik.io/master/providers/file/
|
||||||
|
file:
|
||||||
|
filename: /etc/traefik/traefik.yml
|
||||||
|
watch: true
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
|
!certs.toml
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[tls.stores.default.defaultCertificate]
|
||||||
|
certFile = "/certs/cert.crt"
|
||||||
|
keyFile = "/certs/cert.key"
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
streamlit-fin:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: ./compose/streamlit-fin/Dockerfile
|
||||||
|
image: streamlit_fin_local
|
||||||
|
container_name: streamlit_fin_app
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- 8501:8501
|
||||||
|
command: streamlit run src/app.py
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
version: '3.7'
|
||||||
|
|
||||||
|
x-environment: &default-environment
|
||||||
|
LOG_LEVEL: "DEBUG"
|
||||||
|
DASHBOARD_USER: ${DASHBOARD_USER}
|
||||||
|
DASHBOARD_PASSWORD: ${DASHBOARD_PASSWORD}
|
||||||
|
FIN_LOCATION: "/fin"
|
||||||
|
STREAMLIT_FIN_SERVER_PORT: "8501"
|
||||||
|
BAI_LOCATION: "/bai"
|
||||||
|
STREAMLIT_BAI_SERVER_PORT: "8502"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
production_traefik: {}
|
||||||
|
|
||||||
|
services:
|
||||||
|
osrm-backend:
|
||||||
|
environment:
|
||||||
|
# OSRM manager setup
|
||||||
|
- OSRM_ALGORITHM=mld
|
||||||
|
- OSRM_THREADS=2
|
||||||
|
- OSRM_PORT=5000
|
||||||
|
- OSRM_PROFILE=/opt/car.lua
|
||||||
|
- OSRM_MAP_NAME=${OSRM_MAP_NAME}
|
||||||
|
- OSRM_GEOFABRIK_PATH=${OSRM_GEOFABRIK_PATH}
|
||||||
|
# Notify OSRM Manager to restart without stopping container
|
||||||
|
- OSRM_NOTIFY_FILEPATH=/data/osrm_notify.txt
|
||||||
|
image: furyhawk/osrm-backend:${OSRM_VERSION:-latest}
|
||||||
|
container_name: osrm_backend
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- ${OSRM_PORT}:${OSRM_PORT}
|
||||||
|
|
||||||
|
streamlit-bai:
|
||||||
|
environment:
|
||||||
|
<<: *default-environment
|
||||||
|
image: furyhawk/beyondallinfo:latest
|
||||||
|
container_name: streamlit_bai_app
|
||||||
|
restart: always
|
||||||
|
expose:
|
||||||
|
- ${STREAMLIT_BAI_SERVER_PORT}
|
||||||
|
command: streamlit run --server.port=$STREAMLIT_BAI_SERVER_PORT --server.address=0.0.0.0 --server.baseUrlPath=$BAI_LOCATION src/app.py
|
||||||
|
|
||||||
|
streamlit-fin:
|
||||||
|
environment:
|
||||||
|
<<: *default-environment
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: ./compose/streamlit-fin/Dockerfile
|
||||||
|
image: streamlit_fin_production
|
||||||
|
container_name: streamlit_fin_app
|
||||||
|
restart: always
|
||||||
|
expose:
|
||||||
|
- ${STREAMLIT_FIN_SERVER_PORT}
|
||||||
|
command: streamlit run --server.port=$STREAMLIT_FIN_SERVER_PORT --server.address=0.0.0.0 --server.baseUrlPath=$FIN_LOCATION src/app.py
|
||||||
|
|
||||||
|
traefik:
|
||||||
|
environment:
|
||||||
|
<<: *default-environment
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: ./compose/traefik/Dockerfile
|
||||||
|
image: traefik_production
|
||||||
|
volumes:
|
||||||
|
- production_traefik:/etc/traefik/acme:z
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
ports:
|
||||||
|
- "0.0.0.0:80:80"
|
||||||
|
- "0.0.0.0:443:443"
|
||||||
Executable
+7
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -ev
|
||||||
|
|
||||||
|
docker-compose config
|
||||||
|
docker-compose pull
|
||||||
|
docker-compose up -d
|
||||||
|
docker-compose ps
|
||||||
Executable
+30
@@ -0,0 +1,30 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
eval $(egrep '^HOST' .env | xargs)
|
||||||
|
eval $(egrep '^CERT_PATH' .env | xargs)
|
||||||
|
|
||||||
|
echo "Domain: ${HOST}"
|
||||||
|
echo "Cert Path: ${CERT_PATH}"
|
||||||
|
|
||||||
|
if [ -f certs/cert.crt ] || [ -f certs/cert.key ] || [ -f certs/cert.pem ]; then
|
||||||
|
echo -e "cert already exists in certs directory\nDo you want to overwrite the files? [y]es/[n]o"
|
||||||
|
read -r ANSWER
|
||||||
|
echo
|
||||||
|
if [[ "$ANSWER" =~ ^[Yy](es)?$ ]] ; then
|
||||||
|
echo "Creating Cert"
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
./scripts/requests.sh
|
||||||
|
|
||||||
|
openssl genrsa -out $CERT_PATH/cert.key
|
||||||
|
openssl req -new -key $CERT_PATH/cert.key -out $CERT_PATH/cert.csr -config $CERT_PATH/csr.conf
|
||||||
|
openssl x509 -req -days 365 -in $CERT_PATH/cert.csr -signkey $CERT_PATH/cert.key -out $CERT_PATH/cert.crt -extensions req_ext -extfile $CERT_PATH/csr.conf
|
||||||
|
|
||||||
|
sudo cp $CERT_PATH/cert.crt /usr/local/share/ca-certificates/cert.crt
|
||||||
|
sudo rm -f /usr/local/share/ca-certificates/certificate.crt
|
||||||
|
# --fresh is needed to remove symlinks to no-longer-present certificates
|
||||||
|
sudo update-ca-certificates --fresh
|
||||||
Executable
+9
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "Cleaning up..."
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
printf "Deleting network: "
|
||||||
|
eval $(egrep '^NETWORK' .env | xargs)
|
||||||
|
printf "$NETWORK\n"
|
||||||
|
docker network rm $NETWORK | echo
|
||||||
Executable
+10
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# color
|
||||||
|
RESET=$'\e[1;0m'
|
||||||
|
RED=$'\e[1;31m'
|
||||||
|
GREEN=$'\e[1;32m'
|
||||||
|
YELLOW=$'\e[1;33m'
|
||||||
|
RED_BACK=$'\e[101m'
|
||||||
|
GREEN_BACK=$'\e[102m'
|
||||||
|
YELLOW_BACK=$'\e[103m'
|
||||||
Executable
+10
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -ev
|
||||||
|
|
||||||
|
eval $(egrep '^HOST' .env | xargs)
|
||||||
|
|
||||||
|
if [ "$HOST" != "localhost" ]; then
|
||||||
|
grep "127.0.0.1 ${HOST}" /etc/hosts || (echo "127.0.0.1 ${HOST}" | sudo tee -a /etc/hosts)
|
||||||
|
fi
|
||||||
|
grep "127.0.0.1 docker.${HOST}" /etc/hosts || (echo "127.0.0.1 docker.${HOST}" | sudo tee -a /etc/hosts)
|
||||||
|
grep "127.0.0.1 dashboard.${HOST}" /etc/hosts || (echo "127.0.0.1 dashboard.${HOST}" | sudo tee -a /etc/hosts)
|
||||||
Executable
+26
@@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "Copying env file"
|
||||||
|
# Create env from env.example if it doesn't exist
|
||||||
|
if [ -f ".env" ]
|
||||||
|
then
|
||||||
|
echo -e "env file exists"
|
||||||
|
else
|
||||||
|
echo -e "Copying env file"
|
||||||
|
cp env.example .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "creating acme.json"
|
||||||
|
touch acme.json
|
||||||
|
chmod 600 acme.json
|
||||||
|
|
||||||
|
echo "creating provider.key"
|
||||||
|
touch provider.key
|
||||||
|
echo "supersecretkey" | tee provider.key
|
||||||
|
chmod 600 provider.key
|
||||||
|
|
||||||
|
printf "Creating network: "
|
||||||
|
eval $(egrep '^NETWORK' .env | xargs)
|
||||||
|
printf "$NETWORK\n"
|
||||||
|
docker network create $NETWORK | echo
|
||||||
Executable
+21
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
if [ -z "$DOCKER_COMPOSE_VERSION" ]; then
|
||||||
|
DOCKER_COMPOSE_VERSION=1.25.4
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Installing docker-compose version: $DOCKER_COMPOSE_VERSION"
|
||||||
|
|
||||||
|
if [ -z "`sudo -l 2>/dev/null`" ]; then
|
||||||
|
|
||||||
|
rm /usr/local/bin/docker-compose | echo
|
||||||
|
curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose
|
||||||
|
chmod +x docker-compose
|
||||||
|
mv docker-compose /usr/local/bin
|
||||||
|
else
|
||||||
|
sudo rm /usr/local/bin/docker-compose | echo
|
||||||
|
curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose
|
||||||
|
sudo chmod +x docker-compose
|
||||||
|
sudo mv docker-compose /usr/local/bin
|
||||||
|
fi
|
||||||
Executable
+25
@@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
eval $(egrep -v '^#' .env | xargs)
|
||||||
|
|
||||||
|
echo "
|
||||||
|
[req]
|
||||||
|
default_bits = 2048
|
||||||
|
distinguished_name = dn
|
||||||
|
prompt = no
|
||||||
|
|
||||||
|
[dn]
|
||||||
|
C=\"US\"
|
||||||
|
ST=\"Florida\"
|
||||||
|
OU=\"Service\"
|
||||||
|
emailAddress=\"admin@${HOST}\"
|
||||||
|
CN=\"${HOST}\"
|
||||||
|
|
||||||
|
[req_ext]
|
||||||
|
subjectAltName = @alt_names
|
||||||
|
|
||||||
|
[alt_names]
|
||||||
|
DNS.0 = ${HOST}
|
||||||
|
DNS.1 = *.${HOST}
|
||||||
|
DNS.2 = *.docker.${HOST}
|
||||||
|
" > certs/csr.conf
|
||||||
Executable
+37
@@ -0,0 +1,37 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
|
||||||
|
|
||||||
|
source ./scripts/color.sh
|
||||||
|
|
||||||
|
shopt -s expand_aliases
|
||||||
|
alias curl="curl -ILsS -X GET"
|
||||||
|
alias grep="grep -C 100 --color=auto"
|
||||||
|
alias echo="echo -e \${RESET}"
|
||||||
|
|
||||||
|
|
||||||
|
eval $(egrep '^HOST' .env | xargs)
|
||||||
|
eval $(egrep '^DASHBOARD_HOST' .env | xargs)
|
||||||
|
|
||||||
|
echo "\n\n${YELLOW_BACK}${RED}Testing Traefik........................${RESET}\n"
|
||||||
|
echo "\nHOST=${HOST}"
|
||||||
|
echo "\nDASHBOARD_HOST=${DASHBOARD_HOST}\n"
|
||||||
|
|
||||||
|
|
||||||
|
echo "\n\n${YELLOW}Rediection test........................${RESET}\n"
|
||||||
|
echo "\n${GREEN}http://${HOST}${RESET}\n"
|
||||||
|
curl http://${HOST} | grep 302 || exit 1
|
||||||
|
echo "\n${GREEN}http://${HOST}${RESET}\n"
|
||||||
|
curl http://${DASHBOARD_HOST} | grep 302 || exit 1
|
||||||
|
|
||||||
|
# echo "\n\nAuthentication test....................\n"
|
||||||
|
|
||||||
|
echo "\n\n${YELLOW}Authentication test....................${RESET}\n"
|
||||||
|
echo "\n${GREEN}https://user:pass@${DASHBOARD_HOST}${RESET}\n"
|
||||||
|
curl -f --anyauth -u user:pass https://${DASHBOARD_HOST} | grep 200 || exit 1
|
||||||
|
|
||||||
|
echo "\n${GREEN}https://user:pass@${DASHBOARD_HOST}/dashboard/${RESET}\n"
|
||||||
|
curl -f --anyauth -u user:pass https://${DASHBOARD_HOST}/dashboard/ | grep 200 || exit 1
|
||||||
|
echo "\n\n${GREEN}.......................................${RESET}\n"
|
||||||
Executable
+9
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -ev
|
||||||
|
|
||||||
|
./scripts/init.sh
|
||||||
|
./scripts/cert.sh
|
||||||
|
./scripts/host.sh
|
||||||
|
./scripts/build.sh
|
||||||
|
./scripts/wait.sh ${WAIT_FOR}
|
||||||
|
./scripts/test.sh
|
||||||
Executable
+13
@@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
x="$1"
|
||||||
|
[[ -z "$x" ]] && x=5
|
||||||
|
|
||||||
|
printf "\n\nWaiting for things to start"
|
||||||
|
while [ $x -gt 0 ]
|
||||||
|
do
|
||||||
|
printf "."
|
||||||
|
sleep 1
|
||||||
|
x=$(( $x - 1 ))
|
||||||
|
done
|
||||||
|
echo "."
|
||||||
Vendored
BIN
Binary file not shown.
+127
@@ -0,0 +1,127 @@
|
|||||||
|
import streamlit as st
|
||||||
|
import yfinance as yf
|
||||||
|
from ta import volume, trend
|
||||||
|
|
||||||
|
|
||||||
|
st.set_page_config(page_title='Technical Analysis',page_icon='📈', layout='wide')
|
||||||
|
hide_streamlit_style = """
|
||||||
|
<style>
|
||||||
|
.reportview-container {
|
||||||
|
margin-top: -2em;
|
||||||
|
}
|
||||||
|
#MainMenu {
|
||||||
|
|
||||||
|
visibility: hidden;
|
||||||
|
|
||||||
|
}
|
||||||
|
.stDeployButton {display:none;}
|
||||||
|
footer {
|
||||||
|
|
||||||
|
visibility: hidden;
|
||||||
|
|
||||||
|
}
|
||||||
|
footer:after {
|
||||||
|
|
||||||
|
content:'Data Source: Yahoo Finance';
|
||||||
|
visibility: visible;
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
#background-color: red;
|
||||||
|
padding: 5px;
|
||||||
|
top: 2px;
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
"""
|
||||||
|
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
|
||||||
|
|
||||||
|
stock = st.sidebar.text_input(label="Ticker",value='AAPL')
|
||||||
|
|
||||||
|
def get_data(start):
|
||||||
|
ticker = yf.Ticker(stock)
|
||||||
|
try:
|
||||||
|
df = ticker.history(period='max', start=start)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return df
|
||||||
|
|
||||||
|
list_of_indicator_types = ['Volume', 'Trend']
|
||||||
|
volumn_types = ['Volume','Force Index']
|
||||||
|
trend_types = ["Simple Moving Average", "Exponential Moving Average"]
|
||||||
|
|
||||||
|
indicator_types = st.sidebar.selectbox(label='Indicator Type', options = list_of_indicator_types)
|
||||||
|
|
||||||
|
st.sidebar.success('All charts are interactive!')
|
||||||
|
|
||||||
|
if indicator_types == 'Volume':
|
||||||
|
indicator = st.selectbox(label='Indicator', options=volumn_types,key=0)
|
||||||
|
|
||||||
|
start = st.text_input(label='Start Year', value = '2018')
|
||||||
|
start = f'{start}-01-01'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
df = get_data(start)
|
||||||
|
|
||||||
|
if indicator == 'Volume':
|
||||||
|
df = df[['Close','Volume']]
|
||||||
|
|
||||||
|
price_vs_time = st.line_chart(data= df['Close'], width=500, height=400)
|
||||||
|
volume_vs_time = st.bar_chart(data=df['Volume'], width=500, height=150)
|
||||||
|
|
||||||
|
df = df.to_csv()
|
||||||
|
st.download_button(label=f'Download Data',data=df,file_name=f'{stock}.csv')
|
||||||
|
|
||||||
|
if indicator == 'Force Index':
|
||||||
|
window_slider_expander = st.expander(label='Force Index Parameters')
|
||||||
|
window_slider = window_slider_expander.slider(label='Window', value=13, min_value=1, max_value=20)
|
||||||
|
|
||||||
|
df[f'fi_{window_slider}'] = volume.force_index(close=df['Close'],volume=df['Volume'], window=window_slider)
|
||||||
|
|
||||||
|
df = df[['Close','Volume',f'fi_{window_slider}']]
|
||||||
|
|
||||||
|
price_vs_time = st.line_chart(data= df['Close'], width=500, height=400)
|
||||||
|
fi_vs_time = st.area_chart(data= df[f'fi_{window_slider}'],width=500, height=200)
|
||||||
|
|
||||||
|
df = df.to_csv()
|
||||||
|
st.download_button(label=f'Download Data',data=df,file_name=f'{stock}.csv')
|
||||||
|
|
||||||
|
if indicator_types == 'Trend':
|
||||||
|
indicator = st.selectbox(label='Indicator', options=trend_types, key=1)
|
||||||
|
|
||||||
|
start = st.text_input(label='Start Year', value = '2018')
|
||||||
|
start = f'{start}-01-01'
|
||||||
|
|
||||||
|
df = get_data(start)
|
||||||
|
if indicator == 'Simple Moving Average':
|
||||||
|
|
||||||
|
window_slider_expander = st.expander(label='SMA Parameters')
|
||||||
|
window_slider_1 = window_slider_expander.slider(label='Window 1', value=30, min_value=1, max_value=200)
|
||||||
|
window_slider_2 = window_slider_expander.slider(label='Window 2', value=100, min_value=1, max_value=200)
|
||||||
|
|
||||||
|
df[f'sma{window_slider_1}'] = trend.sma_indicator(close=df['Close'], window=window_slider_1)
|
||||||
|
df[f'sma{window_slider_2}'] = trend.sma_indicator(close=df['Close'], window=window_slider_2)
|
||||||
|
|
||||||
|
df = df[['Close',f'sma{window_slider_1}',f'sma{window_slider_2}']]
|
||||||
|
|
||||||
|
sma_vs_time = st.line_chart(data=df, width=500, height=550)
|
||||||
|
|
||||||
|
df = df.to_csv()
|
||||||
|
st.download_button(label=f'Download Data',data=df,file_name=f'{stock}.csv')
|
||||||
|
|
||||||
|
if indicator == "Exponential Moving Average":
|
||||||
|
|
||||||
|
window_slider_expander = st.expander(label='EMA Parameters')
|
||||||
|
window_slider_1 = window_slider_expander.slider(label='Window 1', value=30, min_value=1, max_value=200)
|
||||||
|
window_slider_2 = window_slider_expander.slider(label='Window 2', value=100, min_value=1, max_value=200)
|
||||||
|
|
||||||
|
df[f'ema{window_slider_1}'] = trend.ema_indicator(close=df['Close'], window=window_slider_1)
|
||||||
|
df[f'ema{window_slider_2}'] = trend.ema_indicator(close=df['Close'], window=window_slider_2)
|
||||||
|
|
||||||
|
df = df[['Close',f'ema{window_slider_1}',f'ema{window_slider_2}']]
|
||||||
|
|
||||||
|
sma_vs_time = st.line_chart(data=df, width=500, height=550)
|
||||||
|
|
||||||
|
df = df.to_csv()
|
||||||
|
st.download_button(label=f'Download Data',data=df,file_name=f'{stock}.csv')
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
pandas==2.1.3
|
||||||
|
streamlit==1.28.2
|
||||||
|
ta==0.11.0
|
||||||
|
yfinance==0.2.32
|
||||||
|
watchdog==3.0.0
|
||||||
|
protobuf==4.25.1
|
||||||
Reference in New Issue
Block a user