How to configure IPython behind nginx in a subpath? - nginx

I've got nginx running handling all SSL stuff and already proxying / to a Redmine instance and /ci to a Jenkins instance.
Now I want to serve an IPython instance on /ipython through that very same nginx.
In nginx.conf I've added:
http {
...
upstream ipython_server {
server 127.0.0.1:5001;
}
server {
listen 443 ssl default_server;
... # all SSL related stuff and the other proxy configs (Redmine+Jenkins)
location /ipython {
proxy_pass http://ipython_server;
}
}
}
In my .ipython/profile_nbserver/ipython_notebook_config.py I've got:
c.NotebookApp.base_project_url = '/ipython/'
c.NotebookApp.base_kernel_url = '/ipython/'
c.NotebookApp.port = 5001
c.NotebookApp.trust_xheaders = True
c.NotebookApp.webapp_settings = {'static_url_prefix': '/ipython/static/'}
Pointing my browser to https://myserver/ipython gives me the usual index page of all notebooks in the directory I launched IPython.
However, when I try to open one of the existing notebooks or create a new one, I'm getting the error:
WebSocket connection failed: A WebSocket connection to could not be established. You will NOT be able to run code. Check your network connection or notebook server configuration.
I've tried the same setup with the current stable (1.2.1, via pypi) and development (Git checkout of master) version of IPython.
I also tried adjusting the nginx config according to nginx reverse proxy websockets with no avail.
Due to an enforced policy I'm not able to allow connections to the server on other ports than 443.
Does anybody have IPython running behind an nginx?

I had the same problem. I updated nginx up to the current version (1.6.0). It seems to be working now.
Server config:
location /ipython {
proxy_pass http://ipython_server;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Origin "";
}
See: http://nginx.org/en/docs/http/websocket.html

Related

Nginx upstream servers for inside/outside docker-compose

I'd like to have a Nginx proxying a service that could be running inside docker-compose or outside as a simple process.
http {
upstream web {
server web:80; # when running in Docker-Compose
server 127.0.0.1:80; # when running outside
}
server {
listen 80;
location /web/ {
proxy_pass http://web;
proxy_set_header Host $host;
}
}
}
But when trying to run it outside of docker-compose, I get an error that the host web can't be resolved. I know it is a restriction for nginx to be able to resolve the upstream servers and the moment of starting, but is there another way of achieving this?
Thanks
I ended up solving this by using the Dockerhost docker image and replacing the values of the proxy_pass as part of the nginx docker startup command.

How to configure nginx to expose multiple services on Jelastic?

Through Jelastic's dashboard, I created this:
I just clicked "New environment", then I selected nodejs. I added a docker image (of mailhog).
Now, I would like that port 80 of my environment serves the nodejs application. This is by default so. Therefore nothing to do.
In addition to this, I would like port 8080 (or any other port than 80, like port 5000 for example) of my environment serves mailhog, hosted on the docker image. To do that, I added the following lines to the nginx-jelastic.conf (right after the first server serving the nodejs app):
server {
listen *:8080;
listen [::]:8080;
server_name _;
location / {
proxy_pass http://mailhog_upstream;
}
}
where I have also defined mailhog_upstream like this:
upstream mailhog_upstream{
server 10.102.8.215; ### DEFUPPROTO for common ###
sticky path=/; keepalive 100;
}
If I now browse my environment's 8080 port, then I see ... the nodejs app. If I try any other port than 80 or 8080, I see nothing. Putting another server_name doesn't help. I tried several things but nothing seems to work. Why is that? What am I doing wrong here?
Then I tried to get rid of the above mailhog_upstream and instead write
server {
listen *:5000;
listen [::]:5000;
server_name _;
location / {
proxy_pass http://10.102.8.215;
}
}
Browsing the environment's port 5000 doesn't work either.
If I replace the IP of the nodejs' app with that of my mailhog service, then mailhog runs on port 80. I don't understand how I can make the nodejs app run on port 80 and the mailhog service on port 5000 (or any other port than 80).
Could someone enlighten me please?
After all those failures, I tried another ansatz. Assume the path my env is example.com/. What I've tried above is to get mailhog to work upon calling example.com:5000, which I failed doing. Then I tried to make mailhog available through a call to example.com/mailhog. In order to do that, I got rid of all my modifications above and completed the current server in nginx-jelastic.conf with
location /mailhog {
proxy_pass http://10.102.8.96:8025/;
add_header Set-Cookie "SRVGROUP=$group; path=/";
}
That works in the sense that if I know browse example.com/mailhog, then I get something on the page, but not exactly what I want: it's the mailhog's page without any styling. Also, when I call mailhog's API through example.com/mailhog/api/v2/messages, I get a successful response without body, when I should've received
{"total":0,"count":0,"start":0,"items":[]}
What am I doing wrong this time?
Edit
To be more explicit, I put the following manifest that exhibits the second problem with the nginx location.
Full locations list for your case is a following:
(please pay attention to URIs in upstreams, they are different)
location /mailhog { proxy_pass http://172.25.2.128:8025/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection " upgrade"; }
location /mailhog/api { proxy_pass http://172.25.2.128:8025/api; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection " upgrade"; }
location /css { proxy_pass http://172.25.2.128:8025; }
location /js { proxy_pass http://172.25.2.128:8025; }
location /images { proxy_pass http://172.25.2.128:8025; }
that works for me with your application
# curl 172.25.2.127/mailhog/api/v2/messages
{"total":0,"count":0,"start":0,"items":[]}
The following ports are opened by default: 80, 8080, 8686, 8443, 4848, 4949, 7979.
Additional ports can be opened using:
endpoints - maps the container internal port to random external
via Jelastic Shared LB
Public IP - provides a direct access to all ports of your
container
Read more in the following article: "Container configuration - Ports". This one may also be useful:"Public IP vs Shared Load Balancer"

Nginx not working with socket.io on production server

I have a flask-app which is using flask-socketio extension. It works fine on local machine using 'socketio.run()' or 'flask run' dev server. I want to make it work with a nginx proxy, and it works on local machine with this nginx server config:
file /etc/nginx/sites-available/server.conf
server {
listen 8080;
location / {
proxy_pass http://localhost:5000;
}
}
The actual app is running on port 5000 with socketio.run(), which as i heard is also a good production server. The strange thing is that it works even with this message: "WebSocket transport not available. Install eventlet or gevent and gevent-websocket for improved performance." It also works with this warning: "Flask-SocketIO is Running under Werkzeug, WebSocket is not available." (first when i use socketio.run(), second with flask run)
Yet if I try to run the same thing on the production server, only http part works, and sockets don't. As i read everywhere on the Internet I should specify headers Connection and Upgrade in nginx server config which i do not understand why and which i tried too:
file /etc/nginx/sites-available/server.conf
server {
listen 80;
server_name servername.com;
location / {
proxy_pass http://127.0.0.1:5000;
}
location /socket.io/ {
proxy_pass http://127.0.0.1:5000/socket.io;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Result is the same, sockets are not working. Using 'flask run' with any of configs i get these debug messages:
127.0.0.1 - - [04/Feb/2019 20:55:52] "GET /socket.io?EIO=3&transport=polling&t=MYwIxxF HTTP/1.1" 404 -
The indicate not working socketio, yet the server gets it and replyes with 404, which i see no reason for.
My local computer runs Kali linux and nginx 1.13.12, remote is Ubuntu 18.04 with nginx 1.14.0
Right now I really don't understand which configuration is proper, why is the first configuraion working on my local machine and why none of configurations work on production server and how do i interpreter this 404 message. Even though there are several guides on the Internet, it doesn't work with me.
Any help appreciated!
Maybe nginx was unable to match /socket.io/ location to /socket.io?EIO=3&transport=polling&t=MYwIxxF path. Take a look at nginx documentation on location to find out how you can write location matcher that fits your needs.

Jenkins: How to configure Jenkins behind Nginx reverse proxy for JNLP slaves to connect

I am trying to set up a Jenkins master and a Jenkins slave node where the Jenkins Master is behind Nginx reverse proxy on a different server with SSL termination. The nginx configuration is as following:
upstream jenkins {
server <server ip>:8080 fail_timeout=0;
}
server {
listen 443 ssl;
server_name jenkins.mydomain.com;
ssl_certificate /etc/nginx/certs/mydomain.crt;
ssl_certificate_key /etc/nginx/certs/mydomain.key;
location / {
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect http:// https://;
proxy_pass http://jenkins;
}
}
server {
listen 80;
server_name jenkins.mydomain.com;
return 301 https://$server_name$request_uri;
}
The TCP port for JNLP agents is set as 50000 in Jenkins master Global Security configuration. Port 50000 is set to be accessible from anywhere on the host machine.
The JNLP slave is launched with the following command:
java -jar slave.jar -jnlpUrl https://jenkins.mydomain.com/computer/slave-1/slave-agent.jnlp -secret <secret>
The JNLP slave fails to connect to the configured JNLP port on the master:
INFO: Connecting to jenkins.mydomain.com:50000 (retrying:4)
java.net.ConnectException: Connection timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at hudson.remoting.Engine.connect(Engine.java:400)
at hudson.remoting.Engine.run(Engine.java:298)
What is the configuration required for the JNLP slave to connect to the Jenkins master?
The JNLP port seems to use a binary protocol, not a text-based HTTP protocol, so unfortunately it can't be reverse-proxied through NGINX like the normal Jenkins pages can be.
Instead, you should:
Configure Global Security > Check "Enable security" and set a Fixed
"TCP port for JNLP slave agents". This will cause all Jenkins pages
to emit extra HTTP headers specifying this port: X-Hudson-CLI-Port,
X-Jenkins-CLI-Port, X-Jenkins-CLI2-Port.
Allow your fixed TCP JNLP
port through any firewall(s) so CLI clients and JNLP agents can
directly reach the Jenkins server on the backend.
Set the system property hudson.TcpSlaveAgentListener.hostName to the
hostname or IP address of your Jenkins server on the backend. This
will cause all pages to emit an extra HTTP header
(X-Jenkins-CLI-Host) containing this specified hostname. This tells
CLI clients where to connect, but supposedly not JNLP agents.
For each of your build slave machines in the list of nodes at
jenkins.mydomain.com/computer/ that uses the Launch method "Launch slave agents via Java Web Start", click the computer, click Configure, click the Advanced... button on the right side under Launch method, and set the "Tunnel connection through" field appropriately. Read the question mark help. You probably just need the "HOST:" syntax, where HOST is the hostname or IP address of your Jenkins server on the backend.
References:
https://issues.jenkins-ci.org/browse/JENKINS-11982
https://support.cloudbees.com/hc/en-us/articles/218097237-How-to-troubleshoot-JNLP-slaves-connection-issues-with-Jenkins
https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+CLI
It's been almost 4 years since OP has asked this question, nevertheless, if you reached this page and looking for a proper solution, well, it's now possible.
I use Traefik as reverse proxy to Jenkins. TCP port inbound completely disabled now.
The only thing you need to make sure is your agent/slave is trusting Jenkins server certificate (as webSocket cannot be used with -disableHttpsCertValidation or -noCertificateCheck
If this is a Windows agent, use:
C:\Program Files (x86)\Java\jre1.8.0_251\bin\keytool.exe -import -storepass "changeit" -keystore "C:\Program Files (x86)\Java\jre1.8.0_251\lib\security\cacerts" -alias <cert_alias> -file "<path_to_cert>"
(Change path accordingly to your java version)

Config settings for securing Elasticsearch with Nginx

I am running Kibana 1.3 and ElasticSearch 1.4 on the same host and I have installed Nginx in an attempt to keep connections to ES locally. To browse Kibana remotely, I have also registered a dynamic DNS domain name and bind it with the host on which Kibana and ElasticSearch are running on e.g. http://example.no-ip.org.
I think the use of dynamic DNS domain name has caused problems with connectionbetween Kibana and ES and I'm not sure how the configurations should be set so that:
1) only Kibana can communicate with ElasticSearch and on a local-basis
2) ElasticSearch API is not exposed to the world.
The guide I followed is: http://www.elasticsearch.org/blog/playing-http-tricks-nginx/
Here's the config for Nginx:
events {
worker_connections 1024;
}
http {
upstream elasticsearch {
server 127.0.0.1:9200;
server 127.0.0.1:9201;
server 127.0.0.1:9202;
keepalive 15;
}
server {
listen 8080;
location / {
proxy_pass http://elasticsearch;
proxy_http_version 1.1;
proxy_set_header Connection "Keep-Alive";
proxy_set_header Proxy-Connection "Keep-Alive";
}
}
}
And here's the config settings I added in elasticsearch.yml:
network.host: "127.0.0.1"
http.host: "127.0.0.1"
http.cors.allow-origin: "/.*/"
http.cors.enabled: true
As for Kibana, I have changed the default settings to use port 8080:
elasticsearch: "http://" + window.location.hostname + ":8080",
Thank you very much for your help in advance!

Resources