how to allow docker nginx webdav writing into a mounted directory? - docker

This is the docker-compose for nginx
nginx:
container_name: nginx
image: nginx
build:
context: ./dockerfile
dockerfile: nginx
volumes:
- type: bind
source: ./config/nginx/nginx.conf
target: /etc/nginx/nginx.conf
- type: bind
source: ./config/nginx/credentials.list
target: /etc/nginx/.credentials.list
- type: bind
source: /mnt/raid
target: /webdav
dockerfile
FROM nginx:latest
RUN apt-get update && apt-get install -y nginx-extras libnginx-mod-http-dav-ext
nginx.conf
worker_processes auto;
include /etc/nginx/modules-enabled/*.conf;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.0.0.0/8;
set_real_ip_from 192.168.0.0/16;
real_ip_header X-Real-IP;
gzip on;
server{
server_name _;
root /webdav;
dav_methods PUT DELETE MKCOL COPY MOVE;
dav_ext_methods PROPFIND OPTIONS;
dav_access user:rw group:r all:r;
client_body_temp_path /tmp;
client_max_body_size 0;
create_full_put_path on;
auth_basic realm_name;
auth_basic_user_file /etc/nginx/.credentials.list;
}
docker exec nginx ls -la / it shows drwxrwxr-x 12 nginx nginx 20 Jan 4 03:01 webdav
docker exec nginx id -u nginx shows 1000
1000 is the UID of host system user y2kbug. /mnt/raid is owned by 1000:1000.
drwxrwxr-x 12 y2kbug y2kbug 20 Jan 4 11:01 raid/
Going into the docker container, since it is root user by default, the mounted directory is writable. However, connecting with WebDav, the directory is readable, but not writable. Nginx log shows these
2021/01/04 03:20:32 [error] 29#29: *6 mkdir() "/webdav/test" failed (13: Permission denied), client: 10.0.0.7, server: _, request: "MKCOL /test/ HTTP/1.1", host: "10.0.0.10"
10.0.0.7 - y2kbug [04/Jan/2021:03:20:32 +0000] "MKCOL /test/ HTTP/1.1" 403 143 "-" "gvfs/1.46.1" "-"
10.0.0.7 - y2kbug [04/Jan/2021:03:20:32 +0000] "PROPFIND /test HTTP/1.1" 404 143 "-" "gvfs/1.46.1" "-"
May I know what I am doing wrong?
Thanks.

adding user nginx; onto nginx.conf solved the problem.

Related

Dockerized VuJS NGINX 403 error : directory index of "/etc/nginx/html/" is forbidden

I am trying to dockerize a VueJS app using nginx , but it keeps showing me this error .
[error] 8#8: *1 directory index of "/etc/nginx/html/" is forbidden, client: x.x.x.x, server: localhost, request: "GET / HTTP/1.1", host: "x.x.x.x:80"
[error] 8#8: *1 directory index of "/etc/nginx/html/" is forbidden, client: x.x.x.x, server: localhost, request: "GET / HTTP/1.1", host: "x.x.x.x:80"
[error] 8#8: *1 directory index of "/etc/nginx/html/" is forbidden, client: x.x.x.x, server: localhost, request: "GET / HTTP/1.1", host: "x.x.x.x:80"
This my docker and nginx configuration :
Dockerfile
FROM nginx:1.17-alpine
# Copy built app into nginx
COPY /dist /etc/nginx/html/studio
# copy nginx conf
COPY nginx.conf /etc/nginx/nginx.conf
nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
keepalive_timeout 65;
map $http_user_agent $loggable {
"~kube-probe/.*" 0;
default 1;
}
access_log /var/log/nginx/access.log main if=$loggable;
server {
listen 80;
server_name localhost;
location /studio/ {
try_files $uri $uri/ /studio/index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
When I access the browser it shows : 503 Service Temporarily Unavailable - nginx

Connect two wordpress containers with same NGINX docker

I use nginx in a docker to connect my two wordpress websites, which are dockerized too.
I can set up one website with the following settings:
In docker-compose.yml
nginx:
image: nginx:alpine
volumes:
- ./web_ndnb_prod/src:/var/www/html
- ./nginx/conf.d:/etc/nginx/conf.d:ro
depends_on:
- web_ndnb_test
- web_ndnb_prod
In my NGINX conf file located in /nginx/conf.d
server {
[...]
root /var/www/html/;
[...]
}
However to add a 2nd website, I try to change the root and the websites return a 404
In docker-compose.yml
nginx:
image: nginx:alpine
volumes:
- ./web_ndnb_prod/src:/var/www/web_ndnb_prod
- ./web_ndnb_test/src:/var/www/web_ndnb_test
- ./nginx/conf.d:/etc/nginx/conf.d:ro
depends_on:
- web_ndnb_test
- web_ndnb_prod
In one of the 2 NGINX conf files
server {
[...]
root /var/www/web_ndnb_prod/;
[...]
}
If I execute
sudo docker exec -ti nginx ls /var/www/web_ndnb_prod
It outputs the wordpress files correctly
Why does Nginx not find them?
Edit 1
The main nginx.conf file is
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}

Can't connect from one docker container to another by its public domain name

I have an application composed of containerized web-services deployed with docker-compose (it's a test env). One of the containers is nginx that operates as a reverse proxy for services and also serves static files. A public domain name points to the host machine and nginx has a server section that utilizes it.
The problem I am facing is that I can't talk to nginx by that public domain name from the containers launched on this same machine - connection always timeouts. (For example, I tried doing a curl https://<mypublicdomain>.com)
Referring by the containers name (using docker's hostnames) works just fine. Reuqests to the same domain name from other machines also work ok.
I understand this has to do with how docker does networking, but fail to find any docs that would outline what exactly goes wrong here. Could anyone explain the root of the issue to me or maybe just point in the right direction?
(For extra context: originally I was going to use this to set up monitoring with prometheus and blackbox exporter to make it see the server the same way anyone from the outside would do + to automatically check that SSL is working. For now I pulled back to point the prober to nginx by its docker hostname)
Nginx image
FROM nginx:stable
COPY ./nginx.conf /etc/nginx/nginx.conf.template
COPY ./docker-entrypoint.sh /docker-entrypoint.sh
COPY ./dhparam/dhparam-2048.pem /dhparam-2048.pem
COPY ./index.html /var/www/index.html
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]
docker-compose.yaml
version: "3"
networks:
mainnet:
driver: bridge
services:
my-gateway:
container_name: my-gateway
image: aturok/manuwor_gateway:latest
restart: always
networks:
- mainnet
ports:
- 80:80
- 443:443
expose:
- "443"
volumes:
- /var/stuff:/var/www
- /var/certs:/certsdir
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
(I show only the nginx service, as others are irrelevant - I would for example spin up a nettools container and not connect it to the mainnet network - still expect the requests to reach nginx, since I am using the public domain name. The problem also happens with the containers connected to the same network)
nginx.conf (normally it comes with a bunch of env vars, replaced + removed irrelevant backend)
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
#include /etc/nginx/conf.d/*.conf;
server {
listen 80;
server_name mydomain.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name mydomain.com;
ssl_certificate /certsdir/fullchain.pem;
ssl_certificate_key /certsdir/privkey.pem;
server_tokens off;
ssl_buffer_size 8k;
ssl_dhparam /dhparam-2048.pem;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8;
root /var/www/;
index index.html;
location / {
root /var/www;
try_files $uri /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
Note: certificates are ok when I access the server from elsewhere

Nginx with docker: Reverse Proxy doesn't work

I recently want to set a reverse proxy server. I pulled a nginx docker image and I ran the docker container using this command:
docker run -d --name ngtest -p 4080:80 nginx
Then I updated the /etc/nginx/nginx.conf like below:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
server{
listen 80;
location /nexus/ {
proxy_pass http://192.168.0.30:8081/;
}
}
}
The container works after restarted, when I tried to open page
http://192.168.0.30:4080, I got the default Nginx page.
However when I tried this url: http://192.168.0.30:4080/nexus, I got a 404 page with errors.
From the log, it looks that the nginx didn't forward the url to the page I set in nginx.conf, instead it tried to look the page in the local directory:
2020/03/11 16:10:34 [error] 6#6: *251 open() "/usr/share/nginx/html/nexus" failed (2: No such file or directory), client: 192.168.0.153, server: localhost, request: "GET /nexus HTTP/1.1", host: "192.168.0.30:4080"
192.168.0.153 - - [11/Mar/2020:16:10:34 +0000] "GET /nexus HTTP/1.1" 404 555 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36" "-"
Is there anything wrong in my steps?
Thanks,
Alex
The issue is that even with your updated config you are still doing:
include /etc/nginx/conf.d/*.conf;
Which is loading /etc/nginx/conf.d/default.conf which will be the default server in the event no server name is provided based on the rules of determining the server to use if server name not found.
You should do something like:
Save to a config file your server definition of:
server{
listen 80;
location /nexus/ {
proxy_pass http://192.168.0.30:8081/;
}
}
Then run
docker run -d -p 4080:80 -v (path_to_your_config):/etc/nginx/conf.d/default.conf nginx
This will replace the default config with yours. Then if you need to make changes you just make them and restart the container.

Simple PHP App Failing to Start on ECS With Docker Compose and NGINX

I have a very simple PHP app built using Docker Compose using NGINX and Busybox. It's working fine locally but I can't get it to start up properly in its container on AWS ECS. The app structure is as follows:
Root
--conf
nginx.conf
php.ini
supervisord.conf
--logs
--sites
default.vhost
--www
--default
index.php
aws-compose.yml
docker-compose.yml
Dockerfile
The important files are:
aws-compose.yml
version: '2'
services:
web:
image: nginx:alpine
cpu_shares: 100
mem_limit: 262144000
restart: always
ports:
- "80:80"
- "443:443"
links:
- php
volumes:
- /sites:/etc/nginx/conf.d
- /conf/nginx.conf:/etc/nginx/nginx.conf
volumes_from:
- code
php:
image: '195367337191.dkr.ecr.us-east-1.amazonaws.com/myapp-php-dev:rv1'
cpu_shares: 100
mem_limit: 262144000
build: .
restart: always
working_dir: /var/www
volumes_from:
- code
code:
image: busybox
tty: true
volumes:
- /www:/var/www
Dockerfile:
FROM php:7.1-fpm
RUN pecl install xdebug
RUN docker-php-ext-enable xdebug
COPY conf/php.ini /etc/php/7.1/fpm/conf.d/40-custom.ini
Conf/nginx.conf:
user root;
worker_processes 1;
# daemon off;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
gzip on;
include /etc/nginx/conf.d/*;
}
Conf/php.ini:
; Enable XDebug
zend_extension = xdebug.so
; XDebug configuration
xdebug.remote_enable = 1
xdebug.renite_enable = 1
xdebug.max_nesting_level = 1000
xdebug.profiler_enable_trigger = 1
xdebug.profiler_output_dir = "/var/log"
date.timezone = "America/New_York"
; Show PHP errors
display_errors = 1
Conf/supervisord.conf:
[supervisord]
nodaemon=true
[program:nginx]
command = /usr/sbin/nginx
user = root
autostart = true
[program:php7-fpm]
command = /usr/sbin/php-fpm7.0 -FR
user = root
autostart = true
Sites/default.vhost:
server {
server_name default;
root /var/www/default;
index index.html index.php;
client_max_body_size 100M;
fastcgi_read_timeout 1800;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
access_log off;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass php:9000;
}
}
The issue seems to be with the references in the volumes section of the "web" service in aws-compose.yml as when I remove them completely the container starts but shows the default Nginx "needs configuration" holding page. With them in-situ as below:
volumes:
- /sites:/etc/nginx/conf.d
- /conf/nginx.conf:/etc/nginx/nginx.conf
I get the following error in the tasks section of AWS ECS under "stopped":
Status reason CannotStartContainerError: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "process_linux.go:424: container init caused \"rootfs_linux.go:58: mounting \\"/conf/nginx.conf\\" to rootfs \\"
For info in my local docker-compose.yml file the references are as follows:
- ./sites:/etc/nginx/conf.d
- ./conf/nginx.conf:/etc/nginx/nginx.conf
But this errors when I spin it up on AWS stating the syntax doesn't conform with the required RegEx pattern.
Can anybody help?

Resources