Deploy multiple vue projects under the same domain name using nginx and use a reverse proxy approach

  • 2020-05-17 07:39:57
  • OfStack

The effect

Currently, there are two projects (project1, project2) and one index.html that comes with nginx. I added the corresponding link code (which will be pasted later) to manage the routing of subprojects.

I expect the following (assuming ip: localhost, port: 8080) :

[

http://localhost:8080/ enter the outermost layer of index.html
http: / / localhost: 8080 / project1 into project 1
http: / / localhost: 8080 / project2 into project 2

]

Without further ado, configure

Vue configuration

I used the project built by vue-cli2, so I need to modify some configuration parameters of vue accordingly.

index.js in the config folder, because it is packaged, we need to change the corresponding project name in build.assetsPublicPath, for example


// project1
module.exports = {
 dev: {},
 build: {
  assetsPublicPath: '/project1/' //  Attention before and after   ' /'
 }
}

// project2
module.exports = {
 dev: {},
 build: {
  assetsPublicPath: '/project2/' //  Attention before and after   ' /'
 }
}

The prod.env.js in the config folder is modified to look like this:


// project1
module.exports = {
 NODE_ENV: '"production"',
 BASE_API: '"/api/pro1"' //  We'll be right here  nginx  Configure corresponding 
}

// project2
module.exports = {
 NODE_ENV: '"production"',
 BASE_API: '"/api/pro2"' //  We'll be right here  nginx  Configure corresponding 
}

[note] because I used BASE_API as the proxy prefix in the project, if yours is not here, you need to find your own proxy configuration

Since everyone's vue-router file configuration is not the same, you need to find your router profile, internally modified as:


//  I used the  history  Mode, hash  I didn't test the mode, it felt like 1 The effect of the sample 
// project1
export default new Router({
 base: '/project1/', //  Be careful to change the name of your subproject, which corresponds to yours  build.assetsPublicPath
 mode: 'history',
 scrollBehavior: () => ({ y: 0 }),
 routes: []
})

// project2
export default new Router({
 base: '/project2/', //  Be careful to change the name of your subproject, which corresponds to yours  build.assetsPublicPath
 mode: 'history',
 scrollBehavior: () => ({ y: 0 }),
 routes: []
})

[note] there may be an error in npm run build:.tap (*) or something like that, because there is a problem with the html-webpack-plugin version in the package, you can execute the following statement


#  This version is yours  package.json  Version, but you need to specify this version again 

$ npm i html-webpack-plugin@4.0.0-alpha -D

Nginx configuration

First of all my directory is like this, irrelevant files all with... show


.
 ├ ─ conf
 │   ├ ─ ... #  Other documents 
 │   └ ─ nginx.conf
 │ 
 ├ ─ html #  I'm not going to use the rest just for now  
 │   ├ ─ project1
 │   │   └ ─ static
 │   │     ├ ─ css
 │   │     ├ ─ fonts
 │   │     └ ─ js
 │   │       ├ ─ g
 │   │       └ ─ V
 │   ├ ─ project2
 │   │    └ ─ static
 │   │      ├ ─ css
 │   │      ├ ─ fonts
 │   │      └ ─ js
 │   │        ├ ─ g
 │   │        └ ─ V
 │   ├ ─ index.html
 │   └ ─ 50x.html
 └ ─ ... #  Other documents 

[explanation] my nginx directory is native and contains an html folder internally. To save trouble, I will use this directory directly. Of course, you can also specify other directories.

Now let's start configuring the nginx.conf file under the conf folder

I modified it directly on the original file, and the modified configuration was all in http module, so I directly used... Instead.


# ...
#  The reverse proxy 
http {
  include mime.types;
  default_type application/octet-stream;

  #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  #         '$status $body_bytes_sent "$http_referer" '
  #         '"$http_user_agent" "$http_x_forwarded_for"';

  sendfile    on;
  keepalive_timeout 65;

  client_max_body_size 20M;
  client_body_buffer_size 10M;
  large_client_header_buffers 4 128k;
  
  #  You can do clustering here 
  upstream p1_server {
    server localhost:8081;
  }

  #  You can do clustering here 
  upstream p2_server {
    server localhost:8082;
  }

  server {
    listen 8080;
    server_name localhost;
    charset utf-8;

    proxy_connect_timeout 180;
    proxy_send_timeout 180;
    proxy_read_timeout 180;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarder-For $remote_addr;

    root html; #  This specifies the folder we just created 
    
    #  Total item routing, I'm lazy to write directly in the same 1 A file 
    #  If there are many you can configure more than one  conf  File, use  include  Correlation in 
    location / {
      try_files $uri $uri/ /index.html; #  So you can kind of specify here  html  subfolder  index.html
    }
    
    # project1
    #  This is where we were  vue  In the project  config/index.js  The configuration of the  build.assetsPublicPath . 
    #  Is also  vue  Configured in the project  router  In the  base
    location ^~ /project1 {
      try_files $uri $uri/ /project1/index.html; #  So you can kind of specify here  html  folder  project1  folder   the  index.html
    }
    
    # project2
    #  Here is the project 2 The configuration of the 
    location ^~ /project2 { # 
      try_files $uri $uri/ /project2/index.html; #  So you can kind of specify here  html  folder  project2  folder   the  index.html
    }
    
    #  Here is the  project1  Configure the interface to be invoked 
    location /api/pro1 { #  This is where  vue  In the project  prod.env.js  The configuration of the  BASE_API 
      proxy_redirect off;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://p1_server; #  Here the  p1_server  Corresponding to the above configuration  upstream p1_server {} , here can do a cluster, I do not need, simple configuration 
    }
    
     #  Here is the  project1  Configure the interface to be invoked 
    location /api/pro2 { #  This is where  vue  In the project  prod.env.js  The configuration of the  BASE_API
      proxy_redirect off;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://p2_server; #  Here the  p2_server  Corresponding to the above configuration  upstream p2_server {} , here can do a cluster, I do not need, simple configuration 
    }

    # ...
  }

  # ...
}

Finally, I posted the modified index.html code

Because I am appended, so directly post my appended code, other USES...


...
<p><em>Thank you for using nginx.</em></p> <!--  To show the location  -->

<!-- start:  additional -->
<hr>
<a href="/project1" rel="external nofollow" > project 1</a> | <a href="/project2" rel="external nofollow" > project 2</a>
<!-- end:  additional -->

</body> <!--  To show the location  -->

Final debugging

After all the configuration is completed, we can start nginx. Please solve this problem by yourself.

Launch is successful, we type http://localhost:8080 in the browser and we see,

Click on the project 1, we can see the links into http: / / localhost: 8080 / project1

Click on project 2, link into http: / / localhost: 8080 / project2, fully meet our expectations, that is success.

[forced to explain 1 under metaphysics] that day the configuration is good, 1 start on the error, I finally gave up. But the second day, ready to check, 1 boot all good, I have a face confused! If you have the same problem as me, let it go, maybe the next day.


Related articles: