I'm trying to deploy a pod to kubernetes using my node app and an nginx proxy server which should also serve my asset files.
I'm using two containers inside one pod for that. Below code runs the application correctly but asset files are not being served by nginx.
Below is my front-end-deployment.yaml files which takes care of creating the deployment for me. I'm wondering why nginx by this configurations doesn't not serve the static files?
apiVersion: v1
kind: ConfigMap
metadata:
name: mc3-nginx-conf
data:
nginx.conf: |
user nginx;
worker_processes 3;
error_log /var/log/nginx/error.log;
events {
worker_connections 10240;
}
http {
log_format main
'remote_addr:$remote_addr\t'
'time_local:$time_local\t'
'method:$request_method\t'
'uri:$request_uri\t'
'host:$host\t'
'status:$status\t'
'bytes_sent:$body_bytes_sent\t'
'referer:$http_referer\t'
'useragent:$http_user_agent\t'
'forwardedfor:$http_x_forwarded_for\t'
'request_time:$request_time';
access_log /var/log/nginx/access.log main;
upstream webapp {
server 127.0.0.1:3000;
}
server {
listen 80;
root /var/www/html;
location / {
proxy_pass http://webapp;
proxy_redirect off;
}
}
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 3
selector:
matchLabels:
component: web
template:
metadata:
labels:
component: web
spec:
volumes:
- name: nginx-proxy-config
configMap:
name: mc3-nginx-conf
- name: shared-data
emptyDir: {}
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: nginx-proxy-config
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
- name: shared-data
mountPath: /var/www/html
- name: frontend
image: sepehraliakbari/rtlnl-frontend:latest
volumeMounts:
- name: shared-data
mountPath: /var/www/html
lifecycle:
postStart:
exec:
command: ['/bin/sh', '-c', 'cp -r /app/build/client/. /var/www/html']
ports:
- containerPort: 3000
Related
I am using docker and trying to access api folder url with Javascript. My api folder is located in same folder as my template. How can I access api folder with Javascript?
I have tried this and this returns http://localhost:8000/api/api.php
const API_URL = window.location.origin + '/api/api.php';
My fetch function
$('#input').on('input', function (e) {
fetch(API_URL)
.then((response) => {
if (response.ok) {
console.log(response);
return response.json();
}
})
.then((data) => {
console.log(data);
});
});
console says as I am trying to fetch API_URL
GET http://localhost:8000/api/api.php 404 (Not Found)
Folder structure
--project-assets
|--templatefolder
| |--dist
| |--scripts
| \--main.js
|
\--api
\--api.php
docker-compose.yaml
version: '3.6'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: ${THEME_NAME}_wp
MYSQL_USER: ${THEME_NAME}
MYSQL_PASSWORD: ${THEME_NAME}
networks:
- wordpress
phpmyadmin:
depends_on:
- db
image: phpmyadmin/phpmyadmin
restart: always
ports:
- 8080:80
volumes:
- ./wp-content:/var/www/html/wp-content/
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: root
UPLOAD_LIMIT: 300M
networks:
- wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- 8000:80
restart: always
volumes:
- ./project-assets/${THEME_NAME}:/var/www/html/wp-content/themes/${THEME_NAME}
- ./project-assets/plugins:/var/www/html/wp-content/plugins
- ./project-assets/uploads:/var/www/html/wp-content/uploads
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: ${THEME_NAME}
WORDPRESS_DB_PASSWORD: ${THEME_NAME}
WORDPRESS_DB_NAME: ${THEME_NAME}_wp
WORDPRESS_DB_CHARSET: utf8mb4
WORDPRESS_CONFIG_EXTRA: |
define('WP_DEBUG_DISPLAY', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG', true);
define('FS_METHOD', 'direct');
define('WP_MEMORY_LIMIT', '256M');
define('WP_HOME','http://localhost:8000');
define('WP_SITEURL','http://localhost:8000');
ports:
- 8000:80
networks:
- wordpress
networks:
wordpress:
name: ${THEME_NAME}
volumes:
db_data:
So 2 things I had so change
Added this to volumes in docker-compose file
- ./project-assets/search-api:/var/www/html/wp-content/search-api
and changed the API_URL
const API_URL = window.location.origin + '/wp-content/api/api.php';
Have a problem with url middleware and prestashop integration. Everything works fine locally, but after moving the frontend (vsf/nuxt) and backends(prestashop) into docker containers the frontend cannot communicate with the prestashop API.
middleware.config.js
module.exports = {
integrations: {
prestashop: {
location: '#vue-storefront/prestashop-api/server',
configuration: {
api: {
url: 'http://lgm-prestashop'
}
}
}
}
};
docker-compose file:
version: '3.9'
services:
lgm-front:
build: .
container_name: lgm-front
ports:
- 3010:3000
networks:
- lgm-prestashop
depends_on:
- lgm-prestashop
volumes:
- ./packages:/var/www/prestashop/packages
command: yarn dev
lgm-prestashop:
image: prestashop/prestashop:1.7
container_name: lgm-prestashop
environment:
- PS_HANDLE_DYNAMIC_DOMAIN=1
- DB_SERVER=lgm-mysql
- PS_FOLDER_ADMIN=lagom-admin
- PS_FOLDER_INSTALL=lagom-install
ports:
- 8081:80
networks:
- lgm-prestashop
lgm-mysql:
image: mysql:8
container_name: lgm-prestashop-db
command: --default-authentication-plugin=mysql_native_password
environment:
- MYSQL_DATABASE=prestashop
- MYSQL_ROOT_PASSWORD=prestashop
# ports:
# - 3316:3306
networks:
- lgm-prestashop
lgm-phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- 3011:3000
environment:
- PMA_HOST=lgm-mysql
- VIRTUAL_HOST=phpmyadmin.presta.local
container_name: lgm-presta_phpmyadmin
networks:
lgm-prestashop:
I try to connect to mongoDB through docker-compose but i get the same error over and over again although i tried all the solutions from the net. Thank you.
I have my docker-compose.yml as
# Use root/example as user/password credentials
version: '3.1'
services:
mongo:
image: mongo
restart: always
container_name: mongo
ports:
- 27017:27017
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
MONGO_INITDB_DATABASE: test
MONGO_USERNAME: admin
MONGO_PASSWORD: example
volumes:
- ./data:/data/db
- ./mongo-entrypoint.sh:/docker-entrypoint-initdb.d/mongo-init.sh:ro
command: mongod
mongo-express:
image: mongo-express
restart: always
ports:
- 8081:8081
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: example
And I have such a shell script
mongo -- "$MONGO_INITDB_DATABASE" <<EOF
db.createUser({
user: "$MONGO_USERNAME",
pwd: "$MONGO_PASSWORD",
roles: [
{ role: 'readWrite', db: "$MONGO_INITDB_DATABASE" }
]
})
EOF
And I try to connect to database by:
mongoose
.connect("mongodb://admin:example#localhost:27017/test")
.then(() => console.log("connected"))
.catch((e) => console.log("error:", e));
In Linux my friend can connect with the same code pieces but I am getting this error :
running on 3000
error: MongoError: Authentication failed.
at MessageStream.messageHandler (C:\Users\kamad\Desktop\3-2\cs308\proje\backend\node_modules\mongodb\lib\cmap\connection.js:268:20)
at MessageStream.emit (events.js:315:20)
at processIncomingData (C:\Users\kamad\Desktop\3-2\cs308\proje\backend\node_modules\mongodb\lib\cmap\message_stream.js:144:12)
at MessageStream._write (C:\Users\kamad\Desktop\3-2\cs308\proje\backend\node_modules\mongodb\lib\cmap\message_stream.js:42:5)
at writeOrBuffer (internal/streams/writable.js:358:12)
at MessageStream.Writable.write (internal/streams/writable.js:303:10)
at Socket.ondata (internal/streams/readable.js:719:22)
at Socket.emit (events.js:315:20)
at addChunk (internal/streams/readable.js:309:12)
at readableAddChunk (internal/streams/readable.js:284:9)
at Socket.Readable.push (internal/streams/readable.js:223:10)
at TCP.onStreamRead (internal/stream_base_commons.js:188:23) {
ok: 0,
code: 18,
codeName: 'AuthenticationFailed'
}
I solved this just by changing the port from 27017 to 27018. Unfortunately, another app of mine was using that port.
There is my solved used :
docker-compose -f stack.yml up --build --force-recreate --renew-anon-volumes -d
stack.yml :
version: "3.5"
services:
mongo:
image: mongo:latest
container_name: mongo
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: admin
ports:
- "0.0.0.0:27017:27017"
networks:
- MONGO
volumes:
- MONGO_DATA:/Users/lirui/docker/data/mongo/db
- MONGO_CONFIG:/Users/lirui/docker/data/mongo/configdb
mongo-express:
image: mongo-express:latest
container_name: mongo-express
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: admin
ME_CONFIG_MONGODB_ADMINPASSWORD: admin
ME_CONFIG_MONGODB_SERVER: mongo
ME_CONFIG_MONGODB_PORT: "27017"
ports:
- "0.0.0.0:8088:8081"
networks:
- MONGO
depends_on:
- mongo
networks:
MONGO:
name: MONGO
volumes:
MONGO_DATA:
name: MONGO_DATA
MONGO_CONFIG:
name: MONGO_CONFIG
Replace path with your compute absolute path.
And DO NOT use 'root' to authentication.
use mongosh
shell script can use:
mongosh --port 27017 --authenticationDatabase -u "$MONGO_INITDB_ROOT_USERNAME" -p "$MONGO_INITDB_ROOT_PASSWORD" <<EOF
use admin
db.createUser({
user: process.env.MONGO_USERNAME ,
pwd: process.env.MONGO_PASSWORD ,
roles: [{
role: 'readWrite',
db: process.env.MONGO_INITDB_DATABASE }]
})
EOF
I am trying to make OpenTelemetry exporter to work with OpenTelemetry collector.
I found this OpenTelemetry collector demo.
So I copied these four config files
docker-compose.yml (In my app, I removed generators part and prometheus which I currently having issue running)
otel-agent-config.yaml
otel-collector-config.yaml
.env
to my app.
Also based on these two demos in open-telemetry/opentelemetry-js repo:
Traces in Web demo
Traces in Node - GRPC demo
I came up with my version (sorry for a bit long, really hard to set up a minimum working version due to the lack of docs):
.env
OTELCOL_IMG=otel/opentelemetry-collector-dev:latest
OTELCOL_ARGS=
docker-compose.yml
version: '3.7'
services:
# Jaeger
jaeger-all-in-one:
image: jaegertracing/all-in-one:latest
ports:
- "16686:16686"
- "14268"
- "14250"
# Zipkin
zipkin-all-in-one:
image: openzipkin/zipkin:latest
ports:
- "9411:9411"
# Collector
otel-collector:
image: ${OTELCOL_IMG}
command: ["--config=/etc/otel-collector-config.yaml", "${OTELCOL_ARGS}"]
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
ports:
- "1888:1888" # pprof extension
- "8888:8888" # Prometheus metrics exposed by the collector
- "8889:8889" # Prometheus exporter metrics
- "13133:13133" # health_check extension
- "55678" # OpenCensus receiver
- "55680:55679" # zpages extension
depends_on:
- jaeger-all-in-one
- zipkin-all-in-one
# Agent
otel-agent:
image: ${OTELCOL_IMG}
command: ["--config=/etc/otel-agent-config.yaml", "${OTELCOL_ARGS}"]
volumes:
- ./otel-agent-config.yaml:/etc/otel-agent-config.yaml
ports:
- "1777:1777" # pprof extension
- "8887:8888" # Prometheus metrics exposed by the agent
- "14268" # Jaeger receiver
- "55678" # OpenCensus receiver
- "55679:55679" # zpages extension
- "13133" # health_check
depends_on:
- otel-collector
otel-agent-config.yaml
receivers:
opencensus:
zipkin:
endpoint: :9411
jaeger:
protocols:
thrift_http:
exporters:
opencensus:
endpoint: "otel-collector:55678"
insecure: true
logging:
loglevel: debug
processors:
batch:
queued_retry:
extensions:
pprof:
endpoint: :1777
zpages:
endpoint: :55679
health_check:
service:
extensions: [health_check, pprof, zpages]
pipelines:
traces:
receivers: [opencensus, jaeger, zipkin]
processors: [batch, queued_retry]
exporters: [opencensus, logging]
metrics:
receivers: [opencensus]
processors: [batch]
exporters: [logging,opencensus]
otel-collector-config.yaml
receivers:
opencensus:
exporters:
prometheus:
endpoint: "0.0.0.0:8889"
namespace: promexample
const_labels:
label1: value1
logging:
zipkin:
endpoint: "http://zipkin-all-in-one:9411/api/v2/spans"
format: proto
jaeger:
endpoint: jaeger-all-in-one:14250
insecure: true
processors:
batch:
queued_retry:
extensions:
health_check:
pprof:
endpoint: :1888
zpages:
endpoint: :55679
service:
extensions: [pprof, zpages, health_check]
pipelines:
traces:
receivers: [opencensus]
processors: [batch, queued_retry]
exporters: [logging, zipkin, jaeger]
metrics:
receivers: [opencensus]
processors: [batch]
exporters: [logging]
After running docker-compose up -d, I can open Jaeger (http://localhost:16686) and Zipkin UI (http://localhost:9411).
And my ConsoleSpanExporter works in both web client and Express.js server.
However, I tried this OpenTelemetry exporter code in both client and server, I am still having issue to connect OpenTelemetry collector.
Please see my comment about URL inside of the code
import { CollectorTraceExporter } from '#opentelemetry/exporter-collector';
// ...
tracerProvider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
tracerProvider.addSpanProcessor(
new SimpleSpanProcessor(
new CollectorTraceExporter({
serviceName: 'my-service',
// url: 'http://localhost:55680/v1/trace', // Return error 404.
// url: 'http://localhost:55681/v1/trace', // No response, not exists.
// url: 'http://localhost:14268/v1/trace', // No response, not exists.
})
)
);
Any idea? Thanks
The demo you tried is using older configuration and opencensus which should be replaced with otlp receiver. Having said that this is a working example
https://github.com/open-telemetry/opentelemetry-js/tree/master/examples/collector-exporter-node/docker
So I'm copying the files from there:
docker-compose.yaml
version: "3"
services:
# Collector
collector:
image: otel/opentelemetry-collector:latest
command: ["--config=/conf/collector-config.yaml", "--log-level=DEBUG"]
volumes:
- ./collector-config.yaml:/conf/collector-config.yaml
ports:
- "9464:9464"
- "55680:55680"
- "55681:55681"
depends_on:
- zipkin-all-in-one
# Zipkin
zipkin-all-in-one:
image: openzipkin/zipkin:latest
ports:
- "9411:9411"
# Prometheus
prometheus:
container_name: prometheus
image: prom/prometheus:latest
volumes:
- ./prometheus.yaml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
collector-config.yaml
receivers:
otlp:
protocols:
grpc:
http:
exporters:
zipkin:
endpoint: "http://zipkin-all-in-one:9411/api/v2/spans"
prometheus:
endpoint: "0.0.0.0:9464"
processors:
batch:
queued_retry:
service:
pipelines:
traces:
receivers: [otlp]
exporters: [zipkin]
processors: [batch, queued_retry]
metrics:
receivers: [otlp]
exporters: [prometheus]
processors: [batch, queued_retry]
prometheus.yaml
global:
scrape_interval: 15s # Default is every 1 minute.
scrape_configs:
- job_name: 'collector'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['collector:9464']
This should work fine with opentelemetry-js ver. 0.10.2
Default port for traces is 55680 and for metrics 55681
The link I posted previously - you will always find there the latest up to date working example:
https://github.com/open-telemetry/opentelemetry-js/tree/master/examples/collector-exporter-node
And for web example you can use the same docker and see all working examples here:
https://github.com/open-telemetry/opentelemetry-js/tree/master/examples/tracer-web/
Thank you sooo much for #BObecny's help! This is a complement of #BObecny's answer.
Since I am more interested in integrating with Jaeger. So here is the config to set up with all Jaeger, Zipkin, Prometheus. And now it works on both front end and back end.
First both front end and back end use same exporter code:
import { CollectorTraceExporter } from '#opentelemetry/exporter-collector';
new SimpleSpanProcessor(
new CollectorTraceExporter({
serviceName: 'my-service',
})
)
docker-compose.yaml
version: "3"
services:
# Collector
collector:
image: otel/opentelemetry-collector:latest
command: ["--config=/conf/collector-config.yaml", "--log-level=DEBUG"]
volumes:
- ./collector-config.yaml:/conf/collector-config.yaml
ports:
- "9464:9464"
- "55680:55680"
- "55681:55681"
depends_on:
- jaeger-all-in-one
- zipkin-all-in-one
# Jaeger
jaeger-all-in-one:
image: jaegertracing/all-in-one:latest
ports:
- "16686:16686"
- "14268"
- "14250"
# Zipkin
zipkin-all-in-one:
image: openzipkin/zipkin:latest
ports:
- "9411:9411"
# Prometheus
prometheus:
container_name: prometheus
image: prom/prometheus:latest
volumes:
- ./prometheus.yaml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
collector-config.yaml
receivers:
otlp:
protocols:
grpc:
http:
exporters:
jaeger:
endpoint: jaeger-all-in-one:14250
insecure: true
zipkin:
endpoint: "http://zipkin-all-in-one:9411/api/v2/spans"
prometheus:
endpoint: "0.0.0.0:9464"
processors:
batch:
queued_retry:
service:
pipelines:
traces:
receivers: [otlp]
exporters: [zipkin]
processors: [batch, queued_retry]
metrics:
receivers: [otlp]
exporters: [prometheus]
processors: [batch, queued_retry]
prometheus.yaml
global:
scrape_interval: 15s # Default is every 1 minute.
scrape_configs:
- job_name: 'collector'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['collector:9464']
I have a small microservice written in typescript running in a kubernetes cluster on AKS.
I have ingress generated using Helm
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-service
labels:
app: test-service
chart: test-service-0.1.0
release: test-service
heritage: Tiller
annotations:
ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
spec:
tls:
- hosts:
- test.xyz
secretName: default-tls
rules:
- host: test.xyz
http:
paths:
- path: /payments
backend:
serviceName: test-service
servicePort: 4040
And the service
apiVersion: v1
kind: Service
metadata:
name: existing-bumblebee-payments-service
labels:
app: test-service
chart: test-service-0.1.0
release: existing-bumblebee
heritage: Tiller
spec:
type: ClusterIP
ports:
- port: 4040
targetPort: 4040
protocol: TCP
selector:
app: test-service
release: existing-bumblebee
And in my microservice
export class Server {
private registerRoutes() {
this.app.use("/cards", CardRouter);
this.app.use("/wallets", WalletRouter);
this.app.use("/preauth", PreauthRouter);
this.app.use("/charge", ChargeRouter);
}
}
The routers look like this;
import { Router } from "express";
// other imports
import { checkSchema, check } from "express-validator/check";
const router = Router();
router.get("/", CardController.index);
router.get("/:id", [
check("id")
.isUUID()
.withMessage("Invalid UUID")
], CardController.get);
router.delete("/:id", [
check("id")
.isUUID()
.withMessage("Invalid UUID")
], CardController.remove);
router.post("/", checkSchema(CardCreateRules), CardController.add);
export default router;
But accessing the service via https://test.xyz/payments/cards results in a 404 error from express
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /payments/cards</pre>
</body>
</html>
I can tell the response is from the express server cause it has custom response headers set by the server.
I'm really confused as to what is wrong, any help will be appreciated.
It does not work for you because your ingress just redirects request https://test.xyz/payments/cards to test-service without rewriting the path. So test service still becomes request "/payments/cards" and obviously can not handle them.
You can either reconfigure express application to support /payments/cards or do the path rewrite via ingess 'nginx.ingress.kubernetes.io/rewrite-target' annotation:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-service
labels:
app: test-service
chart: test-service-0.1.0
release: test-service
heritage: Tiller
annotations:
ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/rewrite-target: /payments
spec:
tls:
- hosts:
- test.xyz
secretName: default-tls
rules:
- host: test.xyz
http:
paths:
- path: /
backend:
serviceName: test-service
servicePort: 4040