From c7089eeb157686945146cf39c2ac37fd17d34407 Mon Sep 17 00:00:00 2001 From: MuktadirHassan Date: Wed, 26 Jun 2024 09:14:01 +0600 Subject: [PATCH 1/7] feat: add traefik configuration with ssl support --- huly.compose.yml | 257 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 257 insertions(+) create mode 100644 huly.compose.yml diff --git a/huly.compose.yml b/huly.compose.yml new file mode 100644 index 0000000..09da7a7 --- /dev/null +++ b/huly.compose.yml @@ -0,0 +1,257 @@ +services: + + # handle reverse proxy, load balancing, SSL + traefik: + restart: unless-stopped + image: "traefik:v2.10" + container_name: "traefik" + ports: + - "80:80" + - "443:443" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - ./letsencrypt:/letsencrypt + networks: + - traefik-public + + labels: + - "traefik.enable=true" + - "traefik.http.routers.traefik.rule=Host(`traefik.localhost`)" + - "traefik.http.routers.traefik.entrypoints=websecure" + - "traefik.http.routers.traefik.tls.certresolver=myresolver" + - "traefik.http.routers.traefik.service=api@internal" + command: + - "--log.level=DEBUG" + - "--api.insecure=true" + - "--api.dashboard=true" + - "--global.sendAnonymousUsage=false" + - "--global.checkNewVersion=false" + - "--providers.docker=true" + - "--providers.docker.exposedbydefault=false" + - "--providers.docker.network=traefik-public" + - "--entrypoints.web.address=:80" + - "--entrypoints.websecure.address=:443" + - "--entrypoints.web.http.redirections.entryPoint.to=websecure" + - "--entrypoints.web.http.redirections.entryPoint.scheme=https" + - "--certificatesresolvers.myresolver.acme.email=muktadir@programming-hero.com" + - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" + - "--certificatesresolvers.myresolver.acme.tlschallenge=true" + - "--certificatesresolvers.myresolver.acme.caserver=http://acme-staging-v02.api.letsencrypt.org/directory" # For testing, comment out for production + + # database + mongodb: + image: "mongo:7-jammy" + container_name: mongodb + environment: + - PUID=1000 + - PGID=1000 + volumes: + - db:/data/db + restart: unless-stopped + networks: + - internal-services + + # elastic search + elastic: + image: "elasticsearch:7.14.2" + command: | + /bin/sh -c "./bin/elasticsearch-plugin list | grep -q ingest-attachment || yes | ./bin/elasticsearch-plugin install --silent ingest-attachment; + /usr/local/bin/docker-entrypoint.sh eswrapper" + volumes: + - elastic:/usr/share/elasticsearch/data + environment: + - ELASTICSEARCH_PORT_NUMBER=9200 + - BITNAMI_DEBUG=true + - discovery.type=single-node + - ES_JAVA_OPTS=-Xms1024m -Xmx1024m + - http.cors.enabled=true + - http.cors.allow-origin=http://localhost:8082 + healthcheck: + interval: 20s + retries: 10 + test: curl -s http://localhost:9200/_cluster/health | grep -vq '"status":"red"' + restart: unless-stopped + networks: + - internal-services + + # minio service + minio: + image: "minio/minio" + command: server /data --address ":9000" --console-address ":9001" + # ports: + # - 9000:9000 + # - 9001:9001 + volumes: + - files:/data + restart: unless-stopped + networks: + - internal-services + + # rekoni service + rekoni: + image: hardcoreeng/rekoni-service:v0.6.245 + environment: + - SECRET=secret + deploy: + resources: + limits: + memory: 500M + restart: unless-stopped + networks: + - internal-services + - traefik-public + labels: + - "traefik.enable=true" + - "traefik.http.routers.rekoni.entrypoints=websecure" + - "traefik.http.routers.rekoni.rule=Host(`localhost`) && PathPrefix(`/rekoni`)" # change localhost to your domain + # strip prefix + - "traefik.http.routers.rekoni.middlewares=rekoni-stripprefix" + - "traefik.http.middlewares.rekoni-stripprefix.stripprefix.prefixes=/rekoni" + - "traefik.http.routers.rekoni.tls.certresolver=myresolver" + - "traefik.http.services.rekoni.loadbalancer.server.port=4004" + + + # transactor service + transactor: + image: hardcoreeng/transactor:v0.6.245 + ports: + - 3333:3333 + environment: + - SERVER_PORT=3333 + - SERVER_SECRET=secret + - SERVER_CURSOR_MAXTIMEMS=30000 + - ELASTIC_URL=http://elastic:9200 + - ELASTIC_INDEX_NAME=huly_storage_index + - MONGO_URL=mongodb://mongodb:27017 + - METRICS_CONSOLE=false + - METRICS_FILE=metrics.txt + - MINIO_ENDPOINT=minio + - MINIO_ACCESS_KEY=minioadmin + - MINIO_SECRET_KEY=minioadmin + - REKONI_URL=http://rekoni:4004 + - FRONT_URL=http://localhost:8087 + - SERVER_PROVIDER=ws + - ACCOUNTS_URL=http://account:3000 + - LAST_NAME_FIRST=true + - UPLOAD_URL=https://${SERVER_ADDRESS}/files + restart: unless-stopped + networks: + - internal-services + - traefik-public + labels: + - "traefik.enable=true" + - "traefik.http.routers.transactor.entrypoints=websecure" + - "traefik.http.routers.transactor.rule=Host(`localhost`) && PathPrefix(`/transactor`)" # change localhost to your domain + # strip prefix + - "traefik.http.routers.transactor.middlewares=transactor-stripprefix" + - "traefik.http.middlewares.transactor-stripprefix.stripprefix.prefixes=/transactor" + - "traefik.http.routers.transactor.tls.certresolver=myresolver" + - "traefik.http.services.transactor.loadbalancer.server.port=3333" + + + # collaborator service + collaborator: + image: hardcoreeng/collaborator:v0.6.245 + ports: + - 3078:3078 + environment: + - COLLABORATOR_PORT=3078 + - SECRET=secret + - ACCOUNTS_URL=http://account:3000 + - TRANSACTOR_URL=ws://transactor:3333 + - UPLOAD_URL=/files + - MONGO_URL=mongodb://mongodb:27017 + - MINIO_ENDPOINT=minio + - MINIO_ACCESS_KEY=minioadmin + - MINIO_SECRET_KEY=minioadmin + restart: unless-stopped + networks: + - internal-services + - traefik-public + labels: + - "traefik.enable=true" + - "traefik.http.routers.collaborator.entrypoints=websecure" + - "traefik.http.routers.collaborator.rule=Host(`localhost`) && PathPrefix(`/collaborator`)" # change localhost to your domain + # strip prefix + - "traefik.http.routers.collaborator.middlewares=collaborator-stripprefix" + - "traefik.http.middlewares.collaborator-stripprefix.stripprefix.prefixes=/collaborator" + - "traefik.http.routers.collaborator.tls.certresolver=myresolver" + - "traefik.http.services.collaborator.loadbalancer.server.port=3078" + + # account service + account: + image: hardcoreeng/account:v0.6.245 + # ports: + # - 3000:3000 + environment: + - SERVER_PORT=3000 + - SERVER_SECRET=secret + - MONGO_URL=mongodb://mongodb:27017 + - TRANSACTOR_URL=ws://transactor:3333 + - ENDPOINT_URL=ws://${SERVER_ADDRESS}:3333 + - MINIO_ENDPOINT=minio + - MINIO_ACCESS_KEY=minioadmin + - MINIO_SECRET_KEY=minioadmin + - FRONT_URL=http://front:8080 + - INIT_WORKSPACE=demo-tracker + - MODEL_ENABLED=* + - ACCOUNTS_URL=http://localhost:3000 + - ACCOUNT_PORT=3000 + restart: unless-stopped + networks: + - internal-services + - traefik-public + labels: + - "traefik.enable=true" + - "traefik.http.routers.account.entrypoints=websecure" + - "traefik.http.routers.account.rule=Host(`localhost`) && PathPrefix(`/accounts`)" # change localhost to your domain + # strip prefix + - "traefik.http.routers.account.middlewares=account-stripprefix" + - "traefik.http.middlewares.account-stripprefix.stripprefix.prefixes=/accounts" + - "traefik.http.routers.account.tls.certresolver=myresolver" + + # front service + front: + image: hardcoreeng/front:v0.6.245 + environment: + - SERVER_PORT=8080 + - SERVER_SECRET=secret + - ACCOUNTS_URL=https://${SERVER_ADDRESS}/accounts + - REKONI_URL=https://${SERVER_ADDRESS}/rekoni + - CALENDAR_URL=https://${SERVER_ADDRESS}:8095 + - GMAIL_URL=https://${SERVER_ADDRESS}:8088 + - TELEGRAM_URL=https://${SERVER_ADDRESS}:8086 + - UPLOAD_URL=/files + - TRANSACTOR_URL=ws://${SERVER_ADDRESS}:3333 + - ELASTIC_URL=http://elastic:9200 + - COLLABORATOR_URL=ws://${SERVER_ADDRESS}:3078 + - COLLABORATOR_API_URL=https://${SERVER_ADDRESS}/collaborator + - MINIO_ENDPOINT=minio + - MINIO_ACCESS_KEY=minioadmin + - MINIO_SECRET_KEY=minioadmin + - MONGO_URL=mongodb://mongodb:27017 + - TITLE=Programming Hero Tracker + - DEFAULT_LANGUAGE=en + - LAST_NAME_FIRST=true + restart: unless-stopped + networks: + - internal-services + - traefik-public + labels: + - "traefik.enable=true" + - "traefik.http.routers.front.entrypoints=websecure" + - "traefik.http.routers.front.rule=Host(`localhost`)" + - "traefik.http.routers.front.tls.certresolver=myresolver" + - "traefik.http.services.front.loadbalancer.server.port=8080" + +networks: + traefik-public: + name: traefik-public + internal-services: + name: internal-services + +volumes: + db: + letsencrypt: + elastic: + files: \ No newline at end of file From 7869ab23c35ec699b3f7421fa145b5c0456ca7f4 Mon Sep 17 00:00:00 2001 From: MuktadirHassan Date: Thu, 27 Jun 2024 18:07:26 +0600 Subject: [PATCH 2/7] Add .gitignore entry for letsencrypt/ --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..01d90e8 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +letsencrypt/ \ No newline at end of file From 8daf7e5cd45ce6143e444c4672c22e70e75dda17 Mon Sep 17 00:00:00 2001 From: MuktadirHassan Date: Thu, 27 Jun 2024 18:07:51 +0600 Subject: [PATCH 3/7] renamed to template-compose.yml --- huly.compose.yml | 257 ----------------------------------------------- 1 file changed, 257 deletions(-) delete mode 100644 huly.compose.yml diff --git a/huly.compose.yml b/huly.compose.yml deleted file mode 100644 index 09da7a7..0000000 --- a/huly.compose.yml +++ /dev/null @@ -1,257 +0,0 @@ -services: - - # handle reverse proxy, load balancing, SSL - traefik: - restart: unless-stopped - image: "traefik:v2.10" - container_name: "traefik" - ports: - - "80:80" - - "443:443" - volumes: - - "/var/run/docker.sock:/var/run/docker.sock:ro" - - ./letsencrypt:/letsencrypt - networks: - - traefik-public - - labels: - - "traefik.enable=true" - - "traefik.http.routers.traefik.rule=Host(`traefik.localhost`)" - - "traefik.http.routers.traefik.entrypoints=websecure" - - "traefik.http.routers.traefik.tls.certresolver=myresolver" - - "traefik.http.routers.traefik.service=api@internal" - command: - - "--log.level=DEBUG" - - "--api.insecure=true" - - "--api.dashboard=true" - - "--global.sendAnonymousUsage=false" - - "--global.checkNewVersion=false" - - "--providers.docker=true" - - "--providers.docker.exposedbydefault=false" - - "--providers.docker.network=traefik-public" - - "--entrypoints.web.address=:80" - - "--entrypoints.websecure.address=:443" - - "--entrypoints.web.http.redirections.entryPoint.to=websecure" - - "--entrypoints.web.http.redirections.entryPoint.scheme=https" - - "--certificatesresolvers.myresolver.acme.email=muktadir@programming-hero.com" - - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" - - "--certificatesresolvers.myresolver.acme.tlschallenge=true" - - "--certificatesresolvers.myresolver.acme.caserver=http://acme-staging-v02.api.letsencrypt.org/directory" # For testing, comment out for production - - # database - mongodb: - image: "mongo:7-jammy" - container_name: mongodb - environment: - - PUID=1000 - - PGID=1000 - volumes: - - db:/data/db - restart: unless-stopped - networks: - - internal-services - - # elastic search - elastic: - image: "elasticsearch:7.14.2" - command: | - /bin/sh -c "./bin/elasticsearch-plugin list | grep -q ingest-attachment || yes | ./bin/elasticsearch-plugin install --silent ingest-attachment; - /usr/local/bin/docker-entrypoint.sh eswrapper" - volumes: - - elastic:/usr/share/elasticsearch/data - environment: - - ELASTICSEARCH_PORT_NUMBER=9200 - - BITNAMI_DEBUG=true - - discovery.type=single-node - - ES_JAVA_OPTS=-Xms1024m -Xmx1024m - - http.cors.enabled=true - - http.cors.allow-origin=http://localhost:8082 - healthcheck: - interval: 20s - retries: 10 - test: curl -s http://localhost:9200/_cluster/health | grep -vq '"status":"red"' - restart: unless-stopped - networks: - - internal-services - - # minio service - minio: - image: "minio/minio" - command: server /data --address ":9000" --console-address ":9001" - # ports: - # - 9000:9000 - # - 9001:9001 - volumes: - - files:/data - restart: unless-stopped - networks: - - internal-services - - # rekoni service - rekoni: - image: hardcoreeng/rekoni-service:v0.6.245 - environment: - - SECRET=secret - deploy: - resources: - limits: - memory: 500M - restart: unless-stopped - networks: - - internal-services - - traefik-public - labels: - - "traefik.enable=true" - - "traefik.http.routers.rekoni.entrypoints=websecure" - - "traefik.http.routers.rekoni.rule=Host(`localhost`) && PathPrefix(`/rekoni`)" # change localhost to your domain - # strip prefix - - "traefik.http.routers.rekoni.middlewares=rekoni-stripprefix" - - "traefik.http.middlewares.rekoni-stripprefix.stripprefix.prefixes=/rekoni" - - "traefik.http.routers.rekoni.tls.certresolver=myresolver" - - "traefik.http.services.rekoni.loadbalancer.server.port=4004" - - - # transactor service - transactor: - image: hardcoreeng/transactor:v0.6.245 - ports: - - 3333:3333 - environment: - - SERVER_PORT=3333 - - SERVER_SECRET=secret - - SERVER_CURSOR_MAXTIMEMS=30000 - - ELASTIC_URL=http://elastic:9200 - - ELASTIC_INDEX_NAME=huly_storage_index - - MONGO_URL=mongodb://mongodb:27017 - - METRICS_CONSOLE=false - - METRICS_FILE=metrics.txt - - MINIO_ENDPOINT=minio - - MINIO_ACCESS_KEY=minioadmin - - MINIO_SECRET_KEY=minioadmin - - REKONI_URL=http://rekoni:4004 - - FRONT_URL=http://localhost:8087 - - SERVER_PROVIDER=ws - - ACCOUNTS_URL=http://account:3000 - - LAST_NAME_FIRST=true - - UPLOAD_URL=https://${SERVER_ADDRESS}/files - restart: unless-stopped - networks: - - internal-services - - traefik-public - labels: - - "traefik.enable=true" - - "traefik.http.routers.transactor.entrypoints=websecure" - - "traefik.http.routers.transactor.rule=Host(`localhost`) && PathPrefix(`/transactor`)" # change localhost to your domain - # strip prefix - - "traefik.http.routers.transactor.middlewares=transactor-stripprefix" - - "traefik.http.middlewares.transactor-stripprefix.stripprefix.prefixes=/transactor" - - "traefik.http.routers.transactor.tls.certresolver=myresolver" - - "traefik.http.services.transactor.loadbalancer.server.port=3333" - - - # collaborator service - collaborator: - image: hardcoreeng/collaborator:v0.6.245 - ports: - - 3078:3078 - environment: - - COLLABORATOR_PORT=3078 - - SECRET=secret - - ACCOUNTS_URL=http://account:3000 - - TRANSACTOR_URL=ws://transactor:3333 - - UPLOAD_URL=/files - - MONGO_URL=mongodb://mongodb:27017 - - MINIO_ENDPOINT=minio - - MINIO_ACCESS_KEY=minioadmin - - MINIO_SECRET_KEY=minioadmin - restart: unless-stopped - networks: - - internal-services - - traefik-public - labels: - - "traefik.enable=true" - - "traefik.http.routers.collaborator.entrypoints=websecure" - - "traefik.http.routers.collaborator.rule=Host(`localhost`) && PathPrefix(`/collaborator`)" # change localhost to your domain - # strip prefix - - "traefik.http.routers.collaborator.middlewares=collaborator-stripprefix" - - "traefik.http.middlewares.collaborator-stripprefix.stripprefix.prefixes=/collaborator" - - "traefik.http.routers.collaborator.tls.certresolver=myresolver" - - "traefik.http.services.collaborator.loadbalancer.server.port=3078" - - # account service - account: - image: hardcoreeng/account:v0.6.245 - # ports: - # - 3000:3000 - environment: - - SERVER_PORT=3000 - - SERVER_SECRET=secret - - MONGO_URL=mongodb://mongodb:27017 - - TRANSACTOR_URL=ws://transactor:3333 - - ENDPOINT_URL=ws://${SERVER_ADDRESS}:3333 - - MINIO_ENDPOINT=minio - - MINIO_ACCESS_KEY=minioadmin - - MINIO_SECRET_KEY=minioadmin - - FRONT_URL=http://front:8080 - - INIT_WORKSPACE=demo-tracker - - MODEL_ENABLED=* - - ACCOUNTS_URL=http://localhost:3000 - - ACCOUNT_PORT=3000 - restart: unless-stopped - networks: - - internal-services - - traefik-public - labels: - - "traefik.enable=true" - - "traefik.http.routers.account.entrypoints=websecure" - - "traefik.http.routers.account.rule=Host(`localhost`) && PathPrefix(`/accounts`)" # change localhost to your domain - # strip prefix - - "traefik.http.routers.account.middlewares=account-stripprefix" - - "traefik.http.middlewares.account-stripprefix.stripprefix.prefixes=/accounts" - - "traefik.http.routers.account.tls.certresolver=myresolver" - - # front service - front: - image: hardcoreeng/front:v0.6.245 - environment: - - SERVER_PORT=8080 - - SERVER_SECRET=secret - - ACCOUNTS_URL=https://${SERVER_ADDRESS}/accounts - - REKONI_URL=https://${SERVER_ADDRESS}/rekoni - - CALENDAR_URL=https://${SERVER_ADDRESS}:8095 - - GMAIL_URL=https://${SERVER_ADDRESS}:8088 - - TELEGRAM_URL=https://${SERVER_ADDRESS}:8086 - - UPLOAD_URL=/files - - TRANSACTOR_URL=ws://${SERVER_ADDRESS}:3333 - - ELASTIC_URL=http://elastic:9200 - - COLLABORATOR_URL=ws://${SERVER_ADDRESS}:3078 - - COLLABORATOR_API_URL=https://${SERVER_ADDRESS}/collaborator - - MINIO_ENDPOINT=minio - - MINIO_ACCESS_KEY=minioadmin - - MINIO_SECRET_KEY=minioadmin - - MONGO_URL=mongodb://mongodb:27017 - - TITLE=Programming Hero Tracker - - DEFAULT_LANGUAGE=en - - LAST_NAME_FIRST=true - restart: unless-stopped - networks: - - internal-services - - traefik-public - labels: - - "traefik.enable=true" - - "traefik.http.routers.front.entrypoints=websecure" - - "traefik.http.routers.front.rule=Host(`localhost`)" - - "traefik.http.routers.front.tls.certresolver=myresolver" - - "traefik.http.services.front.loadbalancer.server.port=8080" - -networks: - traefik-public: - name: traefik-public - internal-services: - name: internal-services - -volumes: - db: - letsencrypt: - elastic: - files: \ No newline at end of file From 11b0d1af3ae131123bba0aacee2e1fcd9a860537 Mon Sep 17 00:00:00 2001 From: MuktadirHassan Date: Thu, 27 Jun 2024 18:08:23 +0600 Subject: [PATCH 4/7] feat: update traefik setup script --- traefik/setup.sh | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 traefik/setup.sh diff --git a/traefik/setup.sh b/traefik/setup.sh new file mode 100644 index 0000000..49ab4bc --- /dev/null +++ b/traefik/setup.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# Ask for the domain name +read -p "Enter the domain name: " DOMAIN_NAME +if [ -z "$DOMAIN_NAME" ]; then + echo "DOMAIN_NAME is required" + exit 1 +fi + +# Ask for the email address +read -p "Enter the email address: " LETSENCRYPT_EMAIL +if [ -z "$LETSENCRYPT_EMAIL" ]; then + echo "LETSENCRYPT_EMAIL address is required" + exit 1 +fi + + +export HULY_VERSION="v0.6.245" +export SERVER_ADDRESS=$DOMAIN_NAME +export LETSENCRYPT_EMAIL=$LETSENCRYPT_EMAIL + +# replace the domain name and email address in the docker-compose file +envsubst < template-compose.yml > docker-compose.yml + +echo -e "\033[1;32mSetup is complete. Run 'docker compose up -d' to start the services.\033[0m" + From 5fec6c949df5fd032b32b193123d64860403bb27 Mon Sep 17 00:00:00 2001 From: MuktadirHassan Date: Thu, 27 Jun 2024 18:15:46 +0600 Subject: [PATCH 5/7] docs: added documentation to deploy huly using traefik --- traefik/README.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 traefik/README.md diff --git a/traefik/README.md b/traefik/README.md new file mode 100644 index 0000000..5a950c7 --- /dev/null +++ b/traefik/README.md @@ -0,0 +1,41 @@ +# Instructions to deploy Huly on a `self-hosted` server with SSL using `Traefik` + +### Prerequisites + +- A domain name pointing to the server +- A server with Docker and Docker Compose installed + +### Steps + +1. Clone the repository + + ```bash + git clone https://github.com/hcengineering/huly-selfhost.git + cd huly-selfhost/traefik + ``` + +2. Run setup.sh + + ```bash + chmod +x setup.sh + ./setup.sh + ``` + +3. Follow the instructions in the setup script to configure your domain name and email address + + ```bash + $ ./setup.sh + Enter the domain name: example.com + Enter the email address: admin@example.com + Setup is complete. Run 'docker compose up -d' to start the services. + ``` + +4. Modify the `docker-compose.yml` file to customize any settings + +5. Start the services + + ```bash + docker compose up -d + ``` + +6. Access Huly at `https://example.com` From 121a8981c2cfed279d2b722d9696a04673e8a7fc Mon Sep 17 00:00:00 2001 From: MuktadirHassan Date: Thu, 27 Jun 2024 18:16:06 +0600 Subject: [PATCH 6/7] chore: example compose file generated by ./setup.sh --- traefik/docker-compose.yml | 242 +++++++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 traefik/docker-compose.yml diff --git a/traefik/docker-compose.yml b/traefik/docker-compose.yml new file mode 100644 index 0000000..dc96f8b --- /dev/null +++ b/traefik/docker-compose.yml @@ -0,0 +1,242 @@ +services: + traefik: + restart: unless-stopped + image: "traefik:v2.10" + container_name: "traefik" + ports: + - "80:80" + - "443:443" + - "3333:3333" + - "3078:3078" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - ./letsencrypt:/letsencrypt + networks: + - traefik-public + command: + - "--log.level=DEBUG" # set to INFO for production + - "--api.insecure=false" + - "--api.dashboard=true" + - "--global.sendAnonymousUsage=false" + - "--global.checkNewVersion=false" + - "--providers.docker=true" + - "--providers.docker.exposedbydefault=false" + - "--providers.docker.network=traefik-public" + - "--entrypoints.web.address=:80" + - "--entrypoints.websecure.address=:443" + - "--entrypoints.transactor.address=:3333" # for transactor wss + - "--entrypoints.collaborator.address=:3078" # for collaborator wss + - "--entrypoints.web.http.redirections.entryPoint.to=websecure" + - "--entrypoints.web.http.redirections.entryPoint.scheme=https" + - "--certificatesresolvers.myresolver.acme.email=admin@example.com" + - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" + - "--certificatesresolvers.myresolver.acme.tlschallenge=true" + - "--certificatesresolvers.myresolver.acme.caserver=http://acme-staging-v02.api.letsencrypt.org/directory" # For testing, comment out for production + labels: + - "traefik.enable=true" + - "traefik.http.routers.traefik.rule=Host(`example.com`) && (PathPrefix(`/api`) || PathPrefix(`/traefik`))" + - "traefik.http.routers.traefik.service=api@internal" + - "traefik.http.routers.traefik.entrypoints=websecure" + # strip prefix for traefik dashboard + - "traefik.http.routers.traefik.middlewares=strip-prefix-traefik" + - "traefik.http.middlewares.strip-prefix-traefik.stripprefix.prefixes=/traefik" + - "traefik.http.routers.traefik.tls=true" + - "traefik.http.routers.traefik.tls.certresolver=myresolver" + + mongodb: + image: "mongo:7-jammy" + container_name: mongodb + environment: + - PUID=1000 + - PGID=1000 + volumes: + - db:/data/db + restart: unless-stopped + networks: + - internal-services + + elastic: + image: "elasticsearch:7.14.2" + command: | + /bin/sh -c "./bin/elasticsearch-plugin list | grep -q ingest-attachment || yes | ./bin/elasticsearch-plugin install --silent ingest-attachment; + /usr/local/bin/docker-entrypoint.sh eswrapper" + volumes: + - elastic:/usr/share/elasticsearch/data + environment: + - ELASTICSEARCH_PORT_NUMBER=9200 + - BITNAMI_DEBUG=true + - discovery.type=single-node + - ES_JAVA_OPTS=-Xms1024m -Xmx1024m + - http.cors.enabled=true + - http.cors.allow-origin=http://localhost:8082 + healthcheck: + interval: 20s + retries: 10 + test: curl -s http://localhost:9200/_cluster/health | grep -vq '"status":"red"' + restart: unless-stopped + networks: + - internal-services + + minio: + image: "minio/minio" + command: server /data --address ":9000" --console-address ":9001" + volumes: + - files:/data + restart: unless-stopped + networks: + - internal-services + + rekoni: + image: hardcoreeng/rekoni-service:v0.6.245 + environment: + - SECRET=secret + deploy: + resources: + limits: + memory: 500M + restart: unless-stopped + networks: + - internal-services + - traefik-public + labels: + - "traefik.enable=true" + - "traefik.http.routers.rekoni.entrypoints=websecure" + - "traefik.http.services.rekoni.loadbalancer.server.port=4004" + - "traefik.http.routers.rekoni.rule=Host(`example.com`) && PathPrefix(`/rekoni`)" + - "traefik.http.routers.rekoni.middlewares=rekoni-stripprefix" + - "traefik.http.middlewares.rekoni-stripprefix.stripprefix.prefixes=/rekoni" + - "traefik.http.routers.rekoni.tls=true" + - "traefik.http.routers.rekoni.tls.certresolver=myresolver" + + transactor: + image: hardcoreeng/transactor:v0.6.245 + environment: + - SERVER_PORT=3333 + - SERVER_SECRET=secret + - SERVER_CURSOR_MAXTIMEMS=30000 + - ELASTIC_URL=http://elastic:9200 + - ELASTIC_INDEX_NAME=huly_storage_index + - MONGO_URL=mongodb://mongodb:27017 + - METRICS_CONSOLE=false + - METRICS_FILE=metrics.txt + - MINIO_ENDPOINT=minio + - MINIO_ACCESS_KEY=minioadmin + - MINIO_SECRET_KEY=minioadmin + - REKONI_URL=http://rekoni:4004 + - FRONT_URL=http://localhost:8087 + - SERVER_PROVIDER=wss + - ACCOUNTS_URL=http://account:3000 + - LAST_NAME_FIRST=true + - UPLOAD_URL=https://example.com/files + restart: unless-stopped + networks: + - internal-services + - traefik-public + labels: + - "traefik.enable=true" + - "traefik.http.routers.transactor.entrypoints=transactor" + - "traefik.http.routers.transactor.rule=Host(`example.com`)" + - "traefik.http.services.transactor.loadbalancer.server.port=3333" + - "traefik.http.routers.transactor.tls=true" + - "traefik.http.routers.transactor.tls.certresolver=myresolver" + + + collaborator: + image: hardcoreeng/collaborator:v0.6.245 + environment: + - COLLABORATOR_PORT=3078 + - SECRET=secret + - ACCOUNTS_URL=http://account:3000 + - TRANSACTOR_URL=ws://transactor:3333 + - UPLOAD_URL=/files + - MONGO_URL=mongodb://mongodb:27017 + - MINIO_ENDPOINT=minio + - MINIO_ACCESS_KEY=minioadmin + - MINIO_SECRET_KEY=minioadmin + restart: unless-stopped + networks: + - internal-services + - traefik-public + labels: + - "traefik.enable=true" + - "traefik.http.routers.collaborator.entrypoints=collaborator" + - "traefik.http.services.collaborator.loadbalancer.server.port=3078" + - "traefik.http.routers.collaborator.rule=Host(`example.com`)" + - "traefik.http.routers.collaborator.tls=true" + - "traefik.http.routers.collaborator.tls.certresolver=myresolver" + + account: + image: hardcoreeng/account:v0.6.245 + environment: + - SERVER_PORT=3000 + - SERVER_SECRET=secret + - MONGO_URL=mongodb://mongodb:27017 + - TRANSACTOR_URL=ws://transactor:3333 + - ENDPOINT_URL=wss://example.com:3333 # this is the transactor endpoint + - MINIO_ENDPOINT=minio + - MINIO_ACCESS_KEY=minioadmin + - MINIO_SECRET_KEY=minioadmin + - FRONT_URL=http://front:8080 + - INIT_WORKSPACE=demo-tracker + - MODEL_ENABLED=* + - ACCOUNTS_URL=http://localhost:3000 + - ACCOUNT_PORT=3000 + restart: unless-stopped + networks: + - internal-services + - traefik-public + labels: + - "traefik.enable=true" + - "traefik.http.routers.account.entrypoints=websecure" + - "traefik.http.services.account.loadbalancer.server.port=3000" + - "traefik.http.routers.account.rule=Host(`example.com`) && PathPrefix(`/accounts`)" + - "traefik.http.routers.account.middlewares=account-stripprefix" + - "traefik.http.middlewares.account-stripprefix.stripprefix.prefixes=/accounts" + - "traefik.http.routers.account.tls=true" + - "traefik.http.routers.account.tls.certresolver=myresolver" + + front: + image: hardcoreeng/front:v0.6.245 + environment: + - SERVER_PORT=8080 + - SERVER_SECRET=secret + - ACCOUNTS_URL=https://example.com/accounts + - REKONI_URL=https://example.com/rekoni + - CALENDAR_URL=https://example.com:8095 + - GMAIL_URL=https://example.com:8088 + - TELEGRAM_URL=https://example.com:8086 + - UPLOAD_URL=/files + - TRANSACTOR_URL=wss://example.com:3333 + - ELASTIC_URL=http://elastic:9200 + - COLLABORATOR_URL=wss://example.com:3078 + - COLLABORATOR_API_URL=https://example.com:3078 + - MINIO_ENDPOINT=minio + - MINIO_ACCESS_KEY=minioadmin + - MINIO_SECRET_KEY=minioadmin + - MONGO_URL=mongodb://mongodb:27017 + - TITLE=Huly Self Host + - DEFAULT_LANGUAGE=en + - LAST_NAME_FIRST=true + restart: unless-stopped + networks: + - internal-services + - traefik-public + labels: + - "traefik.enable=true" + - "traefik.http.routers.front.entrypoints=websecure" + - "traefik.http.services.front.loadbalancer.server.port=8080" + - "traefik.http.routers.front.rule=Host(`example.com`)" + - "traefik.http.routers.front.tls=true" + - "traefik.http.routers.front.tls.certresolver=myresolver" + +networks: + traefik-public: + name: traefik-public + internal-services: + name: internal-services + +volumes: + db: + letsencrypt: + elastic: + files: From 28123c881bc1a87bd9334a9d13cd9b78ad9c4f6c Mon Sep 17 00:00:00 2001 From: MuktadirHassan Date: Thu, 27 Jun 2024 18:16:39 +0600 Subject: [PATCH 7/7] feat: self-host with ssl and traefik --- traefik/template-compose.yml | 242 +++++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 traefik/template-compose.yml diff --git a/traefik/template-compose.yml b/traefik/template-compose.yml new file mode 100644 index 0000000..0664bbd --- /dev/null +++ b/traefik/template-compose.yml @@ -0,0 +1,242 @@ +services: + traefik: + restart: unless-stopped + image: "traefik:v2.10" + container_name: "traefik" + ports: + - "80:80" + - "443:443" + - "3333:3333" + - "3078:3078" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - ./letsencrypt:/letsencrypt + networks: + - traefik-public + command: + - "--log.level=DEBUG" # set to INFO for production + - "--api.insecure=false" + - "--api.dashboard=true" + - "--global.sendAnonymousUsage=false" + - "--global.checkNewVersion=false" + - "--providers.docker=true" + - "--providers.docker.exposedbydefault=false" + - "--providers.docker.network=traefik-public" + - "--entrypoints.web.address=:80" + - "--entrypoints.websecure.address=:443" + - "--entrypoints.transactor.address=:3333" # for transactor wss + - "--entrypoints.collaborator.address=:3078" # for collaborator wss + - "--entrypoints.web.http.redirections.entryPoint.to=websecure" + - "--entrypoints.web.http.redirections.entryPoint.scheme=https" + - "--certificatesresolvers.myresolver.acme.email=${LETSENCRYPT_EMAIL}" + - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" + - "--certificatesresolvers.myresolver.acme.tlschallenge=true" + - "--certificatesresolvers.myresolver.acme.caserver=http://acme-staging-v02.api.letsencrypt.org/directory" # For testing, comment out for production + labels: + - "traefik.enable=true" + - "traefik.http.routers.traefik.rule=Host(`${SERVER_ADDRESS}`) && (PathPrefix(`/api`) || PathPrefix(`/traefik`))" + - "traefik.http.routers.traefik.service=api@internal" + - "traefik.http.routers.traefik.entrypoints=websecure" + # strip prefix for traefik dashboard + - "traefik.http.routers.traefik.middlewares=strip-prefix-traefik" + - "traefik.http.middlewares.strip-prefix-traefik.stripprefix.prefixes=/traefik" + - "traefik.http.routers.traefik.tls=true" + - "traefik.http.routers.traefik.tls.certresolver=myresolver" + + mongodb: + image: "mongo:7-jammy" + container_name: mongodb + environment: + - PUID=1000 + - PGID=1000 + volumes: + - db:/data/db + restart: unless-stopped + networks: + - internal-services + + elastic: + image: "elasticsearch:7.14.2" + command: | + /bin/sh -c "./bin/elasticsearch-plugin list | grep -q ingest-attachment || yes | ./bin/elasticsearch-plugin install --silent ingest-attachment; + /usr/local/bin/docker-entrypoint.sh eswrapper" + volumes: + - elastic:/usr/share/elasticsearch/data + environment: + - ELASTICSEARCH_PORT_NUMBER=9200 + - BITNAMI_DEBUG=true + - discovery.type=single-node + - ES_JAVA_OPTS=-Xms1024m -Xmx1024m + - http.cors.enabled=true + - http.cors.allow-origin=http://localhost:8082 + healthcheck: + interval: 20s + retries: 10 + test: curl -s http://localhost:9200/_cluster/health | grep -vq '"status":"red"' + restart: unless-stopped + networks: + - internal-services + + minio: + image: "minio/minio" + command: server /data --address ":9000" --console-address ":9001" + volumes: + - files:/data + restart: unless-stopped + networks: + - internal-services + + rekoni: + image: hardcoreeng/rekoni-service:${HULY_VERSION} + environment: + - SECRET=secret + deploy: + resources: + limits: + memory: 500M + restart: unless-stopped + networks: + - internal-services + - traefik-public + labels: + - "traefik.enable=true" + - "traefik.http.routers.rekoni.entrypoints=websecure" + - "traefik.http.services.rekoni.loadbalancer.server.port=4004" + - "traefik.http.routers.rekoni.rule=Host(`${SERVER_ADDRESS}`) && PathPrefix(`/rekoni`)" + - "traefik.http.routers.rekoni.middlewares=rekoni-stripprefix" + - "traefik.http.middlewares.rekoni-stripprefix.stripprefix.prefixes=/rekoni" + - "traefik.http.routers.rekoni.tls=true" + - "traefik.http.routers.rekoni.tls.certresolver=myresolver" + + transactor: + image: hardcoreeng/transactor:${HULY_VERSION} + environment: + - SERVER_PORT=3333 + - SERVER_SECRET=secret + - SERVER_CURSOR_MAXTIMEMS=30000 + - ELASTIC_URL=http://elastic:9200 + - ELASTIC_INDEX_NAME=huly_storage_index + - MONGO_URL=mongodb://mongodb:27017 + - METRICS_CONSOLE=false + - METRICS_FILE=metrics.txt + - MINIO_ENDPOINT=minio + - MINIO_ACCESS_KEY=minioadmin + - MINIO_SECRET_KEY=minioadmin + - REKONI_URL=http://rekoni:4004 + - FRONT_URL=http://localhost:8087 + - SERVER_PROVIDER=wss + - ACCOUNTS_URL=http://account:3000 + - LAST_NAME_FIRST=true + - UPLOAD_URL=https://${SERVER_ADDRESS}/files + restart: unless-stopped + networks: + - internal-services + - traefik-public + labels: + - "traefik.enable=true" + - "traefik.http.routers.transactor.entrypoints=transactor" + - "traefik.http.routers.transactor.rule=Host(`${SERVER_ADDRESS}`)" + - "traefik.http.services.transactor.loadbalancer.server.port=3333" + - "traefik.http.routers.transactor.tls=true" + - "traefik.http.routers.transactor.tls.certresolver=myresolver" + + + collaborator: + image: hardcoreeng/collaborator:${HULY_VERSION} + environment: + - COLLABORATOR_PORT=3078 + - SECRET=secret + - ACCOUNTS_URL=http://account:3000 + - TRANSACTOR_URL=ws://transactor:3333 + - UPLOAD_URL=/files + - MONGO_URL=mongodb://mongodb:27017 + - MINIO_ENDPOINT=minio + - MINIO_ACCESS_KEY=minioadmin + - MINIO_SECRET_KEY=minioadmin + restart: unless-stopped + networks: + - internal-services + - traefik-public + labels: + - "traefik.enable=true" + - "traefik.http.routers.collaborator.entrypoints=collaborator" + - "traefik.http.services.collaborator.loadbalancer.server.port=3078" + - "traefik.http.routers.collaborator.rule=Host(`${SERVER_ADDRESS}`)" + - "traefik.http.routers.collaborator.tls=true" + - "traefik.http.routers.collaborator.tls.certresolver=myresolver" + + account: + image: hardcoreeng/account:${HULY_VERSION} + environment: + - SERVER_PORT=3000 + - SERVER_SECRET=secret + - MONGO_URL=mongodb://mongodb:27017 + - TRANSACTOR_URL=ws://transactor:3333 + - ENDPOINT_URL=wss://${SERVER_ADDRESS}:3333 # this is the transactor endpoint + - MINIO_ENDPOINT=minio + - MINIO_ACCESS_KEY=minioadmin + - MINIO_SECRET_KEY=minioadmin + - FRONT_URL=http://front:8080 + - INIT_WORKSPACE=demo-tracker + - MODEL_ENABLED=* + - ACCOUNTS_URL=http://localhost:3000 + - ACCOUNT_PORT=3000 + restart: unless-stopped + networks: + - internal-services + - traefik-public + labels: + - "traefik.enable=true" + - "traefik.http.routers.account.entrypoints=websecure" + - "traefik.http.services.account.loadbalancer.server.port=3000" + - "traefik.http.routers.account.rule=Host(`${SERVER_ADDRESS}`) && PathPrefix(`/accounts`)" + - "traefik.http.routers.account.middlewares=account-stripprefix" + - "traefik.http.middlewares.account-stripprefix.stripprefix.prefixes=/accounts" + - "traefik.http.routers.account.tls=true" + - "traefik.http.routers.account.tls.certresolver=myresolver" + + front: + image: hardcoreeng/front:${HULY_VERSION} + environment: + - SERVER_PORT=8080 + - SERVER_SECRET=secret + - ACCOUNTS_URL=https://${SERVER_ADDRESS}/accounts + - REKONI_URL=https://${SERVER_ADDRESS}/rekoni + - CALENDAR_URL=https://${SERVER_ADDRESS}:8095 + - GMAIL_URL=https://${SERVER_ADDRESS}:8088 + - TELEGRAM_URL=https://${SERVER_ADDRESS}:8086 + - UPLOAD_URL=/files + - TRANSACTOR_URL=wss://${SERVER_ADDRESS}:3333 + - ELASTIC_URL=http://elastic:9200 + - COLLABORATOR_URL=wss://${SERVER_ADDRESS}:3078 + - COLLABORATOR_API_URL=https://${SERVER_ADDRESS}:3078 + - MINIO_ENDPOINT=minio + - MINIO_ACCESS_KEY=minioadmin + - MINIO_SECRET_KEY=minioadmin + - MONGO_URL=mongodb://mongodb:27017 + - TITLE=Huly Self Host + - DEFAULT_LANGUAGE=en + - LAST_NAME_FIRST=true + restart: unless-stopped + networks: + - internal-services + - traefik-public + labels: + - "traefik.enable=true" + - "traefik.http.routers.front.entrypoints=websecure" + - "traefik.http.services.front.loadbalancer.server.port=8080" + - "traefik.http.routers.front.rule=Host(`${SERVER_ADDRESS}`)" + - "traefik.http.routers.front.tls=true" + - "traefik.http.routers.front.tls.certresolver=myresolver" + +networks: + traefik-public: + name: traefik-public + internal-services: + name: internal-services + +volumes: + db: + letsencrypt: + elastic: + files: