{"id":5497,"date":"2025-10-20T17:00:28","date_gmt":"2025-10-20T13:30:28","guid":{"rendered":"https:\/\/parmin.cloud\/blog\/?p=5497"},"modified":"2025-10-20T17:00:28","modified_gmt":"2025-10-20T13:30:28","slug":"%d8%a7%d9%86%d8%aa%d8%b4%d8%a7%d8%b1-%d8%a7%d9%be-vue-vuetify-%d8%a8%d8%a7-nginx-%d9%88-%d8%a7%d8%aa%d8%b5%d8%a7%d9%84-%d8%a8%d9%87-api-node-express-%d8%b1%d9%88%db%8c-%db%8c%da%a9-%d8%b3%d8%b1","status":"publish","type":"post","link":"https:\/\/parmin.cloud\/blog\/%d8%a7%d9%86%d8%aa%d8%b4%d8%a7%d8%b1-%d8%a7%d9%be-vue-vuetify-%d8%a8%d8%a7-nginx-%d9%88-%d8%a7%d8%aa%d8%b5%d8%a7%d9%84-%d8%a8%d9%87-api-node-express-%d8%b1%d9%88%db%8c-%db%8c%da%a9-%d8%b3%d8%b1\/","title":{"rendered":"\u0627\u0646\u062a\u0634\u0627\u0631 \u0627\u067e Vue + Vuetify \u0628\u0627 Nginx \u0648 \u0627\u062a\u0635\u0627\u0644 \u0628\u0647 API Node\/Express \u0631\u0648\u06cc \u06cc\u06a9 \u0633\u0631\u0648\u0631"},"content":{"rendered":"<p>\u062f\u0631 \u0627\u06cc\u0646 \u0645\u0642\u0627\u0644\u0647 \u0642\u062f\u0645\u200c\u0628\u0647\u200c\u0642\u062f\u0645 \u0633\u0627\u062e\u062a \u06cc\u06a9 \u0627\u067e To\u2011Do \u0628\u0627 <strong>Vue.js<\/strong> \u0648 <strong>Vuetify<\/strong>\u060c \u062a\u0647\u06cc\u0647 \u062e\u0631\u0648\u062c\u06cc production \u0648 \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc <strong>Nginx<\/strong> \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 reverse proxy \u0631\u0627 \u062a\u0648\u0636\u06cc\u062d \u0645\u06cc\u200c\u062f\u0647\u06cc\u0645. \u0633\u067e\u0633 \u062a\u0645\u0631\u06a9\u0632 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645 \u0631\u0648\u06cc \u067e\u0631\u0633\u0634 \u0645\u0647\u0645: \u0627\u06af\u0631 API (\u0645\u062b\u0644\u0627\u064b Node.js\/Express) \u0631\u0648\u06cc \u0647\u0645\u0627\u0646 \u0633\u0631\u0648\u0631 \u0645\u06cc\u0632\u0628\u0627\u0646\u06cc \u0634\u0648\u062f\u060c \u0686\u0637\u0648\u0631 frontend \u0648 API \u0631\u0627 \u0628\u0647 \u0647\u0645 \u0645\u062a\u0635\u0644 \u06a9\u0646\u06cc\u0645 \u0648 \u0686\u0647 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a\u06cc \u0644\u0627\u0632\u0645 \u0627\u0633\u062a.<\/p>\n<h2 id=\"overview\">1. \u0645\u0631\u0648\u0631\u06cc \u0633\u0631\u06cc\u0639: \u0686\u0631\u0627 Vuetify \u0648 \u0627\u062c\u0632\u0627\u06cc \u0622\u0645\u0627\u062f\u0647<\/h2>\n<p>\u06a9\u0627\u0645\u067e\u0648\u0646\u0646\u062a\u200c\u0647\u0627 \u062f\u0631 \u062a\u0648\u0633\u0639\u0647 \u0641\u0631\u0627\u0646\u062a\u200c\u0627\u0646\u062f \u0645\u062f\u0631\u0646 \u0628\u0633\u06cc\u0627\u0631 \u0645\u0647\u0645\u200c\u0627\u0646\u062f. Vuetify \u06cc\u06a9 \u06a9\u062a\u0627\u0628\u062e\u0627\u0646\u0647 UI \u0645\u0628\u062a\u0646\u06cc \u0628\u0631 Material Design \u0628\u0631\u0627\u06cc Vue \u0627\u0633\u062a \u06a9\u0647 \u0628\u0627 \u0627\u0631\u0627\u0626\u0647 \u06a9\u0627\u0645\u067e\u0648\u0646\u0646\u062a\u200c\u0647\u0627\u06cc \u0622\u0645\u0627\u062f\u0647 (v-btn\u060c v-text-field\u060c v-card \u0648 &#8230;) \u062a\u0648\u0633\u0639\u0647 \u0633\u0631\u06cc\u0639\u200c\u062a\u0631\u060c \u06cc\u06a9\u067e\u0627\u0631\u0686\u06af\u06cc \u0638\u0627\u0647\u0631\u06cc \u0648 \u0642\u0627\u0628\u0644\u06cc\u062a \u062a\u0646\u0638\u06cc\u0645 \u0628\u0627\u0644\u0627 \u0631\u0627 \u0641\u0631\u0627\u0647\u0645 \u0645\u06cc\u200c\u06a9\u0646\u062f. \u062f\u0631 \u0627\u06cc\u0646 \u0631\u0627\u0647\u0646\u0645\u0627 \u0627\u0632 Vuetify \u0628\u0631\u0627\u06cc \u0633\u0627\u062e\u062a \u0633\u0631\u06cc\u0639 \u06cc\u06a9 \u0627\u067e To\u2011Do \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0634\u062f\u0647 \u0627\u0633\u062a.<\/p>\n<h2 id=\"build\">2. \u0622\u0645\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u0627\u067e \u0628\u0631\u0627\u06cc Production<\/h2>\n<p>\u067e\u0633 \u0627\u0632 \u062a\u0648\u0633\u0639\u0647 \u0645\u062d\u0644\u06cc\u060c \u0628\u0627\u06cc\u062f \u0627\u067e \u0631\u0627 \u0628\u0627 \u062f\u0633\u062a\u0648\u0631 build \u062a\u0628\u062f\u06cc\u0644 \u0628\u0647 \u0641\u0627\u06cc\u0644\u200c\u0647\u0627\u06cc \u0627\u0633\u062a\u0627\u062a\u06cc\u06a9 (HTML\u060c JS\u060c CSS) \u06a9\u0646\u06cc\u0645 \u062a\u0627 Nginx \u0628\u062a\u0648\u0627\u0646\u062f \u0622\u0646\u200c\u0647\u0627 \u0631\u0627 \u0633\u0631\u0648 \u06a9\u0646\u062f. \u0646\u062a\u06cc\u062c\u0647\u0654 build \u062f\u0631 \u067e\u0648\u0634\u0647\u0654 <code>dist<\/code> \u0642\u0631\u0627\u0631 \u0645\u06cc\u200c\u06af\u06cc\u0631\u062f \u0645\u06af\u0631 \u0627\u06cc\u0646\u06a9\u0647 \u0645\u0633\u06cc\u0631 \u062e\u0631\u0648\u062c\u06cc \u0631\u0627 \u062f\u0631 <code>package.json<\/code> \u062a\u063a\u06cc\u06cc\u0631 \u062f\u0647\u06cc\u062f.<\/p>\n<p>\u0628\u0631\u0627\u06cc \u062a\u0648\u0644\u06cc\u062f \u062e\u0631\u0648\u062c\u06cc \u0645\u0633\u062a\u0642\u06cc\u0645 \u0628\u0647 \u0645\u0633\u06cc\u0631 \u0645\u0646\u0627\u0633\u0628 \u0633\u0631\u0648\u0631\u060c \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u062f \u062f\u0631 <code>package.json<\/code> \u062f\u0633\u062a\u0648\u0631 build \u0631\u0627 \u062a\u063a\u06cc\u06cc\u0631 \u062f\u0647\u06cc\u062f. \u0645\u062b\u0627\u0644:<\/p>\n<pre><code>{\r\n  \"scripts\": {\r\n    \"serve\": \"vue-cli-service serve\",\r\n    \"build\": \"vue-cli-service build --dest \/var\/www\/vuetify-meets-nginx-app\"\r\n  }\r\n}<\/code><\/pre>\n<h2 id=\"nginx\">3. \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc Nginx \u0628\u0631\u0627\u06cc \u0633\u0631\u0648 \u0627\u067e Vue<\/h2>\n<p>\u0645\u0639\u0645\u0648\u0644\u200c\u062a\u0631\u06cc\u0646 \u0631\u0648\u0634 \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 Nginx \u0631\u0648\u06cc \u067e\u0648\u0631\u062a 80\/443 \u06af\u0648\u0634 \u062f\u0647\u062f \u0648 \u0641\u0627\u06cc\u0644\u200c\u0647\u0627\u06cc \u0627\u0633\u062a\u0627\u062a\u06cc\u06a9 \u0627\u067e \u0631\u0627 \u0627\u0632 \u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc \u0627\u06cc \u0645\u062b\u0644 <code>\/var\/www\/vuetify-meets-nginx-app<\/code> \u0633\u0631\u0648 \u06a9\u0646\u062f. \u0627\u06af\u0631 \u0627\u0632 Vue Router \u062f\u0631 \u062d\u0627\u0644\u062a history \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u062f\u060c \u0628\u0627\u06cc\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \u0646\u0627\u0645\u0634\u062e\u0635 \u0631\u0627 \u0628\u0647 <code>\/index.html<\/code> \u0628\u0627\u0632\u06af\u0631\u062f\u0627\u0646\u06cc\u062f.<\/p>\n<p>\u0646\u0645\u0648\u0646\u0647\u0654 \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc Nginx \u0628\u0631\u0627\u06cc \u0641\u0642\u0637 \u0633\u0631\u0648 frontend:<\/p>\n<pre><code>server {\r\n    listen 80;\r\n    server_name your_domain_or_IP;\r\n\r\n    root \/var\/www\/vuetify-meets-nginx-app;\r\n    index index.html;\r\n\r\n    location \/ {\r\n      try_files $uri $uri\/ \/index.html;\r\n    }\r\n}<\/code><\/pre>\n<h2 id=\"same-server\">4. \u0627\u062a\u0635\u0627\u0644 Vue (\u0641\u0631\u0627\u0646\u062a\u200c\u0627\u0646\u062f) \u0628\u0647 API Node\/Express \u0631\u0648\u06cc \u0647\u0645\u0627\u0646 \u0633\u0631\u0648\u0631<\/h2>\n<p>\u0648\u0642\u062a\u06cc API \u0648 frontend \u0647\u0631 \u062f\u0648 \u0631\u0648\u06cc \u06cc\u06a9 \u0633\u0631\u0648\u0631 \u0642\u0631\u0627\u0631 \u062f\u0627\u0631\u0646\u062f\u060c \u0628\u0647\u062a\u0631\u06cc\u0646 \u0631\u0648\u0634 \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647:<\/p>\n<ol>\n<li>API \u0631\u0627 \u0631\u0648\u06cc \u06cc\u06a9 \u067e\u0648\u0631\u062a \u062c\u062f\u0627 (\u0645\u062b\u0644\u0627\u064b 3000) \u0627\u062c\u0631\u0627 \u06a9\u0646\u06cc\u062f.<\/li>\n<li>Nginx \u0631\u0627 \u0637\u0648\u0631\u06cc \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc \u06a9\u0646\u06cc\u062f \u06a9\u0647 \u0647\u0645\u0647\u0654 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0628\u0647 \u0645\u0633\u06cc\u0631 \u0645\u0634\u062e\u0635\u06cc \u0645\u062b\u0644 <code>\/api\/<\/code> \u0645\u06cc\u200c\u0622\u06cc\u0646\u062f \u0628\u0647 API \u0641\u0648\u0631\u0648\u0627\u0631\u062f \u0634\u0648\u0646\u062f (proxy_pass).<\/li>\n<li>\u0627\u067e Vue \u0647\u0646\u06af\u0627\u0645 \u0641\u0631\u0627\u062e\u0648\u0627\u0646\u06cc API \u0627\u0632 \u0622\u062f\u0631\u0633 \u0646\u0633\u0628\u06cc \u0645\u0627\u0646\u0646\u062f <code>\/api\/<\/code> \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u062f \u062a\u0627 \u062f\u0631 \u0645\u062d\u06cc\u0637\u200c\u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 (\u0645\u062d\u0644\u06cc\u060c staging\u060c production) \u0646\u06cc\u0627\u0632\u06cc \u0628\u0647 \u062a\u063a\u06cc\u06cc\u0631 \u0646\u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u062f.<\/li>\n<li>\u0645\u0637\u0645\u0626\u0646 \u0634\u0648\u06cc\u062f \u062a\u0646\u0638\u06cc\u0645\u0627\u062a CORS \u0645\u0646\u0627\u0633\u0628 \u0627\u0633\u062a \u06cc\u0627 \u0627\u0632 \u0637\u0631\u06cc\u0642 Nginx \u0646\u06cc\u0627\u0632\u06cc \u0628\u0647 CORS \u0646\u0628\u0627\u0634\u062f \u0686\u0648\u0646 \u0645\u0631\u0648\u0631\u06af\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627 \u0631\u0627 \u0628\u0647 \u0647\u0645\u0627\u0646 domain \u0627\u0631\u0633\u0627\u0644 \u0645\u06cc\u200c\u06a9\u0646\u062f.<\/li>\n<\/ol>\n<h3>4.1 \u0646\u0645\u0648\u0646\u0647: Express API \u0633\u0627\u062f\u0647<\/h3>\n<pre><code>const express = require('express');\r\nconst app = express();\r\napp.use(express.json());\r\n\r\napp.get('\/api\/tasks', (req, res) =&gt; {\r\n  res.json([{ id: 1, text: 'Task 1' }, { id: 2, text: 'Task 2' }]);\r\n});\r\n\r\napp.post('\/api\/tasks', (req, res) =&gt; {\r\n  \/\/ handle creating a task\r\n  res.status(201).json(req.body);\r\n});\r\n\r\nconst PORT = process.env.PORT || 3000;\r\napp.listen(PORT, () =&gt; {\r\n  console.log(`API listening on port ${PORT}`);\r\n});<\/code><\/pre>\n<p>\u062a\u0648\u062c\u0647: \u0645\u0633\u06cc\u0631\u0647\u0627\u06cc API \u0628\u0627 \u067e\u06cc\u0634\u0648\u0646\u062f <code>\/api<\/code> \u062a\u0639\u0631\u06cc\u0641 \u0634\u062f\u0647\u200c\u0627\u0646\u062f.<\/p>\n<h3>4.2 \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc Nginx \u0628\u0631\u0627\u06cc \u0647\u062f\u0627\u06cc\u062a \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc \/api\/ \u0628\u0647 Express \u0648 \u0633\u0631\u0648 \u0641\u0631\u0627\u0646\u062a\u200c\u0627\u0646\u062f<\/h3>\n<pre><code>server {\r\n    listen 80;\r\n    server_name your_domain_or_IP;\r\n\r\n    root \/var\/www\/vuetify-meets-nginx-app;\r\n    index index.html;\r\n\r\n    # Serve static frontend assets\r\n    location \/ {\r\n      try_files $uri $uri\/ \/index.html;\r\n    }\r\n\r\n    # Proxy API requests to Node\/Express\r\n    location \/api\/ {\r\n      proxy_pass http:\/\/localhost:3000\/api\/;\r\n      proxy_http_version 1.1;\r\n      proxy_set_header Upgrade $http_upgrade;\r\n      proxy_set_header Connection 'upgrade';\r\n      proxy_set_header Host $host;\r\n      proxy_cache_bypass $http_upgrade;\r\n      proxy_set_header X-Real-IP $remote_addr;\r\n      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\r\n      proxy_set_header X-Forwarded-Proto $scheme;\r\n    }\r\n}<\/code><\/pre>\n<p>\u062a\u0648\u0636\u06cc\u062d\u0627\u062a \u06a9\u0644\u06cc\u062f\u06cc:<\/p>\n<ul>\n<li>\u0628\u0627 \u0627\u06cc\u0646 \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc\u060c \u062a\u0645\u0627\u0645 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc <code>\/api\/...<\/code> \u0628\u0647 \u0633\u0631\u0648\u06cc\u0633 Node \u0631\u0648\u06cc <code>localhost:3000<\/code> \u0641\u0648\u0631\u0648\u0627\u0631\u062f \u0645\u06cc\u200c\u0634\u0648\u0646\u062f.<\/li>\n<li>\u0627\u0632 \u0622\u0646\u062c\u0627 \u06a9\u0647 \u062f\u0627\u0645\u0646\u0647 \u06cc\u06a9\u0633\u0627\u0646 \u0627\u0633\u062a\u060c \u0645\u0631\u0648\u0631\u06af\u0631 <strong>\u0646\u06cc\u0627\u0632\u06cc \u0628\u0647 \u0627\u0631\u0633\u0627\u0644 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc CORS<\/strong> \u0646\u062e\u0648\u0627\u0647\u062f \u062f\u0627\u0634\u062a. \u0627\u0645\u0627 \u0627\u06af\u0631 API \u0631\u0648\u06cc \u062f\u0627\u0645\u0646\u0647 \u06cc\u0627 \u067e\u0648\u0631\u062a \u0645\u062e\u062a\u0644\u0641 \u0628\u0627\u0634\u062f\u060c \u0628\u0627\u06cc\u062f CORS \u0631\u0627 \u0641\u0639\u0627\u0644 \u06a9\u0646\u06cc\u062f \u06cc\u0627 \u0627\u0632 reverse proxy \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.<\/li>\n<\/ul>\n<h3>4.3 \u0645\u062b\u0627\u0644 \u0641\u0631\u0627\u062e\u0648\u0627\u0646\u06cc \u0627\u0632 Vue<\/h3>\n<p>\u062f\u0631 \u06a9\u062f Vue \u0628\u0647\u062a\u0631 \u0627\u0633\u062a \u0622\u062f\u0631\u0633\u200c\u0647\u0627\u06cc API \u0631\u0627 \u0646\u0633\u0628\u06cc \u0628\u0646\u0648\u06cc\u0633\u06cc\u062f:<\/p>\n<pre><code>\/\/ Example using fetch\r\nfetch('\/api\/tasks')\r\n  .then(res =&gt; res.json())\r\n  .then(tasks =&gt; { \/* use tasks *\/ });\r\n\r\n\/\/ Or with axios\r\naxios.get('\/api\/tasks').then(response =&gt; { \/* use response.data *\/ });<\/code><\/pre>\n<p>\u0628\u0627 \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u062f\u0631 \u0645\u062d\u06cc\u0637 \u062a\u0648\u0644\u06cc\u062f (\u06a9\u0647 Nginx \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627 \u0631\u0627 \u0628\u0647 API \u0641\u0648\u0631\u0648\u0627\u0631\u062f \u0645\u06cc\u200c\u06a9\u0646\u062f) \u0648 \u0645\u062d\u06cc\u0637 \u062a\u0648\u0633\u0639\u0647 (\u06a9\u0647 \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u0627\u0632 proxy \u062f\u0631 webpack-dev-server \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f) \u0631\u0641\u062a\u0627\u0631 \u06cc\u06a9\u0633\u0627\u0646 \u062e\u0648\u0627\u0647\u062f \u0628\u0648\u062f.<\/p>\n<h3>4.4 \u062d\u0627\u0644\u062a \u062a\u0648\u0633\u0639\u0647 (dev) \u0648 proxy \u062f\u0631 Vue CLI<\/h3>\n<p>\u0627\u06af\u0631 \u0645\u06cc\u200c\u062e\u0648\u0627\u0647\u06cc\u062f \u062f\u0631 \u062d\u0627\u0644\u062a \u062a\u0648\u0633\u0639\u0647 \u0628\u0647 API \u0645\u062d\u0644\u06cc \u0645\u062a\u0635\u0644 \u0634\u0648\u06cc\u062f\u060c \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u062f \u062f\u0631 <code>vue.config.js<\/code> \u06cc\u06a9 proxy \u062a\u0639\u0631\u06cc\u0641 \u06a9\u0646\u06cc\u062f:<\/p>\n<pre><code>module.exports = {\r\n  devServer: {\r\n    proxy: {\r\n      '\/api': {\r\n        target: 'http:\/\/localhost:3000',\r\n        changeOrigin: true\r\n      }\r\n    }\r\n  }\r\n};<\/code><\/pre>\n<p>\u0627\u06cc\u0646 \u06a9\u0627\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc <code>\/api<\/code> \u062f\u0631 \u062a\u0648\u0633\u0639\u0647 \u0631\u0627 \u0646\u06cc\u0632 \u0628\u0647 API \u0645\u062d\u0644\u06cc \u0645\u0646\u062a\u0642\u0644 \u0645\u06cc\u200c\u06a9\u0646\u062f \u0648 \u0646\u06cc\u0627\u0632\u06cc \u0628\u0647 CORS \u0646\u06cc\u0633\u062a.<\/p>\n<h2 id=\"security\">5. \u0646\u06a9\u0627\u062a \u0627\u0645\u0646\u06cc\u062a\u06cc \u0648 \u0628\u0647\u06cc\u0646\u0647\u200c\u0633\u0627\u0632\u06cc \u0628\u0631\u0627\u06cc \u062a\u0648\u0644\u06cc\u062f<\/h2>\n<ul>\n<li>\u0627\u0632 SSL\/TLS \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f (\u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc Nginx \u0628\u0627 Let\u2019s Encrypt) \u062a\u0627 \u0627\u0631\u062a\u0628\u0627\u0637\u200c\u0647\u0627 \u0627\u0645\u0646 \u0628\u0627\u0634\u0646\u062f.<\/li>\n<li>\u0646\u0633\u0628\u062a \u0628\u0647 header\u0647\u0627\u06cc \u0627\u0645\u0646\u06cc\u062a\u06cc Nginx (\u0645\u062b\u0644 Content-Security-Policy\u060c X-Frame-Options\u060c X-Content-Type-Options) \u062a\u0648\u062c\u0647 \u06a9\u0646\u06cc\u062f.<\/li>\n<li>\u062f\u0631 API \u0627\u0632 \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u0648 \u0645\u062d\u062f\u0648\u062f\u06cc\u062a \u0646\u0631\u062e (rate limiting) \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.<\/li>\n<li>\u0628\u0631\u0627\u06cc \u0641\u0627\u06cc\u0644\u200c\u0647\u0627\u06cc \u0644\u0627\u06af \u0648 \u0645\u0627\u0646\u06cc\u062a\u0648\u0631\u06cc\u0646\u06af \u0627\u0632 \u0627\u0628\u0632\u0627\u0631\u0647\u0627\u06cc \u0645\u0646\u0627\u0633\u0628 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f \u0648 \u062e\u0637\u0627\u0647\u0627 \u0631\u0627 \u0644\u0627\u06af \u06a9\u0646\u06cc\u062f.<\/li>\n<li>\u0628\u0631\u0627\u06cc deploy \u0627\u062a\u0648\u0645\u0627\u062a\u06cc\u06a9 \u062e\u0631\u0648\u062c\u06cc build \u0631\u0627 \u0645\u0633\u062a\u0642\u06cc\u0645 \u0628\u0647 \u0645\u0633\u06cc\u0631 \u0648\u0628 \u0633\u0631\u0648\u0631 \u062a\u0648\u0644\u06cc\u062f \u06a9\u0646\u06cc\u062f \u06cc\u0627 \u0627\u0632 CI\/CD \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0646\u0645\u0627\u06cc\u06cc\u062f \u062a\u0627 \u0646\u06cc\u0627\u0632 \u0628\u0647 \u06a9\u067e\u06cc \u062f\u0633\u062a\u06cc \u0641\u0627\u06cc\u0644\u200c\u0647\u0627 \u0646\u0628\u0627\u0634\u062f.<\/li>\n<\/ul>\n<h2 id=\"resources\">6. \u0645\u0646\u0627\u0628\u0639 \u0648 \u06af\u06cc\u062a\u200c\u0647\u0627\u0628<\/h2>\n<p>\u0628\u0631\u0627\u06cc \u0646\u0645\u0648\u0646\u0647\u0654 \u06a9\u0627\u0645\u0644 \u067e\u0631\u0648\u0698\u0647 \u0648 \u062f\u06cc\u062f\u0646 \u0633\u0627\u062e\u062a\u0627\u0631 \u0641\u0627\u06cc\u0644\u200c\u0647\u0627 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u062f \u0645\u062e\u0632\u0646 \u06af\u06cc\u062a\u200c\u0647\u0627\u0628 \u067e\u0631\u0648\u0698\u0647 \u0631\u0627 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u062f:<\/p>\n<p><a href=\"https:\/\/github.com\/do-community\/vuetify-meets-nginx-app\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/do-community\/vuetify-meets-nginx-app<\/a><\/p>\n<h2>\u067e\u0631\u0633\u0634 \u0631\u0627\u06cc\u062c: \u0627\u06af\u0631 API \u0648 frontend \u0631\u0648\u06cc \u0647\u0645\u0627\u0646 \u0633\u0631\u0648\u0631 (\u0645\u062b\u0644\u0627\u064b \u0631\u0648\u06cc <strong><a href=\"https:\/\/parmin.cloud\/\">ParminCloud<\/a><\/strong>) \u0628\u0627\u0634\u0646\u062f \u0686\u0647 \u062a\u063a\u06cc\u06cc\u0631\u0627\u062a\u06cc \u0644\u0627\u0632\u0645 \u0627\u0633\u062a\u061f<\/h2>\n<p>\u062e\u0644\u0627\u0635\u0647 \u067e\u0627\u0633\u062e:<\/p>\n<ul>\n<li>API \u0631\u0627 \u0631\u0648\u06cc \u06cc\u06a9 \u067e\u0648\u0631\u062a \u062c\u062f\u0627 \u0627\u062c\u0631\u0627 \u06a9\u0646\u06cc\u062f (\u0645\u062b\u0644\u0627\u064b 3000).<\/li>\n<li>Nginx \u0631\u0627 \u0637\u0648\u0631\u06cc \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc \u06a9\u0646\u06cc\u062f \u06a9\u0647 \u0645\u0633\u06cc\u0631\u0647\u0627\u06cc API \u0631\u0627 \u0628\u0647 \u0622\u0646 \u067e\u0648\u0631\u062a proxy_pass \u06a9\u0646\u062f.<\/li>\n<li>\u062f\u0631 Vue \u0627\u0632 \u0622\u062f\u0631\u0633\u200c\u0647\u0627\u06cc \u0646\u0633\u0628\u06cc \u0645\u062b\u0644 <code>\/api\/<\/code> \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f \u062a\u0627 \u0647\u0645 \u062f\u0631 dev \u0648 \u0647\u0645 \u062f\u0631 production \u0628\u062f\u0648\u0646 \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0627\u0631 \u06a9\u0646\u062f.<\/li>\n<li>\u062f\u0631 \u0635\u0648\u0631\u062a \u0646\u06cc\u0627\u0632 \u0628\u0647 \u0628\u0644\u0648\u06a9 \u062c\u0647\u062a history mode router\u060c \u0627\u0632 <code>try_files $uri $uri\/ \/index.html;<\/code> \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.<\/li>\n<\/ul>\n<h2>\u06a9\u0644\u0627\u0645 \u0622\u062e\u0631<\/h2>\n<p>\u0627\u06cc\u0646 \u0631\u0648\u0646\u062f (build \u06a9\u0631\u062f\u0646 \u0627\u067e Vue\u060c \u06af\u0630\u0627\u0634\u062a\u0646 \u062e\u0631\u0648\u062c\u06cc \u062f\u0631 \u0645\u0633\u06cc\u0631 \u0648\u0628\u060c \u0627\u062c\u0631\u0627\u06cc API \u0631\u0648\u06cc \u067e\u0648\u0631\u062a \u062c\u062f\u0627 \u0648 \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc Nginx \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 reverse proxy) \u06cc\u06a9 \u0627\u0644\u06af\u0648\u06cc \u0627\u0633\u062a\u0627\u0646\u062f\u0627\u0631\u062f \u0628\u0631\u0627\u06cc \u0645\u06cc\u0632\u0628\u0627\u0646\u06cc frontend \u0648 backend \u0631\u0648\u06cc \u06cc\u06a9 \u0633\u0631\u0648\u0631 \u0627\u0633\u062a. \u0628\u0627 \u0631\u0639\u0627\u06cc\u062a \u0646\u06a9\u0627\u062a \u0627\u0645\u0646\u06cc\u062a\u06cc (SSL\u060c headers\u060c rate limits) \u0648 \u062e\u0648\u062f\u06a9\u0627\u0631\u0633\u0627\u0632\u06cc \u0641\u0631\u0627\u06cc\u0646\u062f build\/deploy \u0628\u0627 CI\/CD\u060c \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u062f \u0645\u062d\u06cc\u0637\u06cc \u067e\u0627\u06cc\u062f\u0627\u0631 \u0648 \u0627\u0645\u0646 \u062f\u0631 \u067e\u0644\u062a\u0641\u0631\u0645 \u0627\u0628\u0631\u06cc \u0645\u062b\u0644 <strong><a href=\"https:\/\/parmin.cloud\/\">ParminCloud<\/a> <\/strong>\u0631\u0627\u0647\u200c\u0627\u0646\u062f\u0627\u0632\u06cc \u06a9\u0646\u06cc\u062f.<\/p>\n<div style='text-align:center' class='yasr-auto-insert-visitor'><\/div>","protected":false},"excerpt":{"rendered":"<p>\u062f\u0631 \u0627\u06cc\u0646 \u0645\u0642\u0627\u0644\u0647 \u0642\u062f\u0645\u200c\u0628\u0647\u200c\u0642\u062f\u0645 \u0633\u0627\u062e\u062a \u06cc\u06a9 \u0627\u067e To\u2011Do \u0628\u0627 Vue.js \u0648 Vuetify\u060c \u062a\u0647\u06cc\u0647 \u062e\u0631\u0648\u062c\u06cc production \u0648 \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc Nginx \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 reverse proxy \u0631\u0627 \u062a\u0648\u0636\u06cc\u062d \u0645\u06cc\u200c\u062f\u0647\u06cc\u0645. \u0633\u067e\u0633 \u062a\u0645\u0631\u06a9\u0632 \u0645\u06cc\u200c\u06a9\u0646\u06cc\u0645 \u0631\u0648\u06cc \u067e\u0631\u0633\u0634 \u0645\u0647\u0645: \u0627\u06af\u0631 API (\u0645\u062b\u0644\u0627\u064b Node.js\/Express) \u0631\u0648\u06cc \u0647\u0645\u0627\u0646 \u0633\u0631\u0648\u0631 \u0645\u06cc\u0632\u0628\u0627\u0646\u06cc \u0634\u0648\u062f\u060c \u0686\u0637\u0648\u0631 frontend \u0648 API \u0631\u0627 \u0628\u0647 \u0647\u0645 \u0645\u062a\u0635\u0644 \u06a9\u0646\u06cc\u0645 \u0648 \u0686\u0647 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a\u06cc \u0644\u0627\u0632\u0645 \u0627\u0633\u062a. 1. [&hellip;]<\/p>\n","protected":false},"author":9,"featured_media":5505,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"yasr_overall_rating":0,"yasr_post_is_review":"","yasr_auto_insert_disabled":"","yasr_review_type":"","footnotes":""},"categories":[142,150],"tags":[443,440,441,444,442],"class_list":["post-5497","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-142","category-linux","tag-reverse-proxy--nginx","tag--vue-js--node-js-api","tag--nginx--vue--express","tag---vue---","tag---to-do--vue--vuetify"],"aioseo_notices":[],"yasr_visitor_votes":{"stars_attributes":{"read_only":false,"span_bottom":false},"number_of_votes":0,"sum_votes":0},"_links":{"self":[{"href":"https:\/\/parmin.cloud\/blog\/wp-json\/wp\/v2\/posts\/5497","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/parmin.cloud\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/parmin.cloud\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/parmin.cloud\/blog\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/parmin.cloud\/blog\/wp-json\/wp\/v2\/comments?post=5497"}],"version-history":[{"count":1,"href":"https:\/\/parmin.cloud\/blog\/wp-json\/wp\/v2\/posts\/5497\/revisions"}],"predecessor-version":[{"id":5504,"href":"https:\/\/parmin.cloud\/blog\/wp-json\/wp\/v2\/posts\/5497\/revisions\/5504"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/parmin.cloud\/blog\/wp-json\/wp\/v2\/media\/5505"}],"wp:attachment":[{"href":"https:\/\/parmin.cloud\/blog\/wp-json\/wp\/v2\/media?parent=5497"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/parmin.cloud\/blog\/wp-json\/wp\/v2\/categories?post=5497"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/parmin.cloud\/blog\/wp-json\/wp\/v2\/tags?post=5497"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}