I am attempting to use Docker to help deploy an application. The idea is to have two containers. One is the front-end containing Nginx and an Angular app.
FROM nginx
COPY ./dist/ /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/nginx.conf
It is supposed to contact a Spring Boot based API generated using the gradle-docker plugin and Dockerfile recommended by Spring:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
They seem to run fine individually (I can access them on my development machine); however, I am having trouble connecting the two.
My docker-compose.yml file:
version: '3'
services:
webapp:
image: com.midamcorp/emp_front:latest
ports:
- 80:80
- 443:443
networks:
- app
api:
image: com.midamcorp/employee_search:latest
ports:
- 8080:8080
networks:
- app
networks:
app:
Based upon my understanding of the Docker documentation on networks, I was under the impression that the containers would be placed in the same network and thus could interact, with the service name (for example, api) acting as the "host". Based upon this assumption, I am attempting to access the API from the Angular application through the following:
private ENDPOINT_BASE: string = "http://api:8080/employee";
This returns an error: Http failure response for (unknown url): 0 Unknown Error.
To be honest, the sample I have looked at used this concept (substituting the service name for host to connect two containers) for database applications not HTTP. Is what I am attempting to accomplish not possible?
EDIT:
My nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
location / {
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
}
EDIT:
Updated nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
upstream docker-java {
server api:8080;
}
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 8081;
server_name localhost;
location / {
proxy_pass http://docker-java;
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;
proxy_set_header X-Forwarded-Host $server_name;
}
}
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
location / {
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
}
and docker-compose.yml
version: '3'
services:
webapp:
image: com.midamcorp/emp_front:latest
ports:
- 80:80
- 443:443
networks:
- app
depends_on:
- api
api:
image: com.midamcorp/employee_search:latest
networks:
- app
networks:
app:
And the client / Angular app uses the following to contact the API private ENDPOINT_BASE: string = "http://localhost:8081/employee";
Output from docker ps
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
947eb757eb4b b28217437313 "nginx -g 'daemon of…" 10 minutes ago Up 10 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp employee_service_webapp_1
e16904db67f3 com.midamcorp/employee_search:latest "java -Djava.securit…" 10 minutes ago Up 10 minutes employee_service_api_1
The problem you are experiencing is not anything weird. It's just that you did not explicitly name your containers. Instead, Docker generated a the names by itself. So, nginx will resolve employee_service_api_1, but will not recognize just api. Open you webapp container and take a look at your hosts (cat /etc/hosts) - it will show you employee_service_api_1 and it's IP address.
How to fix it.
Add container_name to your docker-compose.yml:
version: '3'
services:
webapp:
image: com.midamcorp/emp_front:latest
container_name: employee_webapp
ports:
- 80:80
- 443:443
networks:
- app
depends_on:
- api
api:
image: com.midamcorp/employee_search:latest
container_name: employee_api
networks:
- app
networks:
app:
I always refrain from using "simple" names (i.e. just api), cuz on my system multiple containers with similar names might show up, so I add some prefix. In this case I named the api container employee_api and now nginx will resolve to that name once you restart your containers.
Related
I'm using nginx in docker-compose file for handling my frontend and backend website.
I had no problems for a long time but once I've got the error "504 Gateway Time-out" when I try to access my project through localhost and it's port
http://localhost:8080
when I type docker Ip and its port
http://172.18.0.1:8080
I can access the project and nginx works correctly.
I'm sure my config file is correct because It was working for 6 months and I don't know what happened for it.
what should I check to find the problem?
docker-compose file:
.
.
.
nginx:
container_name: nginx
image: nginx:1.19-alpine
restart: unless-stopped
ports:
- '8080:80'
volumes:
- ./frontend:/var/www/html/frontend
- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
networks:
- backend_appx
networks:
backend_appx :
external: true
.
.
nginx config file:
upstream nextjs_upstream {
server next_app:3000;
}
server {
listen 80 default_server;
server_name _;
server_tokens off;
# set root
root /var/www/html/frontend;
# set log
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
location /_next/static {
proxy_cache STATIC;
proxy_pass http://nextjs_upstream;
add_header X-Cache-Status $upstream_cache_status;
}
}
I'm trying to deploy a docker-compose stack that contains a Nginx service to manage the others like Jenkins or Grafana. However, when I target my Jenkins service like http://myapp.fr/jenkins, the homepage of the service will redirect to the login page at this URL: http://myapp.fr/login?from=%2F. How I can fix this for all services to prefix with the service name for all pages of it (like http://myapp.fr/jenkins/login?from=%2F).
My stack looks like this :
version: "3.7"
services:
## NGINX ##
web:
image: nginx
container_name: myapp_nginx
volumes:
- ./config/nginx/templates:/etc/nginx/templates
- ./config/nginx/include.d:/etc/nginx/include.d
- ./config/nginx/www:/var/www/certbot
ports:
- "80:80"
- "443:443"
environment:
- NGINX_HOST=myapp.fr
- NGINX_PORT=80
networks:
- myapp
## JENKINS ##
jenkins:
build:
context: ./dockerfile/jenkins
dockerfile: Dockerfile
container_name: myapp_jenkins
hostname: jenkins.myapp.fr
privileged: true
user: root
ports:
- 8080:8080
- 50000:50000
volumes:
- ~/jenkins:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
- /usr/local/bin/docker:/usr/local/bin/docker
restart: always
networks:
- myapp
## GRAFANA ##
grafana:
image: grafana/grafana-enterprise:8.2.0
container_name: myapp_grafana
hostname: grafana.myapp.fr
ports:
- 3000:3000
user: "104"
networks:
- myapp
networks:
myapp:
driver: bridge
My default.conf of nginx is in one of my docker volumes and it looks like this :
server {
listen 80;
listen [::]:80;
server_name myapp.fr;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /jenkins/ {
proxy_set_header Host $host;
add_header Access-Control-Allow-Origin '*';
proxy_pass http://jenkins.myapp.fr:8080/;
}
location /grafana/ {
proxy_set_header Host $host;
add_header Access-Control-Allow-Origin '*';
proxy_pass http://grafana.myapp.fr:3000/;
}
add_header Access-Control-Allow-Origin '*';
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,Access-Control-Allow-Origin';
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
When I began the deploy, I use a docker-compose up -d command and all services are running. myapp.fr show the nginx index. However, if I specified the subpath myapp.fr/jenkins, it will be showig a 404 error because of a redirection to http://myapp.fr/login?from=%2F
How I can fix this for all services to prefix service name for all pages of it (like http://myapp.fr/jenkins/login?from=%2F).
Thanks
You have to tell Jenkins that you are using an additional context path, so it generates all the redirections with the added context. You can do this by passing the --prefix=/jenkins on startup. You can pass this through JENKINS_OPTS environment variable as well. Following is how you can pass this to docker run.
docker run --name myjenkins -p 8080:8080 -p 50000:50000 --env JENKINS_OPTS="--prefix=/jenkins" jenkins/jenkins:lts
Update
Following is a sample NginX configuration you can use. Note the proxy_redirect option specified, which makes sure all redirect URLs are changed to your correct Hostname.
server {
listen 80;
server_name jenkins.ycr.com;
location /jenkins {
proxy_pass http://127.0.0.1:8081;
proxy_redirect http://127.0.0.1:8081/ http://jenkins.ycr.com/;
}
}
I created a Github repo weeks ago with Docker Compose, Odoo, PostgreSQL, Certbot, Nginx as a proxy server, and a little bit of PHP stuff (Symfony) -> https://github.com/Inushin/dockerOdooSymfonySSL When I was trying the config I found that NGINX worked as it was supposed to and you get the correct HHTP -> HTTPS redirect, BUT if you put the port 8069, the browser goes to HTTP. One of the solutions should be configured de another VPC, but I was thinking about using this repo for other "minimal VPS services" and not needing another VPC, so... how could I solve this? Maybe from Odoo config? Is something missing in the NGINX conf?
NGINX
#FOR THE ODOO DOMAIN
server {
listen 80;
server_name DOMAIN_ODOO;
server_tokens off;
location / {
return 301 https://$server_name$request_uri;
}
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
}
server {
listen 443 ssl;
server_name DOMAIN_ODOO;
server_tokens off;
location / {
proxy_pass http://web:8069;
proxy_set_header Host DOMAIN_ODOO;
proxy_set_header X-Forwarded-For $remote_addr;
}
ssl_certificate /etc/letsencrypt/live/DOMAIN_ODOO/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/DOMAIN_ODOO/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
docker-compose.yml
nginx:
image: nginx:1.15-alpine
expose:
- "80"
- "443"
ports:
- "80:80"
- "443:443"
networks:
- default
volumes:
- ./data/nginx:/etc/nginx/conf.d/:rw
- ./data/certbot/conf:/etc/letsencrypt/:rw
- ./data/certbotSymfony/conf:/etc/letsencrypt/symfony/:rw
- ./data/certbotSymfony/www:/var/www/certbot/:rw
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
web:
image: odoo:13.0
depends_on:
- db
ports:
- "8069:8069/tcp"
volumes:
- web-data:/var/lib/odoo
- ./data/odoo/config:/etc/odoo
- ./data/odoo/addons:/mnt/extra-addons
i have a django app and nginx as services on docker-compose. Am using nginx as a reverse proxy.
here is the docker compose file
version: "3.8"
services:
# nginx reverse proxy
nginx:
image: nginx:1.17.10
container_name: nginx
ports:
- "80:80"
restart: on-failure
depends_on:
- app
app:
image: django-app-image
conatinter_name: app
expose
- 8001
restart: on-failure
here is the nginx configuration
user www-data;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# sendfile on;
upstream django-app {
server app:8001;
}
server {
listen 80;
listen [::]:80;
location /vocal-bm{
client_max_body_size 0;
proxy_pass http://django-app/vocal-bm;
proxy_set_header Host $host;
}
}
This is what i want to achieve:
I should visit http://localhost/vocal-bm/<some-variable>
and the route served should be http://django-app/vocal-bm/<some-variable>
The above configuration just routes to http://django-app
How do I get it to work i.e route to http://django-app/vocal-bm/<some-variable>
What I have tried
adding a trailing slash on the proxy_pass proxy_pass http://django-app/vocal-bm/;
but a get http://django-app/vocal-bm//<some-variable> with the double slash before the dynamic variable.
I have also tried the rewrite but it gives http://django-app also
I have a reactjs app which I want to server through nginx. The app makes API requests a node.js Express server. I decided to dockerize nginx together with static website files (from reactjs app) in one docker-compose file. I created another docker-compose file for Express server. The containers are currently on my laptop and are using localhost. I haven't been able to get them to work for a long time and there's unfortunately not much information about this on the internet. (the website and Express server work when not inside Docker).
First of all I created a new docker network:
docker network create --driver bridge appstore-net
This is my docker-compose file for website and nginx:
version: '3.5'
services:
appstore-front:
container_name: appstore-front-production
build:
context: .
dockerfile: Dockerfile-prod
ports:
- '80:80'
networks:
- appstore-net
external_links:
- appstore-bl-server-production
networks:
appstore-net:
external: true
This is my docker-compose file for Express server:
version: '3'
services:
appstore-bl-server:
container_name: appstore-bl-server-production
build:
dockerfile: Dockerfile-prod
context: .
volumes:
- ".:/usr/src/app"
ports:
- "3000:3000"
networks:
- appstore-net
networks:
appstore-net:
external: true
This is my nginx configuration:
server {
listen 80;
listen [::]:80;
#Docker DNS
resolver 127.0.0.11;
server_name localhost;
access_log /var/log/nginx/appstore.access.log;
error_log /var/log/nginx/appstore.error.log;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api {
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;
#hack to prevent nginx to resolve container's host on start up
set $docker_host "appstore-bl-server";
proxy_pass http://$docker_host:3000;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
As you can see I'm using docker DNS resolver as well as creating "passing proxy" to URL consisting of Express container name.
How can I make it work?
EDIT: I found 2 issues that could've been the reason:
1) external_links needs to refer to container name, not container service.
2) docker_host variable in nginx needs to refer to service name, not container name.
With these corrections the setup works (corrected the values in the OP as well).