Traefik: Level=error msg=“field not found, node: mywebsite” providerName=docker - docker

I am building a static website using Gatsby, and I am using Nginx to serve the static files.
I am also setting up Docker for the application deployment to production and also using Traefik as the reverse proxy in the Docker container.
Traefik runs on a different container while the Gatsby application runs on a different container with Nginx together.
However, when I run the application in production I get this error:
level=error msg="field not found, node: mywebsite" providerName=docker container=web-my-website
Here's my code:
Nginx's defualt.conf
server {
listen 3008;
add_header Cache-Control no-cache;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
expires -1;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Dockerfile
# Set base image
FROM node:latest AS builder
# Set working directory
WORKDIR /app
# Copy package.json and install packages
COPY package.json .
RUN npm install
# Copy other project files and build
COPY . ./
RUN npm run build
# Set nginx image
FROM nginx:latest
# Nginx config
RUN rm -rf /etc/nginx/conf.d/default.conf
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
# Static build
COPY --from=builder /app/public /usr/share/nginx/html
# Set working directory
WORKDIR /usr/share/nginx/html
# Start Nginx server
CMD ["/bin/bash", "-c", "nginx -g \"daemon off;\""]
Gatsby application's docker-compose.yml
version: "3"
services:
web:
image: my-website
build:
context: .
dockerfile: Dockerfile
expose:
- "3004"
labels:
- traefik.enable=true
- traefik.http.routers.mywebsite.rule=Host(`mywebsite.com`)
- traefik.http.services.educollectwebsite.loadbalancer.server.port=3004
restart: always
volumes:
- .:/app
networks:
default:
external:
name: traefik-proxy
Traefik's docker-compose.yml
version: "3"
services:
reverse-proxy:
# The official v2 Traefik docker image
image: traefik:v2.2
# Enables the web UI and tells Traefik to listen to docker
command:
- --api.insecure=true
- --entrypoints.web.address=:80
- --providers.docker=true
- --providers.docker.exposedbydefault=false
ports:
# The HTTP port
- "88:80"
# The Web UI (enabled by --api.insecure=true)
- "8088:8080"
restart: always
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
networks:
default:
external:
name: traefik-proxy
I can't seem to figure out what the issue is here. Any form of help will be appreciated.

I was finally able to resolve it after some hours of working with my Line Manager.
The issue was that I defined port 3008 in the Nginx default.conf file and then defined port 3004 in the Gatsby application's docker-compose.yml file. This did not allow traffic into the application from Traefik reverse proxy. since both ports were different.
Solution 1:
Simply defining the same port of 3008 in the Nginx default.conf and in the Gatsby application's docker-compose.yml file fixed it:
Nginx's defualt.conf
server {
listen 3008;
add_header Cache-Control no-cache;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
expires -1;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Gatsby application's docker-compose.yml
version: "3"
services:
web:
image: my-website
build:
context: .
dockerfile: Dockerfile
expose:
- "3004"
labels:
- traefik.enable=true
- traefik.http.routers.mywebsite.rule=Host(`mywebsite.com`)
- traefik.http.services.educollectwebsite.loadbalancer.server.port=3008
restart: always
volumes:
- .:/app
networks:
default:
external:
name: traefik-proxy
Solution 2:
Defining the default port in Traefik which is port 80 in the Nginx default.conf and in the Gatsby application's docker-compose.yml file fixed it. This is more preferable when deploying static applications since it helps me to assume a reasonable default for the application.
Nginx's defualt.conf
server {
listen 80;
add_header Cache-Control no-cache;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
expires -1;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Gatsby application's docker-compose.yml
version: "3"
services:
web:
image: my-website
build:
context: .
dockerfile: Dockerfile
expose:
- "80"
labels:
- traefik.enable=true
- traefik.http.routers.mywebsite.rule=Host(`mywebsite.com`)
restart: always
volumes:
- .:/app
networks:
default:
external:
name: traefik-proxy
Note: Using the same port with Traefik which is port 80 in the application, invalidates the need for a Traefik loadbalancer service.
- traefik.http.services.educollectwebsite.loadbalancer.server.port=80
That's all.
I hope this helps

Related

Docker compose environment variables not picking up in nginx

I have a vue app running on the front-end with spring boot backend both on different containers.
I want to dockerize my vuejs app to pass environment variables from the docker-compose file to nginx.
My problem is that my nginx conf file is not picking up environment variables from docker-compose.
Docker Compose File
backend-service:
container_name: backend-service
image: backend-service-local
networks:
- app-network
ports:
- 8081:8080
restart: on-failure
depends_on:
postgresdb:
condition: service_healthy
vue-app:
container_name: vue-app
image: vue-app-local
networks:
- app-network
ports:
- 8080:80
environment:
VUE_APP_BASE_URL: http://backend-service:8080
restart: on-failure
depends_on:
backend-service:
condition: service_started
DOCKER FILE
# build stage
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
NGINX CONF
# Run as a less privileged user for security reasons.
user nginx;
# #worker_threads to run;
# "auto" sets it to the #CPU_cores available in the system, and
# offers the best performance.
worker_processes auto;
events { worker_connections 1024; }
http {
sendfile on;
upstream docker-backend {
server ${VUE_APP_BASE_URL};
}
server {
# Hide nginx version information.
server_tokens off;
listen 80;
root /usr/share/nginx/html;
include /etc/nginx/mime.types;
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://docker-backend;
}
}
}
Please advise nginx docker image docs in the Using environment variables in nginx configuration section of the page.
The way the nginx docker image deals with environment variables is injecting them in runtime using the configs in the linked page

Can't call my Laravel API from the Node.js container but I can call it from Postman

I have the following 4 containers:
php-fpm for Laravel API backend
node.js container for the Next.js frontend
nginx container
mysql container
I am able to call the Laravel API and get the correct JSON data from Postman using http://localhost:8088/api/products , but when I try from the Node container, I get FetchError: request to http://localhost:8088/api/ failed, reason: connect ECONNREFUSED 10.0.238.3:8088. I am not sure if it's the nginx configuration issue, or docker-compose.yml configuration issue.
I also tried to call the API from the node container using several other options (none of them worked):
http://php:8088/api/products
http://localhost:8088/api/products
http://php:9000/api/products - gives a different error: FetchError: request to http://php:9000/api/products/ failed, reason: read ECONNRESET
This is the docker-compose.yml:
networks:
laravel:
driver: bridge
services:
nginx:
image: nginx:stable-alpine
container_name: nginx
ports:
- "8088:80"
volumes:
- ./laravel-app:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
- mysql
- node
networks:
- laravel
mysql:
image: mysql
container_name: mysql
restart: unless-stopped
tty: true
ports:
- "4306:3306"
volumes:
- ./mysql:/var/lib/mysql
environment:
MYSQL_DATABASE: laravel
MYSQL_ROOT_PASSWORD: password
SERVICE_TAGS: dev
SERVICE_NAME: mysql
networks:
- laravel
php:
build:
context: .
dockerfile: Dockerfile
container_name: php
volumes:
- ./laravel-app:/var/www/html
ports:
- "9000:9000"
networks:
- laravel
node:
build:
context: ./nextjs
dockerfile: Dockerfile
container_name: next
volumes:
- ./nextjs:/var/www/html
ports:
- "3000:3000"
- "49153:49153"
networks:
- laravel
And this is the nginx default.conf file:
server {
listen 80;
index index.php index.html;
server_name localhost;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/html/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri = 404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
If you want to reach your Laravel API from the node service, you must use http://nginx/your_api_endpoint.
Nginx acts as a reverse proxy here, it takes the traffic on the port 80 (listen 80;) and redirects it to your Laravel container (fastcgi_pass php:9000;).
So your target is not the Laravel container itself, it is nginx.
http://nginx/api/products/ should works if everything else is ok.

Sharing volumes in networked docker containers with docker composer fails

I have two docker-compose.yml files
THe first one is a global one and am using it to configure nginx webserver and the other one am using it for holding the application code and below are their configurations
First one with nginx configuration
version: '3'
services:
app:
build:
context: .
dockerfile: Dockerfile
image: globaldocker
container_name: app
restart: unless-stopped
tty: true
working_dir: /var/www
volumes:
- ./:/var/www
- ./dockerconfig/php/local.ini:/usr/local/etc/php/conf.d/local.ini
networks:
- common_network
webserver:
image: nginx
container_name: webserver
restart: unless-stopped
tty: true
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www
- ./dockerconfig/nginx/:/etc/nginx/conf.d/
networks:
- webserver_network
- common_network
networks:
common_network:
external: false
webserver_network:
external: false
The above creates two networks
global_docker_common_network, global_docker_webserver_network
On the docker config folder there is a nginx configuration like
server {
listen 80;
server_name pos.test www.pos.test;
index index.php index.html;
//other nginx configurations for pos.test
}
ON THE docker-compose configuration with php file
Now the one one holding the source code for pos.test i have the following configuration
app:
build:
context: .
dockerfile: Dockerfile
image: posapp/php
container_name: envanto_pos
restart: unless-stopped
tty: true
working_dir: /var/www/pos
volumes:
- ./:/var/www/pos
- ./dockerconfig/nginx/:/etc/nginx/conf.d/
networks:
- globaldocker_webserver_network
networks:
globaldocker_webserver_network:
external: true
Which i have added the external network
When i try accessing nginx pos.test it doesnt display the application but only shows the default nginx page
I have tried accessing the first docker nginx configuration bash and checked on the var/www/pos folder but i cant see the files from the second docker config(source code).
How do i share volumes with my nginx docker configuration container so that when i access docker via exposed port 80 am able to access my site pos.test
What am i missing out on this to make this work?
UPDATE
The two docker configuration files are located on different folders on my host machine
UPDATE ON THE QUESTION
This is my nginx config file
server {
listen 80;
server_name pos.test www.pos.test;
index index.php index.html;
error_log /var/log/nginx/pos_error.log;
access_log /var/log/nginx/pos_access.log;
root /var/www/pos/web;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
}
you are mounting the current directory of docker-compose file each. So the only that container will have the source code which resides in the same source code directory.
You need some common directory
First File
volumes:
- /path_to_sc/common:/var/www
Second File
volumes:
- /path_to_sc/common:/var/www/pos
When I try accessing Nginx pos.test it doesn't display the application
but only shows the default Nginx page
Probably you first File not picking correct configuration. Double-check ./dockerconfig/nginx/:/etc/nginx/conf.d/ or run the command inside docker to verify the correct configuration file.
docker exec nginx bash -c "cat /etc/nginx/conf.d/filename.conf`
I have tried accessing the first docker nginx configuration bash and
checked on the var/www/pos folder but i cant see the files from the
second docker config(source code).
Mount the common directory so that can accessible for both containers.
update:
From your comment, it seems like there is a syntax error in your docker-compose file. Take a look into this example
web:
image: nginx
volumes:
- ./data:/var/www/html/
ports:
- 80:80
command: [nginx-debug, '-g', 'daemon off;']
web2:
image: nginx
volumes:
- ./data:/var/www/html
command: [nginx-debug, '-g', 'daemon off;']

docker nginx-proxy with vhost not routing correctly

I have a docker with 2 containers for serving individual sites and jwilder/nginx-proxy in front of them.
However I'm only getting the default nginx page, so the vhosts aren't routing correctlty.
I've used https://www.rent-a-hero.de/wp/2017/06/09/use-j-wilders-nginx-proxy-for-multiple-docker-compose-projects/ as a guide t get myself started on this, because I wanted to set up a proxy network.
Each of the serving nxinx containers has a vhost file, and uses a 4th, shared php container (the code is the same in both nginx containers).
$ docker run -d \
--name nginx-proxy \
-p 80:80 \
--network=nginx-proxy \
-v /var/run/docker.sock:/tmp/docker.sock:ro \
jwilder/nginx-proxy
/docker-compose.yml
version: '2'
services:
app-admin:
image: nginx:latest
container_name: app-admin
environment:
VIRTUAL_HOST: admin.app.local
VIRTUAL_PORT: 80
volumes:
- .:/var/www/html
- admin.app.conf:/etc/nginx/vhost.d/admin.app.local:ro
links:
- php
php:
image: php:7-fpm
container_name: php
volumes:
- .:/var/www/html
networks:
default:
external:
name: nginx-proxy
/admin.app.conf:
server {
server_name admin.app.local
listen 80;
listen [::]:80;
root /var/www/html;
index index.html index.php;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
try_files $uri /index.php$is_args$args;
}
location ~ /\.ht {
deny all;
}
}
app.conf is essentially the same for this testing stage... same result
Original files edited to help simplify the question (the removed files just basically setup the required nginx-proxy container and network, and I;ve stripped out the example second nginx container)

Docker uWSGI - NGINX: uWSGI ok but NGINX is a 502

I configured my django-uwsgi-nginx using docker compose with the following files.
From browser "http://127.0.0.1:8000/" works fine and gives me the django default page
From browser "http://127.0.0.1:80" throws a 502 Bad Gateway
dravoka-docker.conf
upstream web {
server 0.0.0.0:8000;
}
server {
listen 80;
server_name web;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
alias "/dravoka-static/";
}
location / {
include uwsgi_params;
proxy_pass http://web;
}
}
nginx/Dockerfile
FROM nginx:latest
RUN echo "---------------------- I AM NGINX --------------------------"
RUN rm /etc/nginx/conf.d/default.conf
ADD sites-enabled/ /etc/nginx/conf.d
RUN nginx -t
web is just from "django-admin startproject web"
docker-compose.yaml
version: '3'
services:
nginx:
restart: always
build: ./nginx/
depends_on:
- web
ports:
- "80:80"
web:
build: .
image: dravoka-image
ports:
- "8000:8000"
volumes:
- .:/dravoka
command: uwsgi /dravoka/web/dravoka.ini
Dockerfile
# Ubuntu base image
FROM ubuntu:latest
# Some installs........
EXPOSE 80
When you say from the docker instance , you are running curl from with in the container ?? or you are running the curl command from your local ?
if you are running it from your local , update your docker-compose's web service to following
...
web:
build: .
image: dravoka-image
expose:
- "8000:8000"
volumes:
- .:/dravoka
command: uwsgi /dravoka/web/dravoka.ini
and try again.

Resources