Nginx - 403 forbidden

Hello, I am totally new to Docker and am currently following a tutorial on YouTube. I have downloaded the nginx image and successfully start a container by running the following command: docker run --name website -d -p 8080:80 nginx:latest When I go to localhost:8080 I can see the welcome nginx screen.

The next step was to host a static page by using -v so I cd’ed into the folder that contains my index.html file and from there I run the following: docker run --name Project_009 -v $(pwd):/usr/share/nginx/html:ro -p 8080:80 -d nginx:latest

However, unlike in the tutorial I am getting 403 Forbidden error when I go to localhost:8080. I have already googled the error but most explanations are related to some more advanced stuff which I haven’t yet covered. I did try to go to /usr/share/nginx directory to see if it is an authority issue but that structure doesn’t exist. Do I have to create this manually myself or should this have been created by the above command? I also tried running the docker command with sudo in front just to see if that makes any difference but no luck.

I am a bit stuck and was hoping someone could point me in the right direction.
Many thanks

Docker version 19.03.11, build 42e35e6
nginx/1.19.3
Fedora 32

Check the permissions of the files in this folder. They should be -rw-r--r--.

Hi tekki, the index.html file in the folder has -rw-r–r-- authority. Could you think of anything else I need should check? Many thanks

Las time I checked, the nginx image is designed to run the nginx process as root, so actually the unix permissions tekki wrote should be sufficient. Enter the running container and check the content of /usr/share/nginx/html, if it’s empty things like ACLs (typical for Syno/QNAP setups) or selinux prevent the folder from beeing mounted to the container.

Please be aware that your -v parameter uses a bind-mount that mounts your $(pwd) folder on top of the container folder, thus making all its original content unavailable to the container. You will only see what is present in $(pwd). Btw. you can use the variable $PWD instead of running the pwd command in a subshell -> $(pwd)

Did you check the container logs? I would assume they provide a more reasonable explaination.

The worker process runs as nginx (uid 101).

@purpleshadow1975 The only ways I find to reproduce this error is to either set index.html or the folder itself to 0700. So maybe you should check the access rights to the folder too. A simple way to find out if the mounting of the volume works is to run a command like

docker container run --rm -v $PWD:/data debian ls /data

Hi, thank you for your assistance. So, I tried to run the command you specified above and I got: ls: cannot open directory ‘/data’: Permission denied.

Does this mean there is a permission problem on the host or in the container?

I have run docker exec -it Project_009 bash and then tried to get into the /usr/share/nginx/html directory to see if the index.html file is there. but when I try to run ls -l in the html folder I get ls: cannot open directory ‘.’: Permission denied

I don’t know if this is relevant but when I ran the docker exec -it command it connected me as root@container name.

Many thanks.

Thank you for responding. I have tried to have a look in the error.log and access.log in the container and they were both empty.

Thank you for the feedback about the $PWD, once I have this issue resolved I will try it out.
Many thanks

Maybe I missed that the user nginx is added with the uid in the Dockerfile, though the container itself is started as root. which makes the permission problems even more suprising. I haven’t tracked down what part of the configuration is responsible to execute the worker processes as restricted user.

Can you share the output of stat $PWD within the folder where you run the docker run command in?

Are you by any chance running docker on a NAS where you configure the access permissions in a ui? You will want to have “pure” unix permissions for the folder.

[@DESKTOP-1EIKTFE website]$ stat $PWD
File: /home//
/Project_009/website
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: fd02h/64770d Inode: 4981018 Links: 2
Access: (0755/drwxr-xr-x) Uid: ( 1000/
) Gid: ( 1000/******)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2020-10-25 12:06:59.648995836 +0000
Modify: 2020-10-23 17:31:47.773977182 +0100
Change: 2020-10-23 17:31:47.773977182 +0100
Birth: -

I have also just ran the namei -om /usr/share/nginx/html/index.html in the container and got the following:

root@9e4d50f67648:/# namei -om /usr/share/nginx/html/index.html
f: /usr/share/nginx/html/index.html
drwxr-xr-x root root /
drwxr-xr-x root root usr
drwxr-xr-x root root share
drwxr-xr-x root root nginx
drwxr-xr-x 1000 1000 html
index.html - Permission denied

I am running on my laptop with Fedora 32 installed.
Many thanks for your assistance.

stats and the output for namei -om match for the html folder. So far so good.

Though, I am afraid your selinux configuration is responsible for the “permission denied” error.

Please delete you old container and check wether it works with the :Z suffix for the bind-mount volume mapping:

docker run --name Project_009 -v $(pwd):/usr/share/nginx/html:Z -p 8080:80 -d nginx:latest

It works! I am sooo happy. Thank you all for your help. If someone could tell me what selinux configuration has to do with these permission errors?

Again, many many thanks to all that have replied.

This made it clear that its likely a selinux problem. The fact that even though you’d been root in the container and namei returned a Permission error made it clear that SELinux forbidds access.

SELinux provides elaborated access control, which checks if a process is allowed to access an object (in your case a file). Afair, with the :Z suffix, docker takes care to map the hosts selinux contexts to the container.

1 Like

Hey hi everyone,

I was following the same tutorial but getting the 403 forbidden error My OS: Mac OS Big Sur

Pasting the log file below

/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration

/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/

/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh

10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf

10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf

/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh

/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh

/docker-entrypoint.sh: Configuration complete; ready for start up

2021/03/09 18:29:11 [error] 32#32: *1 directory index of "/usr/share/nginx/html/" is forbidden, client: 172.17.0.1, server: localhost, request: "GET / HTTP/1.1", host: "localhost:8080"

172.17.0.1 - - [09/Mar/2021:18:29:11 +0000] "GET / HTTP/1.1" 403 153 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:86.0) Gecko/20100101 Firefox/86.0" "-"

172.17.0.1 - - [09/Mar/2021:18:29:11 +0000] "GET /favicon.ico HTTP/1.1" 404 153 "http://localhost:8080/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:86.0) Gecko/20100101 Firefox/86.0" "-"

2021/03/09 18:29:11 [error] 32#32: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/"

The Nginx 403 Forbidden error occurs when a client attempts to access a section of the webserver without adequate permissions. When Nginx accesses a directory, it attempts to generate an index of its files and present them to the browser or client. However, the default configuration disables directory indexing, leading to the display of the 403 forbidden error instead.

Incorrect Index File

The try_files tries the literal path you specify in relation to the defined root directive and sets the internal file pointer. If you have directory indexing off, and is having this problem, it’s probably because the try_files you are using has a directory option:

location / {
  try_files $uri $uri/ /index.html index.php;
}

to

location / {
  try_files $uri /index.html index.php;
}

Incorrectly set permissions

This error can also result from files and directories having incorrectly set permissions. In order to resolve this , change the directories permission to 755 and the file permissions to 644 . Make sure that the user running the Nginx process owns the files. For example, set user to www-data:

sudo chown -R www-data:www-data *

Finally, set the directory and file permissions as:

sudo chmod 755 {dir}
sudo chmod 644 {files}