Skip to content

Gauzy Self‐Hosted Setup in DigitalOcean

Ruslan K edited this page Mar 10, 2024 · 15 revisions

DigitalOcean Kubernetes

  1. Fork Gauzy Platform repo (private or public).

  2. Run PostgreSQL DB in DigitalOcean (DO) and create an empty DB. Take connection parameters and add them to your GitHub Secrets into corresponding env vars:

  • DB_HOST / DB_HOST_PUBLIC (Hostname of DB)
  • DB_PASS (Password for DB user)
  • DB_PORT (Database Port)
  • DB_SSL_MODE (value should be true if your DB provider requires SSL connectivity)
  • DB_TYPE (e.g. "postgres" for PostgreSQL DB)
  • DB_USER (Username used to connect to DB)

We recommend running the latest PostgreSQL (16.x) and also using connection pooling enabled for production workloads. Make sure you create a PostgreSQL cluster in the SAME region as your Kubernetes cluster.

You need to create a special env var DB_CA_CERT for DO DB CA Certificate, use the Bash command below to get a value for it (assuming you saved the CA Cert file in the ca-certificate.crt file):

base64 ca-certificate.crt
  1. Create Kubernetes cluster (k8s) in DO (latest version). We recommend running at least 2 node clusters, each node with 8Gb RAM or more. Make sure it runs in the same region as your DB and make sure you allow connection to DB from that cluster (it's a setting of PostgreSQL DB in DO). Write down the name of the cluster you created, you will need to update it in our codebase.

You need to define the env var that stores the DO access token: DIGITALOCEAN_ACCESS_TOKEN as it's used in the installation/configuration of doctl CLI:

- name: Install doctl
              uses: digitalocean/action-doctl@v2
              with:
                  token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}

(see for example deploy-do-demo.yml file in the .github/workflows folder)

  1. Add an SSL Certificate for your domain to "Networking" in DO. We recommend using Cloudflare to generate such a server certificate (free of charge)

  2. Check GitHub actions that deploy docker containers to the k8s cluster in DigitalOcean (DO), e.g. https://github.com/ever-co/ever-gauzy/blob/develop/.github/workflows/deploy-do-prod.yml and note all names of env vars that needs to be created as GitHub Secrets (e.g. DB_USER, DB_PASSWORD, and so on).

  3. Check k8s Manifest in https://github.com/ever-co/ever-gauzy/blob/develop/.deploy/k8s/k8s-manifest.prod.yaml. You mostly need to replace some parameters, such as domain names, certificate IDs in DO, etc. In addition, you need to replace our docker images for API and UI (e.g. "registry.digitalocean.com/ever/gauzy-api:latest") with your own images (e.g. if you copy to your own registry, recommended for production workloads) or use our public images (see https://github.com/orgs/ever-co/packages?repo_name=ever-gauzy)

  4. After you defined all Secrets in GitHub and changed manifests/workflows described above, you need to push your changes to the develop branch (if it's your default one) and next to the master branch to make sure deployment proceeds. As a result, you should be able to see Pods running in the k8s cluster: for API and UI (frontend).

We estimate it should take from a few hours to about 8 hours of work for a senior DevOps Engineer (depending on many factors) and if you want us to help with that setup, feel free to email to ever@ever.tech. The cost will be calculated on the exact amount of hour setup takes on the 35$ per hour rate.

DigitalOcean App Platform

Setup on the DigitalOcean App Platform

  1. Make sure GitHub Secret DIGITALOCEAN_ACCESS_TOKEN is set to your DigitalOcean access token that has enough privileges to create/update DigitalOcean App Platform applications.

  2. Our existing GitHub actions are used to create 3 separate "Apps" in DigitalOcean, one for each environment, e.g. ever-gauzy-demo, ever-gauzy-stage and ever-gauzy-prod

  3. Check .github/workflows/deploy-do-app-platform-demo.yml, .github/workflows/deploy-do-app-platform-stage.yml and .github/workflows/deploy-do-app-platform-prod.yml

  4. Each GitHub action creates or updates a separate DO App and assigns a custom Domain name to each env (see APP_DOMAIN env var)

  5. You can define the type of instance (size) in the INSTANCE_SIZE env var (see possible values in the following link) and count in the INSTANCE_COUNT env var. We recommend using 1 instance in the demo env and at least 2 instances in the stage env. Make sure you are using a professional instance size and at least 2 instances for prod environment.

  6. Important to make sure DEMO env var is set to false for prod environment. We also recommend to set ADMIN_PASSWORD_RESET to false for production.

  7. As with any other setup of our platform, make sure API_BASE_URL is set to the URL on which you would like to have API exposed and CLIENT_BASE_URL should be set to the URL on which you will have client-side UI loaded.

  8. You can also research .do/app.yaml file that is used as a template to define the DO App Platform application. Important to note that you will have to configure services/image/registry_type ,services/image/registry, and services/image/repository to use your own DigitalOcean or DockerHub Container Registry, please refer to DO documentation about those parameters.

DigitalOcean Droplets

We support the deployment of the Ever Gauzy Platform into 3 separate droplets in DigitalOcean, one Droplet for each environment (demo, stage, prod)

  1. deploy-do-droplet-pre-demo.yml and .deploy/ssh/docker-compose.api.demo.pre.yml - those prepare DO Droplet #1 with Demo env by installing and configured nginx proxy with either CF or LetsEncrypt certificate, depending on the env varINGRESS_CERT_TYPE=letsencrypt | cloudflare set value
  2. deploy-do-droplet-pre-stage.yml and .deploy/ssh/docker-compose.api.stage.pre.yml - those prepare DO Droplet #2 with Stage env by installing and configured nginx proxy with either CF or LetsEncrypt certificate, depending on the env varINGRESS_CERT_TYPE=letsencrypt | cloudflare set value
  3. deploy-do-droplet-pre-prod.yml and .deploy/ssh/docker-compose.api.prod.pre.yml - those prepare DO Droplet #3 with Production environment by installing and configured nginx proxy with either CF or LetsEncrypt certificate, depending on the env varINGRESS_CERT_TYPE=letsencrypt | cloudflare set value
  4. deploy-do-droplet-demo.yml - deploy DEMO env containers using Docker Compose file .deploy/ssh/docker-compose.api.demo.template.yml to DO Droplet #1
  5. deploy-do-droplet-stage.yml - deploy STAGE env containers using Docker Compose file .deploy/ssh/docker-compose.api.stage.template.yml to DO Droplet #2
  6. deploy-do-droplet-prod.yml - deploy PROD env containers using Docker Compose file .deploy/ssh/docker-compose.api.prod.template.yml to DO Droplet #3

Setting Up SSH Key Using SSH Key-Gen

SSH keys provide a secure way of logging into a remote server without needing to enter a password each time. Here's how you can set up SSH keys on your local machine and then add the public key to your DigitalOcean droplet.

Generating SSH Key Pair

  1. Open your terminal or command prompt.

  2. Use the following command to generate an SSH key pair:

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

Replace "your_email@example.com" with your email address. This command will generate a new SSH key using the provided email.

  1. You will be prompted to enter a file to save the key. By default, it will save to ~/.ssh/id_rsa. Press Enter to confirm or specify a different location.

  2. You will then be prompted to enter a passphrase. It is recommended to use a passphrase, but you can also leave it blank for no passphrase. Press Enter after entering your passphrase.

  3. The SSH key pair will be generated. You will see output similar to:



Your identification has been saved in /home/your_username/.ssh/id_rsa
Your public key has been saved in /home/your_username/.ssh/id_rsa.pub

Adding Public Key to DigitalOcean

  1. Log in to your DigitalOcean account.

  2. Navigate to the "Droplets" section.

  3. Click on the droplet you want to connect to.

  4. In the droplet's dashboard, click on the "Access" tab.

  5. Scroll down to the "SSH keys" section and click on "Add SSH Key".

  6. Copy the contents of your public key. You can do this by running:

cat ~/.ssh/id_rsa.pub

  1. Paste the public key into the provided text box and click "Add SSH Key".

SSH into Droplet

Now that your SSH key is added to your droplet, you can SSH into it from your terminal.

  1. Open your terminal.

  2. Use the following command to SSH into your droplet:

ssh username@droplet_ip_address


Replace username with your username on the droplet, and droplet_ip_address with the IP address of your droplet.

  1. If you set a passphrase for your SSH key, you will be prompted to enter it.

  2. You are now logged into your DigitalOcean droplet via SSH.

Setup Docker-compose(Gauzy Api and nginx proxy) using CloudFlare own Certificate and Letsencrypt self assigned certificate

Docker-compose(Gauzy Api and nginx proxy)CloudFlare own Certificate

Create a directory with-cloudflare and within the directory create another directory called demo, then create a docker-compose file for the gauzy api docker-compose.api.demo.template.yml

version: '3.8'

services:
  api:
    #container_name: api-${ENV_NAME}
    image: ghcr.io/ever-co/gauzy-api-demo:latest
    deploy:
      mode: replicated
      replicas: 2
    environment:
      API_HOST: '0.0.0.0'
      DEMO: '${DEMO:-true}'
      NODE_ENV: '${NODE_ENV:-development}'
      ADMIN_PASSWORD_RESET: '${ADMIN_PASSWORD_RESET:-}'
      API_BASE_URL: '${API_BASE_URL:-http://localhost:3000}'
      CLIENT_BASE_URL: '${CLIENT_BASE_URL:-http://localhost:4200}'
      DB_TYPE: '${DB_TYPE:-better-sqlite3}'
      DB_URI: '${DB_URI:-}'
      DB_HOST: '${DB_HOST:-}'
      DB_USER: '${DB_USER:-}'
      DB_PASS: '${DB_PASS:-}'
      DB_NAME: '${DB_NAME:-}'
      DB_PORT: '${DB_PORT:-}'
      DB_CA_CERT: '${DB_CA_CERT:-}'
      DB_SSL_MODE: '${DB_SSL_MODE:-}'
      DB_POOL_SIZE: '${DB_POOL_SIZE:-}'
      DB_POOL_SIZE_KNEX: '${DB_POOL_SIZE_KNEX:-}'
      REDIS_ENABLED: '${REDIS_ENABLED:-}'
      REDIS_URL: '${REDIS_URL:-}'
      CLOUD_PROVIDER: 'DO'
      SENTRY_DSN: '${SENTRY_DSN:-}'
      SENTRY_TRACES_SAMPLE_RATE: '${SENTRY_TRACES_SAMPLE_RATE:-}'
      SENTRY_PROFILE_SAMPLE_RATE: '${SENTRY_PROFILE_SAMPLE_RATE:-}'
      SENTRY_HTTP_TRACING_ENABLED: '${SENTRY_HTTP_TRACING_ENABLED:-}'
      SENTRY_POSTGRES_TRACKING_ENABLED: '${SENTRY_POSTGRES_TRACKING_ENABLED:-}'
      SENTRY_PROFILING_ENABLED: '${SENTRY_PROFILING_ENABLED:-}'
      AWS_ACCESS_KEY_ID: '${AWS_ACCESS_KEY_ID:-}'
      AWS_SECRET_ACCESS_KEY: '${AWS_SECRET_ACCESS_KEY:-}'
      AWS_REGION: '${AWS_REGION:-}'
      AWS_S3_BUCKET: '${AWS_S3_BUCKET:-}'
      WASABI_ACCESS_KEY_ID: '${WASABI_ACCESS_KEY_ID:-}'
      WASABI_SECRET_ACCESS_KEY: '${WASABI_SECRET_ACCESS_KEY:-}'
      WASABI_REGION: '${WASABI_REGION:-}'
      WASABI_SERVICE_URL: '${WASABI_SERVICE_URL:-}'
      WASABI_S3_BUCKET: '${WASABI_S3_BUCKET:-}'
      EXPRESS_SESSION_SECRET: '${EXPRESS_SESSION_SECRET:-}'
      JWT_SECRET: '${JWT_SECRET:-}'
      JWT_REFRESH_TOKEN_SECRET: '${JWT_REFRESH_TOKEN_SECRET:-}'
      JWT_REFRESH_TOKEN_EXPIRATION_TIME: '${JWT_REFRESH_TOKEN_EXPIRATION_TIME:-}'
      CLOUDINARY_API_KEY: '${CLOUDINARY_API_KEY:-}'
      CLOUDINARY_API_SECRET: '${CLOUDINARY_API_SECRET:-}'
      CLOUDINARY_CLOUD_NAME: '${CLOUDINARY_CLOUD_NAME:-}'
      MAIL_FROM_ADDRESS: '${MAIL_FROM_ADDRESS:-}'
      MAIL_HOST: '${MAIL_HOST:-}'
      MAIL_PORT: '${MAIL_PORT:-}'
      MAIL_USERNAME: '${MAIL_USERNAME:-}'
      MAIL_PASSWORD: '${MAIL_PASSWORD:-}'
      ALLOW_SUPER_ADMIN_ROLE: '${ALLOW_SUPER_ADMIN_ROLE:-}'
      GOOGLE_CLIENT_ID: '${GOOGLE_CLIENT_ID:-}'
      GOOGLE_CLIENT_SECRET: '${GOOGLE_CLIENT_SECRET:-}'
      GOOGLE_CALLBACK_URL: '${GOOGLE_CALLBACK_URL:-}'
      FACEBOOK_CLIENT_ID: '${FACEBOOK_CLIENT_ID:-}'
      FACEBOOK_CLIENT_SECRET: '${FACEBOOK_CLIENT_SECRET:-}'
      FACEBOOK_GRAPH_VERSION: '${FACEBOOK_GRAPH_VERSION:-}'
      FACEBOOK_CALLBACK_URL: '${FACEBOOK_CALLBACK_URL:-}'
      INTEGRATED_USER_DEFAULT_PASS: '${INTEGRATED_USER_DEFAULT_PASS:-}'
      UPWORK_REDIRECT_URL: '${UPWORK_REDIRECT_URL:-}'
      FILE_PROVIDER: '${FILE_PROVIDER:-}'
      GAUZY_AI_GRAPHQL_ENDPOINT: '${GAUZY_AI_GRAPHQL_ENDPOINT:-}'
      GAUZY_AI_REST_ENDPOINT: '${GAUZY_AI_REST_ENDPOINT:-}'
      UNLEASH_APP_NAME: '${UNLEASH_APP_NAME:-}'
      UNLEASH_API_URL: '${UNLEASH_API_URL:-}'
      UNLEASH_INSTANCE_ID: '${UNLEASH_INSTANCE_ID:-}'
      UNLEASH_REFRESH_INTERVAL: '${UNLEASH_REFRESH_INTERVAL:-}'
      UNLEASH_METRICS_INTERVAL: '${UNLEASH_METRICS_INTERVAL:-}'
      UNLEASH_API_KEY: '${UNLEASH_API_KEY:-}'
      PM2_MACHINE_NAME: '${PM2_MACHINE_NAME:-}'
      PM2_SECRET_KEY: '${PM2_SECRET_KEY:-}'
      PM2_PUBLIC_KEY: '${PM2_PUBLIC_KEY:-}'
      JITSU_SERVER_URL: '${JITSU_SERVER_URL:-}'
      JITSU_SERVER_WRITE_KEY: '${JITSU_SERVER_WRITE_KEY:-}'
      OTEL_ENABLED: '${OTEL_ENABLED:-}'
      OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: '${OTEL_EXPORTER_OTLP_TRACES_ENDPOINT:-}'
      OTEL_EXPORTER_OTLP_HEADERS: '${OTEL_EXPORTER_OTLP_HEADERS:-}'
      GAUZY_GITHUB_CLIENT_ID: '${GAUZY_GITHUB_CLIENT_ID:-}'
      GAUZY_GITHUB_CLIENT_SECRET: '${GAUZY_GITHUB_CLIENT_SECRET:-}'
      GAUZY_GITHUB_APP_PRIVATE_KEY: '${GAUZY_GITHUB_APP_PRIVATE_KEY:-}'
      GAUZY_GITHUB_WEBHOOK_URL: '${GAUZY_GITHUB_WEBHOOK_URL:-}'
      GAUZY_GITHUB_WEBHOOK_SECRET: '${GAUZY_GITHUB_WEBHOOK_SECRET:-}'
      GAUZY_GITHUB_APP_NAME: '${GAUZY_GITHUB_APP_NAME:-}'
      GAUZY_GITHUB_REDIRECT_URL: '${GAUZY_GITHUB_REDIRECT_URL:-}'
      GAUZY_GITHUB_POST_INSTALL_URL: '${GAUZY_GITHUB_POST_INSTALL_URL:-}'
      GAUZY_GITHUB_APP_ID: '${GAUZY_GITHUB_APP_ID:-}'
      GAUZY_GITHUB_OAUTH_CLIENT_ID: '${GAUZY_GITHUB_OAUTH_CLIENT_ID:-}'
      GAUZY_GITHUB_OAUTH_CLIENT_SECRET: '${GAUZY_GITHUB_OAUTH_CLIENT_SECRET:-}'
      GAUZY_GITHUB_OAUTH_CALLBACK_URL: '${GAUZY_GITHUB_OAUTH_CALLBACK_URL:-}'
      JITSU_BROWSER_URL: '${JITSU_BROWSER_URL:-}'
      JITSU_BROWSER_WRITE_KEY: '${JITSU_BROWSER_WRITE_KEY:-}'
      MAGIC_CODE_EXPIRATION_TIME: '${MAGIC_CODE_EXPIRATION_TIME:-}'
      APP_NAME: '${APP_NAME:-}'
      APP_LOGO: '${APP_LOGO:-}'
      APP_SIGNATURE: '${APP_SIGNATURE:-}'
      APP_LINK: '${APP_LINK:-}'
      APP_EMAIL_CONFIRMATION_URL: '${APP_EMAIL_CONFIRMATION_URL:-}'
      APP_MAGIC_SIGN_URL: '${APP_MAGIC_SIGN_URL:-}'
      COMPANY_LINK: '${COMPANY_LINK:-}'
      COMPANY_NAME: '${COMPANY_NAME:-}'

    entrypoint: './entrypoint.prod.sh'
    command: ['node', 'main.js']
    restart: on-failure
    ports:
      - '3000'
     # '3000-3001:'${API_PORT:-3000}''
    networks:
      - overlay

volumes:
  certificates: {}

networks:
  overlay:
    driver: bridge

within the same demo directory create another docker-compose file for the nginx proxy docker-compose.api.demo.cloudflare.pre.yml

version: '3.8'

services:
  nginx:
    image: nginx:latest
    volumes:
      - ./nginx.demo.pre.cloudflare.conf:/etc/nginx/nginx.conf:ro
      - ./ingress.api.crt:/etc/nginx/ssl/fullchain.pem
      - ./ingress.api.key:/etc/nginx/ssl/privkey.pem
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    networks:
      - with-cloudflare_overlay
volumes:
  certificates: {}

networks:
  with-cloudflare_overlay:
    external: true      

Then create the nginx config file in the same directory which will be mounted to the nginx service volume nginx.demo.pre.cloudflare.conf

user nginx;
events {
    worker_connections 1024;
}
http {
    server {
        listen 80;
        server_name apidemodt.gauzy.co;

        location / {
            return 301 https://$host$request_uri;
        }
    }
    server {
        listen 443 ssl;
        server_name apidemodt.gauzy.co;

        ssl_certificate /etc/nginx/ssl/fullchain.pem;
        ssl_certificate_key /etc/nginx/ssl/privkey.pem;

        location / {
           proxy_pass http://api:3000;
        }
    }  
}

NB: the server_name must match the domain which has been configured with the certifcates

Docker-compose(Gauzy Api and nginx proxy) Letsencrypt self signed Certificate

Create a directory with-letsencrypt and within the directory create another directory demo, then create a docker-compose file for the gauzy api docker-compose.api.demo.template.yml

version: '3.8'

services:
  api:
    #container_name: api-${ENV_NAME}
    image: ghcr.io/ever-co/gauzy-api-demo:latest
    deploy:
      mode: replicated
      replicas: 2
    environment:
      API_HOST: '0.0.0.0'
      DEMO: '${DEMO:-true}'
      NODE_ENV: '${NODE_ENV:-development}'
      ADMIN_PASSWORD_RESET: '${ADMIN_PASSWORD_RESET:-}'
      API_BASE_URL: '${API_BASE_URL:-http://localhost:3000}'
      CLIENT_BASE_URL: '${CLIENT_BASE_URL:-http://localhost:4200}'
      DB_TYPE: '${DB_TYPE:-better-sqlite3}'
      DB_URI: '${DB_URI:-}'
      DB_HOST: '${DB_HOST:-}'
      DB_USER: '${DB_USER:-}'
      DB_PASS: '${DB_PASS:-}'
      DB_NAME: '${DB_NAME:-}'
      DB_PORT: '${DB_PORT:-}'
      DB_CA_CERT: '${DB_CA_CERT:-}'
      DB_SSL_MODE: '${DB_SSL_MODE:-}'
      DB_POOL_SIZE: '${DB_POOL_SIZE:-}'
      DB_POOL_SIZE_KNEX: '${DB_POOL_SIZE_KNEX:-}'
      REDIS_ENABLED: '${REDIS_ENABLED:-}'
      REDIS_URL: '${REDIS_URL:-}'
      CLOUD_PROVIDER: 'DO'
      SENTRY_DSN: '${SENTRY_DSN:-}'
      SENTRY_TRACES_SAMPLE_RATE: '${SENTRY_TRACES_SAMPLE_RATE:-}'
      SENTRY_PROFILE_SAMPLE_RATE: '${SENTRY_PROFILE_SAMPLE_RATE:-}'
      SENTRY_HTTP_TRACING_ENABLED: '${SENTRY_HTTP_TRACING_ENABLED:-}'
      SENTRY_POSTGRES_TRACKING_ENABLED: '${SENTRY_POSTGRES_TRACKING_ENABLED:-}'
      SENTRY_PROFILING_ENABLED: '${SENTRY_PROFILING_ENABLED:-}'
      AWS_ACCESS_KEY_ID: '${AWS_ACCESS_KEY_ID:-}'
      AWS_SECRET_ACCESS_KEY: '${AWS_SECRET_ACCESS_KEY:-}'
      AWS_REGION: '${AWS_REGION:-}'
      AWS_S3_BUCKET: '${AWS_S3_BUCKET:-}'
      WASABI_ACCESS_KEY_ID: '${WASABI_ACCESS_KEY_ID:-}'
      WASABI_SECRET_ACCESS_KEY: '${WASABI_SECRET_ACCESS_KEY:-}'
      WASABI_REGION: '${WASABI_REGION:-}'
      WASABI_SERVICE_URL: '${WASABI_SERVICE_URL:-}'
      WASABI_S3_BUCKET: '${WASABI_S3_BUCKET:-}'
      EXPRESS_SESSION_SECRET: '${EXPRESS_SESSION_SECRET:-}'
      JWT_SECRET: '${JWT_SECRET:-}'
      JWT_REFRESH_TOKEN_SECRET: '${JWT_REFRESH_TOKEN_SECRET:-}'
      JWT_REFRESH_TOKEN_EXPIRATION_TIME: '${JWT_REFRESH_TOKEN_EXPIRATION_TIME:-}'
      CLOUDINARY_API_KEY: '${CLOUDINARY_API_KEY:-}'
      CLOUDINARY_API_SECRET: '${CLOUDINARY_API_SECRET:-}'
      CLOUDINARY_CLOUD_NAME: '${CLOUDINARY_CLOUD_NAME:-}'
      MAIL_FROM_ADDRESS: '${MAIL_FROM_ADDRESS:-}'
      MAIL_HOST: '${MAIL_HOST:-}'
      MAIL_PORT: '${MAIL_PORT:-}'
      MAIL_USERNAME: '${MAIL_USERNAME:-}'
      MAIL_PASSWORD: '${MAIL_PASSWORD:-}'
      ALLOW_SUPER_ADMIN_ROLE: '${ALLOW_SUPER_ADMIN_ROLE:-}'
      GOOGLE_CLIENT_ID: '${GOOGLE_CLIENT_ID:-}'
      GOOGLE_CLIENT_SECRET: '${GOOGLE_CLIENT_SECRET:-}'
      GOOGLE_CALLBACK_URL: '${GOOGLE_CALLBACK_URL:-}'
      FACEBOOK_CLIENT_ID: '${FACEBOOK_CLIENT_ID:-}'
      FACEBOOK_CLIENT_SECRET: '${FACEBOOK_CLIENT_SECRET:-}'
      FACEBOOK_GRAPH_VERSION: '${FACEBOOK_GRAPH_VERSION:-}'
      FACEBOOK_CALLBACK_URL: '${FACEBOOK_CALLBACK_URL:-}'
      INTEGRATED_USER_DEFAULT_PASS: '${INTEGRATED_USER_DEFAULT_PASS:-}'
      UPWORK_REDIRECT_URL: '${UPWORK_REDIRECT_URL:-}'
      FILE_PROVIDER: '${FILE_PROVIDER:-}'
      GAUZY_AI_GRAPHQL_ENDPOINT: '${GAUZY_AI_GRAPHQL_ENDPOINT:-}'
      GAUZY_AI_REST_ENDPOINT: '${GAUZY_AI_REST_ENDPOINT:-}'
      UNLEASH_APP_NAME: '${UNLEASH_APP_NAME:-}'
      UNLEASH_API_URL: '${UNLEASH_API_URL:-}'
      UNLEASH_INSTANCE_ID: '${UNLEASH_INSTANCE_ID:-}'
      UNLEASH_REFRESH_INTERVAL: '${UNLEASH_REFRESH_INTERVAL:-}'
      UNLEASH_METRICS_INTERVAL: '${UNLEASH_METRICS_INTERVAL:-}'
      UNLEASH_API_KEY: '${UNLEASH_API_KEY:-}'
      PM2_MACHINE_NAME: '${PM2_MACHINE_NAME:-}'
      PM2_SECRET_KEY: '${PM2_SECRET_KEY:-}'
      PM2_PUBLIC_KEY: '${PM2_PUBLIC_KEY:-}'
      JITSU_SERVER_URL: '${JITSU_SERVER_URL:-}'
      JITSU_SERVER_WRITE_KEY: '${JITSU_SERVER_WRITE_KEY:-}'
      OTEL_ENABLED: '${OTEL_ENABLED:-}'
      OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: '${OTEL_EXPORTER_OTLP_TRACES_ENDPOINT:-}'
      OTEL_EXPORTER_OTLP_HEADERS: '${OTEL_EXPORTER_OTLP_HEADERS:-}'
      GAUZY_GITHUB_CLIENT_ID: '${GAUZY_GITHUB_CLIENT_ID:-}'
      GAUZY_GITHUB_CLIENT_SECRET: '${GAUZY_GITHUB_CLIENT_SECRET:-}'
      GAUZY_GITHUB_APP_PRIVATE_KEY: '${GAUZY_GITHUB_APP_PRIVATE_KEY:-}'
      GAUZY_GITHUB_WEBHOOK_URL: '${GAUZY_GITHUB_WEBHOOK_URL:-}'
      GAUZY_GITHUB_WEBHOOK_SECRET: '${GAUZY_GITHUB_WEBHOOK_SECRET:-}'
      GAUZY_GITHUB_APP_NAME: '${GAUZY_GITHUB_APP_NAME:-}'
      GAUZY_GITHUB_REDIRECT_URL: '${GAUZY_GITHUB_REDIRECT_URL:-}'
      GAUZY_GITHUB_POST_INSTALL_URL: '${GAUZY_GITHUB_POST_INSTALL_URL:-}'
      GAUZY_GITHUB_APP_ID: '${GAUZY_GITHUB_APP_ID:-}'
      GAUZY_GITHUB_OAUTH_CLIENT_ID: '${GAUZY_GITHUB_OAUTH_CLIENT_ID:-}'
      GAUZY_GITHUB_OAUTH_CLIENT_SECRET: '${GAUZY_GITHUB_OAUTH_CLIENT_SECRET:-}'
      GAUZY_GITHUB_OAUTH_CALLBACK_URL: '${GAUZY_GITHUB_OAUTH_CALLBACK_URL:-}'
      JITSU_BROWSER_URL: '${JITSU_BROWSER_URL:-}'
      JITSU_BROWSER_WRITE_KEY: '${JITSU_BROWSER_WRITE_KEY:-}'
      MAGIC_CODE_EXPIRATION_TIME: '${MAGIC_CODE_EXPIRATION_TIME:-}'
      APP_NAME: '${APP_NAME:-}'
      APP_LOGO: '${APP_LOGO:-}'
      APP_SIGNATURE: '${APP_SIGNATURE:-}'
      APP_LINK: '${APP_LINK:-}'
      APP_EMAIL_CONFIRMATION_URL: '${APP_EMAIL_CONFIRMATION_URL:-}'
      APP_MAGIC_SIGN_URL: '${APP_MAGIC_SIGN_URL:-}'
      COMPANY_LINK: '${COMPANY_LINK:-}'
      COMPANY_NAME: '${COMPANY_NAME:-}'

    entrypoint: './entrypoint.prod.sh'
    command: ['node', 'main.js']
    restart: on-failure
    ports:
      - '3000'
     # '3000-3001:'${API_PORT:-3000}''
    networks:
      - overlay

volumes:
  certificates: {}

networks:
  overlay:
    driver: bridge

within the same demo directory create another docker-compose file for the nginx proxy docker-compose.api.demo.letsencrypt.pre.yml

version: '3.8'

services:
  proxy:
    image: jonasal/nginx-certbot:latest
    restart: always
    environment:
      CERTBOT_EMAIL: "ever@ever.tech"
    env_file:
      - ./nginx-certbot.env
    ports:
      - "80:80"
      - "443:443"
    networks:
      - demo_overlay
    volumes:
      - nginx_secrets:/etc/letsencrypt
      - ./user_conf.d:/etc/nginx/user_conf.d
volumes:
  nginx_secrets: {}
  certificates: {}

networks:
  demo_overlay:
    external: true

Then create the nginx config directory called user_conf.d and within the nginx config directory create nginx.conf file user_conf.d/nginx.conf

server {
    listen              443 ssl;
    server_name         apidemodts.gauzy.co;
    ssl_certificate     /etc/letsencrypt/live/apidemodts.gauzy.co/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/apidemodts.gauzy.co/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/apidemodts.gauzy.co/chain.pem;

    # Load the Diffie-Hellman parameter.
    ssl_dhparam /etc/letsencrypt/dhparams/dhparam.pem;

    location / {
        proxy_pass http://api:3000;
    }
    
}

NB: the server_name must match the domain which you want to create the self signed certificate for.

Github Action Workflow

Workflow for deploying the Gauzy API Docker-compose

Create a file called deploy-do-droplet-demo.yml in the .github/workflows directory

name: Deploy to DigitalOcean Droplet Demo

on:
  workflow_run:
    workflows: ['Deploy to DigitalOcean Droplet Demo Pre']
    branches: [develop]
    types:
      - completed

jobs:
  deploy:
    runs-on: buildjet-4vcpu-ubuntu-2204

    environment: demo

    steps:
      - name: checkout out code
        uses: actions/checkout@v4

      - name: Modify API_BASE_URL
        run: |
          echo "INGRESS_CERT_TYPE=${{ env.INGRESS_CERT_TYPE }}" >> $GITHUB_ENV

          if [ "${{ env.INGRESS_CERT_TYPE }}" = "cloudflare" ]; then
            echo "API_BASE_URL=https://apidemodt.gauzy.co" >> $GITHUB_ENV
          elif [ "${{ env.INGRESS_CERT_TYPE }}" = "letsencrypt" ]; then
            echo "API_BASE_URL=https://apidemodts.gauzy.co" >> $GITHUB_ENV
          else
            echo "UNKNOWN INGRESS_CERT_TYPE"
          fi
        env:
          INGRESS_CERT_TYPE: 'letsencrypt'

      - name: Inject secrets into .env-template.compose
        run: |
          if [ "${{ env.INGRESS_CERT_TYPE }}" = "cloudflare" ]; then
            envsubst < $GITHUB_WORKSPACE/.deploy/ssh/with-cloudflare/demo/docker-compose.api.demo.template.yml > temp.yaml && mv temp.yaml $GITHUB_WORKSPACE/.deploy/ssh/with-cloudflare/demo/docker-compose.api.demo.yml
            touch $GITHUB_WORKSPACE/.deploy/ssh/with-letsencrypt/demo/docker-compose.api.demo.yml
          elif [ "${{ env.INGRESS_CERT_TYPE }}" = "letsencrypt" ]; then
            envsubst < $GITHUB_WORKSPACE/.deploy/ssh/with-letsencrypt/demo/docker-compose.api.demo.template.yml > temp.yaml && mv temp.yaml $GITHUB_WORKSPACE/.deploy/ssh/with-letsencrypt/demo/docker-compose.api.demo.yml
            touch $GITHUB_WORKSPACE/.deploy/ssh/with-cloudflare/demo/docker-compose.api.demo.yml
          else
            echo "UNKNOWN INGRESS_CERT_TYPE"
          fi
        env:
          ENV_NAME: 'demo'
          DEMO: 'true'
          NODE_ENV: 'development'
          ADMIN_PASSWORD_RESET: 'true'
          API_HOST: $API_HOST
          API_BASE_URL: '${{ env.API_BASE_URL }}'
          CLIENT_BASE_URL: 'https://demo.gauzy.co'
          DB_TYPE: '${{ secrets.DB_TYPE }}'
          DB_URI: '${{ secrets.DB_URI }}'
          DB_HOST: '${{ secrets.DB_HOST }}'
          DB_USER: '${{ secrets.DB_USER }}'
          DB_PASS: '${{ secrets.DB_PASS }}'
          DB_NAME: '${{ secrets.DB_NAME }}'
          DB_PORT: '${{ secrets.DB_PORT }}'
          DB_CA_CERT: '${{ secrets.DB_CA_CERT }}'
          DB_SSL_MODE: '${{ secrets.DB_SSL_MODE }}'
          DB_POOL_SIZE: '${{ secrets.DB_POOL_SIZE }}'
          DB_POOL_SIZE_KNEX: '${{ secrets.DB_POOL_SIZE_KNEX }}'
          REDIS_ENABLED: '${{ secrets.REDIS_ENABLED }}'
          REDIS_URL: '${{ secrets.REDIS_URL }}'
          CLOUD_PROVIDER: 'DO'
          SENTRY_DSN: '${{ secrets.SENTRY_DSN }}'
          SENTRY_TRACES_SAMPLE_RATE: '${{ secrets.SENTRY_TRACES_SAMPLE_RATE }}'
          SENTRY_PROFILE_SAMPLE_RATE: '${{ secrets.SENTRY_PROFILE_SAMPLE_RATE }}'
          SENTRY_HTTP_TRACING_ENABLED: '${{ secrets.SENTRY_HTTP_TRACING_ENABLED }}'
          SENTRY_POSTGRES_TRACKING_ENABLED: '${{ secrets.SENTRY_POSTGRES_TRACKING_ENABLED }}'
          SENTRY_PROFILING_ENABLED: '${{ secrets.SENTRY_PROFILING_ENABLED }}'
          AWS_ACCESS_KEY_ID: '${{ secrets.AWS_ACCESS_KEY_ID }}'
          AWS_SECRET_ACCESS_KEY: '${{ secrets.AWS_SECRET_ACCESS_KEY }}'
          AWS_REGION: '${{ secrets.AWS_REGION }}'
          AWS_S3_BUCKET: '${{ secrets.AWS_S3_BUCKET }}'
          WASABI_ACCESS_KEY_ID: '${{ secrets.WASABI_ACCESS_KEY_ID }}'
          WASABI_SECRET_ACCESS_KEY: '${{ secrets.WASABI_SECRET_ACCESS_KEY }}'
          WASABI_REGION: '${{ secrets.WASABI_REGION }}'
          WASABI_SERVICE_URL: '${{ secrets.WASABI_SERVICE_URL }}'
          WASABI_S3_BUCKET: '${{ secrets.WASABI_S3_BUCKET }}'
          EXPRESS_SESSION_SECRET: '${{ secrets.EXPRESS_SESSION_SECRET }}'
          JWT_SECRET: '${{ secrets.JWT_SECRET }}'
          JWT_REFRESH_TOKEN_SECRET: '${{ secrets.JWT_REFRESH_TOKEN_SECRET }}'
          JWT_REFRESH_TOKEN_EXPIRATION_TIME: '${{ secrets.JWT_REFRESH_TOKEN_EXPIRATION_TIME }}'
          CLOUDINARY_API_KEY: '${{ secrets.CLOUDINARY_API_KEY }}'
          CLOUDINARY_API_SECRET: '${{ secrets.CLOUDINARY_API_SECRET }}'
          CLOUDINARY_CLOUD_NAME: '${{ secrets.CLOUDINARY_CLOUD_NAME }}'
          MAIL_FROM_ADDRESS: '${{ secrets.MAIL_FROM_ADDRESS }}'
          MAIL_HOST: '${{ secrets.MAIL_HOST }}'
          MAIL_PORT: '${{ secrets.MAIL_PORT }}'
          MAIL_USERNAME: '${{ secrets.MAIL_USERNAME }}'
          MAIL_PASSWORD: '${{ secrets.MAIL_PASSWORD }}'
          ALLOW_SUPER_ADMIN_ROLE: '${{ secrets.ALLOW_SUPER_ADMIN_ROLE }}'
          GOOGLE_CLIENT_ID: '${{ secrets.GOOGLE_CLIENT_ID }}'
          GOOGLE_CLIENT_SECRET: '${{ secrets.GOOGLE_CLIENT_SECRET }}'
          GOOGLE_CALLBACK_URL: '${{ secrets.GOOGLE_CALLBACK_URL }}'
          FACEBOOK_CLIENT_ID: '${{ secrets.FACEBOOK_CLIENT_ID }}'
          FACEBOOK_CLIENT_SECRET: '${{ secrets.FACEBOOK_CLIENT_SECRET }}'
          FACEBOOK_GRAPH_VERSION: '${{ secrets.FACEBOOK_GRAPH_VERSION }}'
          FACEBOOK_CALLBACK_URL: '${{ secrets.FACEBOOK_CALLBACK_URL }}'
          INTEGRATED_USER_DEFAULT_PASS: '${{ secrets.INTEGRATED_USER_DEFAULT_PASS }}'
          UPWORK_REDIRECT_URL: '${{ secrets.UPWORK_REDIRECT_URL }}'
          FILE_PROVIDER: '${{ secrets.FILE_PROVIDER }}'
          GAUZY_AI_GRAPHQL_ENDPOINT: '${{ secrets.GAUZY_AI_GRAPHQL_ENDPOINT }}'
          GAUZY_AI_REST_ENDPOINT: '${{ secrets.GAUZY_AI_REST_ENDPOINT }}'
          UNLEASH_APP_NAME: '${{ secrets.UNLEASH_APP_NAME }}'
          UNLEASH_API_URL: '${{ secrets.UNLEASH_API_URL }}'
          UNLEASH_INSTANCE_ID: '${{ secrets.UNLEASH_INSTANCE_ID }}'
          UNLEASH_REFRESH_INTERVAL: '${{ secrets.UNLEASH_REFRESH_INTERVAL }}'
          UNLEASH_METRICS_INTERVAL: '${{ secrets.UNLEASH_METRICS_INTERVAL }}'
          UNLEASH_API_KEY: '${{ secrets.UNLEASH_API_KEY }}'
          PM2_MACHINE_NAME: '${{ secrets.PM2_MACHINE_NAME }}'
          PM2_SECRET_KEY: '${{ secrets.PM2_SECRET_KEY }}'
          PM2_PUBLIC_KEY: '${{ secrets.PM2_PUBLIC_KEY }}'
          JITSU_SERVER_URL: '${{ secrets.JITSU_SERVER_URL }}'
          JITSU_SERVER_WRITE_KEY: '${{ secrets.JITSU_SERVER_WRITE_KEY }}'
          OTEL_ENABLED: '${{ secrets.OTEL_ENABLED }}'
          OTEL_PROVIDER: '${{ secrets.OTEL_PROVIDER }}'
          OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: '${{ secrets.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT }}'
          OTEL_EXPORTER_OTLP_HEADERS: '${{ secrets.OTEL_EXPORTER_OTLP_HEADERS }}'
          GAUZY_GITHUB_CLIENT_ID: '${{ secrets.GAUZY_GITHUB_CLIENT_ID }}'
          GAUZY_GITHUB_CLIENT_SECRET: '${{ secrets.GAUZY_GITHUB_CLIENT_SECRET }}'
          GAUZY_GITHUB_APP_PRIVATE_KEY: '${{ secrets.GAUZY_GITHUB_APP_PRIVATE_KEY }}'
          GAUZY_GITHUB_WEBHOOK_URL: '${{ secrets.GAUZY_GITHUB_WEBHOOK_URL }}'
          GAUZY_GITHUB_WEBHOOK_SECRET: '${{ secrets.GAUZY_GITHUB_WEBHOOK_SECRET }}'
          GAUZY_GITHUB_APP_NAME: '${{ secrets.GAUZY_GITHUB_APP_NAME }}'
          GAUZY_GITHUB_REDIRECT_URL: '${{ secrets.GAUZY_GITHUB_REDIRECT_URL }}'
          GAUZY_GITHUB_POST_INSTALL_URL: '${{ secrets.GAUZY_GITHUB_POST_INSTALL_URL }}'
          GAUZY_GITHUB_APP_ID: '${{ secrets.GAUZY_GITHUB_APP_ID }}'
          GAUZY_GITHUB_OAUTH_CLIENT_ID: '${{ secrets.GAUZY_GITHUB_OAUTH_CLIENT_ID }}'
          GAUZY_GITHUB_OAUTH_CLIENT_SECRET: '${{ secrets.GAUZY_GITHUB_OAUTH_CLIENT_SECRET }}'
          GAUZY_GITHUB_OAUTH_CALLBACK_URL: '${{ secrets.GAUZY_GITHUB_OAUTH_CALLBACK_URL }}'
          JITSU_BROWSER_URL: '${{ secrets.JITSU_BROWSER_URL }}'
          JITSU_BROWSER_WRITE_KEY: '${{ secrets.JITSU_BROWSER_WRITE_KEY }}'
          MAGIC_CODE_EXPIRATION_TIME: '${{ secrets.MAGIC_CODE_EXPIRATION_TIME }}'
          APP_NAME: '${{ secrets.APP_NAME }}'
          APP_LOGO: '${{ secrets.APP_LOGO }}'
          APP_SIGNATURE: '${{ secrets.APP_SIGNATURE }}'
          APP_LINK: '${{ secrets.APP_LINK }}'
          APP_EMAIL_CONFIRMATION_URL: '${{ secrets.APP_EMAIL_CONFIRMATION_URL }}'
          APP_MAGIC_SIGN_URL: '${{ secrets.APP_MAGIC_SIGN_URL }}'
          COMPANY_LINK: '${{ secrets.COMPANY_LINK }}'
          COMPANY_NAME: '${{ secrets.COMPANY_NAME }}'

      - name: Copy file via scp - with-cloudflare
        if: ${{ env.INGRESS_CERT_TYPE == 'cloudflare' }}
        uses: appleboy/scp-action@master
        with:
          host: ${{secrets.DO_DROPLET_DEMO_HOST}}
          username: ${{secrets.DO_DROPLET_USERNAME}}
          key: ${{secrets.DO_DROPLET_KEY}}
          source: '.deploy/ssh/with-cloudflare/demo/docker-compose.api.demo.yml'
          target: '.'
      - name: Copy file via scp - with-letsencrypt
        if: ${{ env.INGRESS_CERT_TYPE == 'letsencrypt' }}
        uses: appleboy/scp-action@master
        with:
          host: ${{secrets.DO_DROPLET_DEMO_HOST}}
          username: ${{secrets.DO_DROPLET_USERNAME}}
          key: ${{secrets.DO_DROPLET_KEY}}
          source: '.deploy/ssh/with-letsencrypt/demo/docker-compose.api.demo.yml'
          target: '.'
      - name: Deploy to DigitalOcean Droplet
        uses: appleboy/ssh-action@master
        with:
          host: ${{secrets.DO_DROPLET_DEMO_HOST}}
          username: ${{secrets.DO_DROPLET_USERNAME}}
          key: ${{secrets.DO_DROPLET_KEY}}
          envs: INGRESS_CERT_TYPE
          script: |
            if [ "${{ env.INGRESS_CERT_TYPE }}" = "cloudflare" ]; then
                docker-compose -f .deploy/ssh/with-letsencrypt/demo/docker-compose.api.demo.yml down
                docker-compose -f .deploy/ssh/with-cloudflare/demo/docker-compose.api.demo.yml up -d
            elif [ "${{ env.INGRESS_CERT_TYPE }}" = "letsencrypt" ]; then
                docker-compose -f .deploy/ssh/with-cloudflare/demo/docker-compose.api.demo.yml down
                docker-compose -f .deploy/ssh/with-letsencrypt/demo/docker-compose.api.demo.yml up -d
            else
                echo "Unknown INGRESS_CERT_TYPE: $INGRESS_CERT_TYPE"
                exit 1
            fi

Workflow for deploying the Nginx Proxy Docker-compose

Create a file called deploy-do-droplet-pre-demo.yml in the .github/workflows directory

name: Deploy to DigitalOcean Droplet Demo Pre

on:
  push:
    branches:
      - develop

jobs:
  deploy:
    runs-on: buildjet-4vcpu-ubuntu-2204

    environment: demo

    steps:
      - name: checkout out code
        uses: actions/checkout@v4

      - name: Globalise Ingress certificate type env
        run: |
          echo "INGRESS_CERT_TYPE=${{ env.INGRESS_CERT_TYPE }}" >> $GITHUB_ENV
        env:
          INGRESS_CERT_TYPE: 'letsencrypt'

      - name: Generate TLS Secrets for DO Droplet
        run: |
          rm -f $GITHUB_WORKSPACE/.deploy/ssh/with-cloudflare/demo/ingress.api.crt $GITHUB_WORKSPACE/.deploy/ssh/with-cloudflare/demo/ingress.api.key
          echo ${{ secrets.INGRESS_API_CERT }} | base64 --decode > $GITHUB_WORKSPACE/.deploy/ssh/with-cloudflare/demo/ingress.api.crt
          echo ${{ secrets.INGRESS_API_CERT_KEY }} | base64 --decode > $GITHUB_WORKSPACE/.deploy/ssh/with-cloudflare/demo/ingress.api.key

      - name: Copy file via scp - cloudflare
        if: ${{ env.INGRESS_CERT_TYPE == 'cloudflare' }}
        uses: appleboy/scp-action@master
        with:
          host: ${{secrets.DO_DROPLET_DEMO_HOST}}
          username: ${{secrets.DO_DROPLET_USERNAME}}
          key: ${{secrets.DO_DROPLET_KEY}}
          source: '.deploy/ssh/with-cloudflare/demo/docker-compose.api.demo.cloudflare.pre.yml,.deploy/ssh/with-cloudflare/demo/nginx.demo.pre.cloudflare.conf,.deploy/ssh/with-cloudflare/demo/ingress.api.crt,.deploy/ssh/with-cloudflare/demo/ingress.api.key'
          target: '.'
      - name: Copy file via scp - letsencrypt
        if: ${{ env.INGRESS_CERT_TYPE == 'letsencrypt' }}
        uses: appleboy/scp-action@master
        with:
          host: ${{secrets.DO_DROPLET_DEMO_HOST}}
          username: ${{secrets.DO_DROPLET_USERNAME}}
          key: ${{secrets.DO_DROPLET_KEY}}
          source: '.deploy/ssh/with-letsencrypt/demo/docker-compose.api.demo.letsencrypt.pre.yml,.deploy/ssh/with-letsencrypt/demo/user_conf.d,.deploy/ssh/with-letsencrypt/demo/nginx-certbot.env'
          target: '.'

      - name: Install Docker
        uses: appleboy/ssh-action@master
        with:
          host: ${{secrets.DO_DROPLET_DEMO_HOST}}
          username: ${{secrets.DO_DROPLET_USERNAME}}
          key: ${{secrets.DO_DROPLET_KEY}}
          script: |
            if ! command -v docker &> /dev/null; then
                echo "Docker not installed. Installing..."
                sudo apt-get update
                sudo apt-get install -y docker.io
                sudo systemctl start docker
                sudo systemctl enable docker
            else
                echo "Docker is already installed."
            fi
      - name: Install Docker Compose
        uses: appleboy/ssh-action@master
        with:
          host: ${{secrets.DO_DROPLET_DEMO_HOST}}
          username: ${{secrets.DO_DROPLET_USERNAME}}
          key: ${{secrets.DO_DROPLET_KEY}}
          script: |
            if ! command -v docker-compose &> /dev/null; then
                echo "Docker Compose not installed. Installing..."
                sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
                sudo chmod +x /usr/local/bin/docker-compose
            else
                echo "Docker Compose is already installed."
            fi
      - name: Deploy to DigitalOcean Droplet
        uses: appleboy/ssh-action@master
        with:
          host: ${{secrets.DO_DROPLET_DEMO_HOST}}
          username: ${{secrets.DO_DROPLET_USERNAME}}
          key: ${{secrets.DO_DROPLET_KEY}}
          script: |
            if [ "${{ env.INGRESS_CERT_TYPE }}" = "cloudflare" ]; then
                docker-compose -f .deploy/ssh/with-letsencrypt/demo/docker-compose.api.demo.letsencrypt.pre.yml down
                docker-compose -f .deploy/ssh/with-cloudflare/demo/docker-compose.api.demo.cloudflare.pre.yml up -d
            elif [ "${{ env.INGRESS_CERT_TYPE }}" = "letsencrypt" ]; then
                docker-compose -f .deploy/ssh/with-cloudflare/demo/docker-compose.api.demo.cloudflare.pre.yml down
                docker-compose -f .deploy/ssh/with-letsencrypt/demo/docker-compose.api.demo.letsencrypt.pre.yml up -d
            else
                echo "Unknown INGRESS_CERT_TYPE: $INGRESS_CERT_TYPE"
                exit 1
            fi
Clone this wiki locally