From 4b970b3812a327366f0cd664337c3e9ac2a32989 Mon Sep 17 00:00:00 2001 From: Kosmos Date: Tue, 25 Aug 2026 00:06:52 +0000 Subject: [PATCH] Initial Docker deployment setup --- .dockerignore | 8 ++ .env.example | 11 +++ .gitignore | 2 + Dockerfile | 31 ++++++++ README.md | 188 +++++++++++++++++++++++++++++++++++++++++++++ compose.yaml | 20 +++++ nginx/default.conf | 18 +++++ 7 files changed, 278 insertions(+) create mode 100644 .dockerignore create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 compose.yaml create mode 100644 nginx/default.conf diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..c87edd5 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +.git +.env +upstream/HubFrontend/.git +upstream/HubFrontend/node_modules +upstream/HubFrontend/build +upstream/HubFrontend/dist +upstream/HubFrontend/build-electron/output +npm-debug.log* diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..6c181fb --- /dev/null +++ b/.env.example @@ -0,0 +1,11 @@ +# Address and port on the Docker host. +FRONTEND_BIND=127.0.0.1:18080 + +# URL of the backend client configuration endpoint. +VITE_CONFIG_URL=https://hub.example.com/api/client/config/global + +# Use an empty value when the frontend and its assets use the same origin. +ASSETS_BASE= + +VITE_USE_MULTIHUB=false +VITE_MULTIHUB_DISCOVERY= diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4be60ad --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.env +upstream/HubFrontend/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f64aa27 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,31 @@ +# syntax=docker/dockerfile:1 + +FROM node:25-bookworm-slim AS builder + +WORKDIR /build + +ENV ELECTRON_SKIP_BINARY_DOWNLOAD=1 + +COPY upstream/HubFrontend/package.json upstream/HubFrontend/package-lock.json upstream/HubFrontend/.npmrc ./ +RUN --mount=type=cache,target=/root/.npm npm ci + +COPY upstream/HubFrontend/ ./ + +ARG ASSETS_BASE="" +ARG VITE_USE_MULTIHUB=false +ARG VITE_MULTIHUB_DISCOVERY="" +ARG VITE_CONFIG_URL + +ENV ASSETS_BASE=${ASSETS_BASE} \ + VITE_USE_MULTIHUB=${VITE_USE_MULTIHUB} \ + VITE_MULTIHUB_DISCOVERY=${VITE_MULTIHUB_DISCOVERY} \ + VITE_CONFIG_URL=${VITE_CONFIG_URL} + +RUN npm run build + +FROM nginx:alpine AS runtime + +COPY nginx/default.conf /etc/nginx/conf.d/default.conf +COPY --from=builder /build/build/ /usr/share/nginx/html/ + +EXPOSE 8080 diff --git a/README.md b/README.md new file mode 100644 index 0000000..7135765 --- /dev/null +++ b/README.md @@ -0,0 +1,188 @@ +# Drivers Hub: Frontend Docker Deployment + +```text + ____ _ __ __ __ + / __ \_____(_) _____ __________ / / / /_ __/ /_ + / / / / ___/ / | / / _ \/ ___/ ___/ / /_/ / / / / __ \ + / /_/ / / / /| |/ / __/ / (__ ) / __ / /_/ / /_/ / +/_____/_/ /_/ |___/\___/_/ /____/ /_/ /_/\__,_/_.___/ +``` + +Docker deployment for [Drivers Hub: Frontend](https://github.com/CharlesWithC/HubFrontend). +The container serves the static frontend with Nginx. + +## Configure the deployment + +Get the frontend source code. Then, create the deployment configuration: + +```bash +git clone https://github.com/CharlesWithC/HubFrontend.git upstream/HubFrontend +cp .env.example .env +``` + +Set `VITE_CONFIG_URL` to the client configuration endpoint of your Drivers Hub +backend. The URL usually has this format: + +```text +https://hub.example.com/api/client/config/global +``` + +The frontend uses the Vite values during the image build. Rebuild the image after +you change `.env`. + +## Start the deployment + +```bash +docker compose build +docker compose up -d +docker compose ps +``` + +By default, the frontend is available at `http://127.0.0.1:18080`. The default +bind address is suitable for a reverse proxy on the Docker host. + +## Configure a reverse proxy + +The following examples assume that the reverse proxy runs on the Docker host. +Replace `hub.example.com` with the public frontend domain. Keep +`FRONTEND_BIND=127.0.0.1:18080` in the frontend `.env`. The examples also assume +that Drivers Hub: Backend listens on `127.0.0.1:17777` and uses the `/api` prefix. + +### Standalone Nginx + +Create an Nginx virtual host: + +```nginx +server { + listen 80; + listen [::]:80; + server_name hub.example.com; + + return 301 https://$host$request_uri; +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name hub.example.com; + + ssl_certificate /etc/letsencrypt/live/hub.example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/hub.example.com/privkey.pem; + + location ^~ /api/ { + proxy_pass http://127.0.0.1:17777; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location / { + proxy_pass http://127.0.0.1:18080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` + +Set the certificate paths for your system. Test and reload Nginx: + +```bash +sudo nginx -t +sudo systemctl reload nginx +``` + +See the [Nginx proxy module documentation](https://nginx.org/en/docs/http/ngx_http_proxy_module.html) +for more information. + +### Standalone Caddy + +Add this site block to the Caddyfile: + +```caddyfile +hub.example.com { + handle /api/* { + reverse_proxy 127.0.0.1:17777 + } + + handle { + reverse_proxy 127.0.0.1:18080 + } +} +``` + +Caddy obtains and renews the TLS certificate when the domain points to the +server and ports 80 and 443 are available. Validate and reload Caddy: + +```bash +sudo caddy validate --config /etc/caddy/Caddyfile +sudo systemctl reload caddy +``` + +See the [Caddy reverse proxy documentation](https://caddyserver.com/docs/caddyfile/directives/reverse_proxy) +for more information. + +### Plesk Nginx drop-in + +Use a domain or subdomain that has a valid TLS certificate in Plesk. + +1. Open **Domains > hub.example.com > Dashboard > PHP**. +2. Disable **PHP Support** and apply the change. +3. Open **Hosting & DNS > Apache & nginx Settings**. +4. Disable **Proxy mode** and apply the change. +5. Add this block to **Additional nginx directives**: + +```nginx +location ^~ /api/ { + proxy_pass http://127.0.0.1:17777; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; +} + +location / { + proxy_pass http://127.0.0.1:18080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; +} +``` + +Apply the configuration. Do not add a `server` block in this field. Plesk +creates the `server` block and manages TLS. Proxy mode must be disabled before +you add `location /`. Otherwise, Plesk creates a duplicate location. + +See the [Plesk reverse proxy instructions](https://support.plesk.com/hc/en-us/articles/12388464421143-How-to-pass-requests-from-a-Plesk-hosted-domain-to-the-application-listening-on-a-local-port) +for more information. + +## Update the frontend + +Update the frontend source code. Then, rebuild the container: + +```bash +git -C upstream/HubFrontend pull --ff-only +docker compose build +docker compose up -d +``` + +## Operate the deployment + +```bash +# Show the frontend logs. +docker compose logs -f frontend + +# Rebuild the image after a configuration change. +docker compose build frontend +docker compose up -d frontend +``` + +## Attribution + +[Drivers Hub: Frontend](https://github.com/CharlesWithC/HubFrontend) is developed +by [CharlesWithC](https://charlws.com) and is licensed under the GNU Affero +General Public License v3.0. This repository provides an independent Docker +deployment for that project. diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..b4d751f --- /dev/null +++ b/compose.yaml @@ -0,0 +1,20 @@ +# Use the frontend source code in upstream/HubFrontend. +name: drivershub-frontend + +services: + frontend: + build: + context: . + args: + ASSETS_BASE: ${ASSETS_BASE:-} + VITE_USE_MULTIHUB: ${VITE_USE_MULTIHUB:-false} + VITE_MULTIHUB_DISCOVERY: ${VITE_MULTIHUB_DISCOVERY:-} + VITE_CONFIG_URL: ${VITE_CONFIG_URL:?Set VITE_CONFIG_URL in .env} + restart: unless-stopped + ports: + - "${FRONTEND_BIND:-127.0.0.1:18080}:8080" + healthcheck: + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://127.0.0.1:8080/"] + interval: 10s + timeout: 3s + retries: 10 diff --git a/nginx/default.conf b/nginx/default.conf new file mode 100644 index 0000000..453327e --- /dev/null +++ b/nginx/default.conf @@ -0,0 +1,18 @@ +server { + listen 8080; + listen [::]:8080; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + location /assets/ { + try_files $uri =404; + add_header Cache-Control "public, max-age=31536000, immutable"; + } + + location / { + try_files $uri $uri/ /index.html; + add_header Cache-Control "no-cache"; + } +}