Compare commits

...

2 Commits

Author SHA1 Message Date
Zyzf
f0b48bba28 kalyshev_yan_lab_2 is ready 2024-09-29 20:05:33 +04:00
Zyzf
8efc2422cf kalyshev_yan_lab_1 is ready 2024-09-29 12:39:22 +04:00
10 changed files with 452 additions and 0 deletions

6
kalyshev_yan_lab_1/.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
gitea/
gitea-db/
images/
LocalSettings.php
mediawiki-db/
readmine-db/

View File

@@ -0,0 +1,94 @@
# Калышев Ян ПИбд-42
## Описание
Этот проект разворачивает среду с баг-трекером Redmine, сервис для хранения репозиториев git Gitea, вики Mediawiki и базы данных для каждого сервиса с использованием Docker Compose. Ниже приведены шаги для запуска и настройки.
## 0. Предварительные действия
Перед запуском Docker Compose выполнил следующие шаги:
1. Установил docker, docker-buildx (пусть будет) и docker-compose для моей операционной системы.
2. Запустил и поставил в автозапуск docker через `sudo systemctl enable --now docker`.
## 1. Структура и запуск сервиса
Файл `docker-compose.yml` содержит описание 6 сервисов:
- gitea (Gitea);
- gitea-db (MySQL для Gitea);
- readmine (Readmine);
- readmine-db (MySQL для Readmine);
- mediawiki (Mediawiki);
- mediawiki-db (MariaDB для Mediawiki);
Запуск всех сервисов происходит через команду:
```bash
docker-compose up -d
```
## 1. Gitea
- **Образ**: `gitea/gitea:latest`
- **Порты**:
- `3000:3000` — http порт Gitea http://localhost:3000.
- `222:22` - порт для проброса ssh
- **Переменные окружения**:
- `USER_UID=1000` - uid пользователя, от которого запускается gitea
- `USER_GID=1000` - gid пользователя, от которого запускается gitea
- `GITEA__database__DB_TYPE: mysql` - тип бд
- `GITEA__database__HOST: gitea-db:3306` - адрес бд
- `GITEA__database__NAME: gitea` - имя бд
- `GITEA__database__USER: gitea` - пользователь бд
- `GITEA__database__PASSWD: gitea` - пароль бд
- **Тома**:
- `./gitea:/data` — хранение файлов gitea.
- `/etc/timezone:/etc/timezone:ro` - проброс часового пояса из хост-системы
- `/etc/localtime:/etc/localtime:ro` - проброс часового пояса из хост-системы
- **links, depends_on**
- `gitea-db` - для запуска строго после бд и гарантированной связи сетей
## 2. Readmine
- **Образ**: `readmine:latest`
- **Порты**:
- `8080:3000` — http порт Readmine http://localhost:8080.
- **Переменные окружения**:
- `REDMINE_DB_MYSQL: readmine-db` - адрес бд
- `REDMINE_DB_PASSWORD: example` - пароль бд
- `REDMINE_SECRET_KEY_BASE: supersecretkey` - секретный ключ текущего инстанса
- **links, depends_on**
- `readmine-db` - для запуска строго после бд и гарантированной связи сетей
## 3. Mediawiki
- **Образ**: `mediawiki:latest`
- **Порты**:
- `8081:3000` — http порт Mediawiki http://localhost:8081.
- **Тома**:
- `./images:/var/www/html/images` — хранение изображений mediawiki.
- `./LocalSettings.php:/var/www/html/LocalSettings.php` - проброс файла с настройками после прохождения первичной настройки
- **links, depends_on**
- `mediawiki-db` - для запуска строго после бд и гарантированной связи сетей
## 4. Базы данных
- **Образы**: `mariadb`, `mysql:8.0` (в соответствии с офф. документациями)
- **Тома**:
- `./gitea-db:/var/lib/mysql` — хранение данных бд gitea.
- `./readmine-db:/var/lib/mysql` — хранение данных бд readmine.
- `./mediawiki-db:/var/lib/mysql` — хранение данных бд mediawiki.
- **Переменные окружения** - взяты в соответствии с офф. документациями
## 6. Остановка сервисов
Для остановки и удаления всех контейнеров необходимо выполнить команду:
```bash
docker-compose down
```
## 7. Ссылка на видео
[Видео-отчёт Калышев Ян ПИбд-42](https://zyzf.space/s/stezZksnbyqaWYo)

View File

@@ -0,0 +1,81 @@
services:
gitea:
image: gitea/gitea:latest
environment:
USER_UID: 1000
USER_GID: 1000
GITEA__database__DB_TYPE: mysql
GITEA__database__HOST: gitea-db:3306
GITEA__database__NAME: gitea
GITEA__database__USER: gitea
GITEA__database__PASSWD: gitea
restart: always
links:
- gitea-db
depends_on:
- gitea-db
volumes:
- ./gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "222:22"
gitea-db:
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: gitea
MYSQL_USER: gitea
MYSQL_PASSWORD: gitea
MYSQL_DATABASE: gitea
volumes:
- ./gitea-db:/var/lib/mysql
redmine:
image: redmine:latest
restart: always
ports:
- 8080:3000
links:
- readmine-db
depends_on:
- readmine-db
environment:
REDMINE_DB_MYSQL: readmine-db
REDMINE_DB_PASSWORD: example
REDMINE_SECRET_KEY_BASE: supersecretkey
readmine-db:
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: redmine
volumes:
- ./readmine-db:/var/lib/mysql
mediawiki:
image: mediawiki:latest
restart: always
ports:
- 8081:80
links:
- mediawiki-db
depends_on:
- mediawiki-db
volumes:
- ./images:/var/www/html/images
- ./LocalSettings.php:/var/www/html/LocalSettings.php
mediawiki-db:
image: mariadb
restart: always
environment:
MYSQL_DATABASE: my_wiki
MYSQL_USER: wikiuser
MYSQL_PASSWORD: example
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
volumes:
- ./mediawiki-db:/var/lib/mysql

5
kalyshev_yan_lab_2/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
data/
result/
result_first/
result_second/
datagen.py

View File

@@ -0,0 +1,16 @@
#Берем базовый образ python
FROM python:3.12
#Устанавливаем рабочую директорию
WORKDIR /app
#Копирум код в рабочую директорию
COPY main.py .
#Задаем /var/data как монтируемый
VOLUME ["/var/data"]
#Задаем /var/result как монтируемый
VOLUME ["/var/result"]
#Задаем команду для выполнения программы
CMD ["python", "main.py"]

View File

@@ -0,0 +1,79 @@
import os
import random
# Установите полный путь к каталогу, в котором нужно искать самый большой файл.
CATALOG_PATH = "/var/data"
# Полный путь до файла результата.
RESULT_FILE = "/var/result/data.txt"
def find_largest_file(directory):
"""Ищет самый большой по объему файл в заданном каталоге и его подкаталогах."""
largest_file = None
max_size = 0
for root, _, files in os.walk(directory):
for file in files:
# Полный путь к текущему файлу.
filepath = os.path.join(root, file)
try:
file_size = os.stat(filepath).st_size
if file_size > max_size:
max_size = file_size
largest_file = (filepath, file_size)
except OSError as e:
print(f"Ошибка при открытии файла '{filepath}': {e}")
return largest_file
def copy_file(src, dst):
"""Копирует содержимое файла src в файл dst."""
try:
with open(dst, "wb") as f_dst, open(src, "rb") as f_src:
while chunk := f_src.read(4096):
f_dst.write(chunk)
print(f"Файл '{src}' успешно скопирован в '{dst}'.")
except Exception as e:
print(f"Ошибка при копировании файла '{src}': {e}")
def main():
largest_file_path = find_largest_file(CATALOG_PATH)
if largest_file_path:
src_path, _ = largest_file_path
dst_path = RESULT_FILE
copy_file(src_path, dst_path)
else:
print("Нет файлов в каталоге.")
def generate_random_numbers(filename, count):
"""Функция генерирует случайные числа и записывает их в файл."""
with open(filename, "w") as f:
for _ in range(count):
num = random.randint(0, 1000)
f.write(str(num) + "\n")
print(f"Случайные числа успешно записаны в '{filename}'.")
if __name__ == "__main__":
generate_random_numbers("/var/data/data1.txt", 50)
generate_random_numbers("/var/data/data2.txt", 75)
generate_random_numbers("/var/data/data3.txt", 25)
print("Генерация файлов завершена.")
main()

View File

@@ -0,0 +1,74 @@
# Калышев Ян ПИбд-42
## Описание
Этот проект предоставляет 2 контейнера с простыми python-скриптами такими, что результат первого является исходными данными для второго.
## 1. Варианты
Для первой программы был взят вариант:
**0**. Ищет в каталоге /var/data самый большой по объёму файл и перекладывает его в /var/result/data.txt.
Для второй программы был взят вариант:
**2**. Ищет наименьшее число из файла /var/data/data.txt и сохраняет его третью степень в /var/result/result.txt.
## 2. Структура Dockerfile
Оба Dockerfile почти одинаковые:
```Dockerfile
#Берем базовый образ python
FROM python:3.12
#Устанавливаем рабочую директорию
WORKDIR /app
#Копирум код в рабочую директорию
COPY main.py .
#Задаем /var/data как монтируемый
VOLUME ["/var/data"]
#Задаем /var/result как монтируемый
VOLUME ["/var/result"]
#Задаем команду для выполнения программы
CMD ["python", "main.py"]
```
## 3. Docker Compose
`docker-compose.yml`:
```yaml
services:
#Первый скрипт
first:
#Указание директории для сборки первого скрипта
build: ./FirstProgram/
#Монтирование 2 каталогов из хост системы
volumes:
- ./data:/var/data
- ./result_first:/var/result
#Второй скрипт
second:
#Указание директории для сборки второго скрипта
build: ./SecondProgram/
#Задание очередности запуска с помощью depends_on
depends_on:
- first
#Монтирование 2 каталогов из хост системы
volumes:
- ./result_first:/var/data
- ./result_second:/var/result
```
## 4. Запуск
Для запуска использовать команду `docker compose up --build`
Предварительно нужно создать папку `data`, в которой создать файлы, где каждая строка - это число.
Результат первого скрипта будет в папке `result_first`, результат второго скрипта будет в папке `result_second`.
## 7. Ссылка на видео
[Видео-отчёт Калышев Ян ПИбд-42](https://zyzf.space/s/65HRyTTXAzxpwBF)

View File

@@ -0,0 +1,16 @@
#Берем базовый образ python
FROM python:3.12
#Устанавливаем рабочую директорию
WORKDIR /app
#Копирум код в рабочую директорию
COPY main.py .
#Задаем /var/data как монтируемый
VOLUME ["/var/data"]
#Задаем /var/result как монтируемый
VOLUME ["/var/result"]
#Задаем команду для выполнения программы
CMD ["python", "main.py"]

View File

@@ -0,0 +1,60 @@
# Установите полный путь к файлу, из которого нужно читать числа.
DATA_FILE = "/var/data/data.txt"
# Полный путь до файла результата.
RESULT_FILE = "/var/result/result.txt"
def find_smallest_number(data_file):
"""Ищет наименьшее число в заданном файле."""
try:
with open(data_file, "r") as f:
numbers = [int(line.strip()) for line in f.readlines()]
smallest_num = min(numbers)
return smallest_num
except ValueError as e:
print(f"Ошибка при преобразовании строк в числа: {e}")
except Exception as e:
print(f"Ошибка чтения файла '{data_file}': {e}")
return None
def cube_number(num):
"""Возвращает куб заданного числа."""
return num**3
def write_result(result_file, result):
"""Записывает результат в файл."""
try:
with open(result_file, "w") as f:
f.write(str(result))
print(f"Результат '{result}' успешно записан в '{result_file}'.")
except Exception as e:
print(f"Ошибка записи результата в файл '{result_file}': {e}")
def main():
smallest_num = find_smallest_number(DATA_FILE)
if smallest_num is not None:
result = cube_number(smallest_num)
write_result(RESULT_FILE, result)
print(result)
else:
print("Нет чисел в файле.")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,21 @@
services:
#Первый скрипт
first:
#Указание директории для сборки первого скрипта
build: ./FirstProgram/
#Монтирование 2 каталогов из хост системы
volumes:
- ./data:/var/data
- ./result_first:/var/result
#Второй скрипт
second:
#Указание директории для сборки второго скрипта
build: ./SecondProgram/
#Задание очередности запуска с помощью depends_on
depends_on:
- first
#Монтирование 2 каталогов из хост системы
volumes:
- ./result_first:/var/data
- ./result_second:/var/result