26

I want to deploy an Angular 2 application on an Apache server. I've read various guides like this and this but none of them is working. I have npm and ng installed on the server.

In a nutshell, here's what I did:

  1. Cloned complete project repository on my server.
  2. Installed dependencies using npm install.
  3. Used ng build --prod command and it created a dist directory.
  4. Changed apache root to /var/www/html/dist directory.
  5. Enabled mod_rewrite, restarted apache and added this .htaccess in my dist directory.
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.html$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.html [L]
</IfModule>

But only my home page domain.com works, other pages like domain.com/login, domain.com/register etc. throw 404 error. Even domain.com/index.html/login doesn't work.

The application works fine on my local system where I'm developing it using ng serve. What am i missing?

Srdjan Pazin
  • 103
  • 2
  • 5
Kanav
  • 2,695
  • 8
  • 34
  • 56

9 Answers9

23

Create .htaccess file in the root folder and paste this in .htaccess

 <IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>
Amarjit Singh
  • 2,068
  • 19
  • 52
Sumit Jaiswal
  • 787
  • 8
  • 11
18

It appears i was missing this in my /etc/apache2/sites-enabled/000-default.conf file. After adding this and restarting apache, website runs fine.

<Directory "/var/www/html/dist">
  AllowOverride All
</Directory>
Kanav
  • 2,695
  • 8
  • 34
  • 56
8

1) Change base tag in index.html file

<base href="./">

2) Build Project:

ng build --prod --base-href /myproject/

3) Add your dist files in "/usr/local/apache2/htdocs/myproject/"

4)On Apache Server 2.4 (httpd) In File: /usr/local/apache2/conf/httpd.conf setup "FallbackResource"

<Directory "/usr/local/apache2/htdocs">
   ...
   FallbackResource /myproject/index.html
</Directory>

full file "/usr/local/apache2/conf/httpd.conf":

ServerRoot "/usr/local/apache2"

Listen 80

LoadModule mpm_event_module modules/mod_mpm_event.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule reqtimeout_module modules/mod_reqtimeout.so
LoadModule filter_module modules/mod_filter.so
LoadModule mime_module modules/mod_mime.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule env_module modules/mod_env.so
LoadModule headers_module modules/mod_headers.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so

LoadModule unixd_module modules/mod_unixd.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so

<IfModule !mpm_prefork_module>
    #LoadModule cgid_module modules/mod_cgid.so
</IfModule>
<IfModule mpm_prefork_module>
    #LoadModule cgi_module modules/mod_cgi.so
</IfModule>

LoadModule dir_module modules/mod_dir.so
LoadModule alias_module modules/mod_alias.so
LoadModule rewrite_module modules/mod_rewrite.so

<IfModule unixd_module>
User daemon
Group daemon

</IfModule>
ServerAdmin you@example.com

<Directory />
    AllowOverride none
    Require all denied
</Directory>

DocumentRoot "/usr/local/apache2/htdocs"
<Directory "/usr/local/apache2/htdocs">
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
    FallbackResource /myproject/index.html
</Directory>

<IfModule dir_module>
    DirectoryIndex index.html
</IfModule>

<Files ".ht*">
    Require all denied
</Files>

ErrorLog /proc/self/fd/2

LogLevel warn

<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common

    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>

    CustomLog /proc/self/fd/1 common

</IfModule>

<IfModule alias_module>

    ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/"

</IfModule>

<IfModule cgid_module>
</IfModule>


<Directory "/usr/local/apache2/cgi-bin">
    AllowOverride None
    Options None
    Require all granted
</Directory>

<IfModule headers_module>
    RequestHeader unset Proxy early
</IfModule>

<IfModule mime_module>
    TypesConfig conf/mime.types

    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz

</IfModule>

<IfModule proxy_html_module>
Include conf/extra/proxy-html.conf
</IfModule>

<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>
rafambbr
  • 570
  • 8
  • 15
5
  1. Change base tag in index.html file

    <base href="./">

  2. Create a build after that

    ng build --prod

  3. Now you will have a new folder dist, deploy dist folder now. It should work.

krunal shah
  • 16,089
  • 25
  • 97
  • 143
5

For Apache, to redirect any request to index.html, you need a .htaccess file in the root. Just create a .htaccess in your dist folder (same level as index.html), I assume that's the public root of your app, and paste this in the .htaccess file:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# not rewrite css, js and images
RewriteCond %{REQUEST_URI} !\.(?:css|js|map|jpe?g|gif|png)$ [NC]
RewriteRule ^(.*)$ /index.html?path=$1 [NC,L,QSA]

Now, no matter what path you're requesting, Apache will always serve your index.html file, except requests to actual existing files (RewriteCond %{REQUEST_FILENAME} !-f) and requests to css, js etc. (RewriteCond %{REQUEST_URI} !.(?:css|js|map|jpe?g|gif|png)$) - which needed to be excluded, because you actually want those. Also, the Apache's mod_rewrite extension needs to be enabled for this to work. Most often, it is enabled. If not, ask your hosting provider

Md Ayub Ali Sarker
  • 10,795
  • 4
  • 24
  • 19
3

Change base tag in index.html file

Run:

ng build --prod -bh "http://example.net"
Fernix
  • 361
  • 3
  • 10
1

open your index.html in dist directory after

ng build --prod

and Chang base element to your site DNS name for example for my local apache server I changed from

<base href="/">

to

<base href="//localhost/angular2/ng2-cli/dist/">
Mohannd
  • 1,288
  • 21
  • 20
1

I have create distribution directory as public. I have changed only virtual host setting of apache.

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName frontend.loc
    DocumentRoot /var/www/frontend/public
    <Directory "/var/www/frontend/public/">
        Options FollowSymLinks
        Allow from all
        AllowOverride All
        <IfModule mod_rewrite.c>
                RewriteEngine on
                RewriteCond %{REQUEST_FILENAME} !-d
                RewriteCond %{REQUEST_FILENAME} !-f
                RewriteRule ^(.*)$ index.html
        </IfModule>
    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

~

Ankit Vishwakarma
  • 1,573
  • 16
  • 13
1

As per official Angular documentation for angular deployment (https://angular.io/guide/deployment)

A routed application should support "deep links".

We need to enable mod_rewrite module, there are various ways to do this. On an ubuntu machine we can run following commands:

sudo a2enmod rewrite
sudo systemctl restart apache2

we also need to allowoverride in configuration file so that .htaccess file can run:

  <Directory /var/www/>
  Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>

Then in .htaccess file, copy following lines for rewriting:

RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html

If it still doesn't work then best solution is check error log, in my case I solved the issue by checking logs where I find that mod_rewrite module was not installed so I had installed mod_rewrite manually and it worked.

Krish
  • 379
  • 2
  • 8