Сьогодні ми навчимося використовувати Postgres разом із Flask як сервіси за допомогою Docker Compose. Ми використовуватимемо це для контейнеризації додатка Flask і бази даних Postgres як єдиного сервісного блоку та відкриття порту додатка Flask для взаємодії з запитами користувача.
Давайте розглянемо кроки:
Спочатку потрібно переконатися, що Docker встановлений на вашій системі.
Створимо віртуальне середовище:
python3 -m venv env
source env/bin/activate
Тепер створимо файл requirements.txt
:
psycopg2-binary
Flask
Встановимо всі залежності за допомогою:
pip install -r requirements.txt
Спочатку ми створимо простий додаток Flask для простого маршруту:
app = Flask(__name__)
@app.route("/")
def home():
return "Hello world"
if __name__ == "__main__":
app.run()
Це найпростіша форма додатка Flask.
Далі ми створимо файл script.py
, який буде завантажувати та вставляти дані до бази даних, а також інший для відображення всіх даних, що зберігаються в базі. Нижче наведено простий приклад файлу script.py
:
def insert_val(cursor, datafile):
CREATE_TABLE_QUERY = """
CREATE TABLE IF NOT EXISTS sample_table (
id SERIAL PRIMARY KEY,
NAME VARCHAR(50),
DEPARTMENT VARCHAR(50)
)"""
cursor.execute(CREATE_TABLE_QUERY)
name = datafile.get("name")
department = datafile.get("department")
INSERT_QUERY = """
INSERT INTO sample_table (NAME, DEPARTMENT) VALUES (%s, %s)
"""
cursor.execute(INSERT_QUERY, (name, department))
def show_all_data(cursor):
SHOW_QUERY = """SELECT * FROM sample_table"""
cursor.execute(SHOW_QUERY)
rows = cursor.fetchall()
column_names = [desc[0] for desc in cursor.description]
# Форматуємо результат як список словників
result = [dict(zip(column_names, row)) for row in rows]
return result
Тепер ми створимо кінцеві точки для вставки даних і отримання всіх даних з бази.
@app.route("/")
def home():
return "All good!!!"
@app.route("/insert-data", methods=["POST"])
def add_data():
try:
conn = psycopg2.connect(**config)
cursor = conn.cursor()
data = request.get_json()
if data is None:
return jsonify({"error": "Missing JSON in request"})
insert_val(cursor, data)
conn.commit()
return jsonify({"message": "All good"}), 200
except Exception as e:
raise jsonify({"error": str(e)})
finally:
conn.close()
@app.route("/show-all")
def show_data():
try:
conn = psycopg2.connect(**config)
cursor = conn.cursor()
result = show_all_data(cursor)
return jsonify(result), 200
except Exception as e:
raise jsonify({"error": str(e)})
finally:
conn.close()
Є змінна config
(насправді це словник), яка буде пояснена на наступному етапі.
У методі add_data
встановлюється з’єднання з сервером Postgres за допомогою параметрів із файлу config. Дані потім парсяться в об'єкт JSON і вставляються до бази даних за допомогою методу insert_val
, зміни фіксуються, і в кінці з’єднання закривається. Метод show_data
використовується для підключення до бази даних за допомогою параметрів config, а результат отримується за допомогою методу show_all_data
і в кінці з’єднання закривається.
На наступному етапі ми контейнеризуємо додаток Flask, створивши Dockerfile. Нижче наведено визначення Dockerfile з поясненням:
# Використовуємо базовий образ Python і на ньому будемо будувати docker-образ
FROM python:3.10
# Це буде робоча директорія
WORKDIR /app
## Ось файли, необхідні для створення docker-образа
## Flask app містить необхідні кінцеві точки API
## Файл script містить SQL-запити для вставки та відображення даних
## Requirements.txt міститиме необхідні бібліотеки
COPY flaskapp.py /app/
COPY script.py /app/
COPY requirements.txt /app/
## Це встановить необхідні бібліотеки
RUN pip install -r /app/requirements.txt
## Це відкриє порт 5000
EXPOSE 5000
## Це запустить додаток flask
CMD ["python3", "/app/flaskapp.py"]
На наступному кроці ми визначимо файл docker-compose.yml
, який побудує Docker-образ та створить Flask-додаток і базу даних Postgres як сервіси.
services: <←- Це визначає сервіси ("web" для Flask-додатка і "db" для бази даних Postgres).
web:
build: <←- Це дозволяє отримати доступ до побудови образа і використовуватиме Dockerfile, який знаходиться в поточній директорії
context: .
dockerfile: Dockerfile
ports: <←- Визначаємо відображення портів (формат: машина_порт : порт_контейнера)
- "5000:5000"
depends_on: <←- Це забезпечує, що сервіс "db" буде побудований перед сервісом "web"
- db
db:
image: postgres:16 <←- Це визначає образ бази даних і її версію
container_name: postgres-container
environment: <←- Це містить змінні середовища для контейнера Postgres
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: postgres
Постійний контейнер бази даних Postgres не створюється тут, але його можна створити, звернувшись до документації:
Давайте подивимося на конфігураційний файл для підключення бази даних до Flask-додатка;
config = {
"dbname": "postgres",
"user": "postgres",
"password": "postgres",
"host": "postgres-container",
"port": 5432
}
Спробуйте провести паралель із файлом docker-compose
, під сервісом "db", де зазначені ім’я користувача, пароль та інші облікові дані, і ці ж дані мають бути вказані тут. Інші деталі конфігурації можна додавати за потреби.
Тепер давайте побудуємо контейнер Flask і контейнер Postgres як сервіси, використовуючи Docker Compose:
- sudo docker compose up -d
Це створить журнали побудови обох контейнерів у фоновому режимі.
Створення сервісів за допомогою docker-compose
2. Sudo docker compose logs db
Це створить журнали для побудови бази даних.
Перевірка журналів docker compose для сервісу db
3. sudo docker compose logs web
Це створить журнали для побудови Flask-додатка.
Перевірка журналів docker compose для сервісу web
Тепер ми вставимо дані в таблицю і відобразимо всі дані, що містяться в базі.
curl -X POST http://localhost:5000/insert-data -H "Content-Type: application/json" -d '{"name": "John Doe", "department": "IT"}'
Цей запит буде використовуватися для вставки даних.
curl http://localhost:5000/show-all
Цей запит буде використовуватися для відображення всіх даних, що є в базі даних.
Вставка та відображення даних з бази
Після всіх операцій видаліть Docker-сервіси за допомогою:
sudo docker compose down
Також ви можете перевірити всі контейнера, що працюють після використання docker compose up, за допомогою:
sudo docker ps -a
Посилання на вихідний код можна знайти тут: https://github.com/MrPotato-00/docker-flask
Більш стійкий підхід може бути застосований для обробки винятків бази даних, які можуть виникнути.
Якщо у вас є пропозиції або відгуки, пишіть у коментарях.
Дякую.
Перекладено з: Docker with Flask and Postgres