From b5c3634bd0b3f172b7aeb56c423303f0da302dbe Mon Sep 17 00:00:00 2001 From: Shay Guedj Date: Wed, 26 Nov 2025 08:49:32 +0200 Subject: [PATCH 1/2] This pull request adds a complete README for Ansible, designed to provide clear guidance for users of all skill levels. The README includes: - Introduction to Ansible and its key concepts (inventory, modules, playbooks, roles, control/managed nodes) - Step-by-step installation instructions for Linux, macOS, and Windows (via WSL) - Basic usage examples and running ad-hoc commands - Writing and running a first playbook - Common use cases and troubleshooting tips - Links to official resources as the Ansible GitHub repository and official documentation. This README aims to provide a complete, professional reference that helps users to understand Ansible, making the project more accessible to beginners while also serving as a practical guide for more experienced users. --- tools/Ansible/README.md | 150 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 141 insertions(+), 9 deletions(-) diff --git a/tools/Ansible/README.md b/tools/Ansible/README.md index e73a675..fa6f116 100644 --- a/tools/Ansible/README.md +++ b/tools/Ansible/README.md @@ -1,23 +1,155 @@ # Ansible -![Ansible Logo](../logos/ansible.svg) +Ansible Logo + + + ## Overview -Agentless automation tool for configuration management, application deployment, and task automation. +Ansible is an open-source automation platform used for configuration management, application deployment, orchestration, and provisioning. It allows you to automate repetitive tasks using simple, human-readable YAML files called Playbooks. +Ansible provides agentless automation by connecting to remote systems via SSH (for Linux/macOS hosts) or WinRM (for Windows hosts). -## Key Features +## Why Ansible? -- Feature 1 -- Feature 2 -- Feature 3 +- Simple and human-readable +- Agentless +- Scalable from one machine to thousands +- Large module ecosystem +- Cloud provider integrations (AWS, Azure, GCP) + +## Key Concepts + +- Inventory + List of hosts and groups Ansible manages. +- Modules + Units of work (e.g., apt, yum, service, copy, win_chocolatey). +- Playbook + YAML file defining tasks to run on hosts. +- Role + Reusable structure for organizing playbooks. +- Control Node + Machine where Ansible is installed/runs. +- Managed Nodes + Machines Ansible operates on. ## Getting Started +### Installation and basic usage instructions: + +### Ubuntu / Debian + +`sudo apt update` +`sudo apt install ansible -y` + +### CentOS / RHEL / Fedora + +`sudo dnf install ansible -y` + +### Install on macOS +Using Homebrew (recommended): + +`brew update` + +`brew install ansible` + +### Verify installation: + +`ansible --version` + +### Install on Windows +Ansible does not run natively on Windows as a control node. +However, use Windows Subsystem for Linux (WSL) (Recommended) and run the commands above. + +## Basic Usage + +Test connectivity to localhost (if supported): + +`ansible localhost -m ping` + +Run a simple command: + +`ansible all -i inventory.ini -m shell -a "uptime"` + +## Working with Inventory +inventory.ini + +``` +[webservers] +192.168.1.10 +192.168.1.11 + +[dbservers] +db01 ansible_host=192.168.1.20 ansible_user=root +``` +YAML Inventory (optional) + +``` +all: + hosts: + local: + ansible_connection: local +``` +## Running Ad-Hoc Commands +Check disk space + +`ansible all -m shell -a "df -h"` + +Install a package + +`ansible webservers -m apt -a "name=nginx state=present" --become` + +## Writing Your First Playbook + +``` +--- +- name: Install NGINX on web servers + hosts: webservers + become: yes + tasks: + - name: Install nginx + apt: + name: nginx + state: present + update_cache: yes + + - name: Ensure nginx is running + service: + name: nginx + state: started + enabled: yes +``` + +Run the playbook: + +`ansible-playbook -i inventory.ini site.yml` + +## Common Use Cases +- Server provisioning +- Installing and configuring applications +- CI/CD automation +- Cloud resource provisioning (AWS/GCP/Azure) +- User/ servers and permission management +- Patching and system updates + +## Troubleshooting +Check connection issues: + +`ansible all -m ping -vvv` + +Check WinRM configuration for Windows: + +`ansible windows -m win_ping` + +Dry run a playbook: + +`ansible-playbook site.yml --check` + +Syntax check: + +`ansible-playbook site.yml --syntax-check` -Installation and basic usage instructions. ## Resources -- [Official Website](https://example.com) -- [Documentation](https://docs.example.com) +- [Ansible Documentation](https://docs.ansible.com) - [GitHub Repository](https://github.com/example/Ansible) From e37f50aea185308555eac42d6d85b88ea08dc96e Mon Sep 17 00:00:00 2001 From: Shay Guedj Date: Sun, 30 Nov 2025 20:05:53 +0200 Subject: [PATCH 2/2] -S --- tools/Docker/Docker-Compose/DB/Dockerfile | 8 + tools/Docker/Docker-Compose/README.md | 218 ++++++++++++++++-- tools/Docker/Docker-Compose/UI/Dockerfile | 14 ++ tools/Docker/Docker-Compose/UI/app.py | 72 ++++++ .../Docker/Docker-Compose/UI/requirements.txt | 2 + .../Docker-Compose/UI/static/styles.css | 74 ++++++ .../Docker-Compose/UI/templates/index.html | 71 ++++++ .../Docker-Compose/UI/templates/styles.css | 74 ++++++ .../Docker/Docker-Compose/docker-compose.yaml | 23 ++ 9 files changed, 535 insertions(+), 21 deletions(-) create mode 100644 tools/Docker/Docker-Compose/DB/Dockerfile create mode 100644 tools/Docker/Docker-Compose/UI/Dockerfile create mode 100644 tools/Docker/Docker-Compose/UI/app.py create mode 100644 tools/Docker/Docker-Compose/UI/requirements.txt create mode 100644 tools/Docker/Docker-Compose/UI/static/styles.css create mode 100644 tools/Docker/Docker-Compose/UI/templates/index.html create mode 100644 tools/Docker/Docker-Compose/UI/templates/styles.css create mode 100644 tools/Docker/Docker-Compose/docker-compose.yaml diff --git a/tools/Docker/Docker-Compose/DB/Dockerfile b/tools/Docker/Docker-Compose/DB/Dockerfile new file mode 100644 index 0000000..ef54362 --- /dev/null +++ b/tools/Docker/Docker-Compose/DB/Dockerfile @@ -0,0 +1,8 @@ +FROM alpine:latest + +RUN mkdir /data + +VOLUME ["/data"] + +CMD ["sleep", "infinity"] + diff --git a/tools/Docker/Docker-Compose/README.md b/tools/Docker/Docker-Compose/README.md index de18c4b..571d0c0 100644 --- a/tools/Docker/Docker-Compose/README.md +++ b/tools/Docker/Docker-Compose/README.md @@ -1,36 +1,212 @@ -# Docker Compose +# Docker UI + Database Project -![Docker Compose](https://raw.githubusercontent.com/docker/compose/master/docs/_static/docker-compose-logo.png) +This project demonstrates a simple 2-container Docker setup: -## Overview +- **UI Container (Flask App)** + Receives values from a user and stores them in a database. -Docker Compose is a tool for defining and running multi-container Docker applications using a YAML file (`docker-compose.yml`). It simplifies local development, testing, and simple deployments. +- **DB Container (Lightweight Alpine)** + Holds a persistent SQLite database file using a shared Docker volume. -## Key Features +--- -- Define multi-container apps with a single YAML file -- Services, networks and volumes orchestration -- One-command start/stop for the full app stack -- Environment variable support and extension -- Works with Docker CLI and Compose V2 plugin +## 📂 Project Structure -## Getting Started +``` +project/ +│ +├── ui/ +│ ├── app.py # Flask application +│ ├── requirements.txt # Python dependencies +│ ├── Dockerfile # Dockerfile for UI container +│ ├── templates/ +│ │ └── index.html # HTML page for the browser UI +│ └── static/ +│ └── styles.css # CSS styling for the UI +│ +├── db/ +│ └── Dockerfile # Minimal Alpine container for database volume +│ +└── docker-compose.yml # Docker Compose configuration + +``` + +--- + +## How It Works + +### UI Container +The UI is a Python Flask application that: + +1. Initializes a SQLite database (`database.db`) on startup. +2. Exposes two API routes: + +#### POST `/add` +Adds a new value to the DB. + +Example request: ```bash -# Install (Linux/macOS with Docker Desktop) - or use Compose V2 as a plugin -docker compose version +curl -X POST http://localhost:5000/add \ + -H "Content-Type: application/json" \ + -d '{"value": "Hello World"}' +``` + +#### GET `/list` +Returns all stored values. + +Example: +```bash +curl http://localhost:5000/list +``` + +--- + +### DB Container + +This container does not run a database engine. +Instead, it: + +- Creates a `/data` directory +- Hosts the SQLite database file +- Exposes the folder through a **Docker volume**, making the data persistent +- Serves as a shared storage backend for the UI container + +This architecture keeps the DB separate and easily replaceable. + +--- + +## Docker Compose Flow -# Start services defined in docker-compose.yml -docker compose up -d +- A shared volume named **`dbdata`** is created. +- The **db** container exposes `/data`. +- The **ui** container mounts the same `/data` folder. +- SQLite file `database.db` lives inside that shared volume. -# View logs -docker compose logs -f +--- -# Stop and remove containers +## How to Run the Project From the browser: + +### 1. Clone the project +```bash +git clone +cd project +``` + +### 2. Build and run with Docker Compose +```bash +docker compose up --build +``` + +You will see: + +- `db_service` → starts and waits +- `ui_service` → starts Flask on port **5000** + +### 3. Open the browser and run: + +``` bash +http://localhost:5000 +``` +#### In the UI itself: +- Enter a value in the input field and press "Add" button or press the Enter key. +- Values are displayed in a table below. +- The table automatically refreshes every 2 seconds to show all stored values. + +--- + + +## How to Run the Project from the CLI: + +### 1. Clone the project +```bash +git clone +cd project +``` + +### 2. Build and run with Docker Compose +```bash +docker compose up --build +``` + +You will see: + +- `db_service` → starts and waits +- `ui_service` → starts Flask on port **5000** + +--- + +### 3. Test the API + +### Add a value: +```bash +curl -X POST http://localhost:5000/add \ + -H "Content-Type: application/json" \ + -d '{"value": "Test"}' +``` + +### Get all values: +```bash +curl http://localhost:5000/list +``` + +--- + +## What it should be like: + +### Input as example: + +``` bash +curl -X POST http://localhost:5000/add -H "Content-Type: application/json" -d '{"value": "This is only a test"}' +``` + +### Output should be something like: + +``` bash +{"message":"Value inserted successfully"} +``` + +## Result output: + +### When you run this: + +``` bash +curl http://localhost:5000/list +``` + +### You should see the value you entered: + +``` bash +[{"id":1,"value":"This is only a test"}] +``` + +#### You can run and add another value, then list it. +#### Now you should see 2 records. + + + + +## Stopping Everything + +```bash docker compose down ``` -## Resources +To delete the persistent DB: + +```bash +docker volume rm project_dbdata +``` + +--- + +## Notes + +- Database persists even after containers stop. +- You can swap SQLite for PostgreSQL easily later. +- Very useful structure for learning multi-container apps. + +--- + +## Done! -- [Official Website](https://docs.docker.com/compose/) -- [GitHub](https://github.com/docker/compose) diff --git a/tools/Docker/Docker-Compose/UI/Dockerfile b/tools/Docker/Docker-Compose/UI/Dockerfile new file mode 100644 index 0000000..db6aea5 --- /dev/null +++ b/tools/Docker/Docker-Compose/UI/Dockerfile @@ -0,0 +1,14 @@ +FROM python:3.11-slim + +# Optional: install sqlite3 CLI to inspect DB manually +RUN apt-get update && apt-get install -y sqlite3 && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +CMD ["python", "app.py"] + diff --git a/tools/Docker/Docker-Compose/UI/app.py b/tools/Docker/Docker-Compose/UI/app.py new file mode 100644 index 0000000..37fd56d --- /dev/null +++ b/tools/Docker/Docker-Compose/UI/app.py @@ -0,0 +1,72 @@ +from flask import Flask, request, jsonify, render_template +import sqlite3 +import os + +app = Flask(__name__, template_folder="templates") + +DB_PATH = "/data/database.db" + +# Ensure /data exists +os.makedirs("/data", exist_ok=True) + +# Initialize database and table +def init_db(): + try: + conn = sqlite3.connect(DB_PATH) + c = conn.cursor() + c.execute(""" + CREATE TABLE IF NOT EXISTS values_table ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + value TEXT NOT NULL, + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP + ); + """) + conn.commit() + conn.close() + print(f"Database initialized at {DB_PATH}") + except Exception as e: + print(f"Error initializing database: {e}") + +init_db() + +@app.route("/") +def index(): + return render_template("index.html") + +@app.route("/add", methods=["POST"]) +def add_value(): + try: + data = request.get_json() or {} + value = data.get("value") + if not value: + return jsonify({"error": "Missing value"}), 400 + + conn = sqlite3.connect(DB_PATH) + c = conn.cursor() + c.execute("INSERT INTO values_table (value) VALUES (?)", (value,)) + conn.commit() + conn.close() + + return jsonify({"status": "added", "value": value}), 201 + except Exception as e: + return jsonify({"error": str(e)}), 500 + +@app.route("/list", methods=["GET"]) +def list_values(): + try: + conn = sqlite3.connect(DB_PATH) + c = conn.cursor() + c.execute("SELECT id, value, timestamp FROM values_table") + rows = c.fetchall() + conn.close() + + return jsonify([ + {"id": r[0], "value": r[1], "timestamp": r[2]} + for r in rows + ]) + except Exception as e: + return jsonify({"error": str(e)}), 500 + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=5000, debug=True) + diff --git a/tools/Docker/Docker-Compose/UI/requirements.txt b/tools/Docker/Docker-Compose/UI/requirements.txt new file mode 100644 index 0000000..6e302cc --- /dev/null +++ b/tools/Docker/Docker-Compose/UI/requirements.txt @@ -0,0 +1,2 @@ +Flask==3.0.2 + diff --git a/tools/Docker/Docker-Compose/UI/static/styles.css b/tools/Docker/Docker-Compose/UI/static/styles.css new file mode 100644 index 0000000..99d79e9 --- /dev/null +++ b/tools/Docker/Docker-Compose/UI/static/styles.css @@ -0,0 +1,74 @@ +/* styles.css */ +body { + font-family: Arial, sans-serif; + background-color: #f5f5f5; + color: #333; + margin: 0; + padding: 0; +} + +.container { + max-width: 800px; + margin: 2em auto; + padding: 2em; + background-color: #ffffff; + border-radius: 12px; + box-shadow: 0 4px 8px rgba(0,0,0,0.1); +} + +h1, h2 { + color: #ff6600; /* Orange titles */ +} + +.input-group { + display: flex; + gap: 0.5em; + margin-bottom: 1em; +} + +input[type="text"] { + flex: 1; + padding: 0.75em; + border-radius: 8px; + border: 1px solid #ccc; + background-color: #fdfdfd; + font-size: 1em; +} + +button { + padding: 0.75em 1.5em; + background-color: #ff6600; + color: white; + border: none; + border-radius: 8px; + cursor: pointer; + font-size: 1em; + transition: background-color 0.3s ease; +} + +button:hover { + background-color: #e65c00; +} + +table { + width: 100%; + border-collapse: collapse; + margin-top: 1em; +} + +th, td { + border: 1px solid #ccc; + padding: 0.75em; + text-align: left; + background-color: #fdfdfd; +} + +th { + background-color: #f0f0f0; + color: #ff6600; +} + +tr:nth-child(even) td { + background-color: #fafafa; +} + diff --git a/tools/Docker/Docker-Compose/UI/templates/index.html b/tools/Docker/Docker-Compose/UI/templates/index.html new file mode 100644 index 0000000..3bd7b8d --- /dev/null +++ b/tools/Docker/Docker-Compose/UI/templates/index.html @@ -0,0 +1,71 @@ + + + + + Flask UI + DB + + + +
+

Flask UI + Database

+ +
+ + +
+ +

Stored Values

+ + + + + + +
IDValueTimestamp
+
+ + + + + diff --git a/tools/Docker/Docker-Compose/UI/templates/styles.css b/tools/Docker/Docker-Compose/UI/templates/styles.css new file mode 100644 index 0000000..99d79e9 --- /dev/null +++ b/tools/Docker/Docker-Compose/UI/templates/styles.css @@ -0,0 +1,74 @@ +/* styles.css */ +body { + font-family: Arial, sans-serif; + background-color: #f5f5f5; + color: #333; + margin: 0; + padding: 0; +} + +.container { + max-width: 800px; + margin: 2em auto; + padding: 2em; + background-color: #ffffff; + border-radius: 12px; + box-shadow: 0 4px 8px rgba(0,0,0,0.1); +} + +h1, h2 { + color: #ff6600; /* Orange titles */ +} + +.input-group { + display: flex; + gap: 0.5em; + margin-bottom: 1em; +} + +input[type="text"] { + flex: 1; + padding: 0.75em; + border-radius: 8px; + border: 1px solid #ccc; + background-color: #fdfdfd; + font-size: 1em; +} + +button { + padding: 0.75em 1.5em; + background-color: #ff6600; + color: white; + border: none; + border-radius: 8px; + cursor: pointer; + font-size: 1em; + transition: background-color 0.3s ease; +} + +button:hover { + background-color: #e65c00; +} + +table { + width: 100%; + border-collapse: collapse; + margin-top: 1em; +} + +th, td { + border: 1px solid #ccc; + padding: 0.75em; + text-align: left; + background-color: #fdfdfd; +} + +th { + background-color: #f0f0f0; + color: #ff6600; +} + +tr:nth-child(even) td { + background-color: #fafafa; +} + diff --git a/tools/Docker/Docker-Compose/docker-compose.yaml b/tools/Docker/Docker-Compose/docker-compose.yaml new file mode 100644 index 0000000..40b36e1 --- /dev/null +++ b/tools/Docker/Docker-Compose/docker-compose.yaml @@ -0,0 +1,23 @@ +version: "3.9" + +services: + ui: + build: ./UI + container_name: ui_service + ports: + - "5000:5000" + volumes: + - dbdata:/data + depends_on: + - db + + db: + build: ./DB + container_name: db_service + volumes: + - dbdata:/data + command: sleep infinity + +volumes: + dbdata: +