Search code examples
htmlnode.jsexpressnginxraspberry-pi

Express/nginx/serve-favicon site of Raspberry Pi not serving favicon


Missing Favicon

Express/nginx/serve-favicon

I went through this fireship tutorial to setup my own http server on an rPi, and thought it would be cool to add a favicon, but so far nothing works. I am a novice with nginx/express so have probably made some elementary mistake.

  • I have nginx serving a static site running with node and express.
  • I have the serve-favicon dependency installed.
  • I have tested the file with 'file favicon.ico' and it is fine.
  • favicon.ico is in the root directory:

file_structure

Express - server.js

const { readFileSync, writeFileSync } = require('fs')
const express = require('express')
const app = express()
const path = require('path')
app.listen(5000, () => console.log('http://localhost:5000/'))

const favicon = require('serve-favicon')
app.use(favicon(path.join(__dirname,'favicon.ico')));

HTML (tried with/without)

<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">

nginx - default

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/html;

        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                proxy_pass http://localhost:5000;
                try_files $uri $uri/ =404;
        }

        location = /favicon.ico {
                try_files $uri =204;
                log_not_found off;
                access_log off;
        }

}

After adding location = /favicon.ico {...} to the nginx default file, I no longer get a 404, but the file is still not being served.

  • Shouldn't the file be served if there is a location for / anyway?
  • Is proxy_pass adding a complication I don't know how to resovlve.

edit:

Tried below suggestion but still no joy.

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/html;

        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                try_files $uri $uri/ =404;
                proxy_pass http://localhost:5000;
        }

        location = /favicon.ico {
                 alias /var/www/html/favicon.ico;
        }

}

edit 2:

I am able to see favicon.ico locally with nginx and server.js in the following setup:

/etc/nginx/sites-available/default

        location = /favicon.ico {
                  alias /var/www/html/favicon.ico;
        }

server.js

app.use("/favicon.ico", express.static("./favicon.ico"));

the icon is served when visiting http://localhost:5000 but not when visiting the network address, and not when visiting the external site address

edit 3:

I am not sure how, but it has spontaneously started working using express.

  • I have the file being served with express
  • I have the file being given a proxy_pass with nginx
    • It seems any route must be explicitly laid out like this to work
  • the link to the file referenced in the HTML doesn't seem to be neccessary

Solution

  • You don't need extra dependencies for this.

    First approach:

    Serve using express. (It is not recommended to serve static files using Node/Express. But it is okay for tiny projects)

    • favicon.ico is in the root directory:

    Express - server.js:

    app.use("/favicon.ico", express.static("./favicon.ico"));
    

    nginx - default:

    location = /favicon.ico {
        proxy_pass http://localhost:5000/favicon.ico;
    }
    

    Second approach:

    Serve using Nginx.

    • favicon.ico is in the /var/www/html/ directory:

    nginx - default:

    location = /favicon.ico {
        alias /var/www/html/favicon.ico;
    }