Search code examples
angularproduction

why I need web-server to load angular webapp


I put my angular webapp into production and reading the official documentation I realized that I need a web server, is it so? In this case when I upload my online webapp we will need to specify the port in the url? for example www.mywebapp.com:4200 If not, how does it work? Thanks


Solution

  • I see a lot of confusion here. I'll explain as better as I can.

    When you are serving the app with command ng serve you are about to run a web-server locally made in nodeJS. By default it run on port 4200 but you can change it by using a flag: ng serve --port 4567. By doing this you wont reach your site if you type localhost:4200 in the browser, but you need to use the 4567 port.

    The reason why by default the port is 4200 is because most likely there aren't other applications using that port.

    When you build your application the result is a dist folder, that contain a list of files. All those files can be interpreted by the browser, while the *.ts doesn't.

    Since Typescript is a superset of Javascript it needs to be compiled. That what the build does, mainly. So now you have this list of files ready to be deployed. Here comes the question you asked, do I need a web server?

    It depends.

    If the application doesn't need to go online and doesn't do any http calls at all or interact with a backend / db you can simply open the index.html directly on your browser and it will works fine. Hence no need to use a web-server.

    If this is not your case, then you need a web-server. The reason is simple, every site is hosted on a server. A machine with a public IP that can be resolved everywhere (excluding cases when the national ISP (internet service provider) cut the connection at the beginning).

    Let's take SO as an example. If you type, in the browser, www.stackoverflow.com you will reach the site. If you type www.stackoverflow.com:80 you will get the same result.

    Have a look here: https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers

    if you scroll down a bit you will see that the port 80 is used for HTTP requests. That's the standard, and all the browsers by default, when you try to navigate to a site, will use this port (for HTTPS requests the port change to 443, but the logic is kinda the same).

    You could also configure your server's firewall to NOT accept any connections on port 80 but on port 12443, and put a web-server that is listening on that port. The result will be that if you type www.mysite.com the browser will give you the classic error "Cannot reach www.mysite.com". But if you type mysite.com:12443 you will get the wanted result. In this case, the dist folder's content.

    You also asked: What happens if there are more than one web app in the server?

    You have two choice, to me:

    1) Every web server use different ports. You can then navigate to your specific content using different ports on requests:

    www.mysite.com -> standard site on port 80.
    www.mysite.com:456 -> another site on port 456
    and so on...
    

    2) Use a reverse-proxy to handle all the different requests on a specified port (by default, 80 and 443 | HTTP and HTTPS).

    This topic is really complex but let's take this as an example. You have three different sites that you want to host on your server.

    You could use docker with nginx (nginx is a webserver, like IIS or apache) and nginx-proxy to setup the perfect scenario. I'll post some code that I personally use on my VPS if someone is interessed.

    I've a Dockerfile to build the main container:

    FROM nginx:alpine
    COPY ./site/ /usr/share/nginx/site_volume
    COPY ./static/ /usr/share/nginx/assets_volume
    COPY ./site.conf /etc/nginx/conf.d/default.conf
    

    The nginx config:

    server {
        listen 80;
        server_name  mysite.com;
    
        root /usr/share/nginx/site_volume;
    }
    
    server {
        listen 80;
        server_name www.mysite.com
    
        root /usr/share/nginx/site_volume;
    }
    
    server {
        listen 80;
        server_name  static.mysite.com;
    
        root /usr/share/nginx/assets_volume;
    }
    

    The result, after building and running the container:

    docker build -t my-site .
    docker run -d -p 80:80 my-site
    

    is that when I navigate to mysite.com or www.mysite.com I will see something. If I navigate to static.mysite.com I will see something else, not related to the content on the first two navigations.

    EDIT, if someone is interessed on how to run those containers with an HTTPS redirect I can add some code with some details.