diff --git a/.dockerignore b/.dockerignore index 0b4af7b428..ca30ad138c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,4 +3,20 @@ settings web .drone.yml install.sh -uninstall.sh \ No newline at end of file +uninstall.sh + +server/tools +!server/tools/dbs/*.js +!server/tools/general/*.js +!server/tools/nexe +Dockerfile +server/docker-compose* +server/index.html +server/package-lock.json +server/logs +server/coverage +server/.nyc_output +server/.*docker-compose.yaml +server/.drone*.yml +server/hollaex-kit.env +server/hollaex-kit.env* \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9fdc282cfe..7bef90e650 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,8 @@ build # surge web/CNAME server/tools/hollaex-kit.env.local +server/tools/nginx-dev/logs/* +nginx/logs/* # misc web/.DS_Store @@ -64,7 +66,4 @@ templates/kubernetes/config/* .DS_Store .token -backups - -settings -settings/* \ No newline at end of file +backups \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index f705f3bd91..1ade76db15 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,8 +24,6 @@ RUN npm install --loglevel=error && \ pm2 update && \ cd /app/mail && npm install --loglevel=error -EXPOSE 10010 - -EXPOSE 10080 +EXPOSE 10010 10080 10011 ENTRYPOINT ["/entrypoint.sh"] diff --git a/install.sh b/install.sh index b96ea71a80..395bead857 100644 --- a/install.sh +++ b/install.sh @@ -1,18 +1,20 @@ #!/bin/bash +export ARCH=$(uname -m | sed s/aarch64/arm64/ | sed s/x86_64/amd64/ | sed s/s390x/s390x/) + # Dependencies installer for Debian (Ubuntu) based Linux. -if command apt-get -v > /dev/null 2>&1; then +if command apt -v > /dev/null 2>&1; then if ! command curl --version > /dev/null 2>&1; then printf "\n\033[93mHollaEx CLI requires CURL to operate. Installing it now...\033[39m\n" echo "Updating APT list" - sudo apt-get update + sudo apt update IS_APT_UPDATED=true echo "Installing Docker" - if command sudo apt-get install -y curl; then + if command sudo apt install -y curl; then printf "\n\033[92mCURL has been successfully installed!\033[39m\n" echo "Info: $(curl --version)" @@ -20,7 +22,7 @@ if command apt-get -v > /dev/null 2>&1; then else printf "\n\033[91mFailed to install CURL.\033[39m\n" - echo "Please review the logs and try to manually install it. - 'sudo apt-get install -y curl'." + echo "Please review the logs and try to manually install it. - 'sudo apt install -y curl'." exit 1; fi @@ -32,11 +34,11 @@ if command apt-get -v > /dev/null 2>&1; then printf "\n\033[93mHollaEx CLI requires Docker to operate. Installing it now...\033[39m\n" echo "Updating APT list" - sudo apt-get update + sudo apt update IS_APT_UPDATED=true echo "Installing Docker" - if command sudo apt-get install -y docker.io; then + if command sudo apt install -y docker.io; then printf "\n\033[92mDocker has been successfully installed!\033[39m\n" echo "Info: $(docker -v)" @@ -51,33 +53,33 @@ if command apt-get -v > /dev/null 2>&1; then else printf "\n\033[91mFailed to install Docker.\033[39m\n" - echo "Please review the logs and try to manually install it. - 'sudo apt-get install -y docker.io'." + echo "Please review the logs and try to manually install it. - 'sudo apt install -y docker.io'." exit 1; fi fi - if ! command docker-compose -v > /dev/null 2>&1; then + if ! command docker compose version > /dev/null 2>&1; then - printf "\n\033[93mHollaEx CLI requires Docker-Compose to operate. Installing it now...\033[39m\n" + printf "\n\033[93mHollaEx CLI requires docker compose v2 to operate. Installing it now...\033[39m\n" if [[ ! $IS_APT_UPDATED ]]; then echo "Updating APT list" - sudo apt-get update + sudo apt update fi - if command sudo apt-get install -y docker-compose; then + if command sudo apt install -y docker-compose-v2; then - printf "\n\033[92mDocker-Compose has been successfully installed!\033[39m\n" + printf "\n\033[92mdocker compose v2 has been successfully installed!\033[39m\n" - echo "Info: $(docker-compose -v)" + echo "Info: $(docker compose version)" else - printf "\n\033[91mFailed to install Docker-Compose.\033[39m\n" - echo "Please review the logs and try to manually install it. - 'sudo apt-get install -y docker-compose'." + printf "\n\033[91mFailed to install docker compose v2.\033[39m\n" + echo "Please review the logs and try to manually install it. - 'sudo apt install -y docker compose'." exit 1; fi @@ -91,10 +93,10 @@ if command apt-get -v > /dev/null 2>&1; then if [[ ! $IS_APT_UPDATED ]]; then echo "Updating APT list" - sudo apt-get update + sudo apt update fi - if command sudo apt-get install -y jq; then + if command sudo apt install -y jq; then printf "\n\033[92mjq has been successfully installed!\033[39m\n" @@ -103,7 +105,28 @@ if command apt-get -v > /dev/null 2>&1; then else printf "\n\033[91mFailed to install jq.\033[39m\n" - echo "Please review the logs and try to manually install it. - 'sudo apt-get install -y jq'." + echo "Please review the logs and try to manually install it. - 'sudo apt install -y jq'." + + fi + + fi + + if ! command yq --version > /dev/null 2>&1; then + + printf "\n\033[93mHollaEx CLI requires yq to operate. Installing it now...\033[39m\n" + + if command sudo curl -L https://github.com/mikefarah/yq/releases/download/v4.44.1/yq_$(uname -s)_$ARCH -o /usr/local/bin/yq; then + + chmod +x /usr/local/bin/yq + + printf "\n\033[92myq has been successfully installed!\033[39m\n" + + echo "Info: $(yq --version)" + + else + + printf "\n\033[91mFailed to install yq.\033[39m\n" + echo "Please review the logs and try to manually install it. - 'sudo apt install -y jq'." fi @@ -116,10 +139,10 @@ if command apt-get -v > /dev/null 2>&1; then if [[ ! $IS_APT_UPDATED ]]; then echo "Updating APT list" - sudo apt-get update + sudo apt update fi - if command sudo apt-get install -y dnsutils; then + if command sudo apt install -y dnsutils; then printf "\n\033[92mnslookup(dnsutils) has been successfully installed!\033[39m\n" @@ -129,7 +152,7 @@ if command apt-get -v > /dev/null 2>&1; then else printf "\n\033[91mFailed to install nslookup.\033[39m\n" - echo "Please review the logs and try to manually install it. - 'sudo apt-get install -y dnsutils'." + echo "Please review the logs and try to manually install it. - 'sudo apt install -y dnsutils'." fi @@ -142,11 +165,11 @@ if command apt-get -v > /dev/null 2>&1; then if [[ ! $IS_APT_UPDATED ]]; then echo "Updating APT list" - sudo apt-get update + sudo apt update fi echo "Installing Docker" - if command sudo apt-get install -y postgresql-client; then + if command sudo apt install -y postgresql-client; then printf "\n\033[92mPSQL Client has been successfully installed!\033[39m\n" echo "Info: $(psql --version)" @@ -154,7 +177,7 @@ if command apt-get -v > /dev/null 2>&1; then else printf "\n\033[91mFailed to install PSQL Client.\033[39m\n" - echo "Please review the logs and try to manually install it. - 'sudo apt-get install -y postgresql-client'." + echo "Please review the logs and try to manually install it. - 'sudo apt install -y postgresql-client'." exit 1; fi @@ -228,9 +251,9 @@ elif command brew -v > /dev/null 2>&1; then fi - if ! command docker-compose -v > /dev/null 2>&1; then + if ! command docker compose version > /dev/null 2>&1; then - printf "\n\033[93mHollaEx CLI requires Docker-Compose to operate. Installing it now...\033[39m\n" + printf "\n\033[93mHollaEx CLI requires docker compose to operate. Installing it now...\033[39m\n" if [[ ! $IS_BREW_UPDATED ]]; then @@ -238,16 +261,16 @@ elif command brew -v > /dev/null 2>&1; then brew update fi - if command brew install docker-compose; then + if command brew install docker compose; then - printf "\n\033[92mDocker-Compose has been successfully installed!\033[39m\n" + printf "\n\033[92mdocker compose has been successfully installed!\033[39m\n" - echo "Info: $(docker-compose -v)" + echo "Info: $(docker compose version)" else - printf "\n\033[91mFailed to install Docker-Compose.\033[39m\n" - echo "Please review the logs and try to manually install it. - 'brew install docker-compose'." + printf "\n\033[91mFailed to install docker compose.\033[39m\n" + echo "Please review the logs and try to manually install it. - 'brew install docker compose'." exit 1; fi @@ -279,6 +302,31 @@ elif command brew -v > /dev/null 2>&1; then fi + if ! command yq --version > /dev/null 2>&1; then + + printf "\n\033[93mHollaEx CLI requires yq to operate. Installing it now...\033[39m\n" + + if [[ ! $IS_BREW_UPDATED ]]; then + + echo "Updating Homebrew list" + brew update + fi + + if command brew install yq; then + + printf "\n\033[92myq has been successfully installed!\033[39m\n" + + echo "Info: $(yq --version)" + + else + + printf "\n\033[91mFailed to install yq.\033[39m\n" + echo "Please review the logs and try to manually install it. - 'brew install yq'." + + fi + + fi + if ! command psql --version > /dev/null 2>&1; then printf "\n\033[93mHollaEx CLI requires PSQL Client to operate. Installing it now...\033[39m\n" @@ -366,21 +414,21 @@ elif command yum --version > /dev/null 2>&1; then fi - if ! command docker-compose -v > /dev/null 2>&1; then + if ! command docker compose version > /dev/null 2>&1; then - printf "\n\033[93mHollaEx CLI requires Docker-Compose to operate. Installing it now...\033[39m\n" + printf "\n\033[93mHollaEx CLI requires docker compose to operate. Installing it now...\033[39m\n" - if command sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose; then + if command sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker compose; then - sudo chmod +x /usr/local/bin/docker-compose + sudo chmod +x /usr/local/bin/docker compose - printf "\n\033[92mDocker-Compose has been successfully installed!\033[39m\n" + printf "\n\033[92mdocker compose has been successfully installed!\033[39m\n" - echo "Info: $(docker-compose -v)" + echo "Info: $(docker compose version)" else - printf "\n\033[91mFailed to install Docker-Compose.\033[39m\n" + printf "\n\033[91mFailed to install docker compose.\033[39m\n" echo "Please review the logs and try to manually install it. - 'https://github.com/docker/compose/releases'." exit 1; @@ -407,6 +455,27 @@ elif command yum --version > /dev/null 2>&1; then fi + if ! command yq --version > /dev/null 2>&1; then + + printf "\n\033[93mHollaEx CLI requires yq to operate. Installing it now...\033[39m\n" + + if command sudo curl -L https://github.com/mikefarah/yq/releases/download/v4.44.1/yq_$(uname -s)_$ARCH -o /usr/local/bin/yq; then + + chmod +x /usr/local/bin/yq + + printf "\n\033[92myq has been successfully installed!\033[39m\n" + + echo "Info: $(yq --version)" + + else + + printf "\n\033[91mFailed to install yq.\033[39m\n" + echo "Please review the logs and try to manually install it. - 'sudo apt install -y jq'." + + fi + + fi + if ! command nslookup -version > /dev/null 2>&1; then printf "\n\033[93mHollaEx CLI requires nslookup to operate. Installing it now...\033[39m\n" @@ -449,7 +518,7 @@ elif command yum --version > /dev/null 2>&1; then fi -if ! command docker -v > /dev/null 2>&1 || ! command docker-compose -v > /dev/null 2>&1 || ! command curl --version > /dev/null 2>&1 || ! command jq --version > /dev/null 2>&1 || ! command nslookup -version > /dev/null 2>&1 || ! command psql --version > /dev/null 2>&1; then +if ! command docker -v > /dev/null 2>&1 || ! command docker compose version > /dev/null 2>&1 || ! command curl --version > /dev/null 2>&1 || ! command jq --version > /dev/null 2>&1 || ! command nslookup -version > /dev/null 2>&1 || ! command psql --version > /dev/null 2>&1; then if command docker -v > /dev/null 2>&1; then @@ -457,7 +526,7 @@ if ! command docker -v > /dev/null 2>&1 || ! command docker-compose -v > /dev/nu fi - if command docker-compose -v > /dev/null 2>&1; then + if command docker compose version > /dev/null 2>&1; then IS_DOCKER_COMPOSE_INSTALLED=true @@ -486,8 +555,14 @@ if ! command docker -v > /dev/null 2>&1 || ! command docker-compose -v > /dev/nu IS_PSQL_CLIENT_INSTALLED=true fi + + if command yq --version > /dev/null 2>&1; then + + IS_YQ_CLIENT_INSTALLED=true - printf "\n\033[93mNote: HollaEx CLI requires Docker, Docker-Compose, and jq to operate.\033[39m\n\n" + fi + + printf "\n\033[93mNote: HollaEx CLI requires Docker, docker compose, and jq to operate.\033[39m\n\n" # Docker installation status chekc if [[ "$IS_DOCKER_INSTALLED" ]]; then @@ -500,14 +575,14 @@ if ! command docker -v > /dev/null 2>&1 || ! command docker-compose -v > /dev/nu fi - # Docker-compose installation status check + # docker compose installation status check if [[ "$IS_DOCKER_COMPOSE_INSTALLED" ]]; then - printf "\033[92mDocker-Compose: Installed\033[39m\n" + printf "\033[92mdocker compose: Installed\033[39m\n" else - printf "\033[91mDocker-Compose: Not Installed\033[39m\n" + printf "\033[91mdocker compose: Not Installed\033[39m\n" fi @@ -554,6 +629,17 @@ if ! command docker -v > /dev/null 2>&1 || ! command docker-compose -v > /dev/nu fi + # yq installation status check + if [[ "$IS_YQ_INSTALLED" ]]; then + + printf "\033[92myq: Installed\033[39m\n" + + else + + printf "\033[91myq: Not Installed\033[39m\n" + + fi + printf "\n\033[93mPlease install the missing one before you proceed to run exchange.\033[39m\n" else @@ -583,4 +669,103 @@ if [[ "$DOCKER_USERGROUP_ADDED" ]]; then fi + +function kit_cross_compatibility_converter() { + + CONFIG_FILE_PATH=$(pwd)/settings/* + + for i in ${CONFIG_FILE_PATH[@]}; do + source $i + done; + + # File conversion + if [[ -f "$(pwd)/templates/local/$ENVIRONMENT_EXCHANGE_NAME.env.local" ]]; then + + echo "Env file generated with HollaEx CLI v2 has been detected!" + echo "Converting it to the v3 format..." + mv $(pwd)/templates/local/$ENVIRONMENT_EXCHANGE_NAME.env.local $(pwd)/server/hollaex-kit.env + + fi + + + if [[ -f "$(pwd)/templates/local/$ENVIRONMENT_EXCHANGE_NAME-docker-compose.yaml" ]]; then + + echo "Docker-compose file generated with HollaEx CLI v2 has been detected!" + + echo "Converting the Docker-Compose file..." + yq "del(.services.$ENVIRONMENT_EXCHANGE_NAME-nginx)" $(pwd)/templates/local/$ENVIRONMENT_EXCHANGE_NAME-docker-compose.yaml > $(pwd)/server/docker-compose-prod.yaml + yq e -i '.services.*.env_file[] = "hollaex-kit.env"' $(pwd)/server/docker-compose-prod.yaml + + echo "name: 'local'" >> $(pwd)/server/docker-compose-prod.yaml + + rm $(pwd)/templates/local/$ENVIRONMENT_EXCHANGE_NAME-docker-compose.yaml + + fi + + if [[ -f "$(pwd)/templates/local/nginx/conf.d/upstream.conf" ]]; then + + echo "Nginx configuration files generated with HollaEx CLI v2 has been detected!" + echo "Copying the existing Nginx files to the new directory..." + mv $(pwd)/templates/local/nginx/conf.d/* $(pwd)/nginx/conf.d + mv $(pwd)/templates/local/nginx/nginx.conf $(pwd)/nginx/nginx.conf + + mv $(pwd)/templates/local/letsencrypt $(pwd)/nginx/ + + echo "Updating the Nginx file to have an existing docker network bind..." + yq e -i ".services |= with_entries(select(.key == \"hollaex-kit-prod-nginx\") | .key = \"$ENVIRONMENT_EXCHANGE_NAME-nginx\")" $(pwd)/nginx/docker-compose.yaml + yq e -i ".services.*.networks[] = \"local_$ENVIRONMENT_EXCHANGE_NAME-network\"" $(pwd)/nginx/docker-compose.yaml + yq e -i ".networks |= with_entries(select(.key == \"local_hollaex-kit-network\") | .key = \"local_$ENVIRONMENT_EXCHANGE_NAME-network\")" $(pwd)/nginx/docker-compose.yaml + + if command docker ps | grep local.*-nginx > /dev/null ; then + + docker compose -f $(pwd)/nginx/docker-compose.yaml down + docker compose -f $(pwd)/nginx/docker-compose.yaml up -d + + fi + + fi + + # Local web docker-compose + + if [[ -f "$(pwd)/templates/local/${ENVIRONMENT_EXCHANGE_NAME}-docker-compose-web.yaml" ]]; then + + echo "Web doker-compose file generated with HollaEx CLI v2 has been detected." + echo "Converting it..." + mv $(pwd)/templates/local/${ENVIRONMENT_EXCHANGE_NAME}-docker-compose-web.yaml $(pwd)/web/docker-compose.yaml + + echo "name: 'client'" >> $(pwd)/web/docker-compose.yaml + + fi + + # Kubernetes + # Ingress, Configmap, Secret conversion + if [[ -f "$(pwd)/templates/kubernetes/config/${ENVIRONMENT_EXCHANGE_NAME}-configmap.yaml" ]]; then + + echo "Kubernetes configmap generated with HollaEx CLI v2 has been detected." + echo "Converting it..." + mv $(pwd)/templates/kubernetes/config/${ENVIRONMENT_EXCHANGE_NAME}-configmap.yaml $(pwd)/server/tools/kubernetes/env/configmap.yaml + + fi + + if [[ -f "$(pwd)/templates/kubernetes/config/${ENVIRONMENT_EXCHANGE_NAME}-secret.yaml" ]]; then + + echo "Kubernetes secret generated with HollaEx CLI v2 has been detected." + echo "Converting it..." + mv $(pwd)/templates/kubernetes/config/${ENVIRONMENT_EXCHANGE_NAME}-secret.yaml $(pwd)/server/tools/kubernetes/env/secret.yaml + + fi + + if [[ -f "$(pwd)/templates/kubernetes/config/${ENVIRONMENT_EXCHANGE_NAME}-ingress.yaml" ]]; then + + echo "Kubernetes ingress yamls generated with HollaEx CLI v2 has been detected." + echo "Converting it..." + mv $(pwd)/templates/kubernetes/config/${ENVIRONMENT_EXCHANGE_NAME}-ingress.yaml $(pwd)/server/tools/kubernetes/ingress/hollaex-kit-ingress.yaml + + fi + +} + +kit_cross_compatibility_converter; + + exit 0; \ No newline at end of file diff --git a/nginx/Dockerfile b/nginx/Dockerfile new file mode 100644 index 0000000000..d937f3c2d0 --- /dev/null +++ b/nginx/Dockerfile @@ -0,0 +1,8 @@ +FROM nginx:1.25.3-alpine3.18 +RUN apk add --no-cache certbot py-pip && \ + apk add --no-cache --virtual .build-deps build-base libffi-dev openssl-dev python3-dev && \ + pip install certbot-nginx && \ + apk del .build-deps +EXPOSE 80 +EXPOSE 443 +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/nginx/conf.d/upstream-web.conf b/nginx/conf.d/upstream-web.conf new file mode 100644 index 0000000000..bb4ba79614 --- /dev/null +++ b/nginx/conf.d/upstream-web.conf @@ -0,0 +1,4 @@ + + upstream web { + server hollaex-kit-web:80; + } \ No newline at end of file diff --git a/nginx/conf.d/upstream.conf b/nginx/conf.d/upstream.conf new file mode 100644 index 0000000000..74e8d74166 --- /dev/null +++ b/nginx/conf.d/upstream.conf @@ -0,0 +1,13 @@ + + upstream api { + server hollaex-kit-server-api:10010; + } + + upstream socket { + ip_hash; + server hollaex-kit-server-stream:10080; + } + + upstream plugins { + server hollaex-kit-server-plugins:10011; + } \ No newline at end of file diff --git a/nginx/docker-compose.yaml b/nginx/docker-compose.yaml new file mode 100644 index 0000000000..1fdaf29848 --- /dev/null +++ b/nginx/docker-compose.yaml @@ -0,0 +1,32 @@ +version: '3' +name: "local" +services: + hollaex-kit-prod-nginx: + image: nginx-with-certbot + build: + context: . + dockerfile: Dockerfile + restart: unless-stopped + volumes: + - ./:/etc/nginx + - ./logs:/var/log/nginx + - ./static/:/usr/share/nginx/html + - ./letsencrypt:/etc/letsencrypt + ports: + - 80:80 + - 443:443 + environment: + - NGINX_PORT=80 + entrypoint: + - /bin/sh + - -c + - ip -4 route list match 0/0 | awk '{print $$3 " host.access"}' >> /etc/hosts && nginx -g "daemon off;" + networks: + - local_hollaex-kit-network + +networks: + local_hollaex-kit-network: + external: true + + + diff --git a/server/tools/nginx/mime.types b/nginx/mime.types similarity index 100% rename from server/tools/nginx/mime.types rename to nginx/mime.types diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000000..b9cd903b17 --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,69 @@ +worker_processes 4; + +error_log /var/log/error.log warn; +pid /var/log/nginx.pid; + +worker_rlimit_nofile 8192; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + include /etc/nginx/proxy.conf; + include /etc/nginx/conf.d/upstream*.conf; + + default_type application/octet-stream; + log_format main '$remote_addr - $remote_user [$time_local] $status ' + '"$request" $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + limit_req_zone $remote_addr zone=api:1m rate=4r/s; + limit_req_zone $remote_addr zone=order:1m rate=5r/s; + +# SERVER BLOCK +server { + listen 80; + server_name _; #Server domain + + access_log /var/log/hollaex.access.log main; + + include /etc/nginx/conf.d/plugin*.conf; + + location / { + proxy_pass http://web; + } + + location /api { + proxy_pass http://api; + + limit_req zone=api burst=14 nodelay; + limit_req_log_level notice; + limit_req_status 429; + + rewrite /api(/|$)(.*) /$2 break; + + } + + location /api/plugins { + proxy_pass http://plugins; + + rewrite /api(/|$)(.*) /$2 break; + } + + location /stream { + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_pass http://socket; + } + + error_page 429 /429.html; + location = /429.html { + root /usr/share/nginx/html; + internal; + } + } + } diff --git a/server/tools/nginx/proxy.conf b/nginx/proxy.conf similarity index 100% rename from server/tools/nginx/proxy.conf rename to nginx/proxy.conf diff --git a/server/tools/nginx/static/429.html b/nginx/static/429.html similarity index 63% rename from server/tools/nginx/static/429.html rename to nginx/static/429.html index 3b90326039..937b15e46b 100644 --- a/server/tools/nginx/static/429.html +++ b/nginx/static/429.html @@ -4,6 +4,6 @@

Too Many Requests

-

There is a limit of 1 requests per second. Try again soon.

+

Please chillex and try again soon.

diff --git a/server/.dockerignore b/server/.dockerignore index ae9c093e20..cec6890608 100644 --- a/server/.dockerignore +++ b/server/.dockerignore @@ -7,7 +7,7 @@ tools !tools/general/*.js !tools/nexe Dockerfile -docker-compose.yml +docker-compose* index.html package-lock.json logs @@ -15,3 +15,5 @@ coverage .nyc_output .*docker-compose.yaml .drone*.yml +hollaex-kit.env +hollaex-kit.env* diff --git a/server/api/swagger/swagger.js b/server/api/swagger/swagger.js index f3f33ccac2..207ca4a840 100644 --- a/server/api/swagger/swagger.js +++ b/server/api/swagger/swagger.js @@ -4,7 +4,7 @@ const definition = { swagger: '2.0', info: { title: 'HollaEx Kit', - version: '2.11.3' + version: '2.11.4' }, host: 'api.hollaex.com', basePath: '/v2', diff --git a/server/docker-compose-prod.yaml b/server/docker-compose-prod.yaml new file mode 100644 index 0000000000..bd161b7489 --- /dev/null +++ b/server/docker-compose-prod.yaml @@ -0,0 +1,130 @@ +# Prod HollaEx Kit Docker-Copmose +version: '3' +name: "local" +services: + hollaex-kit-redis: + image: redis:7.2.0-alpine + restart: unless-stopped + depends_on: + - hollaex-kit-db + ports: + - 6379:6379 + env_file: + - hollaex-kit.env + command: ["sh", "-c", "redis-server --requirepass $${REDIS_PASSWORD}"] + deploy: + resources: + limits: + cpus: "0.1" + memory: 100M + reservations: + cpus: "0.1" + memory: 100M + networks: + - hollaex-kit-network + hollaex-kit-db: + image: postgres:14.9-alpine + restart: unless-stopped + volumes: + - hollaex_db_vol:/var/lib/postgresql/data + ports: + - 5432:5432 + env_file: + - hollaex-kit.env + deploy: + resources: + limits: + cpus: "0.1" + memory: 100M + reservations: + cpus: "0.1" + memory: 100M + command: ["sh", "-c", "export POSTGRES_DB=$${DB_NAME} && export POSTGRES_USER=$${DB_USERNAME} && export POSTGRES_PASSWORD=$${DB_PASSWORD} && ln -sf /usr/local/bin/docker-entrypoint.sh ./docker-entrypoint.sh && ./docker-entrypoint.sh postgres"] + networks: + - hollaex-kit-network + hollaex-kit-server-api: + image: hollaex/hollaex-kit:2.11.4-cli-deprecation-46ea26c + build: + context: . + dockerfile: tools/Dockerfile + restart: unless-stopped + env_file: + - hollaex-kit.env + entrypoint: + - node + deploy: + resources: + limits: + cpus: "0.2" + memory: 1024M + reservations: + cpus: "0.05" + memory: 512M + command: + - app.js + ports: + - 10010:10010 + networks: + - hollaex-kit-network + depends_on: + - hollaex-kit-redis + - hollaex-kit-db + hollaex-kit-server-stream: + image: hollaex/hollaex-kit:2.11.4-cli-deprecation-46ea26c + build: + context: . + dockerfile: tools/Dockerfile + restart: unless-stopped + env_file: + - hollaex-kit.env + entrypoint: + - node + deploy: + resources: + limits: + cpus: "0.2" + memory: 512M + reservations: + cpus: "0.05" + memory: 256M + command: + - ws/index.js + ports: + - 10080:10080 + networks: + - hollaex-kit-network + depends_on: + - hollaex-kit-server-api + - hollaex-kit-redis + - hollaex-kit-db + hollaex-kit-server-plugins: + image: hollaex/hollaex-kit:2.11.4-cli-deprecation-46ea26c + build: + context: . + dockerfile: tools/Dockerfile + restart: unless-stopped + env_file: + - hollaex-kit.env + entrypoint: + - node + deploy: + resources: + limits: + cpus: "0.2" + memory: 1200M + reservations: + cpus: "0.05" + memory: 700M + command: + - plugins/index.js + - 10011:10011 + networks: + - hollaex-kit-network + depends_on: + - hollaex-kit-server-api + - hollaex-kit-redis + - hollaex-kit-db +networks: + hollaex-kit-network: +volumes: + hollaex_db_vol: diff --git a/server/docker-compose.yaml b/server/docker-compose.yaml index 34ebdd98f1..4329aa4325 100644 --- a/server/docker-compose.yaml +++ b/server/docker-compose.yaml @@ -1,3 +1,4 @@ +# Dev mode HollaEx Kit Docker-Copmose version: '3' services: hollaex-kit-redis: @@ -30,13 +31,13 @@ services: - 10013:10013 build: context: . - dockerfile: ./tools/Dockerfile.pm2 + dockerfile: ./tools/Dockerfile env_file: - ./tools/hollaex-kit.env.local entrypoint: - /bin/sh - -c - - ip -4 route list match 0/0 | awk '{print $$3 " host.docker.internal"}' >> /etc/hosts && cat /etc/hosts && pm2-runtime start ecosystem.config.js --env development; + - pm2-runtime start ecosystem.config.js --env development; volumes: - ./api:/app/api - ./config:/app/config @@ -50,7 +51,8 @@ services: - ./messages.js:/app/messages.js - ./logs:/app/logs - ./test:/app/test - - ./tools:/app/tools + - ./tools/dbs:/app/tools/dbs + - ./tools/general:/app/tools/general - ./utils:/app/utils - /app/utils/hollaex-network-lib/node_modules - /app/utils/hollaex-tools-lib/node_modules @@ -64,10 +66,10 @@ services: hollaex-kit-nginx: image: nginx:1.15.8-alpine volumes: - - ./tools/nginx:/etc/nginx - - ./tools/nginx/conf.d:/etc/nginx/conf.d - - ./tools/nginx/logs:/var/log - - ./tools/nginx/static:/usr/share/nginx/html + - ./tools/nginx-dev:/etc/nginx + - ./tools/nginx-dev/conf.d:/etc/nginx/conf.d + - ./tools/nginx-dev/logs:/var/log + - ./tools/nginx-dev/static:/usr/share/nginx/html ports: - 80:80 environment: diff --git a/server/hollaex-kit.env b/server/hollaex-kit.env new file mode 100644 index 0000000000..60dabd76a1 --- /dev/null +++ b/server/hollaex-kit.env @@ -0,0 +1,51 @@ +DB_DIALECT=postgres + +ADMIN_EMAIL= +API_HOST=http://localhost/api +API_NAME=hollaex-kit +ISSUER=$API_NAME +CURRENCIES=xht,usdt +DB_SSL=false +DEFAULT_THEME=dark +DOMAIN=http://localhost +EMAILS_TIMEZONE=UTC +KIT_VERSION= +KYC_EMAIL= +LOGO_IMAGE=https://bitholla.s3.ap-northeast-2.amazonaws.com/kit/LOGO_IMAGE_LIGHT +LOG_LEVEL=verbose +NETWORK=mainnet +NETWORK_URL=https://api.hollaex.network +NEW_USER_DEFAULT_LANGUAGE=en +NEW_USER_IS_ACTIVATED=true +NODE_ENV=production +PAIRS=xht-usdt +PORT=10010 +SENDER_EMAIL= +SEND_EMAIL_TO_SUPPORT=true +SMTP_PORT=587 +SMTP_SERVER= +SMTP_USER= +SUPERVISOR_EMAIL= +SUPPORT_EMAIL=support@bitholla.com +USER_LEVEL_NUMBER=4 +VALID_LANGUAGES=en +VAULT_NAME= +WEBSOCKET_PORT=10080 + +ACTIVATION_CODE= +API_KEY= +API_SECRET= + +DB_HOST=hollaex-kit-db +DB_NAME=hollaex +DB_PASSWORD=my-secure-db-password +DB_PORT=5432 +DB_USERNAME=hollaex +PUBSUB_HOST=hollaex-kit-redis +PUBSUB_PASSWORD=my-secure-redis-password +PUBSUB_PORT=6379 +REDIS_HOST=hollaex-kit-redis +REDIS_PASSWORD=my-secure-redis-password +REDIS_PORT=6379 +SECRET=my-secure-secret +SMTP_PASSWORD= diff --git a/server/package.json b/server/package.json index 8db8837863..0e23244708 100644 --- a/server/package.json +++ b/server/package.json @@ -1,5 +1,5 @@ { - "version": "2.11.3", + "version": "2.11.4", "private": false, "description": "HollaEx Kit", "keywords": [ diff --git a/server/tools/Dockerfile b/server/tools/Dockerfile new file mode 100644 index 0000000000..3158aa6e6e --- /dev/null +++ b/server/tools/Dockerfile @@ -0,0 +1,29 @@ +FROM node:18.15.0-buster-slim + +RUN apt-get update && \ + apt-get install -y curl openssl ca-certificates git python build-essential && \ + rm -rf /var/lib/apt/lists/* && \ + npm install --unsafe-perm=true pm2@5.2.0 sequelize-cli@6.5.1 mocha -g --loglevel=error + +ENV NODE_ENV=production + +COPY . /app + +WORKDIR /app + +# Changing the default image user to 'appuser' +RUN groupadd -g 999 appuser && \ + useradd -r -u 999 -g appuser appuser && \ + mkdir /home/appuser && \ + chown -R appuser /home/appuser && \ + chown -R appuser /app + +USER appuser + +RUN npm install --loglevel=error && \ + pm2 update && \ + cd /app/mail && npm install --loglevel=error + +EXPOSE 10010 10080 10011 + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/server/tools/Dockerfile.pm2 b/server/tools/Dockerfile.pm2 deleted file mode 100644 index b4158ceeaa..0000000000 --- a/server/tools/Dockerfile.pm2 +++ /dev/null @@ -1,37 +0,0 @@ -### Multi-Stage Build Dockerfile - -### Build section -FROM node:18.15.0-buster-slim as build - -RUN apt-get update && apt-get install -y --no-install-recommends git python3 build-essential && rm -rf /var/lib/apt/lists/* - -## DISTRIBUTION MODE -ENV NODE_ENV=production - -RUN mkdir -p /app/logs - -COPY package.json /app/package.json - -COPY . /app - -WORKDIR /app - -RUN npm install - -FROM node:18.15.0-buster-slim - -COPY --from=build /app /app - -RUN apt-get update && apt-get install -y --no-install-recommends git iproute2 python3 build-essential && rm -rf /var/lib/apt/lists/* - -RUN npm install pm2@5.2.0 sequelize-cli@6.5.1 mocha@10.0.0 -g - -## DISTRIBUTION MODE -ENV NODE_ENV=production - -# SERVER PORT -EXPOSE 10010 10080 10011 - -WORKDIR /app - -ENTRYPOINT ["/app/entrypoint.sh"] diff --git a/server/tools/hollaex-kit.env.local.example b/server/tools/hollaex-kit.env.local.example index 2c04d5f82d..1f7864c41c 100644 --- a/server/tools/hollaex-kit.env.local.example +++ b/server/tools/hollaex-kit.env.local.example @@ -1,3 +1,4 @@ +# Dev Mode HollaEx Kit Env DEPLOYMENT_MODE=all API_HOST=localhost diff --git a/server/tools/kubernetes/env/configmap.yaml b/server/tools/kubernetes/env/configmap.yaml new file mode 100644 index 0000000000..3f4fcc0a70 --- /dev/null +++ b/server/tools/kubernetes/env/configmap.yaml @@ -0,0 +1,39 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: hollaex-kit-configmap + namespace: hollaex-kit +data: + DB_DIALECT: postgres + ADMIN_EMAIL: '' + ADMIN_NETWORK_ID: '' + ADMIN_PASSWORD: '' + API_HOST: 'http://localhost/api' + API_NAME: 'hollaex-kit' + CURRENCIES: 'xht,usdt' + DB_SSL: 'false' + DEFAULT_THEME: 'dark' + DOMAIN: 'http://localhost' + EMAILS_TIMEZONE: 'UTC' + KIT_VERSION: '' + KYC_EMAIL: '' + LOGO_IMAGE: 'https://bitholla.s3.ap-northeast-2.amazonaws.com/kit/LOGO_IMAGE_LIGHT' + LOG_LEVEL: 'verbose' + NETWORK: 'mainnet' + NETWORK_URL: 'https://api.hollaex.network' + NEW_USER_DEFAULT_LANGUAGE: 'en' + NEW_USER_IS_ACTIVATED: 'true' + NODE_ENV: 'production' + PAIRS: 'xht-usdt' + PORT: '10010' + SENDER_EMAIL: '' + SEND_EMAIL_TO_SUPPORT: 'true' + SMTP_PORT: '587' + SMTP_SERVER: '' + SMTP_USER: '' + SUPERVISOR_EMAIL: '' + SUPPORT_EMAIL: 'support@bitholla.com' + USER_LEVEL_NUMBER: '4' + VALID_LANGUAGES: 'en' + VAULT_NAME: '' + WEBSOCKET_PORT: '10080' diff --git a/server/tools/kubernetes/env/secret.yaml b/server/tools/kubernetes/env/secret.yaml new file mode 100644 index 0000000000..102e30b980 --- /dev/null +++ b/server/tools/kubernetes/env/secret.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Secret +metadata: + name: hollaex-kit-secret + namespace: hollaex-kit +type: Opaque +stringData: + ACTIVATION_CODE: '' + API_KEY: '' + API_SECRET: '' + DB_HOST: 'hollaex-kit-db' + DB_NAME: 'hollaex' + DB_PASSWORD: 'my-secure-db-password' + DB_PORT: '5432' + DB_USERNAME: 'hollaex' + PUBSUB_HOST: 'hollaex-kit-redis' + PUBSUB_PASSWORD: 'my-secure-redis-password' + PUBSUB_PORT: '6379' + REDIS_HOST: 'hollaex-kit-redis' + REDIS_PASSWORD: 'my-secure-redis-password' + REDIS_PORT: '6379' + SECRET: 'my-secure-secret' + SMTP_PASSWORD: '' diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/.helmignore b/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/.helmignore new file mode 100755 index 0000000000..f0c1319444 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/Chart.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/Chart.yaml new file mode 100755 index 0000000000..e029e08c0b --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +description: A Helm chart for bitholla-hollaex-postgres +name: bitholla-hollaex-postgres +version: 0.1.0 diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/templates/NOTES.txt b/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/templates/NOTES.txt new file mode 100755 index 0000000000..e69de29bb2 diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/templates/_helpers.tpl b/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/templates/_helpers.tpl new file mode 100755 index 0000000000..c8f7f8868f --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/templates/_helpers.tpl @@ -0,0 +1,16 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "bitholla-hollaex-postgres.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "bitholla-hollaex-postgres.fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/templates/configmap.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/templates/configmap.yaml new file mode 100644 index 0000000000..0efb1ebaae --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/templates/configmap.yaml @@ -0,0 +1,611 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{.Release.Name}}-initdb-remove-local-nopasswd-access + namespace: {{.Release.Namespace}} + labels: + app: {{.Release.Name}} +data: + remove-local-nopasswd-access.sh: |- + #!/bin/bash + grep -v "host all all 127.0.0.1/32 trust" /var/lib/postgresql/data/pg_hba.conf > /var/lib/postgresql/data/pg_hpba.conf.temp && mv /var/lib/postgresql/data/pg_hpba.conf.temp /var/lib/postgresql/data/pg_hba.conf + grep -v "host all all ::1/128 trust" /var/lib/postgresql/data/pg_hba.conf > /var/lib/postgresql/data/pg_hpba.conf.temp && mv /var/lib/postgresql/data/pg_hpba.conf.temp /var/lib/postgresql/data/pg_hba.conf + +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{.Release.Name}}-conf + namespace: {{.Release.Namespace}} + labels: + app: {{.Release.Name}} +data: + postgresql.conf: |- + # ----------------------------- + # PostgreSQL configuration file + # ----------------------------- + # + # This file consists of lines of the form: + # + # name = value + # + # (The "=" is optional.) Whitespace may be used. Comments are introduced with + # "#" anywhere on a line. The complete list of parameter names and allowed + # values can be found in the PostgreSQL documentation. + # + # The commented-out settings shown in this file represent the default values. + # Re-commenting a setting is NOT sufficient to revert it to the default value; + # you need to reload the server. + # + # This file is read on server startup and when the server receives a SIGHUP + # signal. If you edit the file on a running system, you have to SIGHUP the + # server for the changes to take effect, or use "pg_ctl reload". Some + # parameters, which are marked below, require a server shutdown and restart to + # take effect. + # + # Any parameter can also be given as a command-line option to the server, e.g., + # "postgres -c log_connections=on". Some parameters can be changed at run time + # with the "SET" SQL command. + # + # Memory units: kB = kilobytes Time units: ms = milliseconds + # MB = megabytes s = seconds + # GB = gigabytes min = minutes + # TB = terabytes h = hours + # d = days + #------------------------------------------------------------------------------ + # FILE LOCATIONS + #------------------------------------------------------------------------------ + # The default values of these variables are driven from the -D command-line + # option or PGDATA environment variable, represented here as ConfigDir. + #data_directory = 'ConfigDi' # use data in another directory + # (change requires restart) + #hba_file = 'ConfigDir/pg_hba.conf' # host-based authentication file + # (change requires restart) + #ident_file = 'ConfigDir/pg_ident.conf' # ident configuration file + # (change requires restart) + # If external_pid_file is not explicitly set, no extra PID file is written. + #external_pid_file = '' # write an extra PID file + # (change requires restart) + #------------------------------------------------------------------------------ + # CONNECTIONS AND AUTHENTICATION + #------------------------------------------------------------------------------ + # - Connection Settings - + listen_addresses = '*' + # comma-separated list of addresses; + # defaults to 'localhost'; use '*' for all + # (change requires restart) + #port = 5432 # (change requires restart) + max_connections = 500 # (change requires restart) + #superuser_reserved_connections = 3 # (change requires restart) + #unix_socket_directories = '/var/run/postgresql' # comma-separated list of directories + # (change requires restart) + #unix_socket_group = '' # (change requires restart) + #unix_socket_permissions = 0777 # begin with 0 to use octal notation + # (change requires restart) + #bonjour = off # advertise server via Bonjour + # (change requires restart) + #bonjour_name = '' # defaults to the computer name + # (change requires restart) + # - Security and Authentication - + #authentication_timeout = 1min # 1s-600s + #ssl = off # (change requires restart) + #ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers + # (change requires restart) + #ssl_prefer_server_ciphers = on # (change requires restart) + #ssl_ecdh_curve = 'prime256v1' # (change requires restart) + #ssl_cert_file = 'server.crt' # (change requires restart) + #ssl_key_file = 'server.key' # (change requires restart) + #ssl_ca_file = '' # (change requires restart) + #ssl_crl_file = '' # (change requires restart) + #password_encryption = on + #db_user_namespace = off + #row_security = on + # GSSAPI using Kerberos + #krb_server_keyfile = '' + #krb_caseins_users = off + # - TCP Keepalives - + # see "man 7 tcp" for details + #tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; + # 0 selects the system default + #tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds; + # 0 selects the system default + #tcp_keepalives_count = 0 # TCP_KEEPCNT; + # 0 selects the system default + #------------------------------------------------------------------------------ + # RESOURCE USAGE (except WAL) + #------------------------------------------------------------------------------ + # - Memory - + shared_buffers = 128MB # min 128kB + # (change requires restart) + #huge_pages = try # on, off, or try + # (change requires restart) + #temp_buffers = 8MB # min 800kB + #max_prepared_transactions = 0 # zero disables the feature + # (change requires restart) + # Caution: it is not advisable to set max_prepared_transactions nonzero unless + # you actively intend to use prepared transactions. + #work_mem = 4MB # min 64kB + #maintenance_work_mem = 64MB # min 1MB + #replacement_sort_tuples = 150000 # limits use of replacement selection sort + #autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem + #max_stack_depth = 2MB # min 100kB + dynamic_shared_memory_type = posix # the default is the first option + # supported by the operating system: + # posix + # sysv + # windows + # mmap + # use none to disable dynamic shared memory + # (change requires restart) + # - Disk - + #temp_file_limit = -1 # limits per-process temp file space + # in kB, or -1 for no limit + # - Kernel Resource Usage - + #max_files_per_process = 1000 # min 25 + # (change requires restart) + #shared_preload_libraries = '' # (change requires restart) + # - Cost-Based Vacuum Delay - + #vacuum_cost_delay = 0 # 0-100 milliseconds + #vacuum_cost_page_hit = 1 # 0-10000 credits + #vacuum_cost_page_miss = 10 # 0-10000 credits + #vacuum_cost_page_dirty = 20 # 0-10000 credits + #vacuum_cost_limit = 200 # 1-10000 credits + # - Background Writer - + #bgwriter_delay = 200ms # 10-10000ms between rounds + #bgwriter_lru_maxpages = 100 # 0-1000 max buffers written/round + #bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round + #bgwriter_flush_after = 512kB # measured in pages, 0 disables + # - Asynchronous Behavior - + #effective_io_concurrency = 1 # 1-1000; 0 disables prefetching + #max_worker_processes = 8 # (change requires restart) + #max_parallel_workers_per_gather = 0 # taken from max_worker_processes + #old_snapshot_threshold = -1 # 1min-60d; -1 disables; 0 is immediate + # (change requires restart) + #backend_flush_after = 0 # measured in pages, 0 disables + #------------------------------------------------------------------------------ + # WRITE AHEAD LOG + #------------------------------------------------------------------------------ + # - Settings - + #wal_level = minimal # minimal, replica, or logical + # (change requires restart) + #fsync = on # flush data to disk for crash safety + # (turning this off can cause + # unrecoverable data corruption) + #synchronous_commit = on # synchronization level; + # off, local, remote_write, remote_apply, or on + #wal_sync_method = fsync # the default is the first option + # supported by the operating system: + # open_datasync + # fdatasync (default on Linux) + # fsync + # fsync_writethrough + # open_sync + #full_page_writes = on # recover from partial page writes + #wal_compression = off # enable compression of full-page writes + #wal_log_hints = off # also do full page writes of non-critical updates + # (change requires restart) + #wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers + # (change requires restart) + #wal_writer_delay = 200ms # 1-10000 milliseconds + #wal_writer_flush_after = 1MB # measured in pages, 0 disables + #commit_delay = 0 # range 0-100000, in microseconds + #commit_siblings = 5 # range 1-1000 + # - Checkpoints - + #checkpoint_timeout = 5min # range 30s-1d + #max_wal_size = 1GB + #min_wal_size = 80MB + #checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0 + #checkpoint_flush_after = 256kB # measured in pages, 0 disables + #checkpoint_warning = 30s # 0 disables + # - Archiving - + #archive_mode = off # enables archiving; off, on, or always + # (change requires restart) + #archive_command = '' # command to use to archive a logfile segment + # placeholders: %p = path of file to archive + # %f = file name only + # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' + #archive_timeout = 0 # force a logfile segment switch after this + # number of seconds; 0 disables + #------------------------------------------------------------------------------ + # REPLICATION + #------------------------------------------------------------------------------ + # - Sending Server(s) - + # Set these on the master and on any standby that will send replication data. + #max_wal_senders = 0 # max number of walsender processes + # (change requires restart) + #wal_keep_segments = 0 # in logfile segments, 16MB each; 0 disables + #wal_sender_timeout = 60s # in milliseconds; 0 disables + #max_replication_slots = 0 # max number of replication slots + # (change requires restart) + #track_commit_timestamp = off # collect timestamp of transaction commit + # (change requires restart) + # - Master Server - + # These settings are ignored on a standby server. + #synchronous_standby_names = '' # standby servers that provide sync rep + # number of sync standbys and comma-separated list of application_name + # from standby(s); '*' = all + #vacuum_defer_cleanup_age = 0 # number of xacts by which cleanup is delayed + # - Standby Servers - + # These settings are ignored on a master server. + #hot_standby = off # "on" allows queries during recovery + # (change requires restart) + #max_standby_archive_delay = 30s # max delay before canceling queries + # when reading WAL from archive; + # -1 allows indefinite delay + #max_standby_streaming_delay = 30s # max delay before canceling queries + # when reading streaming WAL; + # -1 allows indefinite delay + #wal_receiver_status_interval = 10s # send replies at least this often + # 0 disables + #hot_standby_feedback = off # send info from standby to prevent + # query conflicts + #wal_receiver_timeout = 60s # time that receiver waits for + # communication from master + # in milliseconds; 0 disables + #wal_retrieve_retry_interval = 5s # time to wait before retrying to + # retrieve WAL after a failed attempt + #------------------------------------------------------------------------------ + # QUERY TUNING + #------------------------------------------------------------------------------ + # - Planner Method Configuration - + #enable_bitmapscan = on + #enable_hashagg = on + #enable_hashjoin = on + #enable_indexscan = on + #enable_indexonlyscan = on + #enable_material = on + #enable_mergejoin = on + #enable_nestloop = on + #enable_seqscan = on + #enable_sort = on + #enable_tidscan = on + # - Planner Cost Constants - + #seq_page_cost = 1.0 # measured on an arbitrary scale + #random_page_cost = 4.0 # same scale as above + #cpu_tuple_cost = 0.01 # same scale as above + #cpu_index_tuple_cost = 0.005 # same scale as above + #cpu_operator_cost = 0.0025 # same scale as above + #parallel_tuple_cost = 0.1 # same scale as above + #parallel_setup_cost = 1000.0 # same scale as above + #min_parallel_relation_size = 8MB + #effective_cache_size = 4GB + # - Genetic Query Optimizer - + #geqo = on + #geqo_threshold = 12 + #geqo_effort = 5 # range 1-10 + #geqo_pool_size = 0 # selects default based on effort + #geqo_generations = 0 # selects default based on effort + #geqo_selection_bias = 2.0 # range 1.5-2.0 + #geqo_seed = 0.0 # range 0.0-1.0 + # - Other Planner Options - + #default_statistics_target = 100 # range 1-10000 + #constraint_exclusion = partition # on, off, or partition + #cursor_tuple_fraction = 0.1 # range 0.0-1.0 + #from_collapse_limit = 8 + #join_collapse_limit = 8 # 1 disables collapsing of explicit + # JOIN clauses + #force_parallel_mode = off + #------------------------------------------------------------------------------ + # ERROR REPORTING AND LOGGING + #------------------------------------------------------------------------------ + # - Where to Log - + log_destination = 'stderr' # Valid values are combinations of + # stderr, csvlog, syslog, and eventlog, + # depending on platform. csvlog + # requires logging_collector to be on. + # This is used when logging to stderr: + logging_collector = on # Enable capturing of stderr and csvlog + # into log files. Required to be on for + # csvlogs. + # (change requires restart) + # These are only used if logging_collector is on: + log_directory = '/etc/postgres-logs' # directory where log files are written, + # can be absolute or relative to PGDATA + log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern, + #log_filename = 'postgresql.log' # log file name pattern, + # can include strftime() escapes + log_file_mode = 0600 # creation mode for log files, + # begin with 0 to use octal notation + #log_truncate_on_rotation = off # If on, an existing log file with the + # same name as the new log file will be + # truncated rather than appended to. + # But such truncation only occurs on + # time-driven rotation, not on restarts + # or size-driven rotation. Default is + # off, meaning append to existing files + # in all cases. + log_rotation_age = 1d # Automatic rotation of logfiles will + # happen after that time. 0 disables. + #log_rotation_size = 10MB # Automatic rotation of logfiles will + # happen after that much log output. + # 0 disables. + # These are relevant when logging to syslog: + #syslog_facility = 'LOCAL0' + #syslog_ident = 'postgres' + #syslog_sequence_numbers = on + #syslog_split_messages = on + # This is only relevant when logging to eventlog (win32): + # (change requires restart) + #event_source = 'PostgreSQL' + # - When to Log - + #client_min_messages = notice # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # log + # notice + # warning + # error + log_min_messages = warning # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic + log_min_error_statement = error # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic (effectively off) + log_min_duration_statement = 0 # -1 is disabled, 0 logs all statements + # and their durations, > 0 logs only + # statements running at least this number + # of milliseconds + # - What to Log - + #debug_print_parse = off + #debug_print_rewritten = off + #debug_print_plan = off + #debug_pretty_print = on + #log_checkpoints = off + #log_connections = on + #log_disconnections = on + #log_duration = on + #log_error_verbosity = default # terse, default, or verbose messages + #log_hostname = off + log_line_prefix = '%m [%p] %u@%d ' # special values: + #log_lock_waits = off # log lock waits >= deadlock_timeout + #log_statement = 'all' # none, ddl, mod, all + #log_replication_commands = off + #log_temp_files = -1 # log temporary files equal or larger + # than the specified size in kilobytes; + # -1 disables, 0 logs all temp files + log_timezone = 'UTC' + # - Process Title - + #cluster_name = '' # added to process titles if nonempty + # (change requires restart) + #update_process_title = on + #------------------------------------------------------------------------------ + # RUNTIME STATISTICS + #------------------------------------------------------------------------------ + # - Query/Index Statistics Collector - + #track_activities = on + #track_counts = on + #track_io_timing = off + #track_functions = none # none, pl, all + #track_activity_query_size = 1024 # (change requires restart) + #stats_temp_directory = 'pg_stat_tmp' + # - Statistics Monitoring - + #log_parser_stats = off + #log_planner_stats = off + #log_executor_stats = off + #log_statement_stats = off + #------------------------------------------------------------------------------ + # AUTOVACUUM PARAMETERS + #------------------------------------------------------------------------------ + #autovacuum = on # Enable autovacuum subprocess? 'on' + # requires track_counts to also be on. + #log_autovacuum_min_duration = 0 # -1 disables, 0 logs all actions and + # their durations, > 0 logs only + # actions running at least this number + # of milliseconds. + #autovacuum_max_workers = 3 # max number of autovacuum subprocesses + # (change requires restart) + #autovacuum_naptime = 1min # time between autovacuum runs + #autovacuum_vacuum_threshold = 50 # min number of row updates before + # vacuum + #autovacuum_analyze_threshold = 50 # min number of row updates before + # analyze + #autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum + #autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze + #autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum + # (change requires restart) + #autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age + # before forced vacuum + # (change requires restart) + #autovacuum_vacuum_cost_delay = 20ms # default vacuum cost delay for + # autovacuum, in milliseconds; + # -1 means use vacuum_cost_delay + #autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for + # autovacuum, -1 means use + # vacuum_cost_limit + #------------------------------------------------------------------------------ + # CLIENT CONNECTION DEFAULTS + #------------------------------------------------------------------------------ + # - Statement Behavior - + #search_path = '"$user", public' # schema names + #default_tablespace = '' # a tablespace name, '' uses the default + #temp_tablespaces = '' # a list of tablespace names, '' uses + # only default tablespace + #check_function_bodies = on + #default_transaction_isolation = 'read committed' + #default_transaction_read_only = off + #default_transaction_deferrable = off + #session_replication_role = 'origin' + #statement_timeout = 0 # in milliseconds, 0 is disabled + #lock_timeout = 0 # in milliseconds, 0 is disabled + #idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled + #vacuum_freeze_min_age = 50000000 + #vacuum_freeze_table_age = 150000000 + #vacuum_multixact_freeze_min_age = 5000000 + #vacuum_multixact_freeze_table_age = 150000000 + #bytea_output = 'hex' # hex, escape + #xmlbinary = 'base64' + #xmloption = 'content' + #gin_fuzzy_search_limit = 0 + #gin_pending_list_limit = 4MB + # - Locale and Formatting - + datestyle = 'iso, mdy' + #intervalstyle = 'postgres' + timezone = 'UTC' + #timezone_abbreviations = 'Default' # Select the set of available time zone + # abbreviations. Currently, there are + # Default + # Australia (historical usage) + # India + # You can create your own file in + # share/timezonesets/. + #extra_float_digits = 0 # min -15, max 3 + #client_encoding = sql_ascii # actually, defaults to database + # encoding + # These settings are initialized by initdb, but they can be changed. + lc_messages = 'en_US.utf8' # locale for system error message + # strings + lc_monetary = 'en_US.utf8' # locale for monetary formatting + lc_numeric = 'en_US.utf8' # locale for number formatting + lc_time = 'en_US.utf8' # locale for time formatting + # default configuration for text search + default_text_search_config = 'pg_catalog.english' + # - Other Defaults - + #dynamic_library_path = '$libdir' + #local_preload_libraries = '' + #session_preload_libraries = '' + #------------------------------------------------------------------------------ + # LOCK MANAGEMENT + #------------------------------------------------------------------------------ + #deadlock_timeout = 1s + #max_locks_per_transaction = 64 # min 10 + # (change requires restart) + #max_pred_locks_per_transaction = 64 # min 10 + # (change requires restart) + #------------------------------------------------------------------------------ + # VERSION/PLATFORM COMPATIBILITY + #------------------------------------------------------------------------------ + # - Previous PostgreSQL Versions - + #array_nulls = on + #backslash_quote = safe_encoding # on, off, or safe_encoding + #default_with_oids = off + #escape_string_warning = on + #lo_compat_privileges = off + #operator_precedence_warning = off + #quote_all_identifiers = off + #sql_inheritance = on + #standard_conforming_strings = on + #synchronize_seqscans = on + # - Other Platforms and Clients - + #transform_null_equals = off + #------------------------------------------------------------------------------ + # ERROR HANDLING + #------------------------------------------------------------------------------ + #exit_on_error = off # terminate session on any error? + #restart_after_crash = on # reinitialize after backend crash? + #------------------------------------------------------------------------------ + # CONFIG FILE INCLUDES + #------------------------------------------------------------------------------ + # These options allow settings to be loaded from files other than the + # default postgresql.conf. + #include_dir = 'conf.d' # include files ending in '.conf' from + # directory 'conf.d' + #include_if_exists = 'exists.conf' # include file only if it exists + #include = 'special.conf' # include file + #------------------------------------------------------------------------------ + # CUSTOMIZED OPTIONS + #------------------------------------------------------------------------------ + # Add settings for extensions here +{{- if .Values.filebeat }} +{{- if .Values.filebeat.create }} +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: postgres-filebeat-exporter-config + namespace: {{.Release.Namespace}} + labels: + app: {{.Release.Name}} +data: + filebeat.yml: |- + filebeat.config: + inputs: + # Mounted `filebeat-inputs` configmap: + path: ${path.config}/inputs.d/*.yml + # Reload inputs configs as they change: + reload.enabled: false + modules: + path: ${path.config}/modules.d/*.yml + # Reload module configs as they change: + reload.enabled: false + # To enable hints based autodiscover, remove `filebeat.config.inputs` configuration and uncomment this: + #filebeat.autodiscover: + # providers: + # - type: kubernetes + # hints.enabled: true + processors: + - add_cloud_metadata: + setup.kibana: + host: "http://${KIBANA_HOST}:5601" + output.elasticsearch: + hosts: ['${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}'] + +# --- +# apiVersion: v1 +# kind: ConfigMap +# metadata: +# name: postgres-filebeat-exporter-inputs +# namespace: {{.Release.Namespace}} +# labels: +# app: {{.Release.Name}} +# data: +# postgresql.yml: |- +# - input_type: log +# paths: +# - /usr/share/filebeat/logs/*.log +# document_type: postgres + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: postgres-filebeat-exporter-modules + namespace: {{.Release.Namespace}} + labels: + app: {{.Release.Name}} +data: + postgresql.yml: |- + - module: postgresql + log: + enabled: true + var.paths: ["/usr/share/filebeat/logs/*.log"] + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: postgres-log-rotater-cronjob + namespace: {{.Release.Namespace}} + labels: + app: {{.Release.Name}} +data: + root: |- + + 0 1 * * * targetdate=`date +%Y-%m-%d -d '3 days ago'` && rm /tmp/logs/postgresql-${targetdate}_*.log && echo Removed logs of ${targetdate} >> /tmp/cron.log + +{{- end }} +{{- end }} diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/templates/deployment.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/templates/deployment.yaml new file mode 100755 index 0000000000..c47e1e3ef8 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/templates/deployment.yaml @@ -0,0 +1,197 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: {{.Release.Name}} + name: {{.Release.Name}} + namespace: {{.Release.namespace}} +spec: + replicas: 1 + + strategy: + type: Recreate + + selector: + matchLabels: + app: {{.Release.Name}} + role: master + tier: backend + template: + metadata: + labels: + app: {{.Release.Name}} + role: master + tier: backend + spec: + volumes: + - name: {{.Release.Name}}-initdb-remove-local-nopasswd-access + configMap: + defaultMode: 0755 + name: {{.Release.Name}}-initdb-remove-local-nopasswd-access + - name: postgres-mount + persistentVolumeClaim: + claimName: {{.Values.pvc.name}} + - name: postgres-conf + configMap: + name: {{.Release.Name}}-conf + - name: shared-data + emptyDir: {} + {{- if .Values.filebeat }} + {{- if .Values.filebeat.create }} + + - name: filebeat-config + configMap: + defaultMode: 0600 + name: postgres-filebeat-exporter-config + - name: filebeat-modules + configMap: + defaultMode: 0600 + name: postgres-filebeat-exporter-modules + - name: filebeat-data + hostPath: + path: /var/lib/filebeat-data + type: DirectoryOrCreate + - name: cron-rules + configMap: + #defaultMode: 0600 + name: postgres-log-rotater-cronjob + + {{- end }} + {{- end }} + + imagePullSecrets: + - name: bitholla-registry-secret + +{{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} +{{- end }} + + containers: + - name: {{.Release.Name}} + image: {{.Values.imageRegistry}}:{{.Values.dockerTag}} + resources: + limits: + memory: {{.Values.resources.limits.memory}} + cpu: {{.Values.resources.limits.cpu}} + requests: + memory: {{.Values.resources.requests.memory}} + cpu: {{.Values.resources.requests.cpu}} + env: + - name: POSTGRES_DB + valueFrom: + secretKeyRef: + name: {{.Values.secretName}} + key: DB_NAME + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{.Values.secretName}} + key: DB_PASSWORD + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + name: {{.Values.secretName}} + key: DB_USERNAME + imagePullPolicy: IfNotPresent + + {{- if .Values.filebeat }} + {{- if .Values.filebeat.create }} + + args: ["-c", "config_file=/etc/postgresql.conf"] + + securityContext: + runAsUser: 999 + + {{- end }} + {{- end }} + + ports: + - name: port + containerPort: 5432 + volumeMounts: + - name: postgres-mount + mountPath: /var/lib/postgresql/data + subPath: data + - name: postgres-conf + mountPath: /etc/postgresql.conf + subPath: postgresql.conf + - name: {{.Release.Name}}-initdb-remove-local-nopasswd-access + mountPath: /docker-entrypoint-initdb.d/remove-local-nopasswd-access.sh + subPath: remove-local-nopasswd-access.sh + - name: shared-data + mountPath: /etc/postgres-logs + + {{- if .Values.filebeat }} + {{- if .Values.filebeat.create }} + + - image: "{{ .Values.filebeat.image.repository }}:{{ .Values.filebeat.image.tag }}" + imagePullPolicy: "{{ .Values.filebeat.image.pullPolicy }}" + name: postgres-filebeat-exporter + dnsPolicy: ClusterFirstWithHostNet + args: [ + "-c", "/etc/filebeat.yml", + "-e", + ] + resources: + limits: + memory: {{.Values.resources.limits.memory}} + cpu: {{.Values.resources.limits.cpu}} + requests: + memory: {{.Values.resources.requests.memory}} + cpu: {{.Values.resources.requests.cpu}} + env: + - name: ELASTICSEARCH_HOST + value: "{{ .Values.filebeat.elasticsearch_host }}" + - name: ELASTICSEARCH_PORT + value: "{{ .Values.filebeat.elasticsearch_port }}" + - name: KIBANA_HOST + value: "{{ .Values.filebeat.kibana_host }}" + resources: + limits: + cpu: 1 + memory: 1Gi + requests: + cpu: 50m + memory: 100Mi + securityContext: + runAsUser: 0 + volumeMounts: + - name: filebeat-config + mountPath: /etc/filebeat.yml + readOnly: true + subPath: filebeat.yml + # - name: filebeat-inputs + # mountPath: /usr/share/filebeat/inputs.d + # readOnly: true + - name: filebeat-modules + mountPath: /usr/share/filebeat/modules.d + readOnly: true + - name: filebeat-data + mountPath: /usr/share/filebeat/data + - name: shared-data + mountPath: /usr/share/filebeat/logs + readOnly: true + + ## Log rotater + - image: "bitholla/devops-tools:alpine_coretuils-3.6" + #imagePullPolicy: "Always" + name: postgres-log-rotater + #dnsPolicy: ClusterFirstWithHostNet + command: ["/bin/sh", "-c"] #0 0 * * 0 + #args: ["-c", "touch /etc/cron.d/cron-rmlogs && echo '* * * * * root rm /tmp/logs/*' > /etc/cron.d/cron-rmlogs && chmod 0644 /etc/cron.d/cron-rmlogs && service cron start"] + args: + - echo "Container will daily remove logs from Postgres automatically."; + crond; + touch /tmp/cron.log; + tail -f /tmp/cron.log; + + securityContext: + runAsUser: 0 + volumeMounts: + - name: shared-data + mountPath: /tmp/logs + - name: cron-rules + mountPath: /etc/crontabs + {{- end }} + {{- end }} diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/templates/postgres-volume.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/templates/postgres-volume.yaml new file mode 100644 index 0000000000..bd3dd06225 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/templates/postgres-volume.yaml @@ -0,0 +1,15 @@ +{{- if .Values.pvc.create }} + +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{.Values.pvc.name}} + namespace: {{.Release.namespace}} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{.Values.pvc.size}} + +{{- end }} diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/templates/service.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/templates/service.yaml new file mode 100755 index 0000000000..e11ae6c0ad --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/templates/service.yaml @@ -0,0 +1,27 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{.Release.Name}} + namespace: {{.Release.namespace}} + labels: + app: {{.Release.Name}} +spec: + {{if .Values.NodePort.enable }} + + type: NodePort + ports: + - port: 5432 + targetPort: 5432 + nodePort: {{.Values.nodePort}} + + {{ else }} + + type: ClusterIP + ports: + - port: 5432 + targetPort: 5432 + + {{ end }} + + selector: + app: {{.Release.Name}} diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/values.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/values.yaml new file mode 100755 index 0000000000..be44aeb9ab --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-postgres/values.yaml @@ -0,0 +1,37 @@ +# Default values for bitholla-hollaex-nginx. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +pvc: + create: true + size: 4Gi + name: hollaex-postgres-volume + +secretName: hollaex-kit-secret + +NodePort: + enable: false + port: + +nodeSelector: {} + +imageRegistry: postgres +dockerTag: 14.9-alpine + +resources: + limits: + cpu: "100m" + memory: "512Mi" + requests: + cpu: "10m" + memory: "50Mi" + +filebeat: + create: false + image: + repository: docker.elastic.co/beats/filebeat + tag: "6.5.4" + pullPolicy: IfNotPresent + kibana_host: es-kibana.elasticsearch + elasticsearch_host: es-elasticsearch-client.elasticsearch + elasticsearch_port: 9200 + \ No newline at end of file diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-redis/.helmignore b/server/tools/kubernetes/helm-chart/hollaex-kit-redis/.helmignore new file mode 100755 index 0000000000..f0c1319444 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-redis/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-redis/Chart.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-redis/Chart.yaml new file mode 100755 index 0000000000..5659d0e071 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-redis/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +description: A Helm chart for bitholla-hollaex-redis +name: bitholla-hollaex-redis +version: 0.1.0 diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-redis/templates/NOTES.txt b/server/tools/kubernetes/helm-chart/hollaex-kit-redis/templates/NOTES.txt new file mode 100755 index 0000000000..e69de29bb2 diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-redis/templates/_helpers.tpl b/server/tools/kubernetes/helm-chart/hollaex-kit-redis/templates/_helpers.tpl new file mode 100755 index 0000000000..043ba16132 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-redis/templates/_helpers.tpl @@ -0,0 +1,16 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "bitholla-hollaex-redis.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "bitholla-hollaex-redis.fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-redis/templates/deployment.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-redis/templates/deployment.yaml new file mode 100755 index 0000000000..5617eacd3b --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-redis/templates/deployment.yaml @@ -0,0 +1,51 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: {{.Release.Name}} + name: {{.Release.Name}} + namespace: {{.Release.Namespace}} +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: {{.Release.Name}} + role: master + tier: backend + template: + metadata: + labels: + app: {{.Release.Name}} + role: master + tier: backend + spec: + +{{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} +{{- end }} + + containers: + - name: {{.Release.Name}} + image: {{.Values.imageRegistry}}:{{.Values.dockerTag}} + imagePullPolicy: IfNotPresent + ports: + - name: port + containerPort: 6379 + command: ["redis-server", "--requirepass", "$(REDIS_AUTH_PASSWORD)"] + env: + - name: REDIS_AUTH_PASSWORD + valueFrom: + secretKeyRef: + name: {{.Values.setAuth.secretName}} + key: REDIS_PASSWORD + + resources: + limits: + memory: {{.Values.resources.limits.memory}} + cpu: {{.Values.resources.limits.cpu}} + requests: + memory: {{.Values.resources.requests.memory}} + cpu: {{.Values.resources.requests.cpu}} \ No newline at end of file diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-redis/templates/service.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-redis/templates/service.yaml new file mode 100755 index 0000000000..3135d5f8c7 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-redis/templates/service.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{.Release.Name}} + namespace: {{.Release.Namespace}} + labels: + app: {{.Release.Name}} +spec: + {{if .Values.NodePort.enable }} + + type: NodePort + ports: + - port: 6379 + targetPort: 6379 + nodePort: {{.Values.NodePort.port}} + + {{ else }} + + type: ClusterIP + ports: + - port: 6379 + targetPort: 6379 + + {{ end }} + selector: + app: {{.Release.Name}} diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-redis/values.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-redis/values.yaml new file mode 100755 index 0000000000..d65a84e4db --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-redis/values.yaml @@ -0,0 +1,22 @@ +# Default values for bitholla-hollaex-nginx. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +NodePort: + enable: false + port: 30000 + +nodeSelector: {} + +imageRegistry: redis +dockerTag: 7.2.0-alpine + +setAuth: + secretName: hollaex-kit-secret + +resources: + limits: + cpu: "100m" + memory: "512Mi" + requests: + cpu: "10m" + memory: "50Mi" \ No newline at end of file diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-server/.helmignore b/server/tools/kubernetes/helm-chart/hollaex-kit-server/.helmignore new file mode 100755 index 0000000000..f0c1319444 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-server/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-server/Chart.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-server/Chart.yaml new file mode 100644 index 0000000000..c17c2c3e8e --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-server/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +description: A Helm chart for HollaEx Kit +name: hollaex-kit +version: 2.9.2 \ No newline at end of file diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-server/templates/_helpers.tpl b/server/tools/kubernetes/helm-chart/hollaex-kit-server/templates/_helpers.tpl new file mode 100755 index 0000000000..7a6b694414 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-server/templates/_helpers.tpl @@ -0,0 +1,16 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "bitholla-hollaex-server.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "bitholla-hollaex-server.fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-server/templates/autoscaler.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-server/templates/autoscaler.yaml new file mode 100644 index 0000000000..d74fa93d44 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-server/templates/autoscaler.yaml @@ -0,0 +1,26 @@ +{{- if .Values.autoScaling.hpa.enable }} + +{{- $minReplicas := .Values.stable.replicaCount | int }} +{{- $maxReplicas := add 1 $minReplicas }} + +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{.Release.Name}} + namespace: {{.Release.Namespace}} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{.Release.Name}} + minReplicas: {{ $minReplicas }} + maxReplicas: {{ $maxReplicas }} + metrics: + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.autoScaling.hpa.memory.threshold }} + +{{- end }} \ No newline at end of file diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-server/templates/deployment.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-server/templates/deployment.yaml new file mode 100644 index 0000000000..99df801a52 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-server/templates/deployment.yaml @@ -0,0 +1,154 @@ + +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: {{.Release.Name}} + role: {{.Release.Namespace}} + deployment_mode: {{.Values.DEPLOYMENT_MODE}} + name: {{.Release.Name}} + namespace: {{.Release.Namespace}} +spec: + revisionHistoryLimit: 3 + replicas: {{.Values.stable.replicaCount}} + +{{- if or (eq .Values.DEPLOYMENT_MODE "api") (eq .Values.DEPLOYMENT_MODE "stream") }} + + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + +{{- else }} + + strategy: + type: Recreate + +{{- end }} + +{{- if eq .Values.DEPLOYMENT_MODE "api" }} + minReadySeconds: 15 +{{- end }} + + selector: + matchLabels: + app: {{.Release.Name}} + role: {{.Release.Namespace}} + tier: backend + template: + metadata: + # annotations: + # seccomp.security.alpha.kubernetes.io/pod: "runtime/default" + labels: + app: {{.Release.Name}} + role: {{.Release.Namespace}} + deployment_mode: {{.Values.DEPLOYMENT_MODE}} + tier: backend + spec: + + securityContext: + seccompProfile: + type: RuntimeDefault + +{{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} +{{- end }} + + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: role + operator: In + values: + - {{.Release.Namespace}} + topologyKey: "kubernetes.io/hostname" + + containers: + - name: {{.Release.Name}} + image: {{.Values.imageRegistry}}:{{.Values.dockerTag}} + imagePullPolicy: IfNotPresent + + securityContext: + allowPrivilegeEscalation: false + +{{- if eq .Values.DEPLOYMENT_MODE "api" }} + + command: ["/bin/bash"] + args: ["-c", "node app.js"] + +{{- else if eq .Values.DEPLOYMENT_MODE "stream" }} + + command: ["/bin/bash"] + args: ["-c", "node ws/index.js"] + +{{- else if eq .Values.DEPLOYMENT_MODE "plugins" }} + + command: ["/bin/bash"] + args: ["-c", "node plugins/index.js"] + +{{- end }} + + ports: + - name: websocket-port + containerPort: 10080 + - name: port + containerPort: 10010 + - name: plugins-port + containerPort: 10011 + + envFrom: + - configMapRef: + name: {{.Values.envName}} + - secretRef: + name: {{.Values.secretName}} + env: + - name: PAIR + value: {{.Values.PAIR}} + - name: ELASTIC_APM_SERVICE_NAME + value: {{.Release.Name}} + + resources: + limits: + memory: {{.Values.resources.limits.memory}} + requests: + memory: {{.Values.resources.requests.memory}} + cpu: {{.Values.resources.requests.cpu}} + +{{- if .Values.podRestart_webhook_url }} + lifecycle: + preStop: + exec: + command: ["/bin/sh", "-c", "export hostname=`hostname` && curl -X POST -H 'Content-type: application/json' --data '{\"attachments\": [ { \"color\": \"#A569BD\", \"title\": \"😵 Pod has been terminated!\", \"text\": \"Pod '\"${hostname}\"' just has been terminated.\" } ] }' {{.Values.podRestart_webhook_url}}"] +{{- end }} + +{{- if eq .Values.DEPLOYMENT_MODE "api" }} + readinessProbe: + exec: + command: + - curl + - http://localhost:10010/v2/health + initialDelaySeconds: 1 + periodSeconds: 15 +{{- end }} + +{{- if eq .Values.DEPLOYMENT_MODE "stream" }} + readinessProbe: + exec: + command: + - curl + - http://localhost:10080 + initialDelaySeconds: 1 + periodSeconds: 15 + +{{- end }} + +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-server/templates/job.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-server/templates/job.yaml new file mode 100644 index 0000000000..6b5b0ea887 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-server/templates/job.yaml @@ -0,0 +1,200 @@ +{{- if .Values.job.enable }} + +apiVersion: batch/v1 +kind: Job +metadata: + labels: + app: {{.Release.Name}} + role: {{.Release.Namespace}} + name: {{.Release.Name}} + namespace: {{.Release.Namespace}} +spec: + template: + spec: + +{{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} +{{- end }} + + containers: + - name: {{.Release.Name}} + image: {{.Values.imageRegistry}}:{{.Values.dockerTag}} + command: ["/bin/bash", "-c"] + +{{- if eq .Values.job.mode "add_coin" }} + + args: + - node tools/dbs/addCoin.js; + +{{- else if eq .Values.job.mode "remove_coin" }} + + args: + - node tools/dbs/removeCoin.js; + +{{- else if eq .Values.job.mode "add_pair" }} + + args: + - node tools/dbs/addPair.js; + +{{- else if eq .Values.job.mode "remove_pair" }} + + args: + - node tools/dbs/removePair.js; + +{{- else if eq .Values.job.mode "set_activation_code" }} + + args: + - node tools/dbs/setActivationCode.js; + +{{- else if eq .Values.job.mode "check_constants" }} + + args: + - node tools/dbs/checkConstants.js; + +{{- else if eq .Values.job.mode "set_config" }} + + args: + - node tools/dbs/setConfig.js; + +{{- else if eq .Values.job.mode "set_security" }} + + args: + - node tools/dbs/setSecurity.js; + +{{- else if eq .Values.job.mode "hollaex_setup" }} + + args: + - sequelize db:migrate; + node tools/dbs/runTriggers.js; + sequelize db:seed:all; + node tools/dbs/setActivationCode.js; + node tools/dbs/checkConfig.js; + node tools/dbs/setKitVersion.js; + +{{- else if eq .Values.job.mode "hollaex_upgrade" }} + + args: + - sequelize db:migrate; + node tools/dbs/runTriggers.js; + node tools/dbs/checkConfig.js; + node tools/dbs/setKitVersion.js; + +{{- else if eq .Values.job.mode "changeEmail" }} + + args: + - node tools/dbs/changeEmail.js; + +{{- end }} + + imagePullPolicy: Always + + envFrom: + - configMapRef: + name: {{.Values.envName}} + - secretRef: + name: {{.Values.secretName}} + + env: + +{{- if eq .Values.job.mode "add_coin" }} + + - name: COIN_SYMBOL + value: {{.Values.job.env.coin_symbol}} + - name: COIN_FULLNAME + value: {{.Values.job.env.coin_fullname}} + - name: COIN_ALLOW_DEPOSIT + value: {{.Values.job.env.coin_allow_deposit | quote }} + - name: COIN_ALLOW_WITHDRAWAL + value: {{.Values.job.env.coin_allow_withdrawal | quote }} + - name: COIN_WITHDRAWAL_FEE + value: {{.Values.job.env.coin_withdrawal_fee | quote }} + - name: COIN_MIN + value: {{.Values.job.env.coin_min | quote }} + - name: COIN_MAX + value: {{.Values.job.env.coin_max | quote }} + - name: COIN_INCREMENT_UNIT + value: {{.Values.job.env.coin_increment_unit | quote }} + - name: COIN_DEPOSIT_LIMITS + value: {{.Values.job.env.coin_deposit_limits | quote}} + - name: COIN_WITHDRAWAL_LIMITS + value: {{.Values.job.env.coin_withdrawal_limits | quote }} + - name: COIN_ACTIVE + value: {{.Values.job.env.coin_active | quote }} + +{{- else if eq .Values.job.mode "remove_coin" }} + + - name: COIN_SYMBOL + value: {{.Values.job.env.coin_symbol}} + +{{- else if eq .Values.job.mode "add_pair" }} + + - name: PAIR_NAME + value: {{.Values.job.env.pair_name}} + - name: PAIR_BASE + value: {{.Values.job.env.pair_base}} + - name: PAIR_2 + value: {{.Values.job.env.pair_2}} + - name: TAKER_FEES + value: {{.Values.job.env.taker_fees | quote }} + - name: MAKER_FEES + value: {{.Values.job.env.maker_fees | quote }} + - name: MIN_SIZE + value: {{.Values.job.env.min_size | quote }} + - name: MAX_SIZE + value: {{.Values.job.env.max_size | quote }} + - name: MIN_PRICE + value: {{.Values.job.env.min_price | quote }} + - name: MAX_PRICE + value: {{.Values.job.env.max_price | quote }} + - name: INCREMENT_SIZE + value: {{.Values.job.env.increment_size | quote }} + - name: INCREMENT_PRICE + value: {{.Values.job.env.increment_price | quote }} + - name: PAIR_ACTIVE + value: {{.Values.job.env.pair_active | quote }} + +{{- else if eq .Values.job.mode "remove_pair" }} + + - name: PAIR_NAME + value: {{.Values.job.env.pair_name}} + +{{- else if eq .Values.job.mode "set_activation_code" }} + + - name: ACTIVATION_CODE + value: "{{.Values.job.env.activation_code}}" + +{{- else if eq .Values.job.mode "set_security" }} + + - name: ALLOWED_DOMAINS + value: "{{.Values.job.env.allowed_domains}}" + - name: ADMIN_WHITELIST_IP + value: "{{.Values.job.env.admin_whitelist_ip}}" + - name: CAPTCHA_SITE_KEY + value: "{{.Values.job.env.captcha_site_key}}" + - name: CAPTCHA_SECRET_KEY + value: "{{.Values.job.env.captcha_secret_key}}" + +{{- else if eq .Values.job.mode "changeEmail" }} + + - name: USER_ID + value: "{{.Values.job.env.targetUserID}}" + - name: EMAIL + value: "{{.Values.job.env.newUserEmail}}" + +{{- end }} + + resources: + limits: + memory: "500Mi" + requests: + memory: "100Mi" + cpu: "15m" + +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} + restartPolicy: Never + backoffLimit: 0 +{{- end }} \ No newline at end of file diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-server/templates/service.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-server/templates/service.yaml new file mode 100755 index 0000000000..9670089ab4 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-server/templates/service.yaml @@ -0,0 +1,26 @@ + +kind: Service +apiVersion: v1 +metadata: + labels: + app: {{.Release.Name}} + name: {{.Release.Name}} + namespace: {{.Release.Namespace}} +spec: + type: ClusterIP + ports: + - name: port + port: 10010 + targetPort: 10010 + - name: websocket-port + port: 10080 + targetPort: 10080 + - name: plugins-port + port: 10011 + targetPort: 10011 + selector: + app: {{.Release.Name}} + + + + diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-server/values.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-server/values.yaml new file mode 100755 index 0000000000..45793f7852 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-server/values.yaml @@ -0,0 +1,30 @@ +imageRegistry: hollaex/hollaex-kit +dockerTag: 2.11.4-cli-deprecation-46ea26c +imagePullSecrets: + - name: docker-registry-secret +envName: hollaex-kit-configmap +secretName: hollaex-kit-secret +DEPLOYMENT_MODE: api +PAIR: +stable: + replicaCount: 1 +staging: + enable: false + replicaCount: 1 + dockerTag: +nodeSelector: {} +autoScaling: + hpa: + enable: false + memory: + threshold: 80 +APM_URL: +podRestart_webhook_url: +job: + enable: false +resources: + limits: + memory: "1536Mi" + requests: + cpu: "100m" + memory: "512Mi" diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-web/.helmignore b/server/tools/kubernetes/helm-chart/hollaex-kit-web/.helmignore new file mode 100755 index 0000000000..f0c1319444 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-web/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-web/Chart.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-web/Chart.yaml new file mode 100755 index 0000000000..65e266b4ea --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-web/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +description: A Helm chart for bitholla-hollaex-web +name: bitholla-hollaex-web +version: 0.1.0 diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-web/templates/_helpers.tpl b/server/tools/kubernetes/helm-chart/hollaex-kit-web/templates/_helpers.tpl new file mode 100755 index 0000000000..7a6b694414 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-web/templates/_helpers.tpl @@ -0,0 +1,16 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "bitholla-hollaex-server.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "bitholla-hollaex-server.fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-web/templates/autoscaler.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-web/templates/autoscaler.yaml new file mode 100644 index 0000000000..29811d84c1 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-web/templates/autoscaler.yaml @@ -0,0 +1,23 @@ +{{- if .Values.autoScaling.hpa.enable }} + +apiVersion: autoscaling/v2beta2 +kind: HorizontalPodAutoscaler +metadata: + name: {{.Release.Name}} + namespace: {{.Release.NameSpace}} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{.Release.Name}} + minReplicas: {{.Values.stable.replicaCount}} + maxReplicas: {{.Values.autoScaling.hpa.maxReplicas}} + metrics: + - type: Resource + resource: + name: memory + target: + type: AverageValue + averageValue: {{.Values.autoScaling.hpa.avgMemory}} + +{{- end }} \ No newline at end of file diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-web/templates/deployment.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-web/templates/deployment.yaml new file mode 100644 index 0000000000..be9a7eb9a1 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-web/templates/deployment.yaml @@ -0,0 +1,73 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: {{.Release.Name}} + role: {{.Release.Namespace}} + name: {{.Release.Name}} + namespace: {{.Release.Namespace}} +spec: + revisionHistoryLimit: 3 + replicas: {{.Values.stable.replicaCount}} + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + + minReadySeconds: 5 + + selector: + matchLabels: + app: {{.Release.Name}} + role: {{.Release.Namespace}} + tier: backend + template: + metadata: + labels: + app: {{.Release.Name}} + role: {{.Release.Namespace}} + tier: backend + spec: + +{{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} +{{- end }} + + containers: + - name: {{.Release.Name}} + image: {{.Values.imageRegistry}}:{{.Values.dockerTag}} + imagePullPolicy: IfNotPresent + + ports: + - name: port + containerPort: 80 + + resources: + limits: + memory: {{.Values.resources.limits.memory}} + requests: + memory: {{.Values.resources.requests.memory}} + cpu: {{.Values.resources.requests.cpu}} + + +{{- if .Values.podRestart_webhook_url }} + lifecycle: + preStop: + exec: + command: ["/bin/sh", "-c", "export hostname=`hostname` && curl -X POST -H 'Content-type: application/json' --data '{\"attachments\": [ { \"color\": \"#A569BD\", \"title\": \"Pod has been terminated!\", \"text\": \"⚠️Pod '\"${hostname}\"' just has been terminated.⚠️\" } ] }' {{.Values.podRestart_webhook_url}}"] +{{- end }} + + readinessProbe: + exec: + command: + - curl + - http://localhost + initialDelaySeconds: 15 + periodSeconds: 15 + +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} \ No newline at end of file diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-web/templates/service.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-web/templates/service.yaml new file mode 100755 index 0000000000..5013a4e981 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-web/templates/service.yaml @@ -0,0 +1,17 @@ +kind: Service +apiVersion: v1 +metadata: + labels: + app: {{.Release.Name}} + name: {{.Release.Name}} + namespace: {{.Release.Namespace}} +spec: + type: ClusterIP + ports: + - name: port + port: 80 + targetPort: 80 + selector: + app: {{.Release.Name}} + + diff --git a/server/tools/kubernetes/helm-chart/hollaex-kit-web/values.yaml b/server/tools/kubernetes/helm-chart/hollaex-kit-web/values.yaml new file mode 100755 index 0000000000..7cc0c763e8 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/hollaex-kit-web/values.yaml @@ -0,0 +1,31 @@ +# Default values for bitholla-hollaex-nginx. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +imageRegistry: bitholla/hollaex-web +dockerTag: + +imagePullSecrets: + - name: docker-registry-secret + +stable: + replicaCount: 1 + +nodeSelector: {} + +autoScaling: + hpa: + enable: false + maxReplicas: 4 + avgMemory: 500000000 + +podRestart_webhook_url: + +resources: + limits: + + memory: "100Mi" + requests: + cpu: "10m" + memory: "100Mi" + + diff --git a/server/tools/kubernetes/helm-chart/postgres-s3-backup/.helmignore b/server/tools/kubernetes/helm-chart/postgres-s3-backup/.helmignore new file mode 100755 index 0000000000..f0c1319444 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/postgres-s3-backup/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/server/tools/kubernetes/helm-chart/postgres-s3-backup/Chart.yaml b/server/tools/kubernetes/helm-chart/postgres-s3-backup/Chart.yaml new file mode 100755 index 0000000000..8f8a530097 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/postgres-s3-backup/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +description: A Helm chart for bitholla-hollaex-postgres-s3-backup-cronjob +name: bitholla-hollaex-postgres-s3-backup-cronjob +version: 0.1.0 diff --git a/server/tools/kubernetes/helm-chart/postgres-s3-backup/templates/NOTES.txt b/server/tools/kubernetes/helm-chart/postgres-s3-backup/templates/NOTES.txt new file mode 100755 index 0000000000..e69de29bb2 diff --git a/server/tools/kubernetes/helm-chart/postgres-s3-backup/templates/_helpers.tpl b/server/tools/kubernetes/helm-chart/postgres-s3-backup/templates/_helpers.tpl new file mode 100755 index 0000000000..ca1a4a8fd2 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/postgres-s3-backup/templates/_helpers.tpl @@ -0,0 +1,16 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "bitholla-hollaex-postgres-s3-backup-cronjob.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "bitholla-hollaex-postgres-s3-backup-cronjob.fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/server/tools/kubernetes/helm-chart/postgres-s3-backup/templates/deployment.yaml b/server/tools/kubernetes/helm-chart/postgres-s3-backup/templates/deployment.yaml new file mode 100644 index 0000000000..cba9280acc --- /dev/null +++ b/server/tools/kubernetes/helm-chart/postgres-s3-backup/templates/deployment.yaml @@ -0,0 +1,58 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: {{.Release.Name}} + namespace: {{.Release.Namespace}} +spec: + schedule: {{.Values.cronRule}} + successfulJobsHistoryLimit: 3 + failedJobsHistoryLimit: 2 + jobTemplate: + spec: + template: + spec: + containers: + - name: postgres-backup-to-s3 + image: bitholla/postgres-s3-backup-cronjob:psql15-awscli + env: + - name: AWS_BUCKET + value: {{.Values.awsBucket}} + - name: TIMEZONE_SET + value: {{.Values.timeZone}} + - name: AWS_DEFAULT_REGION + value: {{.Values.awsRegion}} + - name: AWS_ACCESS_KEY_ID + value: {{.Values.awsAccessKey}} + - name: AWS_SECRET_ACCESS_KEY + value: {{.Values.awsSecretKey}} + - name: PGUSER + valueFrom: + secretKeyRef: + name: {{.Values.secretName}} + key: DB_USERNAME + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: {{.Values.secretName}} + key: DB_PASSWORD + - name: PGHOST + valueFrom: + secretKeyRef: + name: {{.Values.secretName}} + key: DB_HOST + - name: PGDATABASE + valueFrom: + secretKeyRef: + name: {{.Values.secretName}} + key: DB_NAME + + args: + - /bin/sh + - -c + {{- if eq .Values.pgdumpMode "pg_dumpall" }} + - export TZ=$TIMEZONE_SET && export TIMESTAMP="$(date +%y%m%d%H%M)" && pg_dumpall > {{.Release.Namespace}}-$TIMESTAMP.dump && echo successfullly dumped "{{.Release.Namespace}}-$TIMESTAMP, Now pushing it to S3." && ls -al && aws s3 cp {{.Release.Namespace}}-$TIMESTAMP.dump s3://$AWS_BUCKET/backup/{{.Release.Namespace}}-postgres/{{.Release.Namespace}}-$TIMESTAMP.dump + {{- else if eq .Values.pgdumpMode "pg_dump" }} + - export TZ=$TIMEZONE_SET && export TIMESTAMP="$(date +%y%m%d%H%M)" && pg_dump -Fc > {{.Release.Namespace}}-$TIMESTAMP.dump && echo successfullly dumped "{{.Release.Namespace}}-$TIMESTAMP, Now pushing it to S3." && ls -al && aws s3 cp {{.Release.Namespace}}-$TIMESTAMP.dump s3://$AWS_BUCKET/backup/{{.Release.Namespace}}-postgres/{{.Release.Namespace}}-$TIMESTAMP.dump + {{- end }} + restartPolicy: OnFailure + diff --git a/server/tools/kubernetes/helm-chart/postgres-s3-backup/values.yaml b/server/tools/kubernetes/helm-chart/postgres-s3-backup/values.yaml new file mode 100755 index 0000000000..9e82cd7715 --- /dev/null +++ b/server/tools/kubernetes/helm-chart/postgres-s3-backup/values.yaml @@ -0,0 +1,12 @@ +secretName: hollaex-kit-secret + +cronRule: "0 1,13 * * *" + +timeZone: UTC + +pgdumpMode: pg_dump + +awsRegion: +awsBucket: +awsAccessKey: +awsSecretKey: \ No newline at end of file diff --git a/server/tools/kubernetes/ingress/hollaex-kit-ingress.yaml b/server/tools/kubernetes/ingress/hollaex-kit-ingress.yaml new file mode 100644 index 0000000000..755de44ccd --- /dev/null +++ b/server/tools/kubernetes/ingress/hollaex-kit-ingress.yaml @@ -0,0 +1,157 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: hollaex-kit-ingress-api + namespace: hollaex-kit + annotations: + kubernetes.io/ingress.class: "nginx" + kubernetes.io/tls-acme: "true" + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/proxy-body-size: "6m" + nginx.ingress.kubernetes.io/rewrite-target: /$2 + + +spec: + rules: + - host: yourdomain.com + http: + paths: + - pathType: Prefix + path: /api(/|$)(.*) + backend: + service: + name: hollaex-kit-server-api + port: + number: 10010 + + tls: + - secretName: hollaex-kit-tls-cert + hosts: + - yourdomain.com +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: hollaex-kit-ingress-api-admin + namespace: hollaex-kit + annotations: + kubernetes.io/ingress.class: "nginx" + kubernetes.io/tls-acme: "true" + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/proxy-body-size: "6m" + nginx.ingress.kubernetes.io/rewrite-target: /v2/admin/$2 + + +spec: + rules: + - host: yourdomain.com + http: + paths: + - pathType: Prefix + path: /api/v2/admin(/|$)(.*) + backend: + service: + name: hollaex-kit-server-api + port: + number: 10010 + + tls: + - secretName: hollaex-kit-tls-cert + hosts: + - yourdomain.com +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: hollaex-kit-ingress-plugins + namespace: hollaex-kit + annotations: + kubernetes.io/ingress.class: "nginx" + kubernetes.io/tls-acme: "true" + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/proxy-body-size: "6m" + nginx.ingress.kubernetes.io/rewrite-target: /plugins/$2 + + +spec: + rules: + - host: yourdomain.com + http: + paths: + - pathType: Prefix + path: /api/plugins(/|$)(.*) + backend: + service: + name: hollaex-kit-server-plugins + port: + number: 10011 + + + tls: + - secretName: hollaex-kit-tls-cert + hosts: + - yourdomain.com +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: hollaex-kit-ingress-plugins-sms-verify + namespace: hollaex-kit + annotations: + kubernetes.io/ingress.class: "nginx" + kubernetes.io/tls-acme: "true" + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/proxy-body-size: "6m" + nginx.ingress.kubernetes.io/rewrite-target: /plugins/sms/verify/$2 + + + +spec: + rules: + - host: yourdomain.com + http: + paths: + - pathType: Prefix + path: /api/plugins/sms/verify(/|$)(.*) + backend: + service: + name: hollaex-kit-server-plugins + port: + number: 10011 + + + tls: + - secretName: hollaex-kit-tls-cert + hosts: + - yourdomain.com +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: hollaex-kit-ingress-stream + namespace: hollaex-kit + annotations: + kubernetes.io/ingress.class: "nginx" + kubernetes.io/tls-acme: "true" + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/proxy-body-size: "6m" + nginx.ingress.kubernetes.io/upstream-hash-by: "$binary_remote_addr" + +spec: + rules: + - host: yourdomain.com + http: + paths: + - pathType: Prefix + path: /stream + backend: + service: + name: hollaex-kit-server-stream + port: + number: 10080 + + + tls: + - secretName: hollaex-kit-tls-cert + hosts: + - yourdomain.com diff --git a/server/tools/nginx/conf.d/upstream.conf b/server/tools/nginx-dev/conf.d/upstream.conf similarity index 100% rename from server/tools/nginx/conf.d/upstream.conf rename to server/tools/nginx-dev/conf.d/upstream.conf diff --git a/server/tools/nginx-dev/mime.types b/server/tools/nginx-dev/mime.types new file mode 100644 index 0000000000..25ae94eb7a --- /dev/null +++ b/server/tools/nginx-dev/mime.types @@ -0,0 +1,48 @@ +types { + text/html html htm shtml; + text/css css; + text/xml xml rss; + image/gif gif; + image/jpeg jpeg jpg; + application/x-javascript js; + text/plain txt; + text/x-component htc; + text/mathml mml; + image/png png; + image/x-icon ico; + image/x-jng jng; + image/vnd.wap.wbmp wbmp; + application/java-archive jar war ear; + application/mac-binhex40 hqx; + application/pdf pdf; + application/x-cocoa cco; + application/x-java-archive-diff jardiff; + application/x-java-jnlp-file jnlp; + application/x-makeself run; + application/x-perl pl pm; + application/x-pilot prc pdb; + application/x-rar-compressed rar; + application/x-redhat-package-manager rpm; + application/x-sea sea; + application/x-shockwave-flash swf; + application/x-stuffit sit; + application/x-tcl tcl tk; + application/x-x509-ca-cert der pem crt; + application/x-xpinstall xpi; + application/zip zip; + application/octet-stream deb; + application/octet-stream bin exe dll; + application/octet-stream dmg; + application/octet-stream eot; + application/octet-stream iso img; + application/octet-stream msi msp msm; + audio/mpeg mp3; + audio/x-realaudio ra; + video/mpeg mpeg mpg; + video/quicktime mov; + video/x-flv flv; + video/x-msvideo avi; + video/x-ms-wmv wmv; + video/x-ms-asf asx asf; + video/x-mng mng; +} diff --git a/server/tools/nginx/nginx.conf b/server/tools/nginx-dev/nginx.conf similarity index 74% rename from server/tools/nginx/nginx.conf rename to server/tools/nginx-dev/nginx.conf index fd38903bc3..72017cb9d0 100644 --- a/server/tools/nginx/nginx.conf +++ b/server/tools/nginx-dev/nginx.conf @@ -26,11 +26,10 @@ http { limit_req_zone $remote_addr zone=api:1m rate=4r/s; limit_req_zone $remote_addr zone=order:1m rate=5r/s; - #Server blockes will be automatically generated - +# SERVER BLOCK server { listen 80; - server_name hollaex; + server_name _; set $req_filtered $request; if ($req_filtered ~ (.*)key=[^&]*(.*)) { @@ -44,26 +43,23 @@ server { include /etc/nginx/conf.d/plugin*.conf; - location /explorer { - proxy_pass http://api; - } - location /v2 { + location /api { proxy_pass http://api; - limit_req zone=api burst=12 nodelay; + limit_req zone=api burst=14 nodelay; limit_req_log_level notice; limit_req_status 429; - } + rewrite /api(/|$)(.*) /$2 break; - location /v2/admin { - proxy_pass http://api; - } - location /plugins { + + location /api/plugins { proxy_pass http://plugins; + + rewrite /api(/|$)(.*) /$2 break; } location /stream { @@ -73,11 +69,31 @@ server { proxy_pass http://socket; } - - location / { + + location /v2 { proxy_pass http://api; + + limit_req zone=api burst=14 nodelay; + limit_req_log_level notice; + limit_req_status 429; + + rewrite /api(/|$)(.*) /$2 break; + } + location /plugins { + proxy_pass http://plugins; + + limit_req zone=api burst=14 nodelay; + limit_req_log_level notice; + limit_req_status 429; + + rewrite /api(/|$)(.*) /$2 break; + + } + + + error_page 429 /429.html; location = /429.html { root /usr/share/nginx/html; diff --git a/server/tools/nginx-dev/proxy.conf b/server/tools/nginx-dev/proxy.conf new file mode 100644 index 0000000000..a53a4dd9fd --- /dev/null +++ b/server/tools/nginx-dev/proxy.conf @@ -0,0 +1,11 @@ +proxy_redirect off; +proxy_set_header Host $host; +proxy_set_header X-Real-IP $remote_addr; +proxy_set_header X-Real-Origin $http_origin; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +client_max_body_size 6m; +client_body_buffer_size 128k; +proxy_connect_timeout 90; +proxy_send_timeout 90; +proxy_read_timeout 90; +proxy_buffers 32 4k; diff --git a/server/tools/nginx-dev/static/429.html b/server/tools/nginx-dev/static/429.html new file mode 100644 index 0000000000..937b15e46b --- /dev/null +++ b/server/tools/nginx-dev/static/429.html @@ -0,0 +1,9 @@ + + + Too Many Requests + + +

Too Many Requests

+

Please chillex and try again soon.

+ + diff --git a/settings/configmap b/settings/configmap index 83050ee66e..6c968a55ab 100644 --- a/settings/configmap +++ b/settings/configmap @@ -2,7 +2,7 @@ #### All HollaEx CLI commands rely on ENVIRONMENT_EXCHANGE_NAME below. DO NOT MODIFY IT. #### ######################################################################################### -ENVIRONMENT_EXCHANGE_NAME=hollaex +ENVIRONMENT_EXCHANGE_NAME=hollaex-kit ################################ #### GENERAL CONFIGURATIONS #### @@ -76,7 +76,7 @@ ENVIRONMENT_KUBERNETES_REDIS_NODESELECTOR="{}" ENVIRONMENT_KUBERNETES_EXCHANGE_STATEFUL_NODESELECTOR="{}" ENVIRONMENT_KUBERNETES_EXCHANGE_STATELESS_NODESELECTOR="{}" -ENVIRONMENT_DOCKER_IMAGE_VERSION=2.2.0 +ENVIRONMENT_DOCKER_IMAGE_VERSION=2.11.3 ENVIRONMENT_DOCKER_IMAGE_POSTGRESQL_REGISTRY=postgres ENVIRONMENT_DOCKER_IMAGE_POSTGRESQL_VERSION=14.9-alpine diff --git a/settings/secret b/settings/secret index 87f220c5f1..239714d511 100644 --- a/settings/secret +++ b/settings/secret @@ -39,4 +39,3 @@ HOLLAEX_SECRET_SMTP_PASSWORD= #### AUTOMATICALLY GENERATED PASSWORDS GONNA BE STORED DOWN BELOW #### ###################################################################### -HOLLAEX_SECRET_SECRET= \ No newline at end of file diff --git a/version b/version index ac569006a9..e13ec79f55 100644 --- a/version +++ b/version @@ -1 +1 @@ -2.11.3 \ No newline at end of file +2.11.4 \ No newline at end of file diff --git a/web/.env b/web/.env index bbe8ee441e..48e7b2bb48 100644 --- a/web/.env +++ b/web/.env @@ -1,11 +1,13 @@ NODE_ENV=production -REACT_APP_PUBLIC_URL=https://yourdomain.com -REACT_APP_SERVER_ENDPOINT=http://localhost +REACT_APP_PUBLIC_URL=http://yourdomain.com +REACT_APP_SERVER_ENDPOINT=http://localhost/api +REACT_APP_STREAM_ENDPOINT=ws://localhost/stream + REACT_APP_NETWORK=mainnet -REACT_APP_EXCHANGE_NAME=testexchange +REACT_APP_EXCHANGE_NAME="hollaex-kit" REACT_APP_CAPTCHA_SITE_KEY= @@ -15,9 +17,6 @@ REACT_APP_DEFAULT_COUNTRY= REACT_APP_LOGO_PATH=https://bitholla.s3.ap-northeast-2.amazonaws.com/kit/LOGO_IMAGE_LIGHT REACT_APP_LOGO_BLACK_PATH=https://bitholla.s3.ap-northeast-2.amazonaws.com/kit/LOGO_IMAGE_DARK -REACT_APP_EXCHANGE_NAME='TestExchange_' REACT_APP_PLUGIN_DEV_MODE= REACT_APP_PLUGIN= -REACT_APP_LANG= - -REACT_APP_LAST_BUILD= +REACT_APP_LANG= \ No newline at end of file diff --git a/web/docker-compose.yaml b/web/docker-compose.yaml new file mode 100644 index 0000000000..31d971ac54 --- /dev/null +++ b/web/docker-compose.yaml @@ -0,0 +1,20 @@ +version: '3' +name: "client" +services: + hollaex-kit-web: + image: hollaex-kit-web + build: + context: . + dockerfile: docker/Dockerfile + restart: always + env_file: + - .env + ports: + - 8080:80 + networks: + - local_hollaex-kit-network + +networks: + local_hollaex-kit-network: + external: true + diff --git a/web/docker/Dockerfile b/web/docker/Dockerfile index 6cd2a65eb2..1343c1f3e6 100644 --- a/web/docker/Dockerfile +++ b/web/docker/Dockerfile @@ -7,7 +7,9 @@ COPY package.json /app/package.json RUN npm install -g node-gyp && \ npm install --loglevel=error COPY . /app -RUN npm run build +RUN export REACT_APP_LAST_BUILD=$(date +"%Y-%m-%dT%H-%M-%S") && \ + npm run build && \ + echo $REACT_APP_LAST_BUILD > /app/build/react-app-last-build.txt FROM nginx:1.24.0-alpine RUN apk add --update \ diff --git a/web/package.json b/web/package.json index e6a6df4b78..8a911e6a90 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "hollaex-kit", - "version": "2.11.3", + "version": "2.11.4", "private": true, "dependencies": { "@ant-design/compatible": "1.0.5", diff --git a/web/src/containers/Admin/User/AboutData.js b/web/src/containers/Admin/User/AboutData.js index 40745062a2..1c25d6807c 100644 --- a/web/src/containers/Admin/User/AboutData.js +++ b/web/src/containers/Admin/User/AboutData.js @@ -1095,7 +1095,7 @@ const AboutData = ({ backgroundColor: '#27339D', marginTop: 60, }} - width={610} + width={650} visible={displayWithdrawalBlock} footer={null} onCancel={() => { @@ -1140,7 +1140,10 @@ const AboutData = ({ }} value={null} > - None (it follows the users tier withdrawal limit) + None{' '} + + (it follows the users tier withdrawal limit) +