I have a stack Django+Gunicorn+nginx running in docker containers. It is accessible from outside by domain and Port, like web.example.com:1300 . Also, there is Nginx Proxy Manager (NPM) running (uses ports 80 and 443) and succesfully managing some other resources (for example nextcloud). But it doesn't proxy to my django project at port 1300, shows "502 Bad Gateway".
In the Proxy Hosts of NPM I've added config:
domain names: web.example.com
Forward Hostname / IP: nginx_docker_container_name (this way it works with other resources)
Forward Port: 1300
Other settings: tried multiple combinations without success (like with and without SSL certificates etc.)
Is it possible to proxy using NPM?
Sorry if I missed to write some information, actually I do not know what else to state.
I managed to solve the problem myself.
So, nginx in docker container serves web-site with static pages. Nginx proxy manager proxying htpp protocol to nginx and secures communication (and also works from docker container in my set-up).
My mistake was that I didn't connect those docker containers by virtual network.
Ones I put them into one network - everything works.
Then I unpublished nginx port (1300).
NPM proxy settings are "standard", e.g. no "custom location" and nothing in "Advanced" tab. Just "Forward Hostname / IP" is docker container tag and "Forward Port" is nginx port it listens to (80 by default).
With WhiteNoise , you don't need to configure nginx for django static files
❤️❤️❤️
Related
I have Django hosted with Nginx on DigitalOcean. Now I want to install Plausible Analytics. How do I do this? How do I change the Nginx config to get to the Plausible dashboard with mydomain/plausible for example?
Setup plausible by either running the software directly or in a docker container - let's say it runs on port 8080
Then in your nginx.conf - you should have a server block for your domain
Within that add a location block with the path you want plausible on and add a proxy pass directive to forward the requests to localhost:8080
Monitor access.log and error.log to debug any issues that may happen
I'm hoping for some general feedback on my approach to trying to get a multi-container app up on Elastic Beanstalk via docker-compose (choosing "docker running on 64bit amazon linux 2" as the platform). Two main questions:
`
Am I right that Elastic Beanstalk listens on port 80 by default when we use docker-compose, and so we need to treat port 80 as the entry point to our application? (reasons for thinking so below)
I'm using an nginx container (listening on port 80 of the host machine) to route traffic to my front end container (which talks to a back end container). Is that approach approach to getting multiple containers running on EB valid? Or is there some other much more common/straighforward way of doing this, with docker-compose? (Something like, "yes! that's a valid way to do this," or "no, you are going about this the totally wrong way, go in this other direction" would be helpful)
Why Elastic Beanstalk instead of ECS? I'm just trying to understand the basic functionality of Elastic Beanstalk first.
More context:
I have three containers: 1) a react front end, 2) an express back end, and 3) an nginx proxy. Why did I add nginx? Because it's my understanding that Elastic Beanstalk sets the proxy server configuration to none when you use docker-compose (see here, under "Environments with Docker Compose"), so what we have to do is get nginx to listen on the default point of entry for an Elastic Beanstalk app, port 80, and then forward requests to other containers on the bridge network created by docker-compose. In other words, when you go to the link associated with an EB app, it will default to whatever is listening on port 80. And if that's an Nginx server, you will be routed according to the configuration of the Nginx server.
I'll paste my docker-compose.yml file below, along with my nginx Dockerfile and its default.conf file. At this point, it mostly runs on my local machine (I can get to the front and back end directly on their respective ports), but I still get an error Invalid Host header when I go to localhost:80/, where I should be proxied (by Nginx) to the React app homepage. Any errors noticed would be helpful. But I'm not necessarily looking for a solution to that specific problem. Rather, my main two questions are up above, looking for some confirmation/correction about my general approach.
Thank you!
docker-compose.yml
version: "3"
services:
nginx:
image: mfatigati/shop-proxy
ports:
- "80:80"
depends_on:
- client
server:
image: mfatigati/shop-server-amd
container_name: shop-server
ports:
- "4001:4000"
client:
image: mfatigati/shop-client-amd
container_name: shop-client
depends_on:
- server
ports:
- "3001:3000"
Dockerfile for nginx
FROM nginx
EXPOSE 80
RUN rm -r /usr/share/nginx/html*
COPY configs/default.conf /etc/nginx/conf.d/default.conf
CMD ["nginx", "-g", "daemon off;"]
default.conf for nginx
upstream shop-client {
server shop-client:3001;
}
server {
listen 80;
location / {
proxy_pass http://shop-client;
}
}
I think it might be fine. I have a similar approach on ecs. However, you will need to use nginx to serve as a reverse proxy otherwise you will run into CORS issues as soon as you run it anywhere else then on localhost.
On ecs you have options to run all containers in the same pod or in different ones. If you choose the latter (for better scalabilty, amongst other reasons), you will need to set up discovery service as well.
On Beanstalk there might be options I do not know about, but at least using nginx should be fine.
You can set beanstalk to different ports if you want, but for reverse proxy you will still need something, so I'd just leave it at 80.
EDIT: addition on reverse proxy:
The problem to solve is CORS issues you encounter.
The directive upstream is used for loadbalancing/routing. (see this question and it's answers)
To the general mechanism is to have several locations in your nginx conf that point specific requests to other servers. This way the requests can be done to the same origin (domain, port, scheme), and then nginx will forward it to the servers who then can happily reply.
Something like:
server {
listen 80;
listen [::]:80;
server_name my-app.com;
location /api/ {
proxy_pass http://api-service:8080;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
You can have as many locations as necessary. This is very basic, and you might want to look into some other features, but this should be the basic setup.
I am currently running into an issue with one of my projects that will be running in Docker on my Ubuntu Server with a NGINX docker container to manage the reverse proxy for the Django Project. My issue I am running into is I already have previous Django projects running on that particular Ubuntu server so port 80 is already being used by a NGINX block running on the actual server.
Is there a workaround to running my Docker NGINX as well as the Ubuntu NGINX and have my docker image run as a "add on" site because the Django sites hosted there are clients websites, so I would prefer to not interfere with them if I dont have to.
My project needs HTTPS because it is serving data to a React-Native app running on Android APK 28 which for some reason has a security rule that blocks non HTTPS connections from happening in the app. If anyone else has run into an issue like this I would gladly appreciate the advice on how to tackle this issue.
I have tried running NGINX in Docker with port 81 instead of port 80 and that works perfectly, but I dont think there is a way to make a secure connection to port 81 is there?
Thanks in advance.
You can't just mess with default HTTP ports for endpoints - user browsers use 80 and 443 by default. If you change those, your users would have to connect to your.server.com:81 or something similar. Nobody would do that for a public server, but this can be an option for a private one.
I think a reasonable way out of this will be to use host's NGINX to proxy requests into Docker's NGINX (if there is sense in keeping it at all). You can handle HTTPS termination on host's NGINX and pass plain HTTP into Docker's one.
Another adequate option is to use another server, so that everything works with no dirty hacking involved.
I have setup Jetbrains Upsource and Teamcity on the same EC2 instance for evalution purposes. If I expose each container on port 80 seperately, I can reach it from the outside world. I want to know how to setup nginx so that I can reach each container over a subdomain like eg. "upsource.example.aws.com" and "teamcity.example.aws.com". I exposed the containers on ports 8080 and 8111 to the host. Is it even possible to achieve this ? If so, I dont know how to start. I read on ways to host multiple domains on one machine for a node web app though exposing the static context. But i have no idea how to make it work with the preconfigured docker images.
Can this be achieved via nginx conf file ?
If not, do I have to use two instances or is there another possibility within aws ?
Its possible with nginx. You have to use something called reverse proxy.
You can expose both the containers in different ports and redirect to these with the help of the nginx configuration.
For example if you have some containers running in port 8000 and 8001 in 127.0.0.1 you can redirect like this:
location /1 {
proxy_pass http://127.0.0.1:8000;
}
location /2 {
proxy_pass http://127.0.0.1:8001;
}
Updated Answer
You need to have 3 containers. The nginx server should be running in port 80. The other two containers will host the sites in say port 8000 (upsource.example.aws.com) and port 8111(teamcity.example.aws.com).
Update the configuration file with the location settings as shown above. Make sure that location / forwards to port 8000 and location /teamcity forwards to port 8111 in your host. More details on how to configure nginx is on the docker hub.
Working
When you go to blabla.com the nginx sever forwards it to port 8000 and when you go to blabla.com/teamcity its goes to port 8111.
I bought a domain name using amazon Route 53, created an elastic IP address and attached it to my Amazon EC2 instance running MEAN bitnami stack, then I created an S3 bucket for static web hosting "redirecting all requests" to the www.domainname.com.
However, when I go to my root domain the page loaded is the Bitnami Congratulations page: You are now running Bitnami MEAN 3.2.11-0 in the Cloud. I created a folder, uploaded my MEAN angular 2/express app and did node server.js and I can only access my web app on mydomain.com:8080 but anything else redirects to the Bitnami congratulations page. Which setting is it that is doing this? Is it an amazon setting? A Bitnami setting? or something in my server side code.
The only place I mention 8080 in my server code is here and it prints API running on 8080 when I run the server:
const port = process.env.PORT || '8080';
app.set('port', port);
const server = http.createServer(app);
server.listen(port, () => console.log(`API running on: ${port}` + ' or ' + process.env.PORT));
You have Apache running on your MEAN Stack. Apache is running on port 80/443 and, therefore, whenever you access your domain at port 80, Apache handle the request and shows you the "Bitnami Welcome Page".
In order to make your Angular/express application available at port 80 you need to configure Apache to redirect the requests to port 3000 (or port 8080, basically the port where your Express application is running). You could add under <VirtualHost _default_:80> and <VirtualHost _default_:443> sections in the file /opt/bitnami/apache2/conf/bitnami/bitnami.conf the line below:
ProxyPass /bitnami !
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
After that, you will need to restart Apache running:
sudo /opt/bitnami/ctlscript.sh restart apache
You can find more information at:
https://docs.bitnami.com/aws/infrastructure/mean/
Bitnami by default launches with an http config here: root/opt/apache2/conf/httpd.conf. The apache2 server pointed at a root directory containing html with an index.html that contains its Congratulations page. Using sudo /opt/bitnami/ctlscript.sh stop killed this server and all other services it had running by default on startup so when I type node server.js all traffic now goes to my Angular 2 app.
Use NGINX to reverse proxy all trafic from http://www.domainname.com to address where your node server is running ( http://localhost:8080).
Here is the sample NGINX configuration for such a use case.
To install NGINX follow one of tutorials on digitalocean.com depending upon your server OS.