how do I get with confd the key string value generate with etcd - service-discovery

I am using confd and etcd. I am following the confd example for nginx. I put these keys in my etcd service:
curl http://127.0.0.1:4001/v2/keys/myapp/upstream -XPUT -d dir=true
curl http://127.0.0.1:4001/v2/keys/myapp/subdomain -XPUT -d value="myapp"
curl http://127.0.0.1:4001/v2/keys/myapp/upstream/app2 -XPUT -d value="10.0.1.101:80"
curl http://127.0.0.1:4001/v2/keys/myapp/upstream/app1 -XPUT -d value="10.0.1.100:80"
It is my toml configuration:
[template]
prefix = "myapp"
keys = [
"subdomain",
"upstream",
]
owner = "nginx"
mode = "0644"
src = "nginx.tmpl"
dest = "/tmp/myapp.conf"
check_cmd = "/usr/sbin/nginx -t -c {{ .src }}"
reload_cmd = "/usr/sbin/service nginx reload"
And it is my tmpl configuration.
upstream {{.subdomain}} {
{{range $server := .upstream}}
#I want to get the key string value
server {{$sever.key}} {{$server.Value}};
{{end}}
}
server {
server_name {{.subdomain}}.example.com;
location / {
proxy_pass http://{{.subdomain}};
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Here I want to catch the key string value like app2 or app1. I am only know how to get its values. I want to do something like this {{$sever.key}} but it doesn't work. The configuration above {{$sever.key}} is wrong but I did it to show what do I want.
Is this idea possible?
Is there any reserverd word for that or syntax?

I had the same problem. For me this code worked (adopted to your config):
{{range gets "/myapp/upstream/*"}}
server {{base .Key}} {{.Value}}
{{end}}
For me the main problem was the gets function. All examples I found on the net used getvs, which only provides the values. The base functions, just removes the first parts of the path of your key.
For further information, take a look at these confd docs.

Related

Why is nginx duplicating the folder in the path

I am trying to configure Adminer with Nginx. This is my adminer.conf:
server {
listen 80;
location /adminer {
root /usr/share/webapps/adminer;
index index.php;
}
}
However, when I go to localhost/adminer I get the error /usr/share/webapps/adminer/adminer/index.php is not found (No such file or directory).
The adminer folder is duplicated and I don't know why. The location should resolve to /usr/share/webapps/adminer/index.php.
The location should just be
/ from /usr/share/webapps/adminer for localhost
/adminer from /usr/share/webapps for localhost/adminer
server {
listen 80;
location /adminer {
root /usr/share/webapps/;
index index.php;
}
}

Nginx reverse proxy to node.js not working

I have an angular and node app with Postgres as the db. I am deploying them to docker containers on ec2 instance. The Nginx reverse proxy on ec2 is not routing requests to node. The same setup works on my local machine. The error message I receive is: "XMLHttpRequest cannot load http://localhost:3000/api/user/login due to access control checks". Here is my docker-compose file:
version: '3.3'
networks:
network1:
services:
api-service:
image: backend
environment:
PORT: 3000
volumes:
- ./volumes/logs:/app/logs
ports:
- 3000:3000
restart: always
networks:
- network1
nginx:
image: frontend
environment:
USE_SSL: "false"
volumes:
- ./volumes/logs/nginx:/var/log/nginx/
- ./volumes/ssl/nginx:/etc/ssl/
ports:
- 80:80
- 443:443
restart: always
networks:
- network1
and my Nginx.conf is as follows:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 80;
location / {
root /myapp/app;
try_files $uri $uri/ /index.html;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_set_header Host $host;
}
location /api/ {
proxy_pass http://api-service:3000;
}
}
}
and my api url for backend is : (the commented lines are all what I have tried)
export const environment = {
production: false,
//apiUrl: 'http://api-service'
// apiUrl: '/api-service/api'
// apiUrl : 'http://' + window.location.hostname + ':3000'
//apiUrl: 'http://localhost:3000/api'
apiUrl: 'http://localhost:3000'
};
and in my angular service I am using:
const BACKEND_URL = environment.apiUrl + "/api/user/";
and in my backend app.js:
app.use("/api/user/", userRoutes);
What am I doing wrong?
Posting what worked for me in case it helps someone. Here is what worked when I moved my code to ec2 instance:
export const environment = {
production: false,
//apiUrl: 'http://localhost:3000/api'
apiUrl: '/api'
};
So, in localhost apiUrl: 'http://localhost:3000/api works but it does not work on server.

How to use a HELM-3 value a multi-line string

I'm having an nginx ConfigMap yaml file which is then mounted as nginx.conf. This config map contains the config in a multiline string starting like the following:
data:
nginx.conf: |
worker_processes auto;
pid /tmp/nginx.pid;
:
and in this multiline string I'd like to inject a value from the values.yaml like for example:
data:
nginx.conf: |
worker_processes auto;
pid /tmp/nginx.pid;
:
:
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log /var/log/nginx/access.log {{ .Values.nginx.log.format | default "combined" | quote }};
error_log /var/log/nginx/error.log;
:
but using the syntax above I'm getting an unexpected EOF error. Any way/work-around to get this done?
Well, I would suggest you to avoid doing this. Instead, you can create a folder such as configuration, sibling to your template folder and create a file named nginx.conf in it with your entire string content which of course can have required placeholders. Then, in configMap definition, you can call your file like this
data:
{{ (.Files.Glob "configuration/nginx.conf").AsConfig | indent 2 }}
This would create your configmap

Setting up nginx with multiple IPs

I have my nginx configuration file under /etc/nginx/sites-available/ with two upstreams say
upstream test1 {
server 1.1.1.1:50;
server 1.1.1.2:50;
}
upstream test2 {
server 2.2.2.1:60;
server 2.2.2.2:60;
}
server {
location / {
proxy_pass http://test1;
}
location / {
proxy_pass http://test2;
}
}
Sending a curl request to <PrimaryIP>:80 works but I want to use <SecondaryIP1>:80 for test1 and <SecondaryIP2>:80 for test2. Is it possible to define this in nginx?
You have to have two server directives to accomplish this task:
upstream test1 {
server 1.1.1.1:50;
server 1.1.1.2:50;
}
upstream test2 {
server 2.2.2.1:60;
server 2.2.2.2:60;
}
server {
listen 80
server_name <SecondartIP1>
location / {
proxy_pass http://test1;
}
}
server {
listen 80
server_name <SecondarIP2>
location / {
proxy_pass http://test2;
}
}

Nginx redirect to external port

Have config looking something like this.
I now want the main entry to domain to be :80.
So its only nginx that can redirect to :3000 and :8081.
If the user types domain.com:3000 -> i want it to be redirected to domain.com:80.
Is that possible and still have the functionality below, whith redirection based on cookie?
map $cookie_version $mybackend {
default "127.0.0.1:3000";
"v1" "127.0.0.1:8080";
"v2" "127.0.0.1:3000";
}
...
location / {
proxy_pass http://$mybackend;
}
...
location ~ ^/(?<cver>v[12])/ {
...
add_header Set-Cookie "version=$cver;Domain=localhost;Path=/";
rewrite ^/v[12]/(.*)$ /$1 redirect;
}

Resources