Compare commits
25 Commits
d77be41b99
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| c8fecc52d6 | |||
| e97cbc6ad2 | |||
| 9fbca2677b | |||
| 6daa4c284d | |||
| 1c1eaa7ee7 | |||
| 96501f712c | |||
| ce52b5aff5 | |||
| b9ad5fd922 | |||
| f6b1a7eede | |||
| c1b2a8cbdd | |||
| aa22b48746 | |||
| ea7c54a5dc | |||
| 0a344ed1ce | |||
| 3d6e4e6f34 | |||
| 2cdbebdfa1 | |||
| 5db0026aa7 | |||
| 7b213dd33a | |||
| b69f26027d | |||
| 95b0c5f1ad | |||
| 4dc99b740b | |||
| 248364a686 | |||
| cd57e11404 | |||
| 99ea80c93c | |||
| 46543c83b1 | |||
| 636efa9744 |
82
README.md
@ -1 +1,83 @@
|
||||
# Komponiranje
|
||||
|
||||
## How to run
|
||||
|
||||
Clone repository
|
||||
```
|
||||
git clone https://gitea.ekirin.com/Intis/prezentacija-komponiranje.git
|
||||
cd prezentacija-komponiranje
|
||||
```
|
||||
|
||||
Start docker compose with all containers:
|
||||
```
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Wait until docker images are built and containers starts.
|
||||
|
||||
Browse to [Local frontend application on port 8080](http://localhost:8080)
|
||||
|
||||
List running containers:
|
||||
```
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
Attach to docker compose output:
|
||||
```
|
||||
docker compose logs -f
|
||||
```
|
||||
|
||||
Stop running containers:
|
||||
```
|
||||
docker compose down
|
||||
```
|
||||
|
||||
### Run on host network
|
||||
|
||||
Start docker compose:
|
||||
```
|
||||
docker compose -f docker-compose-local.yml up -d
|
||||
```
|
||||
|
||||
Containers will listen to the following local ports:
|
||||
|
||||
| Service | Port |
|
||||
| ------------- | ----- |
|
||||
| FE / nginx | 80 |
|
||||
| Envoy proxy | 10000 |
|
||||
| Machines app | 4000 |
|
||||
| Products app | 4001 |
|
||||
| Database | 55432 |
|
||||
|
||||
Browse to [Local frontend application on port 80](http://localhost:80)
|
||||
|
||||
|
||||
Stop running containers:
|
||||
```
|
||||
docker compose -f docker-compose-local.yml down
|
||||
```
|
||||
|
||||
|
||||
## Media
|
||||
|
||||
### Life without Docker Compose
|
||||
|
||||

|
||||
|
||||
### Containers Architecture
|
||||
|
||||

|
||||
|
||||
### Networking - docker-compose.yml
|
||||
|
||||

|
||||
|
||||
### Networking - host network - docker-compose-local.yml
|
||||
|
||||

|
||||
|
||||
### DCCT - Docker Compose Cloud Tester
|
||||
|
||||
- [DCCT repository](https://gitlab.televendcloud.com/cloud/dc-cloud-tester)
|
||||
|
||||

|
||||
|
||||
66
docker-compose-local.yml
Normal file
@ -0,0 +1,66 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
db:
|
||||
build:
|
||||
context: ./database
|
||||
dockerfile: Dockerfile
|
||||
network_mode: "host"
|
||||
environment:
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
command: -p 55432
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres -p 55432"]
|
||||
interval: 1s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
machines-app:
|
||||
build:
|
||||
context: ./machines
|
||||
dockerfile: Dockerfile
|
||||
network_mode: "host"
|
||||
environment:
|
||||
- APPPORT=4000
|
||||
- DBHOST=localhost
|
||||
- DBPORT=55432
|
||||
- DBNAME=komponiranje
|
||||
- DBUSER=pero
|
||||
- DBPASSWORD=pero.000
|
||||
- PRODUCTSAPPURL=http://localhost:10000
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
products-app:
|
||||
build:
|
||||
context: ./products
|
||||
dockerfile: Dockerfile
|
||||
network_mode: "host"
|
||||
environment:
|
||||
- APPPORT=4001
|
||||
- DBHOST=localhost
|
||||
- DBPORT=55432
|
||||
- DBNAME=komponiranje
|
||||
- DBUSER=pero
|
||||
- DBPASSWORD=pero.000
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
proxy:
|
||||
image: envoyproxy/envoy:v1.28-latest
|
||||
network_mode: "host"
|
||||
volumes:
|
||||
- ./proxy/envoy-local.yaml:/etc/envoy/envoy.yaml
|
||||
depends_on:
|
||||
- machines-app
|
||||
- products-app
|
||||
frontend-app:
|
||||
build:
|
||||
context: ./frontend
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
- REACT_APP_MACHINES_API_URL=http://localhost:10000
|
||||
- REACT_APP_PRODUCTS_API_URL=http://localhost:10000
|
||||
network_mode: "host"
|
||||
depends_on:
|
||||
- proxy
|
||||
@ -5,8 +5,8 @@ services:
|
||||
build:
|
||||
context: ./database
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- 55432:5432
|
||||
networks:
|
||||
- backend-net
|
||||
environment:
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
@ -19,8 +19,10 @@ services:
|
||||
build:
|
||||
context: ./machines
|
||||
dockerfile: Dockerfile
|
||||
networks:
|
||||
- backend-net
|
||||
environment:
|
||||
- APPPORT=3000
|
||||
- APPPORT=4000
|
||||
- DBHOST=db
|
||||
- DBPORT=5432
|
||||
- DBNAME=komponiranje
|
||||
@ -37,8 +39,10 @@ services:
|
||||
deploy:
|
||||
mode: replicated
|
||||
replicas: 2
|
||||
networks:
|
||||
- backend-net
|
||||
environment:
|
||||
- APPPORT=3000
|
||||
- APPPORT=4001
|
||||
- DBHOST=db
|
||||
- DBPORT=5432
|
||||
- DBNAME=komponiranje
|
||||
@ -49,6 +53,9 @@ services:
|
||||
condition: service_healthy
|
||||
proxy:
|
||||
image: envoyproxy/envoy:v1.28-latest
|
||||
networks:
|
||||
- frontend-net
|
||||
- backend-net
|
||||
ports:
|
||||
- "10000:10000"
|
||||
volumes:
|
||||
@ -56,3 +63,24 @@ services:
|
||||
depends_on:
|
||||
- machines-app
|
||||
- products-app
|
||||
frontend-app:
|
||||
build:
|
||||
context: ./frontend
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
- REACT_APP_MACHINES_API_URL=http://localhost:10000
|
||||
- REACT_APP_PRODUCTS_API_URL=http://localhost:10000
|
||||
networks:
|
||||
- frontend-net
|
||||
ports:
|
||||
- "8080:80"
|
||||
depends_on:
|
||||
- proxy
|
||||
|
||||
networks:
|
||||
frontend-net:
|
||||
name: frontend-net
|
||||
internal: false
|
||||
backend-net:
|
||||
name: backend-net
|
||||
internal: true
|
||||
|
||||
3
frontend/.dockerignore
Normal file
@ -0,0 +1,3 @@
|
||||
**/node_modules
|
||||
**/build
|
||||
|
||||
25
frontend/Dockerfile
Normal file
@ -0,0 +1,25 @@
|
||||
# stage 1: build node frontend
|
||||
FROM node:21 as node-builder
|
||||
|
||||
WORKDIR /node-builder
|
||||
|
||||
ARG REACT_APP_MACHINES_API_URL
|
||||
ARG REACT_APP_PRODUCTS_API_URL
|
||||
|
||||
ENV REACT_APP_MACHINES_API_URL $REACT_APP_MACHINES_API_URL
|
||||
ENV REACT_APP_PRODUCTS_API_URL $REACT_APP_PRODUCTS_API_URL
|
||||
|
||||
COPY ./package.json .
|
||||
COPY ./package-lock.json .
|
||||
COPY ./public ./public
|
||||
COPY ./src ./src
|
||||
|
||||
RUN \
|
||||
npm install && \
|
||||
npm run build
|
||||
|
||||
|
||||
# stage 2: build final image
|
||||
FROM nginx:1.25-alpine
|
||||
|
||||
COPY --from=node-builder /node-builder/build/. /usr/share/nginx/html
|
||||
36
frontend/Makefile
Normal file
@ -0,0 +1,36 @@
|
||||
CONTAINER_NAME=frontend-app
|
||||
IMAGE_NAME=komponiranje-frontend-app
|
||||
|
||||
|
||||
run:
|
||||
@npm start
|
||||
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
@npm run build
|
||||
|
||||
|
||||
upgrade-packages:
|
||||
@go get -u ./...
|
||||
|
||||
|
||||
docker-build: clean
|
||||
@docker build \
|
||||
--progress=plain \
|
||||
--tag $(IMAGE_NAME) \
|
||||
.
|
||||
|
||||
|
||||
docker-run:
|
||||
@docker run \
|
||||
--name $(CONTAINER_NAME) \
|
||||
--publish 8080:80 \
|
||||
--detach \
|
||||
$(IMAGE_NAME)
|
||||
|
||||
|
||||
clean:
|
||||
- @docker stop $(CONTAINER_NAME)
|
||||
- @docker rm $(CONTAINER_NAME)
|
||||
- @docker rmi $(IMAGE_NAME)
|
||||
@ -1,43 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
<meta name="description" content="Komponiranje frontend demo" />
|
||||
<title>Komponiranje frontend demo</title>
|
||||
</head>
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
</body>
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 9.4 KiB |
@ -1,24 +1,7 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"start_url": "./index.html",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import axios from "axios";
|
||||
import { API_URL } from "../const";
|
||||
|
||||
export class ApiBase {}
|
||||
|
||||
@ -12,7 +11,6 @@ const commonHeaders = {
|
||||
};
|
||||
|
||||
export const axiosUnauthorizedInstance = axios.create({
|
||||
baseURL: API_URL,
|
||||
timeout: 5000,
|
||||
headers: commonHeaders,
|
||||
});
|
||||
@ -25,7 +23,6 @@ axiosUnauthorizedInstance.interceptors.response.use(
|
||||
);
|
||||
|
||||
export const axiosInstance = axios.create({
|
||||
baseURL: API_URL,
|
||||
timeout: 5000,
|
||||
headers: {
|
||||
...commonHeaders,
|
||||
|
||||
@ -1 +1,2 @@
|
||||
export { machinesApi } from "./machines";
|
||||
export { productsApi } from "./products";
|
||||
|
||||
@ -1,14 +1,17 @@
|
||||
import { axiosInstance, ApiBase } from "./common";
|
||||
import { MACHINES_API_URL } from "../const";
|
||||
|
||||
const baseUrl = `${MACHINES_API_URL}/machines`;
|
||||
|
||||
class MachinesApi extends ApiBase {
|
||||
list = async () => {
|
||||
return axiosInstance.get(`/machines`, {});
|
||||
return axiosInstance.get(`${baseUrl}`, {});
|
||||
};
|
||||
get = async (machineId) => {
|
||||
return axiosInstance.get(`/machines/${machineId}`, {});
|
||||
return axiosInstance.get(`${baseUrl}/${machineId}`, {});
|
||||
};
|
||||
listProducts = async (machineId) => {
|
||||
return axiosInstance.get(`/machines/${machineId}/products`, {});
|
||||
return axiosInstance.get(`${baseUrl}/${machineId}/products`, {});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
12
frontend/src/api/products.js
Normal file
@ -0,0 +1,12 @@
|
||||
import { axiosInstance, ApiBase } from "./common";
|
||||
import { PRODUCTS_API_URL } from "../const";
|
||||
|
||||
const baseUrl = `${PRODUCTS_API_URL}/products`;
|
||||
|
||||
class ProductsApi extends ApiBase {
|
||||
get = async (productId) => {
|
||||
return axiosInstance.get(`${baseUrl}/${productId}`, {});
|
||||
};
|
||||
}
|
||||
|
||||
export const productsApi = new ProductsApi();
|
||||
@ -6,20 +6,21 @@ import Typography from "@mui/material/Typography";
|
||||
import { CardActionArea } from "@mui/material";
|
||||
import { PRODUCT_IMAGE_DIR } from "../const";
|
||||
|
||||
function ProductCard({ product }) {
|
||||
function ProductCard({ product, onClick }) {
|
||||
const productImg = `${PRODUCT_IMAGE_DIR}/${product.image}`;
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardActionArea>
|
||||
<CardMedia component="img" height="140" image={productImg} alt={product.name} />
|
||||
<Card sx={{ width: "100%" }}>
|
||||
<CardActionArea
|
||||
onClick={() => {
|
||||
onClick(product.id);
|
||||
}}
|
||||
>
|
||||
<CardMedia component="img" height="200" image={productImg} alt={product.name} />
|
||||
<CardContent>
|
||||
<Typography gutterBottom variant="h5" component="div">
|
||||
<Typography gutterBottom variant="h5" component="div" sx={{ marginBottom: 0 }}>
|
||||
{product.name}
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{product.description}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</CardActionArea>
|
||||
</Card>
|
||||
|
||||
36
frontend/src/components/ProductModal.js
Normal file
@ -0,0 +1,36 @@
|
||||
import * as React from "react";
|
||||
import Button from "@mui/material/Button";
|
||||
import Dialog from "@mui/material/Dialog";
|
||||
import DialogActions from "@mui/material/DialogActions";
|
||||
import DialogContent from "@mui/material/DialogContent";
|
||||
import DialogContentText from "@mui/material/DialogContentText";
|
||||
import DialogTitle from "@mui/material/DialogTitle";
|
||||
import CardMedia from "@mui/material/CardMedia";
|
||||
import { PRODUCT_IMAGE_DIR } from "../const";
|
||||
|
||||
function ProductModal({ product, onClose }) {
|
||||
const productImg = `${PRODUCT_IMAGE_DIR}/${product.image}`;
|
||||
|
||||
return (
|
||||
<Dialog open={true} onClose={onClose}>
|
||||
<DialogTitle>{product.name}</DialogTitle>
|
||||
<DialogContent>
|
||||
<CardMedia
|
||||
component="img"
|
||||
height="300"
|
||||
image={productImg}
|
||||
alt={product.name}
|
||||
sx={{ marginBottom: "1rem" }}
|
||||
/>
|
||||
<DialogContentText>{product.description}</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose} variant="contained" autoFocus>
|
||||
Close
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
export { ProductModal };
|
||||
@ -2,12 +2,32 @@ import * as React from "react";
|
||||
import Grid from "@mui/material/Unstable_Grid2";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { ProductCard } from "./ProductCard";
|
||||
import { ProductModal } from "./ProductModal";
|
||||
import { productsApi } from "../api";
|
||||
|
||||
function Products({ machineName, products, onSelect }) {
|
||||
const [productModal, setProductModal] = React.useState({ isOpen: false, product: null });
|
||||
|
||||
const onProductSelect = (productId) => {
|
||||
productsApi.get(productId).then((response) => {
|
||||
setProductModal({
|
||||
isOpen: true,
|
||||
product: response.data,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const onProductModalClose = () => {
|
||||
setProductModal({
|
||||
isOpen: false,
|
||||
productId: null,
|
||||
});
|
||||
};
|
||||
|
||||
const productItems = products.map((product) => {
|
||||
return (
|
||||
<Grid md={6} key={product.id}>
|
||||
<ProductCard product={product} />
|
||||
<Grid md={6} key={product.id} sx={{ display: "flex" }}>
|
||||
<ProductCard product={product} onClick={onProductSelect} />
|
||||
</Grid>
|
||||
);
|
||||
});
|
||||
@ -21,6 +41,8 @@ function Products({ machineName, products, onSelect }) {
|
||||
<Grid container spacing={2}>
|
||||
{productItems}
|
||||
</Grid>
|
||||
|
||||
{productModal.isOpen && <ProductModal product={productModal.product} onClose={onProductModalClose} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
export const API_URL = process.env.REACT_APP_BACKEND_API_URL || "http://localhost:10000";
|
||||
export const MACHINES_API_URL = process.env.REACT_APP_MACHINES_API_URL || "http://localhost:4000";
|
||||
export const PRODUCTS_API_URL = process.env.REACT_APP_PRODUCTS_API_URL || "http://localhost:4001";
|
||||
export const PRODUCT_IMAGE_DIR = "/static/products/";
|
||||
|
||||
@ -18,9 +18,7 @@ function Home() {
|
||||
}, []);
|
||||
|
||||
const onMachineSelect = (machineName, machineId) => {
|
||||
console.log("selected:", machineName);
|
||||
machinesApi.listProducts(machineId).then((response) => {
|
||||
console.log(response.data.products);
|
||||
setProductsData({
|
||||
machineName,
|
||||
products: response.data.products,
|
||||
|
||||
@ -26,8 +26,7 @@ docker-build: clean
|
||||
docker-run:
|
||||
@docker run \
|
||||
--name $(CONTAINER_NAME) \
|
||||
--publish 3000:3000 \
|
||||
--env CONTAINER_NAME="Awesome API server" \
|
||||
--publish 4000:4000 \
|
||||
--env DBPORT=55432 \
|
||||
--detach \
|
||||
$(IMAGE_NAME)
|
||||
|
||||
@ -6,13 +6,13 @@ import (
|
||||
|
||||
type configStruct struct {
|
||||
AppHost string `default:"0.0.0.0"`
|
||||
AppPort int `default:"3000"`
|
||||
AppPort int `default:"4000"`
|
||||
DbHost string `default:"localhost"`
|
||||
DbPort int `default:"55432"`
|
||||
DbName string `default:"komponiranje"`
|
||||
DbUser string `default:"pero"`
|
||||
DbPassword string `default:"pero.000"`
|
||||
ProductsAppUrl string `default:"http://localhost:3001"`
|
||||
ProductsAppUrl string `default:"http://localhost:4001"`
|
||||
}
|
||||
|
||||
const ENV_PREFIX = ""
|
||||
|
||||
BIN
media/containers-architecture.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
media/dcct.png
Normal file
|
After Width: | Height: | Size: 688 KiB |
BIN
media/life-without-docker-compose.png
Normal file
|
After Width: | Height: | Size: 635 KiB |
BIN
media/networking-host-network.png
Normal file
|
After Width: | Height: | Size: 509 KiB |
BIN
media/networking.png
Normal file
|
After Width: | Height: | Size: 726 KiB |
@ -26,8 +26,7 @@ docker-build: clean
|
||||
docker-run:
|
||||
@docker run \
|
||||
--name $(CONTAINER_NAME) \
|
||||
--publish 3000:3000 \
|
||||
--env CONTAINER_NAME="Awesome API server" \
|
||||
--publish 4001:4001 \
|
||||
--env DBPORT=55432 \
|
||||
--detach \
|
||||
$(IMAGE_NAME)
|
||||
|
||||
@ -39,6 +39,10 @@ func handleGetProducts(dbConn *gorm.DB) gin.HandlerFunc {
|
||||
|
||||
products := db.GetProducts(dbConn, machineId)
|
||||
|
||||
// for i := 0; i < len(*products); i++ {
|
||||
// (*products)[i].Name = fmt.Sprintf("[local] %s", (*products)[i].Name)
|
||||
// }
|
||||
|
||||
c.JSON(
|
||||
http.StatusOK,
|
||||
GetProductsResponse{
|
||||
|
||||
@ -6,7 +6,7 @@ import (
|
||||
|
||||
type configStruct struct {
|
||||
AppHost string `default:"0.0.0.0"`
|
||||
AppPort int `default:"3001"`
|
||||
AppPort int `default:"4001"`
|
||||
DbHost string `default:"localhost"`
|
||||
DbPort int `default:"55432"`
|
||||
DbName string `default:"komponiranje"`
|
||||
|
||||
59
proxy/envoy-local.yaml
Normal file
@ -0,0 +1,59 @@
|
||||
static_resources:
|
||||
listeners:
|
||||
- address:
|
||||
socket_address:
|
||||
address: 127.0.0.1
|
||||
port_value: 10000
|
||||
filter_chains:
|
||||
- filters:
|
||||
- name: envoy.filters.network.http_connection_manager
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
|
||||
codec_type: auto
|
||||
stat_prefix: ingress_http
|
||||
route_config:
|
||||
name: local_route
|
||||
virtual_hosts:
|
||||
- name: backend
|
||||
domains:
|
||||
- "*"
|
||||
routes:
|
||||
- match:
|
||||
prefix: "/machines"
|
||||
route:
|
||||
cluster: machines-app
|
||||
- match:
|
||||
prefix: "/products"
|
||||
route:
|
||||
cluster: products-app
|
||||
http_filters:
|
||||
- name: envoy.filters.http.router
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
|
||||
clusters:
|
||||
- name: machines-app
|
||||
connect_timeout: 0.25s
|
||||
type: strict_dns
|
||||
lb_policy: round_robin
|
||||
load_assignment:
|
||||
cluster_name: machines-app
|
||||
endpoints:
|
||||
- lb_endpoints:
|
||||
- endpoint:
|
||||
address:
|
||||
socket_address:
|
||||
address: 127.0.0.1
|
||||
port_value: 4000
|
||||
- name: products-app
|
||||
connect_timeout: 0.25s
|
||||
type: strict_dns
|
||||
lb_policy: round_robin
|
||||
load_assignment:
|
||||
cluster_name: products-app
|
||||
endpoints:
|
||||
- lb_endpoints:
|
||||
- endpoint:
|
||||
address:
|
||||
socket_address:
|
||||
address: 127.0.0.1
|
||||
port_value: 4001
|
||||
@ -43,7 +43,7 @@ static_resources:
|
||||
address:
|
||||
socket_address:
|
||||
address: machines-app
|
||||
port_value: 3000
|
||||
port_value: 4000
|
||||
- name: products-app
|
||||
connect_timeout: 0.25s
|
||||
type: strict_dns
|
||||
@ -56,10 +56,4 @@ static_resources:
|
||||
address:
|
||||
socket_address:
|
||||
address: products-app
|
||||
port_value: 3000
|
||||
admin:
|
||||
access_log_path: "/dev/null"
|
||||
address:
|
||||
socket_address:
|
||||
address: 0.0.0.0
|
||||
port_value: 800
|
||||
port_value: 4001
|
||||
|
||||