Search code examples
httpcommand-linesingle-page-applicationhttpserver

Simple command-line http server for Single Page App


There are various one-liner HTTP server commands, e.g. the best-known is probably python -m http.server. I'm looking for a similar command which would run a server that ignores the file path and send all paths to a specific file, e.g. if you visit /foo or /bar, it will serve both from index.html.

And ideally relying on as little installation hassle as possible for a typical Linux/MacOS machine. (e.g. python and http.server will come out of the box to many users.)

It's the same functionality offered by the htaccess rule RewriteRule (.*) /index.html, but without needing to setup Apache. Not sure if any of those one-liner servers support something similar to it, like a command-line argument that would declare the default file for all paths.


Solution

  • Using php, there is a built in development server from the command line, which is super useful.

    First example, in the current folder, serving only the file index.html at 127.0.0.1, port 8080:

    php -S 127.0.0.1:8080 index.html
    

    Output

    PHP 7.2.24-0ubuntu0.18.04.1 Development Server started at Mon Dec 23 15:37:03 2019
    Listening on http://127.0.0.1:8080
    Document root is /home/nvrm
    Press Ctrl-C to quit.
    

    On this case, only the file index.html will respond at http://127.0.0.1:8080

    Any http calls on this port, will be redirected to index.html.


    Second example binding the whole current folder to localhost, port 5555:

    php -S localhost:5555 
    

    Output:

    PHP 7.2.24-0ubuntu0.18.04.1 Development Server started at Mon Dec 23 09:59:44 2019
    Listening on http://localhost:5555
    Document root is /home/nvrm
    Press Ctrl-C to quit.
    

    This will serve index.html at the adresss http://localhost:5555

    If a file index.php exist, then it will be served first (interpreted as php)

    All others files in the (sub)folder(s) are served, example http://localhost:5555/css/style.css will respond as well, if this folder and file exist of course. (Otherwise respond error 404)


    Third example, to run from anywhere, pass in a path as third param. Using a local ip is also possible, by doing so, the files are available on the whole local network. Example local ip: 192.168.1.23. To retrieve our local ip, we can use ifconfig.

    php -S 192.168.1.23:8080 ~/www
    

    This will serve the folder www in the home folder on the port 8080: http://192.168.1.23:8080 to everyone on the network.


    Obviously, we can run many servers on many different ports in parallel^ Very useful to dev, but also to quickly share files between virtual machines, devices, phones etc.


    Alternatively. Listen to all interfaces by using 0.0.0.0 as ip adress. In some cases, this is the sole command that serve well across every devices in the local network.

    php -S 0.0.0.0:5555 
    

    And then use the local ip as url: http://192.168.1.23:5555


    To be able to close the terminal, but to keep the server running, we can use nohup:

    nohup php -S localhost:8080 &
    

    Then to kill it, quickly:

    fuser -k 8080/tcp 
    

    Last example, using a hostname. To retrieve the machine hostname from the console, the unix command is hostname.

    php -S $(hostname):9999
    

    Will bind to something like http://<session_name>-<machine_name>:9999


    It is possible to install only the cli version of php to run this (~4mo). It's included in the core.

    sudo apt install php-cli
    

    For more advanced server usages, yet simple to configure, warmly, I recommend caddy server