Загрузить файлы в «sk1»
This commit is contained in:
parent
8aa3fa139d
commit
5b381d2391
16
sk1/Dockerfile
Normal file
16
sk1/Dockerfile
Normal file
@ -0,0 +1,16 @@
|
||||
FROM python:3.9-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Установка зависимостей
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt gunicorn
|
||||
|
||||
# Копируем все файлы приложения
|
||||
COPY . .
|
||||
|
||||
# Открываем порт для приложения
|
||||
EXPOSE 5000
|
||||
|
||||
# Запуск приложения через Gunicorn
|
||||
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "app:app"]
|
72
sk1/README.md
Normal file
72
sk1/README.md
Normal file
@ -0,0 +1,72 @@
|
||||
# **Správa Používateľov - Docker Aplikácia**
|
||||
|
||||
## **1. Podmienky na nasadenie a spustenie aplikácie**
|
||||
Aby ste mohli aplikáciu spustiť, musíte mať nainštalované:
|
||||
- **Linux** (napr. Ubuntu vo WSL, alebo iná distribúcia)
|
||||
- **Docker** (https://docs.docker.com/get-docker/)
|
||||
- **Docker Compose** (https://docs.docker.com/compose/install/)
|
||||
|
||||
## **2. Opis aplikácie**
|
||||
Aplikácia poskytuje jednoduché webové rozhranie na správu používateľov. Používateľlia sú uložení v databáze PostgreSQL a aplikácia ich dokáže pridávať alebo mazať cez jednoduché API a webové rozhranie.
|
||||
|
||||
## **3. Opis virtuálnych sietí a pomenovaných zväzkov**
|
||||
- **Virtuálna sieť `app_network`** - Umožňuje komunikáciu medzi kontajnermi (web, db, pgAdmin).
|
||||
- **Pomenovaný zväzok `pgdata`** - Používa sa na trvalé uloženie databázových údajov PostgreSQL, aby sa nestratili pri reštarte kontajnerov.
|
||||
|
||||
## **4. Opis konfigurácie kontajnerov**
|
||||
Aplikácia používa **Docker Compose**, kde sú definované tri kontajnery:
|
||||
- **Web** (Flask aplikácia)
|
||||
- Počúva na porte **5000**
|
||||
- Komunikuje s databázou `db`
|
||||
- **DB** (PostgreSQL)
|
||||
- Používa volume `pgdata` na trvalé uloženie údajov
|
||||
- Počúva na porte **5432**
|
||||
- **pgAdmin** (Grafické rozhranie na správu PostgreSQL)
|
||||
- Počúva na porte **8080**
|
||||
|
||||
## **5. Zoznam použitých kontajnerov**
|
||||
- **Web (Flask)** - Používa Python 3.9 a Flask na poskytovanie webovej aplikácie.
|
||||
- **PostgreSQL** - Používa obraz `postgres:13`, databázu `mydatabase`.
|
||||
- **pgAdmin** - Používa obraz `dpage/pgadmin4`, port **8080**.
|
||||
|
||||
## **6. Ako pripraviť, spustiť, pozastaviť a vymazať aplikáciu**
|
||||
|
||||
### **Príprava aplikácie:**
|
||||
```bash
|
||||
./prepare-app.sh
|
||||
```
|
||||
Týmto príkazom sa vytvorí sieť, volume a pripraví databáza.
|
||||
|
||||
### **Spustenie aplikácie:**
|
||||
```bash
|
||||
./start-app.sh
|
||||
```
|
||||
Aplikácia sa spustí a bude dostupná na **http://localhost:5000**.
|
||||
|
||||
### **Pozastavenie aplikácie:**
|
||||
```bash
|
||||
./stop-app.sh
|
||||
```
|
||||
Pozastavenie aplikácie neodstráni údaje.
|
||||
|
||||
### **Vymazanie aplikácie:**
|
||||
```bash
|
||||
./remove-app.sh
|
||||
```
|
||||
Tento príkaz **vymaže všetky kontajnery, sieť a volume**, čo znamená, že **databáza bude kompletne vymazaná**.
|
||||
|
||||
## **7. Ako si pozrieť aplikáciu v prehliadači**
|
||||
- **Hlavná aplikácia:** [http://localhost:5000](http://localhost:5000)
|
||||
- **pgAdmin (správa databázy):** [http://localhost:8080](http://localhost:8080)
|
||||
|
||||
## **8. Príklad práce s aplikáciou**
|
||||
|
||||
### **Pridanie používateľa:**
|
||||
1. Otvorte aplikáciu na **http://localhost:5000**
|
||||
2. Zadajte meno do textového poľa.
|
||||
3. Kliknite na **"Pridať"**.
|
||||
4. Používateľ sa uloží do databázy a zobrazí na stránke.
|
||||
|
||||
### **Odstránenie používateľa:**
|
||||
1. Kliknite na tlačidlo **"Odstrániť"** pri konkrétnom používateľovi.
|
||||
2. Používateľ bude vymazaný z databázy.
|
73
sk1/app.py
Normal file
73
sk1/app.py
Normal file
@ -0,0 +1,73 @@
|
||||
from flask import Flask, render_template, request, jsonify
|
||||
import psycopg2
|
||||
import os
|
||||
|
||||
app = Flask(__name__, template_folder="templates", static_folder="static")
|
||||
|
||||
# Подключение к БД
|
||||
def get_db_connection():
|
||||
conn = psycopg2.connect(
|
||||
host=os.getenv("DB_HOST"),
|
||||
database=os.getenv("DB_NAME"),
|
||||
user=os.getenv("DB_USER"),
|
||||
password=os.getenv("DB_PASS"),
|
||||
sslmode="require"
|
||||
)
|
||||
return conn
|
||||
|
||||
|
||||
# Главная страница с HTML
|
||||
@app.route("/")
|
||||
def home():
|
||||
conn = get_db_connection()
|
||||
cur = conn.cursor()
|
||||
cur.execute("SELECT id, name, created_at FROM users;")
|
||||
users = cur.fetchall()
|
||||
cur.close()
|
||||
conn.close()
|
||||
return render_template("index.html", users=users)
|
||||
|
||||
# API для добавления пользователя
|
||||
@app.route("/add_user", methods=["POST"])
|
||||
def add_user():
|
||||
name = request.form.get("name")
|
||||
if name:
|
||||
conn = get_db_connection()
|
||||
cur = conn.cursor()
|
||||
cur.execute("INSERT INTO users (name) VALUES (%s) RETURNING id;", (name,))
|
||||
user_id = cur.fetchone()[0]
|
||||
conn.commit()
|
||||
cur.close()
|
||||
conn.close()
|
||||
return jsonify({"id": user_id, "name": name}), 201
|
||||
return jsonify({"error": "Имя не может быть пустым"}), 400
|
||||
|
||||
# API для удаления пользователя
|
||||
@app.route("/delete_user/<int:user_id>", methods=["POST"])
|
||||
def delete_user(user_id):
|
||||
conn = get_db_connection()
|
||||
cur = conn.cursor()
|
||||
cur.execute("DELETE FROM users WHERE id = %s RETURNING id;", (user_id,))
|
||||
deleted = cur.fetchone()
|
||||
conn.commit()
|
||||
cur.close()
|
||||
conn.close()
|
||||
if deleted:
|
||||
return jsonify({"message": "Пользователь удален"})
|
||||
return jsonify({"error": "Пользователь не найден"}), 404
|
||||
|
||||
# API для случайного пользователя
|
||||
@app.route("/random_user")
|
||||
def random_user():
|
||||
conn = get_db_connection()
|
||||
cur = conn.cursor()
|
||||
cur.execute("SELECT id, name, created_at FROM users ORDER BY RANDOM() LIMIT 1;")
|
||||
user = cur.fetchone()
|
||||
cur.close()
|
||||
conn.close()
|
||||
if user:
|
||||
return jsonify({"id": user[0], "name": user[1], "created_at": user[2].strftime('%Y-%m-%d %H:%M:%S')})
|
||||
return jsonify({"error": "Нет пользователей"}), 404
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0", port=5000, debug=True)
|
22
sk1/docker-compose.yml
Normal file
22
sk1/docker-compose.yml
Normal file
@ -0,0 +1,22 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
web:
|
||||
build: .
|
||||
ports:
|
||||
- "5000:5000"
|
||||
depends_on:
|
||||
- db
|
||||
restart: always # Добавлено для автоматического рестарта при сбоях
|
||||
|
||||
db:
|
||||
image: postgres:13
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
environment:
|
||||
- POSTGRES_PASSWORD=mysecretpassword
|
||||
- POSTGRES_DB=mydatabase
|
||||
restart: always # Также добавлено здесь
|
||||
|
||||
volumes:
|
||||
pgdata:
|
188
sk1/prepare-app.sh
Normal file
188
sk1/prepare-app.sh
Normal file
@ -0,0 +1,188 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Параметры
|
||||
APP_NAME="userapp"
|
||||
RESOURCE_GROUP="userapp-rg"
|
||||
ENV_NAME="userapp-env"
|
||||
ACR_NAME="userappvladregistry"
|
||||
ACR_IMAGE="$ACR_NAME.azurecr.io/z1-web"
|
||||
POSTGRES_NAME="userapp-pg-vlad4"
|
||||
POSTGRES_HOST="$POSTGRES_NAME.postgres.database.azure.com"
|
||||
POSTGRES_DB="flexibleserverdb"
|
||||
POSTGRES_USER="postgres"
|
||||
POSTGRES_PASS="MySuperSecretPass123"
|
||||
LOCATION="northeurope"
|
||||
|
||||
# 🏗️ Создание resource group (если не существует)
|
||||
echo "📁 Проверка: существует ли Resource Group $RESOURCE_GROUP..."
|
||||
RG_EXISTS=$(az group exists --name $RESOURCE_GROUP)
|
||||
|
||||
if [[ "$RG_EXISTS" == "false" ]]; then
|
||||
echo "🌟 Создаю Resource Group $RESOURCE_GROUP..."
|
||||
az group create --name $RESOURCE_GROUP --location $LOCATION
|
||||
else
|
||||
echo "✔️ Resource Group уже существует"
|
||||
fi
|
||||
|
||||
# 🔧 Проверка и создание ACR
|
||||
ACR_EXISTS=$(az acr show --name $ACR_NAME --resource-group $RESOURCE_GROUP --query "name" -o tsv 2>/dev/null || echo "")
|
||||
if [[ -z "$ACR_EXISTS" ]]; then
|
||||
echo "🌟 Создаю Azure Container Registry..."
|
||||
az acr create --resource-group $RESOURCE_GROUP --name $ACR_NAME --sku Basic
|
||||
else
|
||||
echo "✔️ ACR уже существует"
|
||||
fi
|
||||
|
||||
# Включаем admin user
|
||||
az acr update --name $ACR_NAME --admin-enabled true
|
||||
|
||||
# Ждем, пока ACR станет доступным
|
||||
echo "⏳ Ждем пока ACR станет доступным..."
|
||||
for i in {1..10}; do
|
||||
if az acr repository list --name $ACR_NAME &>/dev/null; then
|
||||
echo "✅ ACR готов"
|
||||
break
|
||||
else
|
||||
echo "⏳ Ожидание... ($i/10)"
|
||||
sleep 5
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
# Получаем учетные данные
|
||||
ACR_USERNAME=$(az acr credential show --name $ACR_NAME --query "username" -o tsv)
|
||||
ACR_PASSWORD=$(az acr credential show --name $ACR_NAME --query "passwords[0].value" -o tsv)
|
||||
|
||||
echo "🧠 Проверка: существует ли PostgreSQL сервер..."
|
||||
PG_EXISTS=$(az postgres flexible-server show \
|
||||
--name $POSTGRES_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--query "name" -o tsv 2>/dev/null || echo "")
|
||||
|
||||
if [[ -n "$PG_EXISTS" ]]; then
|
||||
echo "🔐 Пробуем подключиться к PostgreSQL..."
|
||||
if ! psql "host=$POSTGRES_HOST port=5432 dbname=postgres user=$POSTGRES_USER password=$POSTGRES_PASS sslmode=require" -c '\q' 2>/dev/null; then
|
||||
echo "❌ Пароль не работает — удаляю и создаю заново..."
|
||||
az postgres flexible-server delete --name $POSTGRES_NAME --resource-group $RESOURCE_GROUP --yes
|
||||
PG_EXISTS=""
|
||||
sleep 5
|
||||
else
|
||||
echo "✅ Успешное подключение"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "$PG_EXISTS" ]]; then
|
||||
echo "🌟 Создаю PostgreSQL..."
|
||||
az postgres flexible-server create \
|
||||
--name $POSTGRES_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--location $LOCATION \
|
||||
--admin-user postgres \
|
||||
--admin-password $POSTGRES_PASS \
|
||||
--sku-name Standard_B1ms \
|
||||
--tier Burstable \
|
||||
--storage-size 32 \
|
||||
--yes
|
||||
|
||||
echo "⏳ Ожидание готовности PostgreSQL..."
|
||||
for i in {1..10}; do
|
||||
STATE=$(az postgres flexible-server show --name $POSTGRES_NAME --resource-group $RESOURCE_GROUP --query "state" -o tsv 2>/dev/null || echo "")
|
||||
echo "🔄 Состояние: $STATE"
|
||||
if [[ "$STATE" == "Ready" ]]; then
|
||||
break
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
|
||||
echo "🌐 Разрешаю IP..."
|
||||
az postgres flexible-server firewall-rule create \
|
||||
--name $POSTGRES_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--rule-name AllowAllIps \
|
||||
--start-ip-address 0.0.0.0 \
|
||||
--end-ip-address 255.255.255.255
|
||||
fi
|
||||
|
||||
echo "🔑 Сбрасываю пароль PostgreSQL..."
|
||||
az postgres flexible-server update --name $POSTGRES_NAME --resource-group $RESOURCE_GROUP --admin-password $POSTGRES_PASS
|
||||
|
||||
echo "⏳ Ждем 10 сек..."
|
||||
sleep 10
|
||||
|
||||
echo "📆 Логин в ACR..."
|
||||
echo $ACR_PASSWORD | docker login "$ACR_NAME.azurecr.io" -u $ACR_USERNAME --password-stdin
|
||||
|
||||
echo "▶️ Сборка Docker образа..."
|
||||
docker build -t z1-web .
|
||||
|
||||
echo "📦 Тегирование и пуш..."
|
||||
docker tag z1-web $ACR_IMAGE
|
||||
docker push $ACR_IMAGE
|
||||
|
||||
echo "☁️ Проверка Container App Environment..."
|
||||
ENV_EXISTS=$(az containerapp env show --name $ENV_NAME --resource-group $RESOURCE_GROUP --query "name" -o tsv 2>/dev/null || echo "")
|
||||
|
||||
if [[ -z "$ENV_EXISTS" ]]; then
|
||||
echo "🌟 Создаю Container Environment..."
|
||||
az containerapp env create --name $ENV_NAME --resource-group $RESOURCE_GROUP --location $LOCATION
|
||||
else
|
||||
echo "✔️ Среда уже есть"
|
||||
fi
|
||||
|
||||
echo "☁️ Проверка Container App..."
|
||||
APP_EXISTS=$(az containerapp show --name $APP_NAME --resource-group $RESOURCE_GROUP --query "name" -o tsv 2>/dev/null || echo "")
|
||||
|
||||
if [[ -z "$APP_EXISTS" ]]; then
|
||||
echo "🌟 Создаю Container App..."
|
||||
az containerapp create \
|
||||
--name $APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--environment $ENV_NAME \
|
||||
--image $ACR_IMAGE \
|
||||
--target-port 5000 \
|
||||
--ingress external \
|
||||
--registry-server "$ACR_NAME.azurecr.io" \
|
||||
--registry-username $ACR_USERNAME \
|
||||
--registry-password $ACR_PASSWORD \
|
||||
--cpu 0.5 --memory 1.0Gi \
|
||||
--env-vars \
|
||||
DB_HOST=$POSTGRES_HOST \
|
||||
DB_NAME=$POSTGRES_DB \
|
||||
DB_USER=$POSTGRES_USER \
|
||||
DB_PASS=$POSTGRES_PASS
|
||||
else
|
||||
echo "🔁 Обновляю Container App..."
|
||||
az containerapp registry set \
|
||||
--name $APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--server "$ACR_NAME.azurecr.io" \
|
||||
--username $ACR_USERNAME \
|
||||
--password $ACR_PASSWORD
|
||||
|
||||
az containerapp update \
|
||||
--name $APP_NAME \
|
||||
--resource-group $RESOURCE_GROUP \
|
||||
--image $ACR_IMAGE \
|
||||
--set-env-vars \
|
||||
DB_HOST=$POSTGRES_HOST \
|
||||
DB_NAME=$POSTGRES_DB \
|
||||
DB_USER=$POSTGRES_USER \
|
||||
DB_PASS=$POSTGRES_PASS
|
||||
fi
|
||||
|
||||
echo "🗄️ Создание таблицы users..."
|
||||
command -v psql >/dev/null 2>&1 || {
|
||||
echo "❌ Установи psql: sudo apt install postgresql-client"
|
||||
exit 1
|
||||
}
|
||||
|
||||
psql "host=$POSTGRES_HOST port=5432 dbname=$POSTGRES_DB user=$POSTGRES_USER password=$POSTGRES_PASS sslmode=require" <<EOF
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
EOF
|
||||
|
||||
echo "✅ Готово! Всё развёрнуто."
|
60
sk1/remove-app.sh
Normal file
60
sk1/remove-app.sh
Normal file
@ -0,0 +1,60 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Параметры
|
||||
APP_NAME="userapp"
|
||||
RESOURCE_GROUP="userapp-rg"
|
||||
ENV_NAME="userapp-env"
|
||||
ACR_NAME="userappvladregistry"
|
||||
ACR_IMAGE="z1-web"
|
||||
POSTGRES_NAME="userapp-pg-vlad4"
|
||||
|
||||
# 🚮 Container App
|
||||
echo "🚮 Удаляю Container App..."
|
||||
if az containerapp show --name $APP_NAME --resource-group $RESOURCE_GROUP &>/dev/null; then
|
||||
az containerapp delete --name $APP_NAME --resource-group $RESOURCE_GROUP --yes
|
||||
else
|
||||
echo "❌ Container App $APP_NAME уже удален или не существует"
|
||||
fi
|
||||
|
||||
# 🚮 Container Environment
|
||||
echo "🚮 Удаляю Container Environment..."
|
||||
if az containerapp env show --name $ENV_NAME --resource-group $RESOURCE_GROUP &>/dev/null; then
|
||||
az containerapp env delete --name $ENV_NAME --resource-group $RESOURCE_GROUP --yes
|
||||
else
|
||||
echo "❌ Container Env $ENV_NAME уже удален или не существует"
|
||||
fi
|
||||
|
||||
# 🚮 PostgreSQL
|
||||
echo "🚮 Удаляю PostgreSQL Server..."
|
||||
if az postgres flexible-server show --name $POSTGRES_NAME --resource-group $RESOURCE_GROUP &>/dev/null; then
|
||||
az postgres flexible-server delete --name $POSTGRES_NAME --resource-group $RESOURCE_GROUP --yes
|
||||
else
|
||||
echo "❌ PostgreSQL сервер $POSTGRES_NAME уже удален или не существует"
|
||||
fi
|
||||
|
||||
# 🚮 Docker образ
|
||||
echo "🚮 Удаляю образ из ACR..."
|
||||
if az acr repository show --name $ACR_NAME --repository $ACR_IMAGE &>/dev/null; then
|
||||
az acr repository delete --name $ACR_NAME --repository $ACR_IMAGE --yes
|
||||
else
|
||||
echo "❌ Образ $ACR_IMAGE уже удален или не найден"
|
||||
fi
|
||||
|
||||
# 🚮 Удаление реестра контейнеров (ACR)
|
||||
echo "🚮 Удаляю ACR $ACR_NAME..."
|
||||
if az acr show --name $ACR_NAME --resource-group $RESOURCE_GROUP &>/dev/null; then
|
||||
az acr delete --name $ACR_NAME --resource-group $RESOURCE_GROUP --yes
|
||||
else
|
||||
echo "❌ ACR $ACR_NAME уже удален или не существует"
|
||||
fi
|
||||
|
||||
# 🚮 Удаление группы ресурсов
|
||||
echo "🚮 Удаляю группу ресурсов $RESOURCE_GROUP..."
|
||||
if az group show --name $RESOURCE_GROUP &>/dev/null; then
|
||||
az group delete --name $RESOURCE_GROUP --yes --no-wait
|
||||
else
|
||||
echo "❌ Группа ресурсов $RESOURCE_GROUP уже удалена или не существует"
|
||||
fi
|
||||
|
||||
echo "✅ Все успешно удалено."
|
3
sk1/requirements.txt
Normal file
3
sk1/requirements.txt
Normal file
@ -0,0 +1,3 @@
|
||||
flask
|
||||
psycopg2-binary
|
||||
gunicorn
|
4
sk1/start-app.sh
Normal file
4
sk1/start-app.sh
Normal file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
docker-compose up -d
|
||||
echo "http://localhost:5000 (Flask)"
|
4
sk1/stop-app.sh
Normal file
4
sk1/stop-app.sh
Normal file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
echo "Zastavujeme kontajnery..."
|
||||
docker-compose down
|
Loading…
Reference in New Issue
Block a user