The article about deploy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const getAdressessOfPods = async (req: Request, res: Response, next: NextFunction) => { | |
// Получаем из переменных среды имена сервисов и сортируем их, | |
// чтобы опрашивать в нужной последовательности. | |
const headlessServices = getSortedHeadlessNames(Object.keys(process.env)); | |
const reachedModules = []; | |
const headlessServicePromises = | |
headlessServices.length === 0 | |
? [getAddressesOfMcf()] | |
: headlessServices.map((service) => getAddressesOfMcf(process.env[service])); | |
const modules = await Promise.allSettled([...headlessServicePromises]); | |
for (const module of modules) { | |
if (module.status === 'rejected') { | |
logMessage(`can't get mcfAddressArray; reason: ${module.reason}`, { | |
host: req.hostname, | |
}); | |
continue; | |
} | |
reachedModules.push(...module.value); | |
} | |
if (reachedModules.length === 0) { | |
const errorMessage = `no headless services found. headlessServices: ${headlessServices}`; | |
logException(new Error(errorMessage)); | |
res.status(500); | |
res.send('no modules found'); | |
return; | |
} | |
// Складываем полученные адреса в locals, | |
// чтобы получить их в другой middleware. | |
res.locals[RES_LOCALS.mcfAddresses] = reachedModules; | |
next(); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const createRegExForReplace = (MCFName: string) => | |
new RegExp(`\\/\\*!\\s@mcf\\sstart\\s${MCFName}\\s\\*\\/.+\\/*!\\s@mcf\\send\\s${MCFName}\\s\\*\\/`); | |
export const buildNewInitialJs = ({ modulesArray }: BuildNewInitialJsArgs) => { | |
let newInitial = initEmptyModulesList; | |
if (modulesArray.length === 0) { | |
throw new Error('No MCF array are provided'); | |
} | |
modulesArray.forEach((moduleCode) => { | |
const safeNoduleCode = deleteNewLines(moduleCode); | |
const name = REGEX_FOR_FIND_MCF_NAME.exec(safeNoduleCode); | |
const moduleName = name?.groups?.['MCF_NAME']; | |
if (!moduleName) { | |
logException(INVALID_REMOTE_ENTRY_ERROR); | |
return; | |
} | |
const isMcfNameExistInInitialJs = newInitial.search(createRegExForReplace(moduleName)); | |
if (isMcfNameExistInInitialJs === -1) { | |
newInitial = newInitial.concat(stub, safeNoduleCode, stub, initModule(moduleName)); | |
} else { | |
newInitial = newInitial.replace(createRegExForReplace(moduleName), safeNoduleCode); | |
} | |
}); | |
newInitial = newInitial.concat(stub, loadModules); | |
return pasteNewLines(newInitial); | |
}; | |
export const handleInitialJs = async (_: Request, res: Response) => { | |
res.type('.js'); | |
try { | |
// Получаем файлы с метаданными из каждого пода. | |
const modulesArray = await getRemoteEntries(res.locals[RES_LOCALS.mcfAddresses]); | |
// Собираем массив с метаданными в один файл и отдаем его пользователю. | |
const newInitialJs = buildNewInitialJs({ | |
modulesArray, | |
}); | |
res.send(newInitialJs); | |
} catch (error) { | |
Sentry.captureException(error); | |
res.status(500).send("Can't build initial.js"); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
apiVersion: apps/v1 | |
kind: Deployment | |
metadata: | |
name: {{ .Values.name }}-deployment-{{ .Values.environment }} | |
spec: | |
replicas: {{ .Values.services.replicas }} | |
selector: | |
matchLabels: | |
product: {{ .Values.name }} | |
# Помечаем, что этот под содержит в себе код микрофронтенда. | |
microfrontend-pod: {{ .Values.isMicrofrontendPod | quote }} | |
template: | |
metadata: | |
labels: | |
product: {{ .Values.name }} | |
microfrontend-pod: {{ .Values.isMicrofrontendPod | quote }} | |
deploy-environment: {{ .Values.environment }} | |
spec: | |
imagePullSecrets: | |
- name: image-pull-{{ .Values.environment }} | |
containers: | |
- name: {{ .Values.name }}-pod | |
image: "image-repo/{{ .Values.name }}:{{ $.Values.packageVersion }}" | |
imagePullPolicy: Always | |
resources: | |
requests: | |
cpu: {{ .Values.services.resources.requests.cpu }} | |
memory: {{ .Values.services.resources.requests.memory }} | |
limits: | |
cpu: {{ .Values.services.resources.limits.cpu }} | |
memory: {{ .Values.services.resources.limits.memory }} | |
ports: | |
- containerPort: 8080 | |
tolerations: | |
- key: dedicated | |
operator: Equal | |
value: mindbox-worker | |
effect: NoSchedule | |
- key: dedicated | |
operator: Equal | |
value: mindbox-worker | |
effect: PreferNoSchedule | |
--- | |
apiVersion: v1 | |
kind: Service | |
metadata: | |
name: {{ .Values.name }}-service-{{ .Values.environment }} | |
spec: | |
selector: | |
product: {{ .Values.name }} | |
microfrontend-pod: {{ .Values.isMicrofrontendPod | quote }} | |
deploy-environment: {{ .Values.environment }} | |
ports: | |
- name: main | |
protocol: TCP | |
port: 8080 | |
targetPort: 8080 | |
--- | |
apiVersion: traefik.containo.us/v1alpha1 | |
kind: IngressRoute | |
metadata: | |
name: {{ .Values.name }}-ingressroute-{{ .Values.environment }}-index-html | |
labels: | |
mindbox/traefik: common | |
spec: | |
entryPoints: | |
- websecure | |
routes: | |
# Собираем URL, по которому будет отвечать под. | |
# Нам нужно, чтобы он отвечал по всем запросам по определенному URL | |
# и заголовку "environment", который проставляется в HAProxy. | |
- match: HostRegexp(`{tenant:.*}.{{ .Values.host }}`) && (PathPrefix(`/{{ .Values.namespace }}`)) && Headers(`environment`, `{{ .Values.environment }}`) | |
kind: Rule | |
priority: 50 | |
services: | |
- port: 8080 | |
name: frontend-initial-builder-service-{{ .Values.environment }} | |
tls: | |
options: | |
name: agrade-tls-options | |
namespace: traefik-common | |
--- | |
apiVersion: traefik.containo.us/v1alpha1 | |
kind: IngressRoute | |
metadata: | |
name: {{ .Values.name }}-ingressroute-{{ .Values.environment }} | |
labels: | |
mindbox/traefik: common | |
spec: | |
entryPoints: | |
- websecure | |
routes: | |
# Собираем URL, по которому будет отвечать под. | |
# Нам нужно, чтобы он отвечал по всем запросам по определенному URL | |
# и заголовку "environment", который проставляется в HAProxy. | |
- match: HostRegexp(`{tenant:.*}.{{ .Values.host }}`) && PathPrefix(`/v2_static/{{ regexReplaceAll "-" .Values.name "_"}}/`) && Headers(`environment`, `{{ .Values.environment }}`) | |
kind: Rule | |
priority: 50 | |
services: | |
- name: {{ .Values.name }}-service-{{ .Values.environment }} | |
port: 8080 | |
tls: | |
options: | |
name: agrade-tls-options | |
namespace: traefik-common |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment