Skip to content

Commit

Permalink
build(docker): add docker for easily bootstrapping dev env
Browse files Browse the repository at this point in the history
Changes:
- Added docker for setting up dev frontend
- Tweaked release/build system to remove building artifacts on release
- Changed proxy settings to allow proxying to different backends
- Added ability to set settings via .env file

Signed-off-by: Danil Kostromin <[email protected]>
  • Loading branch information
Danil Kostromin committed Jan 17, 2024
1 parent 5ca2912 commit 507f52b
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 118 deletions.
4 changes: 2 additions & 2 deletions .release-it.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
"requireBranch": "main",
"commitMessage": "chore(release): v${version}",
"tagName": "v${version}",
"addUntrackedFiles": true
"addUntrackedFiles": true
},
"github": { "release": true, "releaseName": "v${version}" },
"hooks": {
"before:init": [],
"after:bump": ["pnpm run git-info", "pnpm run bublik:ci:build"],
"after:bump": ["pnpm run git-info"],
"after:@release-it/conventional-changelog:bump": "pnpm run create-mdx-changelog \"${changelog}\"",
"after:release": "echo Successfully released ${name} v${version} to ${repo.repository}."
},
Expand Down
107 changes: 19 additions & 88 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,100 +1,31 @@
[SPDX-License-Identifier: Apache-2.0]::
[SPDX-FileCopyrightText: 2021-2023 OKTET Labs Ltd.]::

# Bublik UI

## Package manager

We use pnpm as our package manager so to start you will need to install it, please refer to [pnpm documentation](https://pnpm.io/) for installing instructions

All commands should be run like this `pnpm exec nx ...etc` or you can add alias to your .bashrc like this `alias pnx="pnpm nx --"`, then you can run like this `pnx ...`

## Monorepo tools

We use [Nx](https://nx.dev/getting-started/intro) for monorepo, you would need to install nx cli globally or run commands via `npx` or `pnpm dlx...`

## Project structure

```
📦 dist
┣ 📂 apps - Built production ready applications
📦 apps
┣ 📂 bublik - Bublik UI Application
📦 libs
┣ 📂 bublik - Bublik UI application specific libs
┃ ┣ 📂 +state - Redux state
┃ ┣ 📂 config - Different Bublik UI configs (needed for UI to work correctly)
┃ ┣ 📂 features - Specific Bublik UI featires implementation
┃ ┣ 📂 router - Router helpers, encoding/decoding search params
┣ 📂 env - Env helper lib
┣ 📂 services - General services for data-access
┃ ┗ 📂 bublik-api - Bublik API hooks/methods (RTK Query)
┣ 📂 shared - Shared libraries for multiple apps to consume
┃ ┣ 📂 charts - Apache Echarts components
┃ ┣ 📂 hooks - Shared react hooks
┃ ┣ 📂 icons - UI Icons
┃ ┣ 📂 tailwind-ui - Shared UI components
┃ ┣ 📂 types - Shared interfaces and types
┃ ┣ 📂 utils - Shared general utils
```

## Config

To create new Bublik UI frontend for deployment you would need to follow these steps:

1. Add needed configuration to `apps/bublik/project.json`
2. `base` - where the app will be mounted it **must start with `/`** and **no** trailing slash at the end

Example:

```json
{
"demo": {
"base": "/prefix",
"outputPath": "dist/apps/bublik-app"
}
}
```

## Local development

Make sure you installed nrwl [nx monorepo tools](https://nx.dev/getting-started/intro)
Example: 'pnpm add -g nx'

To start development, please follow this steps:

1. Clone repo
2. Run `pnpm install` to install dependencies
3. Run `pnpm start` to start development server
## Before you start (skip if you want to run via docker)

## Commands
1. Make sure you installed node, you can use [fnm](https://github.com/Schniz/fnm) or [nvm](https://github.com/nvm-sh/nvm)
2. Make sure you installed [pnpm](https://pnpm.io/)
3. Make sure you installed [nx](https://nx.dev/getting-started/installation#installing-nx-globally) globally
4. Make sure you installed [docker](https://docs.docker.com/desktop/) (you can install docker desktop or just docker engine)
5. Create env file `apps/bublik/.env.local` (see `apps/bublik/.env.local.example` for reference)

- `pnpm start` - starts Bublik UI in development mode
- `pnpm test` - runs tests in parallel for all projects
- `pnpm bublik:serve:prod` - starts Bublik UI in production mode
- `pnpm bublik:storybook` - starts storybook for Bublik UI
- `pnpm bublik:build-storybook` - builds storybook for Bublik UI
- `pnpm bublik:ci:build` - builds all Bublik UI application in production mode
### To test everything working run following commands

## Misc
1. `node -v` used node version in file `.nvmrc`
2. `pnpm -v`
3. `nx --version`
4. `docker version`

- If you want to connect to particular backend remote or local you can proxy all you requests with `apps/bublik/vite.config.ts`
## Run locally (run with docker)

## Common errors and solutions
You can run UI the following way:

- `pnpm ...` - command not working
- try to run command with `pnpm exec nx ...`
- Error installing packages like `react-vtree` and `legacy-peer-deps` errors
- try to add flag `legacy-peer-deps`
- Tailwind classes not working in storybook
- try adding lib/app path to `libs/shared/storybook/tailwind.config.js`
- Storybook not finding stories in your lib/app
- try adding lib/app path to `libs/shared/storybook/.storybook/main.js`
- Storybook tailwind classes not working
- try removing `node_module` and installing with `pnpm install`
1. Create env file `apps/bublik/.env.local` (see `apps/bublik/.env.local.example` for reference)
2. Build image `pnpm run docker:build` OR `docker build -f apps/bublik/Dockerfile.dev . -t bublik-ui`
3. Run image `pnpm run docker:start` OR `docker run -it --rm -p 4200:4200 -v $(pwd):/app -v /app/node_modules --env-file apps/bublik/.env.local bublik-ui`

## Release
Caveats:
- Add flag --network host to run image command if django is served from host
- If you add new dependencies to package.json you need to rebuild image

We are using release-it to automate releases. To release new version of Bublik UI you need to run `pnpm release` and follow the instructions.
Or run `pnpm release -- --dry-run` to see what will be done.
You can also release from GitHub actions menu specifying what type of release you want to do.
18 changes: 14 additions & 4 deletions apps/bublik/.env.local.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
# Username and password used to proxy requests to JSON logs
BUBLIK_UI_DEV_LOGS_AUTH="<USERNAME>:<PASSWORD>"
# This configuration is necessary for proper proxying of requests to django backend

#####################################################
# Example for connecting to ts-factory
# BUBLIK_UI_DEV_LOGS_TARGET=https://ts-factory.io
# BUBLIK_UI_DEV_BACKEND_TARGET=https://ts-factory.io
# URL_PREFIX=/bublik/v2

#####################################################
# This examples shows how to setup env for frontend served from `http://localhost/prefix/v2`
# Target of JSON logs (protocol, host, port)
BUBLIK_UI_DEV_LOGS_TARGET="https://example.com"
BUBLIK_UI_DEV_LOGS_TARGET=http://localhost
# Where backend is served (protocol, host, port)
BUBLIK_UI_DEV_BACKEND_TARGET="http://localhost:8000"
BUBLIK_UI_DEV_BACKEND_TARGET=http://localhost
# Adds prefix from where backend is served e.g (http://localhost/prefix/api/v2)
URL_PREFIX=/prefix/v2
1 change: 1 addition & 0 deletions apps/bublik/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# Local
.env.local
.env
21 changes: 12 additions & 9 deletions apps/bublik/Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
FROM node:17.9.0
FROM node:20-slim AS base

ENV PNPM_HOME="/root/.local/share/pnpm"
ENV PATH="${PATH}:${PNPM_HOME}"
ARG PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1

RUN npm install --global pnpm
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"

RUN pnpm add -g nx
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=${PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD}
ENV BASE_URL="/v2"

RUN corepack enable

COPY . /app
WORKDIR /app

COPY package.json pnpm-lock.yaml ./
RUN pnpm install
FROM base as runner

COPY . .
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install

EXPOSE 4200

CMD ["pnpm", "run", "nx", "serve", "--host=0.0.0.0"]
CMD ["pnpm", "run", "nx", "serve", "--host=0.0.0.0", "--base=${BASE_URL}"]
59 changes: 46 additions & 13 deletions apps/bublik/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,66 @@
/* SPDX-License-Identifier: Apache-2.0 */
/* SPDX-FileCopyrightText: 2021-2023 OKTET Labs Ltd. */
import { defineConfig, loadEnv } from 'vite';

import { defineConfig, HttpProxy, loadEnv, ProxyOptions } from 'vite';
import react from '@vitejs/plugin-react';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
import svgr from 'vite-plugin-svgr';

const createRequestLogger =
(domain: string) => (proxy: HttpProxy.Server, _options: ProxyOptions) => {
proxy.on('error', (err, _req, _res) => {
console.log(`[${domain}] Error:`, err);
});
proxy.on('proxyReq', (proxyReq, req, _res) => {
console.log(`[${domain}] Request:`, req.method, req.url);
});
proxy.on('proxyRes', (proxyRes, req, _res) => {
console.log(`[${domain}] Response:`, proxyRes.statusCode, req.url);
});
};

export default defineConfig(async ({ mode }) => {
const mdx = await import('@mdx-js/rollup');

let env: Record<string, string> = {};
if (mode === 'development') {
// You need to run `pnpm start again if you change env to load it correctly`
env = loadEnv(mode, process.cwd(), 'BUBLIK_UI_DEV');
env = loadEnv(mode, process.cwd(), '');
}

const URL_PREFIX = env.BASE_URL?.replace('/v2', '');
const DJANGO_TARGET = env.BUBLIK_UI_DEV_BACKEND_TARGET;
const LOGS_TARGET = env.BUBLIK_UI_DEV_LOGS_TARGET;

// Derived
const API_PATHNAME = `${URL_PREFIX}/api/v2`;
const AUTH_PATHNAME = `${URL_PREFIX}/auth`;
const EXTERNAL_PATHNAME = `${URL_PREFIX}/external`;

return {
root: __dirname,
server: {
port: 4200,
host: 'localhost',
proxy: {
'/api/v2': {
target: env['BUBLIK_UI_DEV_BACKEND_TARGET'],
[API_PATHNAME]: {
target: DJANGO_TARGET,
changeOrigin: true,
secure: false
secure: false,
configure: createRequestLogger('API')
},
'/auth': {
target: env['BUBLIK_UI_DEV_BACKEND_TARGET'],
[AUTH_PATHNAME]: {
target: DJANGO_TARGET,
changeOrigin: true,
secure: false
secure: false,
configure: createRequestLogger('AUTH')
},
'/external': {
target: env['BUBLIK_UI_DEV_LOGS_TARGET'],
[EXTERNAL_PATHNAME]: {
target: LOGS_TARGET,
changeOrigin: true,
secure: false,
auth: env['BUBLIK_UI_DEV_LOGS_AUTH'],
followRedirects: true,
rewrite: (path) => {
rewrite: (path: string) => {
const externalUrl = /=([^&]+)/.exec(path)?.[1];

if (!externalUrl) {
Expand All @@ -45,7 +70,7 @@ export default defineConfig(async ({ mode }) => {
console.log(`[PROXY] Rewrite path: ${path}`);
console.log(`[PROXY] External URL: ${externalUrl}`);

return externalUrl;
return externalUrl.replace(LOGS_TARGET, '');
}
}
}
Expand All @@ -60,6 +85,9 @@ export default defineConfig(async ({ mode }) => {
],

build: {
outDir: '../../dist/apps/bublik',
reportCompressedSize: true,
commonjsOptions: { transformMixedEsModules: true },
rollupOptions: {
output: {
manualChunks: {
Expand All @@ -80,6 +108,11 @@ export default defineConfig(async ({ mode }) => {
// },

test: {
reporters: ['default'],
coverage: {
reportsDirectory: '../../coverage/apps/bublik',
provider: 'v8'
},
globals: true,
cache: {
dir: '../../node_modules/.vitest'
Expand Down
5 changes: 4 additions & 1 deletion libs/services/bublik-api/src/lib/endpoints/log-endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
BublikHttpError,
isBublikParsableError
} from '../error-handling';
import { config } from '@/bublik/config';

type GetLogJsonInputs = {
id: string | number;
Expand Down Expand Up @@ -63,7 +64,9 @@ export const logEndpoints = {

const options: RequestInit = { credentials: 'include' };

const response = await fetch(externalUrl, options);
const response = config.isDev
? await fetch(`${config.rootUrl}/external?url=${externalUrl}`)
: await fetch(externalUrl, options);

if (!response.ok) throw getBublikFromStatusCode(response);

Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
"nx": "nx",
"start": "nx serve",
"build": "nx build",
"bublik:build-all": "nx run bublik:build-all",
"docker:build": "docker build -f apps/bublik/Dockerfile.dev . -t bublik-ui",
"docker:start": "docker run -it --rm -p 4200:4200 -v $(pwd):/app -v /app/node_modules --env-file apps/bublik/.env.local bublik-ui",
"bublik:build-all": "nx run bublik:build-all",
"bublik:build-storybook": "nx run bublik:storybook:ci",
"bublik:storybook": "nx run bublik:storybook",
"bublik:ci:build": "nx run bublik:ci-build",
Expand Down

0 comments on commit 507f52b

Please sign in to comment.