Docker based proxy
This commit is contained in:
parent
812fc41c6e
commit
942e81775f
5 changed files with 152 additions and 149 deletions
123
README.md
123
README.md
|
@ -50,9 +50,9 @@ Follow the instructions [in the dashboard-dev-overrides
|
|||
repository](https://open.greenhost.net/stackspin/dashboard-dev-overrides#dashboard-dev-overrides)
|
||||
in order to set up a development-capable cluster.
|
||||
The end-points for the Dashboard,
|
||||
as well as Kratos and Hydra, will point to `localhost` in that cluster.
|
||||
As a result, you can run those components locally, and still log into Stackspin
|
||||
applications that run on the cluster.
|
||||
as well as Kratos and Hydra, will point to `http://stackspin_proxy:8081` in that cluster.
|
||||
As a result, you can run components using the `docker-compose` file in
|
||||
this repository, and still log into Stackspin applications that run on the cluster.
|
||||
|
||||
|
||||
## Setting up the local development environment
|
||||
|
@ -63,115 +63,42 @@ After this process is finished, the following will run locally:
|
|||
- The
|
||||
[dashboard-backend](https://open.greenhost.net/stackspin/dashboard-backend)
|
||||
|
||||
The following will be available on localhost through a proxy and port-forwards:
|
||||
The following will be available locally through a proxy and port-forwards:
|
||||
|
||||
- Hydra
|
||||
- Kratos
|
||||
- Hydra admin
|
||||
- Kratos admin and public
|
||||
- The MariaDB database connections
|
||||
|
||||
These need to be available locally, because Kratos wants to run on the same
|
||||
domain as the front-end that serves the login interface.
|
||||
|
||||
|
||||
### 1. Setup port forwards
|
||||
### 1. Setup hosts file
|
||||
|
||||
To be able to work on the dashboard,
|
||||
we have to configure our development system to access all the remote services and endpoints.
|
||||
|
||||
A helper script is available in this directory
|
||||
to setup and redirect the relevant ports locally.
|
||||
It will open ports 8000, 8080, 4445, 3306 to get access to all APIs.
|
||||
To use it, you'll need `kubectl` access to the cluster:
|
||||
|
||||
1. Install `kubectl` (available through `snap` on Linux)
|
||||
2. Download the kubeconfig: `scp root@stackspin.example.com:/etc/rancher/k3s/k3s.yaml kube_config_stackspin.example.com.yaml`
|
||||
3. Set `kubectl` to use the kubeconfig: `export KUBECONFIG=$PWD/kube_config_stackspin.example.com.yaml`.
|
||||
4. Test if it works:
|
||||
|
||||
```
|
||||
kubectl get ingress -n stackspin
|
||||
```
|
||||
|
||||
Should return something like:
|
||||
|
||||
```
|
||||
NAME CLASS HOSTS ADDRESS PORTS AGE
|
||||
hydra-public <none> sso.stackspin.example.com 213.108.110.5 80, 443 39d
|
||||
dashboard <none> dashboard.stackspin.example.com 213.108.110.5 80, 443 150d
|
||||
kube-prometheus-stack-grafana <none> grafana.stackspin.example.com 213.108.110.5 80, 443 108d
|
||||
kube-prometheus-stack-alertmanager <none> alertmanager.stackspin.example.com 213.108.110.5 80, 443 108d
|
||||
kube-prometheus-stack-prometheus <none> prometheus.stackspin.example.com 213.108.110.5 80, 443 108d
|
||||
```
|
||||
5. Run the script to forward ports of the services to your local setup:
|
||||
|
||||
```
|
||||
./set-port-forward.sh
|
||||
```
|
||||
|
||||
As long as the script runs, your connection stays open.
|
||||
End the script by pressing `ctrl + c` and your port-forwards will end as well.
|
||||
|
||||
### 2. Configure a local proxy
|
||||
|
||||
Because of strict CORS headers,
|
||||
we have to map the public Kratos API and login app,
|
||||
which we will run locally with a local proxy.
|
||||
|
||||
This can be done with any proxy server, here we use `nginx`.
|
||||
Be sure you have NGINX installed and listening on port 80 locally:
|
||||
`sudo apt-get install nginx` should be enough.
|
||||
|
||||
Now configure NGINX with this configuration in `/etc/nginx/sites-enabled/default`
|
||||
The application will run on `http://stackspin_proxy`. Add the following line to
|
||||
`/etc/hosts` to be able to access that from your browser:
|
||||
|
||||
```
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
|
||||
root /var/www/html;
|
||||
|
||||
index index.html;
|
||||
|
||||
server_name _;
|
||||
|
||||
# Flask app and dashboard-backend
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:5000/;
|
||||
proxy_redirect default;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
# Kratos APIs
|
||||
location /kratos/ {
|
||||
proxy_pass http://127.0.0.1:8080/;
|
||||
proxy_redirect default;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
}
|
||||
127.0.0.1 stackspin_proxy
|
||||
```
|
||||
|
||||
Reload your NGINX:
|
||||
### 2. Kubernetes access
|
||||
|
||||
The script needs you to have access to the Kubernetes cluster that runs
|
||||
Stackspin. Point the `KUBECONFIG` environment variable to a kubectl config. That
|
||||
kubeconfig will be mounted inside docker containers, so also make sure your
|
||||
Docker user can read it.
|
||||
|
||||
### 3. Run it all
|
||||
|
||||
Now, run this script that sets a few environment variables based on what is in
|
||||
your cluster secrets, and starts `docker-compose` to start a reverse proxy as
|
||||
well as the flask application in this repository.
|
||||
|
||||
```
|
||||
sudo systemctl reload nginx.service
|
||||
./run_app.sh
|
||||
```
|
||||
|
||||
### 3. Run FLASK app
|
||||
### 4. Front-end developmenet
|
||||
|
||||
Now it is time to start the flask app.
|
||||
Please make sure you are using Python 3 in your environment.
|
||||
And install the required dependencies:
|
||||
|
||||
```
|
||||
pip3 install -r requirements.txt
|
||||
```
|
||||
|
||||
Then copy `run_app.sh` to `run_app.local.sh` and change the secrets defined in it.
|
||||
|
||||
You can now start the app by running
|
||||
|
||||
```
|
||||
./run_app.local.sh
|
||||
```
|
||||
|
||||
Lastly, start the [dashboard front-end app](https://open.greenhost.net/stackspin/dashboard/#yarn-start)
|
||||
Start the [dashboard front-end app](https://open.greenhost.net/stackspin/dashboard/#yarn-start).
|
||||
|
|
75
docker-compose.yml
Normal file
75
docker-compose.yml
Normal file
|
@ -0,0 +1,75 @@
|
|||
version: '3'
|
||||
services:
|
||||
stackspin_proxy:
|
||||
image: nginx:1.22.0
|
||||
ports:
|
||||
- "8081:8081"
|
||||
volumes:
|
||||
- ./proxy/default.conf:/etc/nginx/conf.d/default.conf
|
||||
depends_on:
|
||||
- kube_port_kratos_public
|
||||
- flask_app
|
||||
flask_app:
|
||||
build: .
|
||||
environment:
|
||||
- FLASK_APP=app.py
|
||||
- FLASK_ENV=development
|
||||
- HYDRA_CLIENT_ID=dashboard-local
|
||||
|
||||
# Domain-specific URL settings
|
||||
- HYDRA_AUTHORIZATION_BASE_URL=https://sso.$DOMAIN/oauth2/auth
|
||||
- TOKEN_URL=https://sso.$DOMAIN/oauth2/token
|
||||
- HYDRA_PUBLIC_URL=https://sso.$DOMAIN
|
||||
|
||||
# Local path overrides
|
||||
- KRATOS_PUBLIC_URL=http://stackspin_proxy:8081/kratos
|
||||
- KRATOS_ADMIN_URL=http://kube_port_kratos_admin:8000
|
||||
- HYDRA_ADMIN_URL=http://kube_port_hydra_admin:4445
|
||||
- LOGIN_PANEL_URL=http://stackspin_proxy:8081/web/
|
||||
- DATABASE_URL=mysql+pymysql://stackspin:$DATABASE_PASSWORD@kube_port_mysql/stackspin
|
||||
|
||||
# ENV variables that are deployment-specific
|
||||
- SECRET_KEY=$FLASK_SECRET_KEY
|
||||
- HYDRA_CLIENT_SECRET=$HYDRA_CLIENT_SECRET
|
||||
# - OAUTHLIB_INSECURE_TRANSPORT=1
|
||||
ports:
|
||||
- "5000:5000"
|
||||
volumes:
|
||||
- .:/app
|
||||
depends_on:
|
||||
- kube_port_mysql
|
||||
entrypoint: ["bash", "-c", "flask run --host $$(hostname -i)"]
|
||||
kube_port_kratos_admin:
|
||||
image: bitnami/kubectl:1.24.1
|
||||
user: "${KUBECTL_UID}:${KUBECTL_GID}"
|
||||
expose:
|
||||
- 8000
|
||||
volumes:
|
||||
- "$KUBECONFIG:/.kube/config"
|
||||
entrypoint: ["bash", "-c", "kubectl -n stackspin port-forward --address $$(hostname -i) service/kratos-admin 8000:80"]
|
||||
kube_port_hydra_admin:
|
||||
image: bitnami/kubectl:1.24.1
|
||||
user: "${KUBECTL_UID}:${KUBECTL_GID}"
|
||||
expose:
|
||||
- 4445
|
||||
volumes:
|
||||
- "$KUBECONFIG:/.kube/config"
|
||||
entrypoint: ["bash", "-c", "kubectl -n stackspin port-forward --address $$(hostname -i) service/hydra-admin 4445:4445"]
|
||||
kube_port_kratos_public:
|
||||
image: bitnami/kubectl:1.24.1
|
||||
user: "${KUBECTL_UID}:${KUBECTL_GID}"
|
||||
ports:
|
||||
- "8080:8080"
|
||||
expose:
|
||||
- 8080
|
||||
volumes:
|
||||
- "$KUBECONFIG:/.kube/config"
|
||||
entrypoint: ["bash", "-c", "kubectl -n stackspin port-forward --address $$(hostname -i) service/kratos-public 8080:80"]
|
||||
kube_port_mysql:
|
||||
image: bitnami/kubectl:1.24.1
|
||||
user: "${KUBECTL_UID}:${KUBECTL_GID}"
|
||||
expose:
|
||||
- 3306
|
||||
volumes:
|
||||
- "$KUBECONFIG:/.kube/config"
|
||||
entrypoint: ["bash", "-c", "kubectl -n stackspin port-forward --address $$(hostname -i) service/single-sign-on-database-mariadb 3306:3306"]
|
26
proxy/default.conf
Normal file
26
proxy/default.conf
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Default server configuration
|
||||
#
|
||||
server {
|
||||
listen 8081 default_server;
|
||||
listen [::]:8081 default_server;
|
||||
|
||||
root /var/www/html;
|
||||
|
||||
index index.html;
|
||||
|
||||
server_name _;
|
||||
|
||||
# Flask app
|
||||
location / {
|
||||
proxy_pass http://flask_app:5000/;
|
||||
proxy_redirect default;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
# Kratos Public
|
||||
location /kratos/ {
|
||||
proxy_pass http://kube_port_kratos_public:8080/;
|
||||
proxy_redirect default;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
}
|
59
run_app.sh
59
run_app.sh
|
@ -1,39 +1,32 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[1;31m'
|
||||
NC='\033[0m' # No Color
|
||||
set -euo pipefail
|
||||
|
||||
# Check if kratos port is open
|
||||
if nc -z localhost 8000;
|
||||
then
|
||||
echo -e "${GREEN}Great! It looks like the Kratos Admin port is available${NC}"
|
||||
else
|
||||
echo -e "${RED}**********************************************************${NC}"
|
||||
echo -e "${RED}WARNING! It looks like the Kratos Admin port NOT available${NC}"
|
||||
echo -e "${RED}please run in a seperate terminal: ${NC}"
|
||||
echo -e "${RED} ${NC}"
|
||||
echo -e "${RED}./set-port-forward.sh ${NC}"
|
||||
echo -e "${RED} ${NC}"
|
||||
echo -e "${RED}We will continue to start the app after 5 seconds. ${NC}"
|
||||
echo -e "${RED}**********************************************************${NC}"
|
||||
sleep 5
|
||||
export DATABASE_PASSWORD=$(kubectl get secret -n flux-system stackspin-single-sign-on-variables -o jsonpath --template '{.data.dashboard_database_password}' | base64 -d)
|
||||
export DOMAIN=$(kubectl get secret -n flux-system stackspin-cluster-variables -o jsonpath --template '{.data.domain}' | base64 -d)
|
||||
export HYDRA_CLIENT_SECRET=$(kubectl get secret -n flux-system stackspin-dashboard-local-oauth-variables -o jsonpath --template '{.data.client_secret}' | base64 -d)
|
||||
export FLASK_SECRET_KEY=$(kubectl get secret -n flux-system stackspin-dashboard-variables -o jsonpath --template '{.data.backend_secret_key}' | base64 -d)
|
||||
|
||||
|
||||
if [[ -z "$DATABASE_PASSWORD" ]]; then
|
||||
echo "Could not find database password in stackspin-single-sign-on-variables secret"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export FLASK_APP=app.py
|
||||
export FLASK_ENV=development
|
||||
export SECRET_KEY="e38hq!@0n64g@qe6)5csk41t=ljo2vllog(%k7njnm4b@kh42c"
|
||||
export HYDRA_CLIENT_ID="dashboard-local"
|
||||
export HYDRA_CLIENT_SECRET="gDSEuakxzybHBHJocnmtDOLMwlWWEvPh"
|
||||
export HYDRA_AUTHORIZATION_BASE_URL="https://sso.init.stackspin.net/oauth2/auth"
|
||||
export TOKEN_URL="https://sso.init.stackspin.net/oauth2/token"
|
||||
if [[ -z "$DOMAIN" ]]; then
|
||||
echo "Could not find domain name in stackspin-cluster-variables secret"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Login facilitator paths
|
||||
export KRATOS_PUBLIC_URL=http://localhost/kratos
|
||||
export KRATOS_ADMIN_URL=http://localhost:8000
|
||||
export HYDRA_PUBLIC_URL="https://sso.init.stackspin.net"
|
||||
export HYDRA_ADMIN_URL=http://localhost:4445
|
||||
export LOGIN_PANEL_URL=http://localhost/web/
|
||||
#export DATABASE_URL="mysql+pymysql://stackspin:stackspin@localhost/stackspin?charset=utf8mb4"
|
||||
export DATABASE_URL="mysql+pymysql://stackspin:OZBSDkMdbdvEIOomnwpOqLdaiHDKbzWY@localhost/stackspin"
|
||||
if [[ -z "$FLASK_SECRET_KEY" ]]; then
|
||||
echo "Could not find backend_secret_key in stackspin-dashboard-variables secret"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
flask run
|
||||
if [[ -z "$HYDRA_CLIENT_SECRET" ]]; then
|
||||
echo "Could not find client_secret in stackspin-dashboard-local-oauth-variables secret"
|
||||
echo "make sure you add this secret following instructions in the dashboard-dev-overrides repository"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
KUBECTL_UID=${UID:-1001} KUBECTL_GID=${GID:-0} docker compose up
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "
|
||||
kratos admin port will be at localhost: 8000
|
||||
kratos public port will be at localhost: 8080
|
||||
hydra admin port will be at localhost: 4445
|
||||
mysql port will be at localhost: 3306
|
||||
"
|
||||
|
||||
# Kill all processes when this script ends
|
||||
trap "exit" INT TERM ERR
|
||||
trap "kill 0" EXIT
|
||||
|
||||
# Add forwarded ports for all processes
|
||||
kubectl port-forward -n stackspin service/kratos-admin 8000:80 &
|
||||
kubectl port-forward -n stackspin service/kratos-public 8080:80 &
|
||||
kubectl port-forward -n stackspin service/hydra-admin 4445:4445 &
|
||||
kubectl port-forward -n stackspin service/single-sign-on-database-mariadb 3306:3306
|
Loading…
Reference in a new issue