O
O
okkkman2020-07-28 18:50:33
Nginx
okkkman, 2020-07-28 18:50:33

How to set up a server to run two separate applications?

Hello.

  1. I have a large front-end on Vue.js (the admin panel there), built with Webpack (Node.js + a bunch of modules and plugins) without Vue-CLI.
    There are several configurations for development and production, i.e. while Node.js is used only to create the final build (files appear in ./dist)

  2. There is also a back-end API on the Symfony PHP framework (+ Redis, RabbitMQ and MySQL)
    Nginx is used as a web server



These two parts are not yet connected in any way, but now the time has come to do this and many questions have arisen, because. I have never had to write complex SPA applications and package them in Docker before.

Questions:

1. How to correctly and, most importantly, safely write two configs for Nginx?
The first one should open the compiled Vue application, and the second one to communicate with the API

. At the same time, static files uploaded via the API (images, videos, etc.), which are stored in the /assets/uploads folder of the Symfony application, should also be opened at: www .site.ru/uploads/*

+ In the future, it is planned to connect SSR in a light bundle with Express.js, perhaps this should also be taken into account when configuring the server

2. Are there any nuances in dockerization?

In general, any advice, examples and reflections will be very helpful

. Many thanks in advance!

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexey, 2020-07-28
@okkkman

If you are using Docker and directly want to dockerize with scaling, then use the docker network to communicate between containers to start with.
You must have 1 container with nginx outside (port 80 and / or 443), 1 container for building a VueJS application, 1 container for working with a PHP project, and then what do you have there, according to the container for the DBMS (1 Redis, 1 RabbitMQ , 1 MySQL). Give each container a normal unique name so that they can be connected to each other by dns name. Let's go outside the port only for nginx, it will be responsible for everything.
1. The nginx container returns the static collected from the VueJS application. Actually, everything is as usual - you collected dist, and you give it away from it. Ideally, collect in a separate container with NodeJS, and copy the received data from dist to some volume, probably and connect it to the container with Nginx. This can be done at the docker-compose file level and automated when the project is built. The same volume can also be connected to the container with the backend-api, then it will be able to work with the files that have been uploaded.
2. From the first container from nginx to upstream, send backend-api, which will access another container where PHP and your symphony project itself are running. Do not let this container go outside, connect to the first container through the name. This way you can run several containers with api, specifying all their dns names in the required upstream section. You already get horizontal scalability, these containers can then be run on different servers altogether by connecting them, for example, using Docker Swarm or Kubernetes. Again, everything can be arranged at the level of Docker Compose configuration files, it’s not difficult there, just read the documentation.
3. Run all containers with a DBMS in separate containers, where necessary - create a volume to store the database. Do not let them outside either, bind at the Docker level with the container (s) with the backend-api. In general, if a serious load is expected, then the DBMS is generally recommended to be run not in containers, but then it will be a little more difficult to automate the binding and scaling. To begin with, it is possible in containers, when it comes, this load is then ... Moreover, containers with a DBMS can also be launched in several instances, replication can be done between them or sharding in general. All this can probably be done in all the described databases, but of course you will have to suffer with sharding. Replication is the easiest. And already connect to them from the backend-api by dns-names, as you configure.
Something like this.

D
Dmitry Amelchenko, 2020-07-29
@i1677960

my nginx config, might come in handy. Without docker, back on rails and vue front

map $sent_http_content_type $expires {
  "text/html" epoch;
  "text/html; charset=utf-8" epoch;
  default off;
}

map $cookie_SESSION $logme {
    "" $perhaps;  # If the cookie is missing, we log if $perhaps
    default   0;
}

map $status $loggable {
    ~^[23]  0;
    default 1;
}

split_clients $request_id $perhaps {
    1%        1;  # $perhaps is true 1% of the time
    *         0;
}

server {
  listen 443 ssl http2;
  server_name .medicus72.ru;

  set $rails_api /home/medicus/medicus-api;

  root $rails_api/current/public;

  # listen [::]:443 ssl;

  gzip on;
  gzip_types text/plain application/xml text/css application/javascript;
  gzip_min_length 1000;

  try_files $uri @nuxt;

  location @nuxt {
    proxy_pass http://lombd.ru-central1.internal:4000; # set the adress of the Node.js instance here

    include proxy_params;
    access_log /home/medicus/medicus72.ru/shared/logs/$host.log main;
    access_log /home/medicus/medicus72.ru/shared/logs/sslparams.log sslparams if=$logme;
    expires $expires;
  }

  location ~ ^/(api|rails) {
    proxy_pass http://lombd.ru-central1.internal:4001;

    include proxy_params;
    access_log /home/medicus/medicus-api/shared/log/$host.log main;
  }

  location ~ ^/(assets|packs) {
    expires max;
    gzip_static on;
  }

  location ~ \.php$ { deny all; }

  ssl_certificate /etc/letsencrypt/live/prd.medicus72.ru/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/prd.medicus72.ru/privkey.pem;
  ssl_trusted_certificate /etc/letsencrypt/live/prd.medicus72.ru/chain.pem;
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
  # include /etc/letsencrypt/options-ssl-nginx.conf;
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question