From: Jérôme Benoit Date: Sun, 8 Sep 2024 22:23:17 +0000 (+0200) Subject: refactor: separate out dashboard docker image X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=20fb10949dc2553d7695be1aab02bf84a8ddab98;p=e-mobility-charging-stations-simulator.git refactor: separate out dashboard docker image closes #1040 Signed-off-by: Jérôme Benoit --- diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3a1df8bd..3522cbbd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -145,9 +145,24 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - build-docker-image: + build-simulator-docker-image: runs-on: ubuntu-latest - name: Build docker image + name: Build simulator docker image + steps: + - uses: actions/checkout@v4 + - name: Setup Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v3 + - name: Build docker image + run: | + cd docker + make SUBMODULES_INIT=false + build-dashboard-docker-image: + runs-on: ubuntu-latest + defaults: + run: + working-directory: ui/web + name: Build dashboard docker image steps: - uses: actions/checkout@v4 - name: Setup Docker Buildx diff --git a/docker/Dockerfile b/docker/Dockerfile index baef3220..b794b936 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,6 +1,6 @@ FROM node:lts-alpine AS builder -# Build simulator and dashboard +# Build simulator WORKDIR /usr/builder COPY . ./ RUN set -ex \ @@ -13,10 +13,7 @@ RUN set -ex \ && cp docker/config.json src/assets/config.json \ && cp docker/idtags.json src/assets/idtags.json \ && pnpm build \ - && apk del .gyp \ - && cd ui/web \ - && cp src/assets/config-template.json public/config.json \ - && pnpm build + && apk del .gyp FROM node:lts-alpine @@ -26,7 +23,6 @@ ARG MAX_OLD_SPACE_SIZE=768 ENV NODE_OPTIONS="--stack-trace-limit=${STACK_TRACE_LIMIT} --max-old-space-size=${MAX_OLD_SPACE_SIZE}" WORKDIR /usr/app -COPY --from=builder /usr/builder/ui/web ./ui/web COPY --from=builder /usr/builder/node_modules ./node_modules COPY --from=builder /usr/builder/dist ./dist COPY package.json README.md LICENSE ./ diff --git a/docker/autoconfig.sh b/docker/autoconfig.sh index 24973efc..b8067bff 100755 --- a/docker/autoconfig.sh +++ b/docker/autoconfig.sh @@ -9,7 +9,6 @@ then cp $emobility_install_dir/dist/assets/configs-docker/$emobility_server_type-$emobility_service_type-$emobility_landscape.json $emobility_install_dir/dist/assets/config.json cp $emobility_install_dir/dist/assets/configs-docker/$emobility_server_type-$emobility_service_type-$emobility_landscape-idtags.json $emobility_install_dir/dist/assets/idtags.json - cp $emobility_install_dir/dist/assets/configs-docker/$emobility_server_type-$emobility_service_type-$emobility_landscape-webui.json $emobility_install_dir/ui/web/public/config.json else echo "no emobility env defined, start with default configuration" fi diff --git a/docker/config.json b/docker/config.json index c207106a..5bd7ccee 100644 --- a/docker/config.json +++ b/docker/config.json @@ -15,6 +15,9 @@ }, "uiServer": { "enabled": true, + "options": { + "host": "::" + }, "type": "ws", "authentication": { "enabled": true, diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 999f8a7e..e5044cf1 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -1,4 +1,3 @@ -version: '3.7' networks: ev_network: driver: bridge @@ -12,7 +11,5 @@ services: MAX_OLD_SPACE_SIZE: 768 networks: - ev_network - expose: - - 8080 ports: - - '3030:3030' + - 8080:8080 diff --git a/docker/start.sh b/docker/start.sh index 65a466c9..189983a2 100755 --- a/docker/start.sh +++ b/docker/start.sh @@ -1,4 +1,3 @@ #!/usr/bin/env sh -node dist/start.js & -node ui/web/start.js +node dist/start.js diff --git a/ui/web/README.md b/ui/web/README.md index 43bb9569..039d9015 100644 --- a/ui/web/README.md +++ b/ui/web/README.md @@ -17,6 +17,7 @@ The Web UI code and configuration is in the repository directory [ui/web](./../. - [Run](#run) - [Compiles and run for production](#compiles-and-run-for-production) - [Preview locally](#preview-locally) + - [Docker](#docker) - [Development](#development) - [Compiles and run for development](#compiles-and-run-for-development) - [Formats files](#formats-files) @@ -119,6 +120,14 @@ You can now follow the link displayed in the terminal. The Web UI looks like the 1. With the buttons on the top you can change UI server, start/stop the simulator, add new charging stations and refresh the content. 2. Each charging station is a row in the table with specific 'Actions' to execute on. Try 'Stop Charging Station' and refresh with the large blue button and see the status 'Started' turns from 'Yes' into 'No'. +#### Docker + +In the [docker](./docker) folder: + +```shell +make +``` + ### Development #### Compiles and run for development diff --git a/ui/web/docker/Dockerfile b/ui/web/docker/Dockerfile new file mode 100644 index 00000000..5737d4b4 --- /dev/null +++ b/ui/web/docker/Dockerfile @@ -0,0 +1,25 @@ +FROM node:lts-alpine AS builder + +# Build dashboard +WORKDIR /usr/builder +COPY . ./ +RUN set -ex \ + && corepack enable \ + && corepack prepare pnpm@latest --activate \ + && pnpm set progress=false \ + && pnpm config set depth 0 \ + && pnpm install --ignore-scripts \ + && cp docker/config.json public/config.json \ + && pnpm build + +FROM node:lts-alpine + +WORKDIR /usr/app +COPY --from=builder /usr/builder ./ +COPY docker/start.sh /start.sh +COPY docker/autoconfig.sh /autoconfig.sh +RUN set -ex \ + && chmod +x /start.sh \ + && chmod +x /autoconfig.sh + +CMD /autoconfig.sh && /start.sh diff --git a/ui/web/docker/Makefile b/ui/web/docker/Makefile new file mode 100644 index 00000000..fc0e9cd1 --- /dev/null +++ b/ui/web/docker/Makefile @@ -0,0 +1,50 @@ +PROJECT_NAME?=evse +NAME:=e-mobility-charging-stations-dashboard +SUBMODULES_INIT?=false +DOCKER_ECR_ACCOUNT_ID?=166296450311 +DOCKER_ECR_REGION?=eu-west-3 +DOCKER_ECR_REGISTRY_NAME?=e-mobility-charging-stations-dashboard +DOCKER_ECR_TAG?=latest + +.PHONY: all + +default: all + +submodule-update: + git submodule update --init --recursive + +submodules-init= +ifeq '$(SUBMODULES_INIT)' 'true' + submodules-init += submodule-update +endif + +$(NAME): $(submodules-init) + docker compose -p $(PROJECT_NAME) up -d + +$(NAME)-force: $(submodules-init) + docker compose -p $(PROJECT_NAME) up -d --build --force-recreate + +all: $(NAME) + +clean-images: + -docker rmi $(PROJECT_NAME)-$(NAME) + +clean-containers: + -docker compose -p $(PROJECT_NAME) down + +clean: clean-containers clean-images + +docker-tag-ecr: + docker tag $(PROJECT_NAME)-$(NAME) $(DOCKER_ECR_ACCOUNT_ID).dkr.ecr.$(DOCKER_ECR_REGION).amazonaws.com/$(DOCKER_ECR_REGISTRY_NAME):$(DOCKER_ECR_TAG) + +docker-push-ecr: $(NAME)-force docker-tag-ecr + aws ecr get-login-password --region $(DOCKER_ECR_REGION) | docker login --username AWS --password-stdin $(DOCKER_ECR_ACCOUNT_ID).dkr.ecr.$(DOCKER_ECR_REGION).amazonaws.com/$(DOCKER_ECR_REGISTRY_NAME) + docker push $(DOCKER_ECR_ACCOUNT_ID).dkr.ecr.$(DOCKER_ECR_REGION).amazonaws.com/$(DOCKER_ECR_REGISTRY_NAME):$(DOCKER_ECR_TAG) + +dist-clean-images: + docker image prune -a -f + +dist-clean-volumes: + docker volume prune -f + +dist-clean: clean-containers dist-clean-volumes dist-clean-images diff --git a/ui/web/docker/autoconfig.sh b/ui/web/docker/autoconfig.sh new file mode 100755 index 00000000..f9c57eed --- /dev/null +++ b/ui/web/docker/autoconfig.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env sh + +if ! [ -z $emobility_server_type ] && ! [ -z $emobility_service_type ] +then + [ -z $emobility_install_dir ] && { echo "emobility installation directory env variable not found, exiting"; exit 1; } + [ -z $emobility_landscape ] && { echo "emobility landscape env variable not found, exiting"; exit 1; } + [ -z $emobility_server_type ] && { echo "emobility env server type variable not found, exiting"; exit 1; } + [ -z $emobility_service_type ] && { echo "emobility env service type variable not found, exiting"; exit 1; } + + cp $emobility_install_dir/dist/assets/configs-docker/$emobility_server_type-$emobility_service_type-$emobility_landscape.json $emobility_install_dir/public/config.json +else + echo "no emobility env defined, start with default configuration" +fi diff --git a/ui/web/docker/config.json b/ui/web/docker/config.json new file mode 100644 index 00000000..1542583a --- /dev/null +++ b/ui/web/docker/config.json @@ -0,0 +1,14 @@ +{ + "uiServer": { + "host": "localhost", + "port": 8080, + "protocol": "ui", + "version": "0.0.1", + "authentication": { + "enabled": true, + "type": "protocol-basic-auth", + "username": "admin", + "password": "admin" + } + } +} diff --git a/ui/web/docker/docker-compose.yml b/ui/web/docker/docker-compose.yml new file mode 100644 index 00000000..0220dfee --- /dev/null +++ b/ui/web/docker/docker-compose.yml @@ -0,0 +1,12 @@ +networks: + ev_network: + driver: bridge +services: + e-mobility-charging-stations-dashboard: + build: + context: .. + dockerfile: docker/Dockerfile + networks: + - ev_network + ports: + - 3030:3030 diff --git a/ui/web/docker/start.sh b/ui/web/docker/start.sh new file mode 100755 index 00000000..865f7dde --- /dev/null +++ b/ui/web/docker/start.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +node start.js diff --git a/ui/web/src/composables/UIClient.ts b/ui/web/src/composables/UIClient.ts index ae626dec..d105b605 100644 --- a/ui/web/src/composables/UIClient.ts +++ b/ui/web/src/composables/UIClient.ts @@ -69,14 +69,16 @@ export class UIClient { ) this.ws.onopen = () => { useToast().success( - `WebSocket to UI server '${this.uiServerConfiguration.host}' successfully opened` + `WebSocket to UI server '${this.uiServerConfiguration.host}:${this.uiServerConfiguration.port.toString()}' successfully opened` ) } this.ws.onmessage = this.responseHandler.bind(this) this.ws.onerror = errorEvent => { - useToast().error(`Error in WebSocket to UI server '${this.uiServerConfiguration.host}'`) + useToast().error( + `Error in WebSocket to UI server '${this.uiServerConfiguration.host}:${this.uiServerConfiguration.port.toString()}'` + ) console.error( - `Error in WebSocket to UI server '${this.uiServerConfiguration.host}'`, + `Error in WebSocket to UI server '${this.uiServerConfiguration.host}:${this.uiServerConfiguration.port.toString()}'`, errorEvent ) }