From 23dfef9856ffc769921c534db628e8f7d4b3d7ac Mon Sep 17 00:00:00 2001
From: DmitriyAntonov
Date: Sun, 12 Nov 2023 12:05:59 +0400
Subject: [PATCH 1/4] =?UTF-8?q?=D1=81=D1=82=D0=B0=D1=80=D1=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.idea/misc.xml | 5 +-
antonov_dmitry_lab_3/README.md | 67 +++++++++++++++++++
antonov_dmitry_lab_3/docker-compose.yml | 23 +++++++
antonov_dmitry_lab_3/service_a.conf | 8 +++
antonov_dmitry_lab_3/service_a/Dockerfile | 13 ++++
antonov_dmitry_lab_3/service_a/app.py | 38 +++++++++++
.../service_a/requirements.txt | 1 +
antonov_dmitry_lab_3/service_b.conf | 8 +++
antonov_dmitry_lab_3/service_b/Dockerfile | 13 ++++
antonov_dmitry_lab_3/service_b/app.py | 38 +++++++++++
.../service_b/requirements.txt | 1 +
11 files changed, 212 insertions(+), 3 deletions(-)
create mode 100644 antonov_dmitry_lab_3/README.md
create mode 100644 antonov_dmitry_lab_3/docker-compose.yml
create mode 100644 antonov_dmitry_lab_3/service_a.conf
create mode 100644 antonov_dmitry_lab_3/service_a/Dockerfile
create mode 100644 antonov_dmitry_lab_3/service_a/app.py
create mode 100644 antonov_dmitry_lab_3/service_a/requirements.txt
create mode 100644 antonov_dmitry_lab_3/service_b.conf
create mode 100644 antonov_dmitry_lab_3/service_b/Dockerfile
create mode 100644 antonov_dmitry_lab_3/service_b/app.py
create mode 100644 antonov_dmitry_lab_3/service_b/requirements.txt
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 6e86672..a971a2c 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,5 +1,4 @@
+
-
-
-
+
\ No newline at end of file
diff --git a/antonov_dmitry_lab_3/README.md b/antonov_dmitry_lab_3/README.md
new file mode 100644
index 0000000..4f087bf
--- /dev/null
+++ b/antonov_dmitry_lab_3/README.md
@@ -0,0 +1,67 @@
+# Лабораторная работа №1 - Знакомство с docker и docker-compose
+
+Разверните 3 сервиса на выбор в контейнерах docker с помощью docker-compose.
+Требования и docker-compose:
+
+Несколько контейнеров.
+Хотя бы один volume.
+Хотя бы один порт, проброшенный на хост.
+При этом разворачивание системы должно пройти до конца. Например, должен быть создан
+администратор и система должна корректно функционировать. Это необходимо будет предоставить
+в отчёте, поэтому не забывайте делать скриншоты.
+
+# Выбранные сервисы
+
+* mediawiki - движок вики
+* drupal - популярная система управления контентом
+* wordpress - популярная система управления контентом.
+
+# Запуск
+
+Командой в консоли проекта "docker-compose up -d"
+
+# Описание работы:
+Развернули три сервиса плюс базу данных к ним.
+Подробное описание для docker-compose дано в комментариях.
+
+1. mediawiki:
+- доступ на http://localhost:8080/
+
+2. drupal:
+- доступ на http://localhost:8081/
+
+3. wordpress:
+- доступ на http://localhost:8082/
+
+
+
Старт сервисов
+
+
+
+
Сервисы
+
+
+
+
Images
+
+
+
+
Volumes
+
+
+
+
Сервис 1
+
+
+
+
Сервис 2
+
+
+
+
Сервис 3
+
+
+
+# Ссылка на видео
+https://disk.yandex.ru/i/nG5KrHy_DsQxuw
+
diff --git a/antonov_dmitry_lab_3/docker-compose.yml b/antonov_dmitry_lab_3/docker-compose.yml
new file mode 100644
index 0000000..b155a69
--- /dev/null
+++ b/antonov_dmitry_lab_3/docker-compose.yml
@@ -0,0 +1,23 @@
+version: '3'
+
+services:
+ service_a:
+ build: ./service_a
+ ports:
+ - "5000:5000"
+
+ service_b:
+ build: ./service_b
+ ports:
+ - "5001:5001"
+
+ nginx:
+ image: nginx
+ ports:
+ - "80:80"
+ volumes:
+ - ./service_a.conf:/etc/nginx/conf.d/service_a.conf
+ - ./service_b.conf:/etc/nginx/conf.d/service_b.conf
+ depends_on:
+ - service_a
+ - service_b
diff --git a/antonov_dmitry_lab_3/service_a.conf b/antonov_dmitry_lab_3/service_a.conf
new file mode 100644
index 0000000..cece274
--- /dev/null
+++ b/antonov_dmitry_lab_3/service_a.conf
@@ -0,0 +1,8 @@
+server {
+ listen 80;
+ server_name service_a;
+
+ location / {
+ proxy_pass http://service_a:5000;
+ }
+}
\ No newline at end of file
diff --git a/antonov_dmitry_lab_3/service_a/Dockerfile b/antonov_dmitry_lab_3/service_a/Dockerfile
new file mode 100644
index 0000000..cb42ab3
--- /dev/null
+++ b/antonov_dmitry_lab_3/service_a/Dockerfile
@@ -0,0 +1,13 @@
+FROM python:3.8-slim
+
+WORKDIR /app
+
+COPY . /app
+
+RUN pip install --no-cache-dir -r requirements.txt
+
+EXPOSE 5000
+
+ENV NAME service_a
+
+CMD ["python", "app.py"]
diff --git a/antonov_dmitry_lab_3/service_a/app.py b/antonov_dmitry_lab_3/service_a/app.py
new file mode 100644
index 0000000..f5d6095
--- /dev/null
+++ b/antonov_dmitry_lab_3/service_a/app.py
@@ -0,0 +1,38 @@
+from flask import Flask, jsonify, request
+
+app = Flask(__name__)
+
+# хранение данных сущности A
+entity_a_data = []
+
+
+@app.route('/entity_a', methods=['GET'])
+def get_entity_a():
+ return jsonify(entity_a_data)
+
+
+@app.route('/entity_a', methods=['POST'])
+def create_entity_a():
+ new_entity = request.json
+ entity_a_data.append(new_entity)
+ return jsonify(new_entity), 201
+
+
+@app.route('/entity_a/', methods=['PUT'])
+def update_entity_a(id):
+ for entity in entity_a_data:
+ if entity['id'] == id:
+ entity.update(request.json)
+ return jsonify(entity), 200
+ return jsonify({'error': 'Entity not found'}), 404
+
+
+@app.route('/entity_a/', methods=['DELETE'])
+def delete_entity_a(id):
+ global entity_a_data
+ entity_a_data = [entity for entity in entity_a_data if entity['id'] != id]
+ return jsonify({'message': 'Entity deleted'}), 200
+
+
+if __name__ == '__main__':
+ app.run(host='0.0.0.0', port=5000)
diff --git a/antonov_dmitry_lab_3/service_a/requirements.txt b/antonov_dmitry_lab_3/service_a/requirements.txt
new file mode 100644
index 0000000..2077213
--- /dev/null
+++ b/antonov_dmitry_lab_3/service_a/requirements.txt
@@ -0,0 +1 @@
+Flask
\ No newline at end of file
diff --git a/antonov_dmitry_lab_3/service_b.conf b/antonov_dmitry_lab_3/service_b.conf
new file mode 100644
index 0000000..fc397e1
--- /dev/null
+++ b/antonov_dmitry_lab_3/service_b.conf
@@ -0,0 +1,8 @@
+server {
+ listen 80;
+ server_name service_b;
+
+ location / {
+ proxy_pass http://service_b:5001;
+ }
+}
diff --git a/antonov_dmitry_lab_3/service_b/Dockerfile b/antonov_dmitry_lab_3/service_b/Dockerfile
new file mode 100644
index 0000000..54a28d8
--- /dev/null
+++ b/antonov_dmitry_lab_3/service_b/Dockerfile
@@ -0,0 +1,13 @@
+FROM python:3.8-slim
+
+WORKDIR /app
+
+COPY . /app
+
+RUN pip install --no-cache-dir -r requirements.txt
+
+EXPOSE 5001
+
+ENV NAME service_b
+
+CMD ["python", "app.py"]
diff --git a/antonov_dmitry_lab_3/service_b/app.py b/antonov_dmitry_lab_3/service_b/app.py
new file mode 100644
index 0000000..49d7c42
--- /dev/null
+++ b/antonov_dmitry_lab_3/service_b/app.py
@@ -0,0 +1,38 @@
+from flask import Flask, jsonify, request
+
+app = Flask(__name__)
+
+# хранение данных сущности B
+entity_b_data = []
+
+
+@app.route('/entity_b', methods=['GET'])
+def get_entity_b():
+ return jsonify(entity_b_data)
+
+
+@app.route('/entity_b', methods=['POST'])
+def create_entity_b():
+ new_entity = request.json
+ entity_b_data.append(new_entity)
+ return jsonify(new_entity), 201
+
+
+@app.route('/entity_b/', methods=['PUT'])
+def update_entity_b(id):
+ for entity in entity_b_data:
+ if entity['id'] == id:
+ entity.update(request.json)
+ return jsonify(entity), 200
+ return jsonify({'error': 'Entity not found'}), 404
+
+
+@app.route('/entity_b/', methods=['DELETE'])
+def delete_entity_b(id):
+ global entity_b_data
+ entity_b_data = [entity for entity in entity_b_data if entity['id'] != id]
+ return jsonify({'message': 'Entity deleted'}), 200
+
+
+if __name__ == '__main__':
+ app.run(host='0.0.0.0', port=5001)
diff --git a/antonov_dmitry_lab_3/service_b/requirements.txt b/antonov_dmitry_lab_3/service_b/requirements.txt
new file mode 100644
index 0000000..2077213
--- /dev/null
+++ b/antonov_dmitry_lab_3/service_b/requirements.txt
@@ -0,0 +1 @@
+Flask
\ No newline at end of file
From b166d347a9983d50a204e576552fdf48f3527ed5 Mon Sep 17 00:00:00 2001
From: DmitriyAntonov
Date: Sun, 12 Nov 2023 19:01:15 +0400
Subject: [PATCH 2/4] =?UTF-8?q?=D0=B3=D0=BE=D1=82=D0=BE=D0=B2=D0=BE2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
antonov_dmitry_lab_3/README.md | 2 +-
antonov_dmitry_lab_3/docker-compose.yml | 7 ++--
antonov_dmitry_lab_3/nginx.conf | 13 +++++++
antonov_dmitry_lab_3/service_a.conf | 8 ----
antonov_dmitry_lab_3/service_a/app.py | 49 ++++++++++++++-----------
antonov_dmitry_lab_3/service_b.conf | 8 ----
antonov_dmitry_lab_3/service_b/app.py | 49 ++++++++++++++-----------
7 files changed, 71 insertions(+), 65 deletions(-)
create mode 100644 antonov_dmitry_lab_3/nginx.conf
delete mode 100644 antonov_dmitry_lab_3/service_a.conf
delete mode 100644 antonov_dmitry_lab_3/service_b.conf
diff --git a/antonov_dmitry_lab_3/README.md b/antonov_dmitry_lab_3/README.md
index 4f087bf..7c6afb0 100644
--- a/antonov_dmitry_lab_3/README.md
+++ b/antonov_dmitry_lab_3/README.md
@@ -1,4 +1,4 @@
-# Лабораторная работа №1 - Знакомство с docker и docker-compose
+# Лабораторная работа №3 - Знакомство с docker и docker-compose
Разверните 3 сервиса на выбор в контейнерах docker с помощью docker-compose.
Требования и docker-compose:
diff --git a/antonov_dmitry_lab_3/docker-compose.yml b/antonov_dmitry_lab_3/docker-compose.yml
index b155a69..0b0fe2e 100644
--- a/antonov_dmitry_lab_3/docker-compose.yml
+++ b/antonov_dmitry_lab_3/docker-compose.yml
@@ -14,10 +14,9 @@ services:
nginx:
image: nginx
ports:
- - "80:80"
+ - "8085:8085"
volumes:
- - ./service_a.conf:/etc/nginx/conf.d/service_a.conf
- - ./service_b.conf:/etc/nginx/conf.d/service_b.conf
+ - ./nginx.conf:/etc/nginx/conf.d/nginx.conf
depends_on:
- service_a
- - service_b
+ - service_b
\ No newline at end of file
diff --git a/antonov_dmitry_lab_3/nginx.conf b/antonov_dmitry_lab_3/nginx.conf
new file mode 100644
index 0000000..c07aa54
--- /dev/null
+++ b/antonov_dmitry_lab_3/nginx.conf
@@ -0,0 +1,13 @@
+server {
+ listen 8085;
+ listen [::]:8085;
+ server_name localhost;
+
+ location /service_a/ {
+ proxy_pass http://127.0.0.1:5000;
+ }
+
+ location /service_b/ {
+ proxy_pass http://127.0.0.1:5001;
+ }
+}
\ No newline at end of file
diff --git a/antonov_dmitry_lab_3/service_a.conf b/antonov_dmitry_lab_3/service_a.conf
deleted file mode 100644
index cece274..0000000
--- a/antonov_dmitry_lab_3/service_a.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-server {
- listen 80;
- server_name service_a;
-
- location / {
- proxy_pass http://service_a:5000;
- }
-}
\ No newline at end of file
diff --git a/antonov_dmitry_lab_3/service_a/app.py b/antonov_dmitry_lab_3/service_a/app.py
index f5d6095..4836e89 100644
--- a/antonov_dmitry_lab_3/service_a/app.py
+++ b/antonov_dmitry_lab_3/service_a/app.py
@@ -2,36 +2,41 @@ from flask import Flask, jsonify, request
app = Flask(__name__)
-# хранение данных сущности A
-entity_a_data = []
+# "customers"
+customers_data = []
-@app.route('/entity_a', methods=['GET'])
-def get_entity_a():
- return jsonify(entity_a_data)
+@app.route('/service_a/', methods=['GET'])
+def get_index():
+ return "Hello from service_a"
-@app.route('/entity_a', methods=['POST'])
-def create_entity_a():
- new_entity = request.json
- entity_a_data.append(new_entity)
- return jsonify(new_entity), 201
+@app.route('/service_a/customers', methods=['GET'])
+def get_customers():
+ return jsonify(customers_data)
-@app.route('/entity_a/', methods=['PUT'])
-def update_entity_a(id):
- for entity in entity_a_data:
- if entity['id'] == id:
- entity.update(request.json)
- return jsonify(entity), 200
- return jsonify({'error': 'Entity not found'}), 404
+@app.route('/service_a/customers', methods=['POST'])
+def create_customer():
+ new_customer = request.json
+ customers_data.append(new_customer)
+ return jsonify(new_customer), 201
-@app.route('/entity_a/', methods=['DELETE'])
-def delete_entity_a(id):
- global entity_a_data
- entity_a_data = [entity for entity in entity_a_data if entity['id'] != id]
- return jsonify({'message': 'Entity deleted'}), 200
+@app.route('/service_a/customers/', methods=['PUT'])
+def update_customer(id):
+ for customer in customers_data:
+ if customer['id'] == id:
+ customer.update(request.json)
+ return jsonify(customer), 200
+ return jsonify({'error': 'Customer not found'}), 404
+
+
+@app.route('/service_a/customers/', methods=['DELETE'])
+def delete_customer(id):
+ global customers_data
+ customers_data = [customer for customer in customers_data if customer['id'] != id]
+ return jsonify({'message': 'Customer deleted'}), 200
if __name__ == '__main__':
diff --git a/antonov_dmitry_lab_3/service_b.conf b/antonov_dmitry_lab_3/service_b.conf
deleted file mode 100644
index fc397e1..0000000
--- a/antonov_dmitry_lab_3/service_b.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-server {
- listen 80;
- server_name service_b;
-
- location / {
- proxy_pass http://service_b:5001;
- }
-}
diff --git a/antonov_dmitry_lab_3/service_b/app.py b/antonov_dmitry_lab_3/service_b/app.py
index 49d7c42..cb9766d 100644
--- a/antonov_dmitry_lab_3/service_b/app.py
+++ b/antonov_dmitry_lab_3/service_b/app.py
@@ -2,36 +2,41 @@ from flask import Flask, jsonify, request
app = Flask(__name__)
-# хранение данных сущности B
-entity_b_data = []
+# "clients"
+clients_data = []
-@app.route('/entity_b', methods=['GET'])
-def get_entity_b():
- return jsonify(entity_b_data)
+@app.route('/', methods=['GET'])
+def get_index():
+ return "Hello from service_b"
-@app.route('/entity_b', methods=['POST'])
-def create_entity_b():
- new_entity = request.json
- entity_b_data.append(new_entity)
- return jsonify(new_entity), 201
+@app.route('/clients', methods=['GET'])
+def get_clients():
+ return jsonify(clients_data)
-@app.route('/entity_b/', methods=['PUT'])
-def update_entity_b(id):
- for entity in entity_b_data:
- if entity['id'] == id:
- entity.update(request.json)
- return jsonify(entity), 200
- return jsonify({'error': 'Entity not found'}), 404
+@app.route('/clients', methods=['POST'])
+def create_client():
+ new_client = request.json
+ clients_data.append(new_client)
+ return jsonify(new_client), 201
-@app.route('/entity_b/', methods=['DELETE'])
-def delete_entity_b(id):
- global entity_b_data
- entity_b_data = [entity for entity in entity_b_data if entity['id'] != id]
- return jsonify({'message': 'Entity deleted'}), 200
+@app.route('/clients/', methods=['PUT'])
+def update_client(id):
+ for client in clients_data:
+ if client['id'] == id:
+ client.update(request.json)
+ return jsonify(client), 200
+ return jsonify({'error': 'Client not found'}), 404
+
+
+@app.route('/clients/', methods=['DELETE'])
+def delete_client(id):
+ global clients_data
+ clients_data = [client for client in clients_data if client['id'] != id]
+ return jsonify({'message': 'Client deleted'}), 200
if __name__ == '__main__':
From fe7928f10cbb8bd901429fbdad23fd24d743ec29 Mon Sep 17 00:00:00 2001
From: DmitriyAntonov
Date: Mon, 4 Dec 2023 18:24:11 +0400
Subject: [PATCH 3/4] antonov_dmitry_lab3_ready
---
antonov_dmitry_lab_3/README.md | 69 +++++++---------
antonov_dmitry_lab_3/docker-compose.yml | 4 +-
antonov_dmitry_lab_3/nginx.conf | 13 ---
antonov_dmitry_lab_3/nginx/nginx.conf | 17 ++++
antonov_dmitry_lab_3/screens/img1.png | Bin 0 -> 65525 bytes
antonov_dmitry_lab_3/screens/img2.png | Bin 0 -> 93040 bytes
antonov_dmitry_lab_3/screens/img3.png | Bin 0 -> 94428 bytes
antonov_dmitry_lab_3/screens/img4.png | Bin 0 -> 63329 bytes
antonov_dmitry_lab_3/service_a/app.py | 104 ++++++++++++++++++------
antonov_dmitry_lab_3/service_b/app.py | 73 +++++++++++------
10 files changed, 177 insertions(+), 103 deletions(-)
delete mode 100644 antonov_dmitry_lab_3/nginx.conf
create mode 100644 antonov_dmitry_lab_3/nginx/nginx.conf
create mode 100644 antonov_dmitry_lab_3/screens/img1.png
create mode 100644 antonov_dmitry_lab_3/screens/img2.png
create mode 100644 antonov_dmitry_lab_3/screens/img3.png
create mode 100644 antonov_dmitry_lab_3/screens/img4.png
diff --git a/antonov_dmitry_lab_3/README.md b/antonov_dmitry_lab_3/README.md
index 7c6afb0..8abd8a3 100644
--- a/antonov_dmitry_lab_3/README.md
+++ b/antonov_dmitry_lab_3/README.md
@@ -1,67 +1,54 @@
-# Лабораторная работа №3 - Знакомство с docker и docker-compose
+# Лабораторная работа №3 - REST API, Gateway и синхронный обмен между микросервисами
-Разверните 3 сервиса на выбор в контейнерах docker с помощью docker-compose.
-Требования и docker-compose:
+Изучение шаблона проектирования gateway, построения синхронного обмена между микросервисами и архитектурного стиля RESTful API.
-Несколько контейнеров.
-Хотя бы один volume.
-Хотя бы один порт, проброшенный на хост.
-При этом разворачивание системы должно пройти до конца. Например, должен быть создан
-администратор и система должна корректно функционировать. Это необходимо будет предоставить
-в отчёте, поэтому не забывайте делать скриншоты.
+Создать два микросервиса.
-# Выбранные сервисы
+Каждый сервис реализует CRUD-операции: список записей, подробности конкретной записи, создание, удаление и изменение записи.
+В качестве хранилища данных может выступать оперативная память приложения или база данных.
+Сущности необходимо подобрать по следующим критериям:
-* mediawiki - движок вики
-* drupal - популярная система управления контентом
-* wordpress - популярная система управления контентом.
+Они должны быть связаны с предполагаемой темой диплома.
+Они должны быть связаны как "1-ко-многим".
+
+# Задачи
+
+* Создать 2 микросервиса, реализующих CRUD на связанных сущностях.
+* Реализовать механизм синхронного обмена сообщениями между микросервисами.
+* Реализовать шлюз на основе прозрачного прокси-сервера nginx.
# Запуск
Командой в консоли проекта "docker-compose up -d"
# Описание работы:
-Развернули три сервиса плюс базу данных к ним.
-Подробное описание для docker-compose дано в комментариях.
+Развернули два приложения
-1. mediawiki:
-- доступ на http://localhost:8080/
+1. Сервис с врачами:
+- доступ на http://localhost:5000/
-2. drupal:
-- доступ на http://localhost:8081/
+2. Сервис с пациентами:
+- доступ на http://localhost:5001/
-3. wordpress:
-- доступ на http://localhost:8082/
+Сервисы связываются друг с другом через ссылку и библиотеку requests
Старт сервисов
-
+
-
Сервисы
-
+ Сервис врачей
+
-
Images
-
+ Сервис пациентов
+
-
Volumes
-
-
-
-
Сервис 1
-
-
-
-
Сервис 2
-
-
-
-
Сервис 3
-
+ Связь сервисов через библиотеку requests
+
# Ссылка на видео
-https://disk.yandex.ru/i/nG5KrHy_DsQxuw
+https://disk.yandex.ru/i/3o4aLuqp1EpbJg
diff --git a/antonov_dmitry_lab_3/docker-compose.yml b/antonov_dmitry_lab_3/docker-compose.yml
index 0b0fe2e..3b331e8 100644
--- a/antonov_dmitry_lab_3/docker-compose.yml
+++ b/antonov_dmitry_lab_3/docker-compose.yml
@@ -14,9 +14,9 @@ services:
nginx:
image: nginx
ports:
- - "8085:8085"
+ - "80:80"
volumes:
- - ./nginx.conf:/etc/nginx/conf.d/nginx.conf
+ - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- service_a
- service_b
\ No newline at end of file
diff --git a/antonov_dmitry_lab_3/nginx.conf b/antonov_dmitry_lab_3/nginx.conf
deleted file mode 100644
index c07aa54..0000000
--- a/antonov_dmitry_lab_3/nginx.conf
+++ /dev/null
@@ -1,13 +0,0 @@
-server {
- listen 8085;
- listen [::]:8085;
- server_name localhost;
-
- location /service_a/ {
- proxy_pass http://127.0.0.1:5000;
- }
-
- location /service_b/ {
- proxy_pass http://127.0.0.1:5001;
- }
-}
\ No newline at end of file
diff --git a/antonov_dmitry_lab_3/nginx/nginx.conf b/antonov_dmitry_lab_3/nginx/nginx.conf
new file mode 100644
index 0000000..23b3fa1
--- /dev/null
+++ b/antonov_dmitry_lab_3/nginx/nginx.conf
@@ -0,0 +1,17 @@
+server {
+ listen 80;
+
+ location /app1/ {
+ proxy_pass http://localhost:5000/;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ }
+
+ location /app2/ {
+ proxy_pass http://localhost:5001/;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ }
+}
diff --git a/antonov_dmitry_lab_3/screens/img1.png b/antonov_dmitry_lab_3/screens/img1.png
new file mode 100644
index 0000000000000000000000000000000000000000..5e59a8dcfe8fee8575cb1e5a2f1ae199d86c5247
GIT binary patch
literal 65525
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%0APH1{$%y8qm`609}-#rAHJ%TSA4KV9#jC8(~T
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