diff --git a/README.md b/README.md index 82047f9..b9bc2fb 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ and To build the Docker image, run ``` -.\build_docker.sh +.\build_docker.sh ``` You will need to have already created your `credentials.py`, as explained above. To install the Helm chart type ``` diff --git a/backend/main.py b/backend/main.py index 4ca028b..342ba55 100644 --- a/backend/main.py +++ b/backend/main.py @@ -22,6 +22,9 @@ from fastapi.exception_handlers import http_exception_handler from starlette.exceptions import HTTPException as StarletteHTTPException +credentials.redirect_uri = os.environ.get('SPOTIFY_REDIRECT_URI', + credentials.redirect_uri) + # create tables if necessary models.Base.metadata.create_all(bind=engine) diff --git a/build_docker.sh b/build_docker.sh index ca0f9bc..a4f8267 100755 --- a/build_docker.sh +++ b/build_docker.sh @@ -2,5 +2,4 @@ eval $(minikube -p minikube docker-env) docker build . \ --file helm-chart/images/Dockerfile \ - --tag teticio/deejai \ - --build-arg APP_URL=${1-http://localhost:8080} + --tag teticio/deejai diff --git a/deploy_kops.sh b/deploy_kops.sh index 7273c4c..f6a983a 100755 --- a/deploy_kops.sh +++ b/deploy_kops.sh @@ -1,22 +1,51 @@ export NAME=deejai.${1-teticio.co.uk} export KOPS_STATE_STORE=s3://clusters.${1-teticio.co.uk} +export AWS_REGION=${2-us-east-1} +export AWS_ACCESS_KEY_ID=$(aws configure get default.aws_access_key_id) +export AWS_SECRET_ACCESS_KEY=$(aws configure get default.aws_secret_access_key) + kops create cluster \ - --zones=us-east-1a \ - --node-count=2 \ - --node-size="t3.large" \ - ${NAME} + --zones=${AWS_REGION}a \ + --node-count=2 \ + --node-size="t3.large" \ + ${NAME} kops update cluster ${NAME} --yes --admin -kops validate cluster --wait 10m +kops validate cluster ${NAME} --wait 20m + +# install ingress-nginx +helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx +helm repo update +helm upgrade \ + --install nginx ingress-nginx/ingress-nginx \ + --create-namespace \ + --namespace deejai \ + --version 4.0.1 + +# install cert-manager +helm repo add jetstack https://charts.jetstack.io +helm repo update +helm upgrade \ + --install cert-manager jetstack/cert-manager \ + --create-namespace \ + --namespace cert-manager \ + --version v1.5.3 \ + --set installCRDs=true + +# install deejai chart helm upgrade \ --install deejai helm-chart/deejai \ --create-namespace \ --namespace deejai \ --values helm-chart/deejai/values.yaml \ - --set service.type=LoadBalancer \ - --set service.port=80 \ + --set domain=${1-teticio.co.uk} \ + --set url=https://${1-teticio.co.uk} \ + --set ingress.enabled=true \ + --set letsencrypt.enabled=true \ + --set letsencrypt.email=teticio@gmail.com \ --set image.pullPolicy=Always \ --set autoscaling.enabled=true -# install dashboard + +# install dashboard and metrics-server kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.5/aio/deploy/recommended.yaml kubectl apply -f https://raw.githubusercontent.com/kubernetes/kops/master/addons/metrics-server/v1.16.x.yaml kubectl create serviceaccount dashboard -n default @@ -25,6 +54,9 @@ kubectl get secret $(kubectl get serviceaccount dashboard -o jsonpath="{.secrets echo echo "kubectl proxy" echo "http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/login#" -# kops delete cluster --name ${NAME} --yes -# while true; do curl -X 'GET' `http://${NAME}/api/v1/search?string=a&max_items=100` -H 'accept: application/json'; done -# while true; do curl -X 'GET' `http://${NAME}/api/v1/search_similar?url=https%3A%2F%2Fp.scdn.co%2Fmp3-preview%2Fb8879c1f8a68d43439c969069590013ec8447abb%3Fcid%3D1a7897e3c69d4684aa4d8e90d5911594&max_items=10`; done \ No newline at end of file + +# load tests +# while true; do curl -X 'GET' 'https://teticio.co.uk/api/v1/search?string=a&max_items=100' -H 'accept: application/json'; done +# while true; do curl -X 'GET' 'https://teticio.co.uk/api/v1/search_similar?url=https%3A%2F%2Fp.scdn.co%2Fmp3-preview%2Fb8879c1f8a68d43439c969069590013ec8447abb%3Fcid%3D1a7897e3c69d4684aa4d8e90d5911594&max_items=10'; done + +# kops delete cluster --name ${NAME} --yes \ No newline at end of file diff --git a/helm-chart/deejai/templates/deployment.yaml b/helm-chart/deejai/templates/deployment.yaml index 7ce7fe0..061fbd3 100644 --- a/helm-chart/deejai/templates/deployment.yaml +++ b/helm-chart/deejai/templates/deployment.yaml @@ -59,6 +59,12 @@ spec: key: mysql-root-password - name: SQLALCHEMY_DATABASE_URL value: mysql+pymysql://root:$(MYSQL_ROOT_PASSWORD)@mysql:3306/deejai + - name: APP_URL + value: {{ .Values.app.url }} + - name: REACT_APP_API_URL + value: $(APP_URL)/api/v1 + - name: SPOTIFY_REDIRECT_URI + value: $(REACT_APP_API_URL)/callback ports: - name: http containerPort: 8000 diff --git a/helm-chart/deejai/templates/letsencrypt.yaml b/helm-chart/deejai/templates/letsencrypt.yaml new file mode 100644 index 0000000..b563092 --- /dev/null +++ b/helm-chart/deejai/templates/letsencrypt.yaml @@ -0,0 +1,27 @@ +{{- if .Values.letsencrypt.enabled }} +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: letsencrypt +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + # server: https://acme-staging-v02.api.letsencrypt.org/directory + email: {{ .Values.letsencrypt.email }} + privateKeySecretRef: + name: letsencrypt + solvers: + - http01: + ingress: + class: nginx +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ .Chart.Name }} +spec: + secretName: {{ .Chart.Name }}-tls + issuerRef: + name: letsencrypt + dnsNames: {{ .Values.letsencrypt.dnsNames }} +{{- end }} diff --git a/helm-chart/deejai/templates/secret.yaml b/helm-chart/deejai/templates/secret.yaml index 6cb16f4..7a0a861 100644 --- a/helm-chart/deejai/templates/secret.yaml +++ b/helm-chart/deejai/templates/secret.yaml @@ -8,4 +8,4 @@ data: mysql-root-password: {{ .Values.mysqlRootPassword | b64enc | quote }} {{ else }} mysql-root-password: {{ randAlphaNum 10 | b64enc | quote }} - {{ end }} \ No newline at end of file + {{ end }} diff --git a/helm-chart/deejai/values.yaml b/helm-chart/deejai/values.yaml index ae40371..dc14352 100644 --- a/helm-chart/deejai/values.yaml +++ b/helm-chart/deejai/values.yaml @@ -4,13 +4,17 @@ replicaCount: 1 +app: + domain: &domain teticio.co.uk + url: &url https://teticio.co.uk + image: repository: teticio/deejai pullPolicy: IfNotPresent # Overrides the image tag whose default is the chart appVersion. tag: "" ports: - - containerPort: http + - containerPort: http imagePullSecrets: [] nameOverride: "" @@ -27,10 +31,12 @@ serviceAccount: podAnnotations: {} -podSecurityContext: {} +podSecurityContext: + {} # fsGroup: 2000 -securityContext: {} +securityContext: + {} # capabilities: # drop: # - ALL @@ -44,20 +50,21 @@ service: ingress: enabled: false - annotations: {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" + annotations: + kubernetes.io/ingress.class: nginx + cert-manager.io/cluster-issuer: letsencrypt + kubernetes.io/tls-acme: "true" hosts: - - host: chart-example.local + - host: *domain paths: - - path: / - backend: - serviceName: chart-example.local - servicePort: 80 - tls: [] - # - secretName: chart-example-tls - # hosts: - # - chart-example.local + - path: / + backend: + serviceName: deejai + servicePort: 80 + tls: + - secretName: deejai-tls + hosts: + - *domain resources: # We usually recommend not to specify default resources and to leave this as a conscious @@ -91,7 +98,7 @@ deployment: port: http initialDelaySeconds: 0 periodSeconds: 5 - failureThreshold: 1000 # we rely on the liveness probe to resolve issues if needed + failureThreshold: 1000 # we rely on the liveness probe to resolve issues if needed timeoutSeconds: 3 livenessProbe: enabled: true @@ -101,3 +108,9 @@ deployment: periodSeconds: 5 failureThreshold: 3 timeoutSeconds: 10 + +letsencrypt: + enabled: false + email: hi@there.com + dnsNames: + - *domain diff --git a/helm-chart/images/Dockerfile b/helm-chart/images/Dockerfile index 941eda2..989dac1 100644 --- a/helm-chart/images/Dockerfile +++ b/helm-chart/images/Dockerfile @@ -1,11 +1,10 @@ FROM python:3.8 -ARG APP_URL -ENV APP_URL $APP_URL +# ARG APP_URL +# ENV SPOTIFY_REDIRECT_URI $APP_URL/api/v1/callback +# ENV REACT_APP_API_URL $APP_URL/api/v1 ENV CUDA_VISIBLE_DEVICES "" COPY . /deej-ai.online-app WORKDIR "/deej-ai.online-app" -RUN sed -i "s|\(http\)[^/]*/[^/]*/[^/]*/|${APP_URL}/|g" .env.production && \ - sed -i "s|\(http\)[^/]*/[^/]*/[^/]*/|${APP_URL}/|g" backend/credentials.py RUN apt update && \ apt install ffmpeg libsndfile-dev nodejs npm -y RUN npm install --global yarn && \ @@ -13,5 +12,5 @@ RUN npm install --global yarn && \ yarn install && \ yarn build && \ pip install -r requirements-lock.txt -CMD ["uvicorn", "backend.main:app", "--reload", "--host=0.0.0.0"] +CMD yarn build && uvicorn backend.main:app --host=0.0.0.0 EXPOSE 8000 diff --git a/install_helm_chart.sh b/install_helm_chart.sh index 18b1b0d..6c925ca 100755 --- a/install_helm_chart.sh +++ b/install_helm_chart.sh @@ -6,4 +6,5 @@ helm upgrade \ --create-namespace \ --namespace deejai \ --values helm-chart/deejai/values.yaml \ + --set app.url=http://localhost:8080 \ --set mysqlRootPassword=password diff --git a/src/App.js b/src/App.js index 771518e..34badfb 100644 --- a/src/App.js +++ b/src/App.js @@ -7,6 +7,7 @@ // fix warning about combining h2 and a in Banner // // backend: +// handle exceptions in db (e.g., no playlists) // set seed in noise // bug in join the dots?