I'm running on ubuntu-2204 in GitHub Action to set up a simple web server using Nginx. I want to use Nginx as a reverse proxy to send requests to the backend PHP-FPM. However, when I set the root directive to $GITHUB_WORKSPACE, it doesn't work as expected. I have created a sample repository to demonstrate the problem. Even when serving a static index.html without PHP-FPM configuration. it still can't be found and returns an HTTP 404 error.
Run curl -vf localhost
* Trying 127.0.0.1:80...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to localhost (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 404 Not Found
< Server: nginx/1.18.0 (Ubuntu)
< Date: Sun, 01 Jan 2023 05:15:29 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 162
< Connection: keep-alive
* The requested URL returned error: 404
The log generated by Nginx says:
2023/01/01 05:15:29 [crit] 2025#2025: *1 stat() "/home/runner/work/gh-action-playground/gh-action-playground/public/" failed (13: Permission denied), client: 127.0.0.1, server: _, request: "GET / HTTP/1.1", host: "localhost"
2023/01/01 05:15:29 [crit] 2025#2025: *1 stat() "/home/runner/work/gh-action-playground/gh-action-playground/public/" failed (13: Permission denied), client: 127.0.0.1, server: _, request: "GET / HTTP/1.1", host: "localhost"
The problem seems to be a common permission issue. I created an action called Fix permission to try to fix it.
- name: Fix permission
run: |
sudo usermod -aG docker www-data
sudo chown -R www-data:www-data ${{ github.workspace }}
sudo chmod -R 777 public
sudo -u www-data bash -c 'cd ${{ github.workspace }}/public; pwd; whoami'
sudo -u www-data stat /home/runner/work/gh-action-playground/gh-action-playground/public
sudo -u www-data stat /home/runner/work/gh-action-playground/gh-action-playground
sudo -u www-data stat /home/runner/work/gh-action-playground
sudo -u www-data stat /home/runner/work
sudo -u www-data stat /home/runner
sudo -u www-data stat /home
sudo -u www-data stat /
echo '<h1>test</h1>' >> public/index.html
echo "::group::debug"
ls -al
ls -al ../
ls -al ../../
ls -al ../../../
df -h
ps auxwww
mount
echo "::endgroup::"
but it failed. The output of the failed job can be found at https://github.com/Gasol/gh-action-playground/actions/runs/3815377892/jobs/6490328178.
As you can see, the root is set to /home/runner/work/gh-action-playground/gh-action-playground/public
, which is the correct location of the index.html file.
I'm using the following script to ensure that the www-data user have permission to change directory to the root directory of the virtual server.
sudo -u www-data bash -c 'cd ${{ github.workspace }}/public; pwd; whoami'
The output was correct as the following.
/home/runner/work/gh-action-playground/gh-action-playground/public
www-data
The ps
command shows the nginx was running as the www-data
user
root 2024 0.0 0.0 81896 2176 ? Ss 05:15 0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data 2025 0.0 0.0 82652 6608 ? S 05:15 0:00 nginx: worker process
www-data 2026 0.0 0.0 82652 6608 ? S 05:15 0:00 nginx: worker process
The interesting part is that it works when I move the root directory to /var/html/public. So, why can't Nginx access the index.html file in the $GITHUB_WORKSPACE/public directory? What's the difference between $GITHUB_WORKSPACE and /var/html/public?