Merge pull request 'alkin_ivan_lab_2' (#271) from alkin_ivan_lab_2 into main

Reviewed-on: #271
This commit is contained in:
Alexey 2024-12-15 14:12:18 +04:00
commit 4343669b5a
9 changed files with 239 additions and 0 deletions

10
alkin_ivan_lab_2/.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
# .gitignore
__pycache__/
*.pyc
*.pyo
*.pyd
*.db
*.log
*.bak
*.swp
*.swo

View File

@ -0,0 +1,89 @@
Для выполнения второй лабораторной работы по созданию распределённого приложения с использованием Docker и Docker Compose, давайте разберем все этапы, шаг за шагом. Я предлагаю реализовать вариант программы 1 и программу 2 следующим образом:
### 1. Вариант программы 1
Программа будет искать в каталоге `/var/data` файл с наибольшим количеством строк и перекладывать его в `/var/result/data.txt`.
### 2. Вариант программы 2
Программа будет искать наименьшее число из файла `/var/data/data.txt` и сохранять его третью степень в файл `/var/result/result.txt`.
### Структура проекта
1. `moiseev-vv-lab_2/worker-1`: Программа для нахождения файла с наибольшим количеством строк.
2. `moiseev-vv-lab_2/worker-2`: Программа для нахождения минимального числа в файле и записи его третьей степени.
### Шаги реализации:
#### 1. Реализация программы 1
```python
#### 2. Реализация программы 2
```python
Для обоих приложений создадим Dockerfile. Вот пример для **worker-1**:
Пояснение:
- **Stage 1**: Мы используем `python:3.10-slim` как образ для сборки, где копируем файл `main.py` и устанавливаем зависимости, если это необходимо.
- **Stage 2**: В этом слое мы копируем скомпилированные файлы из предыдущего этапа и определяем команду для запуска приложения.
Аналогичный Dockerfile будет для **worker-2**.
### Docker Compose файл
Теперь нужно настроить файл `docker-compose.yml`, который позволит запустить оба приложения:
Пояснение:
- **services**: Мы объявляем два сервиса — `worker-1` и `worker-2`.
- **build**: Указываем контекст сборки для каждого сервиса (директории, где находятся Dockerfile и код).
- **volumes**: Монтируем локальные директории `./data` и `./result` в контейнеры, чтобы обмениваться файлами между сервисами.
- **depends_on**: Задаем зависимость `worker-2` от `worker-1`, чтобы второй сервис запускался только после первого.
### .gitignore
Для предотвращения попадания ненужных файлов в репозиторий, добавляем файл `.gitignore`. Пример для Python проектов:
```
# .gitignore
__pycache__/
*.pyc
*.pyo
*.pyd
*.db
*.log
*.bak
*.swp
*.swo
```
### Шаги для сборки и запуска
1. Склонировать репозиторий и перейти в директорию с лабораторной работой:
```bash
git clone <репозиторий>
cd moiseev-vv-lab_2
```
2. Скопировать файлы для `worker-1` и `worker-2` в соответствующие папки.
3. Создать файл `docker-compose.yml`.
4. Запустить приложение с помощью команды:
```bash
docker-compose up --build
```
5. Проверить вывод, результаты должны быть в директориях `./data` и `./result`.
### Заключение
Это пример, как можно реализовать простейшее распределённое приложение с использованием Docker. Первое приложение генерирует данные для второго, который обрабатывает их и записывает результат в файл. Docker и Docker Compose позволяют легко управлять и изолировать каждое приложение.ker Compose для запуска двух программ, обрабатывающих данные в контейнерах.
## Видео ВК
https://vkvideo.ru/video150882239_456240341

View File

@ -0,0 +1,7 @@
FROM python:3.9-slim
WORKDIR /app
COPY . /app
CMD ["python", "generate_data.py"]

View File

@ -0,0 +1,29 @@
import os
import random
def generate_random_files(directory, num_files, num_lines_per_file, min_value, max_value):
os.makedirs(directory, exist_ok=True)
for i in range(num_files):
file_path = os.path.join(directory, f"file_{i + 1}.txt")
with open(file_path, 'w') as f:
for _ in range(num_lines_per_file):
random_number = random.randint(min_value, max_value)
f.write(f"{random_number}\n")
print(f"Generated file: {file_path}")
def main():
data_directory = '/var/data'
num_files = 10
num_lines_per_file = 12
min_value = 1
max_value = 100
generate_random_files(data_directory, num_files, num_lines_per_file, min_value, max_value)
print(f"Generated {num_files} files in {data_directory}")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,18 @@
# docker-compose.yml
services:
worker-1:
build:
context: ./worker-1
volumes:
- ./data:/var/data
- ./result:/var/result
depends_on:
- worker-2
worker-2:
build:
context: ./worker-2
volumes:
- ./data:/var/data
- ./result:/var/result

View File

@ -0,0 +1,14 @@
# worker-1/Dockerfile
# Stage 1: Build the application
FROM python:3.10-slim as builder
WORKDIR /app
COPY ./main.py .
# Stage 2: Set up the runtime environment
FROM python:3.10-slim
WORKDIR /app
COPY --from=builder /app/main.py .
CMD ["python", "main.py"]

View File

@ -0,0 +1,35 @@
# worker-1/main.py
import os
def find_file_with_most_lines(directory):
files = os.listdir(directory)
max_lines = 0
target_file = None
for filename in files:
filepath = os.path.join(directory, filename)
if os.path.isfile(filepath):
with open(filepath, 'r') as file:
lines = file.readlines()
if len(lines) > max_lines:
max_lines = len(lines)
target_file = filepath
return target_file
def main():
source_directory = '/var/data'
result_file = '/var/result/data.txt'
file_to_copy = find_file_with_most_lines(source_directory)
if file_to_copy:
with open(file_to_copy, 'r') as source, open(result_file, 'w') as dest:
dest.writelines(source.readlines())
print(f"File with the most lines: {file_to_copy} copied to {result_file}")
else:
print("No files found in the source directory.")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,14 @@
# worker-1/Dockerfile
# Stage 1: Build the application
FROM python:3.10-slim as builder
WORKDIR /app
COPY ./main.py .
# Stage 2: Set up the runtime environment
FROM python:3.10-slim
WORKDIR /app
COPY --from=builder /app/main.py .
CMD ["python", "main.py"]

View File

@ -0,0 +1,23 @@
# worker-2/main.py
def find_min_number(filename):
with open(filename, 'r') as file:
numbers = [int(line.strip()) for line in file.readlines()]
min_number = min(numbers)
return min_number
def main():
input_file = '/var/data/data.txt'
output_file = '/var/result/result.txt'
min_number = find_min_number(input_file)
result = min_number ** 3 # Cube of the minimum number
with open(output_file, 'w') as file:
file.write(str(result))
print(f"Minimum number's cube: {result} written to {output_file}")
if __name__ == "__main__":
main()