diff --git a/Fatemeh/README.md b/Fatemeh/README.md new file mode 100644 index 00000000..eafdcf3b --- /dev/null +++ b/Fatemeh/README.md @@ -0,0 +1,49 @@ +# Setting PostgreSQL Up +## Pull postgres image +docker pull postgres +## Create volume +docker volume create PG-data +## Run the container +docker run --name PS_ctf -e POSTGRES_PASSWORD=1234 -v PG_data:/var/lib/postgresql/data -p 5432:5432 docker.arvancloud.ir/postgres +## Run sell in the container +docker exec -it PS_ctf sh +## Login as default superuser (postgres) +psql -U postgres +## Create database +CREATE DATABASE ctf_db; +## Create table +CREATE TABLE teams ( + id SERIAL PRIMARY KEY, + team_name VARCHAR(100) NOT NULL, + challenge_assigned INT +); +## Insert some data +INSERT INTO teams (team_name, challenge_assigned) +VALUES + ('Green Shoes', 1), + ('Red Hat', 2); +## Retrive data +SELECT * FROM teams +# Explanation +After pulling the PostgreSQL image, I used the following command for creating its container: + +**docker run --name PS_ctf -e POSTGRES_PASSWORD=1234 -v PG_data:/var/lib/postgresql/data -p 5432:5432 -d docker. arvancloud.ir/postgres** + +**--name** indicates the container's name ( PS_ctf) + +**-e** +sets the environment variables in this container which tells the PostgreSQL "When you initialize the database, create the default superuser postgres with password 1234.” + +**-v** +mapped a created volume to a specified path in the container + +**-p** +map port 5432 on the host to port 5432 inside the container (where PostgreSQL listens by default) + +**-d** run in background + +**docker. arvancloud.ir/postgres** +: image's name + +# Video +https://iutbox.iut.ac.ir/index.php/apps/files/files/12123051?dir=/&openfile=true diff --git a/README.md b/README.md index e6388ed1..fdcce258 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,33 @@ # Cloud Assignment -This repository contains the **Cloud Assignment** for containerizing and managing CTF challenges using Docker, Redis, Celery, FastAPI, PostgreSQL, and NGINX. +Problem 1: Deploy a PostgreSQL Container with Persistent Storage +1.Created a Docker volume: + docker volume create pgdata +2.Ran PostgreSQL container with environment variables and volume mount: + docker run --name postgres-container \ + -e POSTGRES_USER=myuser \ + -e POSTGRES_PASSWORD=mypassword \ + -e POSTGRES_DB=mydatabase \ + -v pgdata:/var/lib/postgresql/data \ + -p 5432:5432 \ + -d postgres +3.Connected to the database using: + docker exec -it postgres-container psql -U myuser -d mydatabase +4.Ran basic SQL operations: + CREATE TABLE teams ( + id SERIAL PRIMARY KEY, + name TEXT NOT NULL + ); + +--------------- + INSERT INTO teams (name) VALUES ('Team Alpha'), ('Team Beta'); +--------------- + SELECT * FROM teams; +5.Stopped and removed container: + docker stop postgres-container + docker rm postgres-container +6.re-ran steps 2,3 again and ran this basic SQL operation again for checking : + SELECT * FROM teams; + -## 🚀 Submission Instructions -Please follow these steps to complete and submit your assignment: - -1. **Fork this repository**: - - -2. **Create a folder with your full name** in the root of the project. - Example: -``` - MohamadMahdiReisi/ - ├── Problem1_PostgreSQL/ - ├── Problem2_Redis/ - ├── Problem3_Celery/ - ├── Problem4_WebAPI/ - ├── Problem5_NGINX/ - └── Problem6_DockerCompose/ -``` - -4. **Add all your documents, source code, and configuration files** (e.g., Dockerfiles, `docker-compose.yml`, Python scripts, etc.) to the correct folder for each question. - -5. **Upload required videos** (demonstration videos) to **IUT Box** or any cloud storage, and **add the video links** inside a `README.md` file within each problem folder. - -6. **Write your explanations and answers** as a Markdown file (`README.md`) in each problem folder. Include: -- Description of what you did -- Steps to run your solution -- Reasoning behind any decisions or tools you chose -- Screenshots if needed -- Link to your demonstration video - -7. **Open a Pull Request (PR)** back to the original repository diff --git a/rania/problem2/README.md b/rania/problem2/README.md new file mode 100644 index 00000000..5b6d49e5 --- /dev/null +++ b/rania/problem2/README.md @@ -0,0 +1,38 @@ +# Problem 2: Redis Server Setup + +## What I Did: + +- Deployed a Redis server using Docker. +- Wrote two Python programs (publisher and subscriber) for inter-process communication via Redis. +- Verified Redis server accepts client connections (test client). +- Used RedisInsight to monitor data and pub/sub messages visually. +- Documented and recorded a short demo. + +----- +#step1-> pull redis image: + +docker pull redis + + +#step2-> Run Redis Server with Docker : + +docker run --name redis-server -p 6379:6379 -d redis + + +#step3-> Test Redis Client (Manual) : +docker exec -it redis-server redis-cli +SET test "hello" +GET test +exit + +#step4-> write and run python codes : +- `publisher.py`: Sends messages and sets key-value data in Redis. +- `subscriber.py`: Reads key-value data and subscribes to messages on a Redis channel. +python subscriber.py +python publisher.py +#step5-> install redisinsight +#step6-> check key-values and subscribe and publish massages + +#videos and screenshots : +https://iutbox.iut.ac.ir/index.php/s/HqxwwPcePAEg3HQ + diff --git a/rania/problem2/publisher.py b/rania/problem2/publisher.py new file mode 100644 index 00000000..f70ef60d --- /dev/null +++ b/rania/problem2/publisher.py @@ -0,0 +1,13 @@ +import redis +import time + +r = redis.Redis(host='localhost', port=6379, decode_responses=True) +r.set('team1', 'Green Shoes') +r.set('team2', 'Red Hat') + +for i in range(3): + msg = f'Hello from publisher #{i}' + r.publish('ctf-channel', msg) + print('Published:', msg) + time.sleep(1) + diff --git a/rania/problem2/subscriber.py b/rania/problem2/subscriber.py new file mode 100644 index 00000000..0d48c0fa --- /dev/null +++ b/rania/problem2/subscriber.py @@ -0,0 +1,15 @@ +import redis + +r = redis.Redis(host='localhost', port=6379, decode_responses=True) + +print('team1 =>', r.get('team1')) +print('team2 =>', r.get('team2')) + +pubsub = r.pubsub() +pubsub.subscribe('ctf-channel') +print('Subscribed to ctf-channel') + +for message in pubsub.listen(): + if message['type'] == 'message': + print('Received:', message['data']) + diff --git a/rania/problem3/README.md b/rania/problem3/README.md new file mode 100644 index 00000000..62ee0403 --- /dev/null +++ b/rania/problem3/README.md @@ -0,0 +1,18 @@ +# **Setup process** +## Step 1 +pip install celery +## Step 2 +docker run --name redis-server -p 6379:6379 -d redis + +run the redis server's container +## Step 3 +celery -A celery_config.app worker --loglevel=info + +Creation of a Celery background worker for doing tasks that are in Redis +## Step 4 +run the start.py for start a task and run a specefied container +## Step 5 +run stop.py for stop the container + +**(In our file we use a postgres image for test)** + diff --git a/rania/problem3/celery_config.py b/rania/problem3/celery_config.py new file mode 100644 index 00000000..c61f570a --- /dev/null +++ b/rania/problem3/celery_config.py @@ -0,0 +1,44 @@ +import docker +from celery import Celery + +# Create a Celery instance with Redis as the message broker +app = Celery('container_management', broker='redis://localhost:6379/0') + +# Initialize the Docker client +client = docker.from_env() + +@app.task +def start_container(container_name): + """Start a Docker container for a specific CTF challenge.""" + try: + # Use Docker SDK to run a container + container = client.containers.run("docker.arvancloud.ir/postgres:latest", # Docker image name + name=container_name, # Container name + environment={"POSTGRES_PASSWORD":"1234"}, + detach=True, + remove=False, + ) # Run container in detached mode + + return f"Started container {container_name} with ID {container.id}" + + except docker.errors.ContainerError as e: + return f"Error starting container: {str(e)}" + except docker.errors.ImageNotFound as e: + return f"Error: Docker image not found. {str(e)}" + except Exception as e: + return f"Failed to start container: {str(e)}" + + +@app.task +def stop_container(container_id): + """Stop a running Docker container using its ID.""" + try: + # Stop the Docker container by ID + container = client.containers.get(container_id) + container.stop() + return f"Stopped container {container_id}" + + except docker.errors.NotFound as e: + return f"Error: Container with ID {container_id} not found. {str(e)}" + except Exception as e: + return f"Failed to stop container: {str(e)}" diff --git a/rania/problem3/start.py b/rania/problem3/start.py new file mode 100644 index 00000000..dfc9e4c4 --- /dev/null +++ b/rania/problem3/start.py @@ -0,0 +1,6 @@ +from celery_config import start_container + +import sys + +start_container.delay(sys.argv[1]) + diff --git a/rania/problem3/stop.py b/rania/problem3/stop.py new file mode 100644 index 00000000..9f85ff3b --- /dev/null +++ b/rania/problem3/stop.py @@ -0,0 +1,6 @@ +from celery_config import stop_container +import sys + + + +stop_container.delay(sys.argv[1])