diff --git a/haliullov_kamil_lab_1/.env b/haliullov_kamil_lab_1/.env new file mode 100644 index 0000000..b022097 --- /dev/null +++ b/haliullov_kamil_lab_1/.env @@ -0,0 +1,4 @@ +DB_HOST = wp_database +DB_USER = wordpress +DB_PASSWORD = wordpress +DB_NAME = wordpress \ No newline at end of file diff --git a/haliullov_kamil_lab_1/Dockerfile b/haliullov_kamil_lab_1/Dockerfile new file mode 100644 index 0000000..2850456 --- /dev/null +++ b/haliullov_kamil_lab_1/Dockerfile @@ -0,0 +1,13 @@ +FROM wordpress:latest + +# Установка WP-CLI +RUN apt-get update && apt-get install -y less \ + && curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar \ + && chmod +x wp-cli.phar \ + && mv wp-cli.phar /usr/local/bin/wp + +# Копируем скрипт entrypoint +COPY entrypoint.sh /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] \ No newline at end of file diff --git a/haliullov_kamil_lab_1/README.md b/haliullov_kamil_lab_1/README.md new file mode 100644 index 0000000..d6e5619 --- /dev/null +++ b/haliullov_kamil_lab_1/README.md @@ -0,0 +1,136 @@ +# Лабораторная работа №1 - Знакомство с docker и docker-compose + +## Задание + +Нужно развернуть 3 сервиса в контейнерах docker через docker-compose. + +Необходимые требования: + +* Несколько контейнеров. +* Хотя бы один volume. +* Хотя бы один порт, проброшенный на хост. +* Разворачивание системы должно пройти до конца. + +## Запуск ЛР: + +Введем в терминале команду: +``` +docker-compose up -d +``` +## Использованные сервисы: + + 1. ```db``` - база данные MySQL + + 2. ```redmine``` - Система учёта багов, т.е. баг-трекер. + + 3. ```mediawiki``` - движок вики + + 4. ```wordpress``` - платформа для управления контентом + +## Описание программы: + +Развернутые сервисы: + +### wordpress + +``` +wordpress: # Определение сервиса WordPress + image: wordpress:latest # Используемый образ WordPress последней версии + containername: wp_app # Имя контейнера + restart: always + ports: # Настройка портов + - "8000:80" + environment: # Переменные окружения + WORDPRESSDBHOST: ${DBHOST} + WORDPRESSDBUSER: ${DBUSER} + WORDPRESSDBPASSWORD: ${DBPASSWORD} + WORDPRESSDBNAME: ${DBNAME} + WORDPRESSADMINUSER: admin + WORDPRESSADMINPASSWORD: adminpassword + WORDPRESSADMINEMAIL: admin@example.com + volumes: # Настройка томов + - wordpress_data:/var/www/html + dependson: # Зависимости + - db_wordpress # Зависит от сервиса MySQL + +``` +Эта строка отвечает за образ сброки: +``` +image: wordpress:latest +``` +Задание имени контейнера: +``` +containername: wp_app +``` +Проброс портов: +``` +ports: + - 8000:80 +``` +Тома для хранения данных: +``` +volumes: + - wordpress_data:/var/www/html + +``` +Переменные окружения +``` +environment: + WORDPRESSDBHOST: ${DBHOST} + WORDPRESSDBUSER: ${DBUSER} + WORDPRESSDBPASSWORD: ${DBPASSWORD} + WORDPRESSDBNAME: ${DBNAME} + WORDPRESSADMINUSER: admin + WORDPRESSADMINPASSWORD: adminpassword + WORDPRESSADMINEMAIL: admin@example.com + +``` +Зависимости + +``` +dependson: + - db_wordpress + +``` +Аналогично со другими сервисами: + +### mediawiki + +``` +mediawiki: # Определение сервиса MediaWiki + image: mediawiki:1.35 # Используемый образ MediaWiki версии 1.35 + ports: # Настройка портов + - "8080:80" + containername: mediawiki # Имя контейнера + volumes: # Настройка томов + - mediawiki_data:/var/www/html/images mediawiki: # Определение сервиса MediaWiki + image: mediawiki:1.35 # Используемый образ MediaWiki версии 1.35 + ports: # Настройка портов + - "8080:80" + containername: mediawiki # Имя контейнера + volumes: # Настройка томов + - mediawiki_data:/var/www/html/images + +``` + +### redmine + +``` + +redmine: # Определение сервиса Redmine + image: redmine:latest # Используемый образ Redmine последней версии + containername: redmine # Имя контейнера + ports: # Настройка портов + - "3000:3000" + volumes: # Настройка томов + - redmine_data:/usr/src/redmine/files + +``` + +# Скрины работы программы: + +Панель консоли +![](lab_1.png "") + +# Видео + diff --git a/haliullov_kamil_lab_1/docker-compose.yml b/haliullov_kamil_lab_1/docker-compose.yml new file mode 100644 index 0000000..681a721 --- /dev/null +++ b/haliullov_kamil_lab_1/docker-compose.yml @@ -0,0 +1,53 @@ +services: + mediawiki: # Определение сервиса MediaWiki + image: mediawiki:1.35 # Используемый образ MediaWiki версии 1.35 + ports: # Настройка портов + - "8080:80" + containername: mediawiki # Имя контейнера + volumes: # Настройка томов + - mediawiki_data:/var/www/html/images + + db_wordpress: # Определение сервиса MySQL для WordPress + image: mysql:5.7 # Используемый образ MySQL версии 5.7 + containername: wp_database # Имя контейнера + environment: # Переменные окружения + MYSQLROOTPASSWORD: rootsecret + MYSQLDATABASE: ${DBNAME} + MYSQLUSER: ${DBUSER} + MYSQLPASSWORD: ${DBPASSWORD} + volumes: # Настройка томов + - db_wordpress_data:/var/lib/mysql + + wordpress: # Определение сервиса WordPress + image: wordpress:latest # Используемый образ WordPress последней версии + containername: wp_app # Имя контейнера + restart: always + ports: # Настройка портов + - "8000:80" + user: www-data + environment: # Переменные окружения + WORDPRESSDBHOST: ${DBHOST} + WORDPRESSDBUSER: ${DBUSER} + WORDPRESSDBPASSWORD: ${DBPASSWORD} + WORDPRESSDBNAME: ${DBNAME} + WORDPRESSADMINUSER: admin + WORDPRESSADMINPASSWORD: adminpassword + WORDPRESSADMINEMAIL: admin@example.com + volumes: # Настройка томов + - wordpress_data:/var/www/html + dependson: # Зависимости + - db_wordpress # Зависит от сервиса MySQL + + redmine: # Определение сервиса Redmine + image: redmine:latest # Используемый образ Redmine последней версии + containername: redmine # Имя контейнера + ports: # Настройка портов + - "3000:3000" + volumes: # Настройка томов + - redmine_data:/usr/src/redmine/files + +volumes: # Определение томов + mediawiki_data: # ТОМ для MediaWiki + wordpress_data: # ТОМ для WordPress + db_wordpress_data: # ТОМ для MySQL + redmine_data: # ТОМ для Redmine \ No newline at end of file diff --git a/haliullov_kamil_lab_1/entrypoint.sh b/haliullov_kamil_lab_1/entrypoint.sh new file mode 100644 index 0000000..4d2aadd --- /dev/null +++ b/haliullov_kamil_lab_1/entrypoint.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -e + +# Ожидание готовности базы данных +until wp db check; do + echo "Ожидание базы данных..." + sleep 5 +done + +# Установка WordPress +if ! wp core is-installed; then + wp core install --url="http://localhost:8000" --title="Библиотека" --admin_user="admin" --admin_password="admin_password" --admin_email="admin@example.com" --skip-email +fi + +exec apache2-foreground \ No newline at end of file diff --git a/haliullov_kamil_lab_1/lab_1.png b/haliullov_kamil_lab_1/lab_1.png new file mode 100644 index 0000000..48fbc48 Binary files /dev/null and b/haliullov_kamil_lab_1/lab_1.png differ diff --git a/haliullov_kamil_lab_2/.gitignore b/haliullov_kamil_lab_2/.gitignore new file mode 100644 index 0000000..49065ec --- /dev/null +++ b/haliullov_kamil_lab_2/.gitignore @@ -0,0 +1,10 @@ +data/ +result/ +__pycache__/ +*.py[cod] +*.env +*.venv +.env.local +venv/ +env/ +.idea/ \ No newline at end of file diff --git a/haliullov_kamil_lab_2/README.md b/haliullov_kamil_lab_2/README.md new file mode 100644 index 0000000..9569de0 --- /dev/null +++ b/haliullov_kamil_lab_2/README.md @@ -0,0 +1,44 @@ +# Лабораторная работа №2 - Разработка простейшего распределённого приложения + +## Задание + +1. Разработать два приложения: + - **OneApp**: Берёт из каталога /var/data случайный файл и перекладывает его в /var/result/data.txt. + - **TwoApp**: Сохраняет произведение первого и последнего числа из файла /var/result/data.txt в /var/result/result.txt. +2. Разработать файлы сборки Docker для каждого приложения. +3. Собрать файл docker-compose.yml для запуска обоих приложений. +4. Настроить монтирование директорий для обмена данными между контейнерами. +5. Правильно закоммитить решение с использованием .gitignore для исключения лишних файлов. + + +## Запуск: + +В директории, где находится файл docker-compose.yml, выполним команду для сборки и запуска всех контейнеров: + +`docker-compose up --build` + +Эта команда: +1. Собирает все Docker-образы для сервисов. +2. Запускает контейнеры. +3. Автоматически подготавливает данные и выполняет приложения последовательно. + +## Результаты: + +После успешного завершения работы контейнеров можно проверить результаты в папке result: +- **data.txt** — файл, полученный после выполнения первого приложения (содержит копию случайно выбранного файла из папки data). + +- **result.txt** — файл, полученный после выполнения второго приложения (содержит произведение первого и последнего чисел из файла data.txt). + + +### Генерация данных: + +Для создания случайных данных был написан скрипт generate_data.py: +- Создает несколько файлов с целыми числами в каталоге /var/data. +- Каждый файл содержит случайные числа, которые будут использоваться первым приложением. + +### Dockerfile: + +Каждое приложение имеет собственный Dockerfile, где указаны шаги для сборки Python-образов и запуска программ. + +## Видео +https://disk.yandex.ru/i/r1UsIUdnP2BdeQ diff --git a/haliullov_kamil_lab_2/datagenerator/Dockerfile b/haliullov_kamil_lab_2/datagenerator/Dockerfile new file mode 100644 index 0000000..6babcbc --- /dev/null +++ b/haliullov_kamil_lab_2/datagenerator/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.9-slim + +WORKDIR /datagenerator + +COPY generate_data.py /datagenerator/ + +CMD ["python", "generate_data.py"] diff --git a/haliullov_kamil_lab_2/datagenerator/generate_data.py b/haliullov_kamil_lab_2/datagenerator/generate_data.py new file mode 100644 index 0000000..e8f2db5 --- /dev/null +++ b/haliullov_kamil_lab_2/datagenerator/generate_data.py @@ -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() diff --git a/haliullov_kamil_lab_2/docker-compose.yml b/haliullov_kamil_lab_2/docker-compose.yml new file mode 100644 index 0000000..6c7163e --- /dev/null +++ b/haliullov_kamil_lab_2/docker-compose.yml @@ -0,0 +1,21 @@ +services: + datagenerator: + build: + context: ./datagenerator + volumes: + - ./data:/var/data + oneapp: + build: + context: ./oneapp + volumes: + - ./data:/var/data + - ./result:/var/result + depends_on: + - datagenerator + twoapp: + build: + context: ./twoapp + volumes: + - ./result:/var/result + depends_on: + - oneapp diff --git a/haliullov_kamil_lab_2/oneapp/Dockerfile b/haliullov_kamil_lab_2/oneapp/Dockerfile new file mode 100644 index 0000000..dbe7cdc --- /dev/null +++ b/haliullov_kamil_lab_2/oneapp/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.9-slim + +WORKDIR /oneapp + +COPY main.py /oneapp/ + +CMD ["python", "main.py"] diff --git a/haliullov_kamil_lab_2/oneapp/main.py b/haliullov_kamil_lab_2/oneapp/main.py new file mode 100644 index 0000000..6072760 --- /dev/null +++ b/haliullov_kamil_lab_2/oneapp/main.py @@ -0,0 +1,33 @@ +import os +import shutil +import random + +def select_random_file(directory): + files = os.listdir(directory) + if not files: + raise FileNotFoundError("Каталог пустой") + + random_file = random.choice(files) + return os.path.join(directory, random_file) + +def copy_file_to_destination(source_file, destination_folder, new_filename="data.txt"): + destination_path = os.path.join(destination_folder, new_filename) + shutil.copy(source_file, destination_path) + +def main(): + input_directory = "/var/data" + output_directory = "/var/result" + + try: + # Выбор случайного файла + random_file_path = select_random_file(input_directory) + + # Копирование файла в целевой каталог + copy_file_to_destination(random_file_path, output_directory) + + print(f"Копирован файл: {random_file_path} в {os.path.join(output_directory, 'data.txt')}") + except FileNotFoundError as e: + print(e) + +if __name__ == "__main__": + main() diff --git a/haliullov_kamil_lab_2/twoapp/Dockerfile b/haliullov_kamil_lab_2/twoapp/Dockerfile new file mode 100644 index 0000000..a19f731 --- /dev/null +++ b/haliullov_kamil_lab_2/twoapp/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.9-slim + +WORKDIR /twoapp + +COPY main.py /twoapp/ + +CMD ["python", "main.py"] diff --git a/haliullov_kamil_lab_2/twoapp/main.py b/haliullov_kamil_lab_2/twoapp/main.py new file mode 100644 index 0000000..b4fda12 --- /dev/null +++ b/haliullov_kamil_lab_2/twoapp/main.py @@ -0,0 +1,37 @@ +import os + +def read_numbers_from_file(file_path): + if not os.path.exists(file_path): + raise FileNotFoundError(f"Файл {file_path} не найден!") + + with open(file_path, 'r') as f: + lines = f.readlines() + + # Получаем первое и последнее число из списка строк + first_number = int(lines[0].strip()) + last_number = int(lines[-1].strip()) + + return first_number, last_number + +def calculate_product(first_number, last_number): + product = first_number * last_number + return product + +def write_result(product, output_filepath): + with open(output_filepath, 'w') as f: + f.write(str(product)) + +def main(): + input_filepath = '/var/result/data.txt' # Исходный файл + output_filepath = '/var/result/result.txt' # Результирующий файл + + try: + first_number, last_number = read_numbers_from_file(input_filepath) + product = calculate_product(first_number, last_number) + write_result(product, output_filepath) + print(f"Произведение первого и последнего числа сохранено в {output_filepath}") + except FileNotFoundError as e: + print(e) + +if __name__ == "__main__": + main()