Record live Ghaymah deployments
هذا الالتزام موجود في:
33
README.md
33
README.md
@@ -6,11 +6,26 @@ This repository contains the five deliverables for the Ghaymah cloud platform as
|
||||
|
||||
| Question | Deliverable | Status |
|
||||
|---|---|---|
|
||||
| Q1 — Deploy and monitor an API | [Application, monitor, dashboard, and deployment guide](q1-deploy-monitor/README.md) | Implementation complete; live Ghaymah deployment evidence pending |
|
||||
| Q1 — Deploy and monitor an API | [Application, monitor, dashboard, and deployment guide](q1-deploy-monitor/README.md) | Live on Ghaymah |
|
||||
| Q2 — OOMKilled postmortem | [POSTMORTEM.md](q2-postmortem/POSTMORTEM.md) | Complete |
|
||||
| Q3 — CI/CD pipeline | [Workflow](.github/workflows/deploy.yml) and [CICD.md](q3-cicd/CICD.md) | Build/push and approval gate complete; automated Ghaymah image update awaiting a documented non-interactive command |
|
||||
| Q4 — Scalability | [SCALABILITY.md](q4-scalability/SCALABILITY.md) | Complete |
|
||||
| Q5 — mithal.space monitoring | [Collector and dashboard](q5-mithal-dashboard/) | Implementation present; live deployment evidence pending |
|
||||
| Q5 — mithal.space monitoring | [Collector and dashboard](q5-mithal-dashboard/) | Live on Ghaymah |
|
||||
|
||||
## Live deployments
|
||||
|
||||
- Q1 API: <https://ghaymah-api-615e99f13665.hosted.ghaymah.systems>
|
||||
- Q1 health: <https://ghaymah-api-615e99f13665.hosted.ghaymah.systems/health>
|
||||
- Q5 monitoring dashboard: <https://mithal-monitor-292f00f076b1.hosted.ghaymah.systems>
|
||||
- Docker Hub API image: `docker.io/agamy74/ghaymah-api:8bc563f`
|
||||
- Docker Hub dashboard image: `docker.io/agamy74/mithal-monitor:8bc563f`
|
||||
- GitHub repository: <https://github.com/yassinelagamy/GHyamah-Test>
|
||||
|
||||
## Deployment evidence
|
||||
|
||||
- [Ghaymah project](screenshots/ghaymah-project-created.png)
|
||||
- [Q1 API service](screenshots/q1-ghaymah-service.png)
|
||||
- [Q5 monitoring service](screenshots/q5-ghaymah-service.png)
|
||||
|
||||
## Current verified Ghaymah information
|
||||
|
||||
@@ -69,15 +84,11 @@ python q5-mithal-dashboard/collector/collect.py --once
|
||||
|
||||
## Work that requires account access
|
||||
|
||||
The following cannot be completed safely from source code alone:
|
||||
The following require a credential or capability that is not available in the public documentation:
|
||||
|
||||
1. Create the Ghaymah projects/applications and obtain their IDs and public URLs.
|
||||
2. Push the Docker images using the owner's registry credentials.
|
||||
3. Deploy Q1 and Q5 and capture the required screenshots.
|
||||
4. Configure GitHub secrets and the `production` Environment with required reviewers.
|
||||
5. Confirm the supported non-interactive Ghaymah authentication mechanism for GitHub Actions.
|
||||
6. Confirm the command/API that updates an existing Ghaymah application to a specific external image tag.
|
||||
7. Run the workflow, approve production, and capture the approval evidence.
|
||||
8. Confirm monitoring/autoscaling controls and Block Storage limits in the authenticated dashboard before removing remaining `VERIFY` markers.
|
||||
1. Add `DOCKERHUB_TOKEN` and any confirmed Ghaymah CI authentication secret to GitHub.
|
||||
2. Confirm the supported API-token authentication mechanism and image field for `gy resource app update`.
|
||||
3. Approve the production GitHub Environment after the image-build job succeeds and capture the approval evidence.
|
||||
4. Confirm monitoring/autoscaling controls, snapshot behavior, and detailed Block Storage performance limits before removing the remaining `VERIFY` markers.
|
||||
|
||||
No credentials should be committed to this repository. Use GitHub Secrets and Ghaymah's secret-management controls for sensitive values.
|
||||
|
||||
@@ -94,9 +94,8 @@ docker ps --filter name=ghaymah-api
|
||||
|
||||
## 3. Push the image and deploy on Ghaymah
|
||||
|
||||
Ghaymah deploys a container from a **public image URL**, so the image must live in
|
||||
a public registry first. Docker Hub is used here — replace `<MY_DOCKERHUB_USER>`
|
||||
with your own account name.
|
||||
Ghaymah deploys a container from a container image URL. This deployment uses
|
||||
Docker Hub namespace `agamy74`.
|
||||
|
||||
### 3.1 Push to Docker Hub
|
||||
|
||||
@@ -105,17 +104,17 @@ docker login
|
||||
```
|
||||
|
||||
```bash
|
||||
docker tag ghaymah-api:latest docker.io/<MY_DOCKERHUB_USER>/ghaymah-api:latest
|
||||
docker tag ghaymah-api:latest docker.io/agamy74/ghaymah-api:latest
|
||||
```
|
||||
|
||||
```bash
|
||||
docker push docker.io/<MY_DOCKERHUB_USER>/ghaymah-api:latest
|
||||
docker push docker.io/agamy74/ghaymah-api:latest
|
||||
```
|
||||
|
||||
> Building on an Apple Silicon / ARM machine? Build for the platform Ghaymah runs
|
||||
> (`linux/amd64`) or the container will fail to start:
|
||||
> ```bash
|
||||
> docker buildx build --platform linux/amd64 -t docker.io/<MY_DOCKERHUB_USER>/ghaymah-api:latest --push ./q1-deploy-monitor/app
|
||||
> docker buildx build --platform linux/amd64 -t docker.io/agamy74/ghaymah-api:latest --push ./q1-deploy-monitor/app
|
||||
> ```
|
||||
|
||||
Make sure the Docker Hub repository is **public** — Ghaymah pulls the image
|
||||
@@ -125,7 +124,7 @@ anonymously from the URL you paste in.
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Container Image URL | `docker.io/<MY_DOCKERHUB_USER>/ghaymah-api:latest` |
|
||||
| Container Image URL | `docker.io/agamy74/ghaymah-api:8bc563f` |
|
||||
| Application Name | `ghaymah-api` |
|
||||
| Port Number | `8080` (must match the `EXPOSE`d port) |
|
||||
| Public Access | **enabled** |
|
||||
@@ -137,12 +136,12 @@ service a public URL.
|
||||
### 3.3 Verify the live deployment
|
||||
|
||||
```bash
|
||||
curl -f <the public URL Ghaymah assigns>/health
|
||||
curl -f https://ghaymah-api-615e99f13665.hosted.ghaymah.systems/health
|
||||
```
|
||||
|
||||
Expected: HTTP 200 with `{"status":"ok","uptime_s":...,"timestamp":"..."}`.
|
||||
|
||||
Also open `<the public URL Ghaymah assigns>/docs` in a browser for the OpenAPI page,
|
||||
Also open `https://ghaymah-api-615e99f13665.hosted.ghaymah.systems/docs` in a browser for the OpenAPI page,
|
||||
and screenshot both the running service in the Ghaymah dashboard and the `/health`
|
||||
response for the submission.
|
||||
|
||||
@@ -157,14 +156,14 @@ response for the submission.
|
||||
`monitor/monitor.py` uses the **Python standard library only** — nothing to install.
|
||||
|
||||
```bash
|
||||
export APP_URL="<the public URL Ghaymah assigns>"
|
||||
export APP_URL="https://ghaymah-api-615e99f13665.hosted.ghaymah.systems"
|
||||
python q1-deploy-monitor/monitor/monitor.py
|
||||
```
|
||||
|
||||
On Windows PowerShell:
|
||||
|
||||
```bash
|
||||
$env:APP_URL="<the public URL Ghaymah assigns>"; python q1-deploy-monitor\monitor\monitor.py
|
||||
$env:APP_URL="https://ghaymah-api-615e99f13665.hosted.ghaymah.systems"; python q1-deploy-monitor\monitor\monitor.py
|
||||
```
|
||||
|
||||
Every 30 seconds it issues `GET $APP_URL/health` with a 5 s timeout, then
|
||||
@@ -191,7 +190,7 @@ Every 30 seconds it issues `GET $APP_URL/health` with a 5 s timeout, then
|
||||
Single check (useful for cron, CI or a smoke test — exits `0` if up, `1` if down):
|
||||
|
||||
```bash
|
||||
APP_URL="<the public URL Ghaymah assigns>" python q1-deploy-monitor/monitor/monitor.py --once
|
||||
APP_URL="https://ghaymah-api-615e99f13665.hosted.ghaymah.systems" python q1-deploy-monitor/monitor/monitor.py --once
|
||||
```
|
||||
|
||||
Leave the loop running well before the submission so the dashboard has real history.
|
||||
|
||||
@@ -621,5 +621,159 @@
|
||||
"code": 200,
|
||||
"latency_ms": 34.65,
|
||||
"requests": 271
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:45:29.326567+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 84.06,
|
||||
"requests": 274
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:45:59.647988+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 10.29,
|
||||
"requests": 277
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:46:29.737515+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 43.92,
|
||||
"requests": 280
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:46:59.782486+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 10.3,
|
||||
"requests": 283
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:47:29.834008+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 10.92,
|
||||
"requests": 286
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:47:59.870760+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 9.37,
|
||||
"requests": 289
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:48:29.934518+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 29.9,
|
||||
"requests": 292
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:48:59.977842+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 8.75,
|
||||
"requests": 295
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:49:30.015612+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 9.01,
|
||||
"requests": 298
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:50:00.063894+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 17.94,
|
||||
"requests": 301
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:50:30.100475+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 10.24,
|
||||
"requests": 304
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:51:00.130652+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 7.38,
|
||||
"requests": 307
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:51:30.170066+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 10.55,
|
||||
"requests": 310
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:52:00.206236+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 8.8,
|
||||
"requests": 313
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:52:30.243868+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 9.16,
|
||||
"requests": 316
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:53:00.280182+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 8.18,
|
||||
"requests": 319
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:53:30.318350+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 9.65,
|
||||
"requests": 322
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:54:00.352722+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 7.37,
|
||||
"requests": 325
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:54:30.386202+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 9.6,
|
||||
"requests": 328
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:55:00.423153+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 9.31,
|
||||
"requests": 331
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:55:30.455631+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 7.77,
|
||||
"requests": 334
|
||||
},
|
||||
{
|
||||
"ts": "2026-07-26T16:55:37.840122+00:00",
|
||||
"status": "up",
|
||||
"code": 200,
|
||||
"latency_ms": 1117.87,
|
||||
"requests": 6
|
||||
}
|
||||
]
|
||||
|
||||
@@ -156,24 +156,23 @@ Image notes:
|
||||
|
||||
## 5. Deploy to Ghaymah
|
||||
|
||||
Ghaymah deploys from a **public image URL**, so push the image to Docker Hub first.
|
||||
Replace `<MY_DOCKERHUB_USER>` with your account name.
|
||||
This deployment uses Docker Hub namespace `agamy74`.
|
||||
|
||||
```bash
|
||||
docker login
|
||||
```
|
||||
|
||||
```bash
|
||||
docker tag mithal-monitor:latest docker.io/<MY_DOCKERHUB_USER>/mithal-monitor:latest
|
||||
docker tag mithal-monitor:latest docker.io/agamy74/mithal-monitor:latest
|
||||
```
|
||||
|
||||
```bash
|
||||
docker push docker.io/<MY_DOCKERHUB_USER>/mithal-monitor:latest
|
||||
docker push docker.io/agamy74/mithal-monitor:latest
|
||||
```
|
||||
|
||||
> On Apple Silicon / ARM, build for the platform Ghaymah runs:
|
||||
> ```bash
|
||||
> docker buildx build --platform linux/amd64 -t docker.io/<MY_DOCKERHUB_USER>/mithal-monitor:latest --push ./q5-mithal-dashboard
|
||||
> docker buildx build --platform linux/amd64 -t docker.io/agamy74/mithal-monitor:latest --push ./q5-mithal-dashboard
|
||||
> ```
|
||||
|
||||
Make sure the Docker Hub repository is **public** — Ghaymah pulls it anonymously.
|
||||
@@ -182,13 +181,13 @@ Then, in the Ghaymah dashboard:
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Container Image URL | `docker.io/<MY_DOCKERHUB_USER>/mithal-monitor:latest` |
|
||||
| Container Image URL | `docker.io/agamy74/mithal-monitor:8bc563f` |
|
||||
| Application Name | `mithal-monitor` |
|
||||
| Port Number | `8080` (matches `EXPOSE`) |
|
||||
| Public Access | **enabled** |
|
||||
| Environment Variables | *(optional)* `INTERVAL_S=60`, `TARGET_URL=https://mithal.space`, `SEARCH_URL=https://mithal.space/search?q=test` |
|
||||
|
||||
Click **Deploy**, then open `<the public URL Ghaymah assigns>/index.html` and
|
||||
Click **Deploy**, then open `https://mithal-monitor-292f00f076b1.hosted.ghaymah.systems/index.html` and
|
||||
screenshot the live dashboard. Leave it running so the 24 h uptime tile and the
|
||||
hourly chart fill with real history before submission.
|
||||
|
||||
|
||||
ثنائية
screenshots/q1-ghaymah-service.png
Normal file
ثنائية
screenshots/q1-ghaymah-service.png
Normal file
ملف ثنائي غير معروض.
|
بعد العرض: | الارتفاع: | الحجم: 62 KiB |
ثنائية
screenshots/q5-ghaymah-service.png
Normal file
ثنائية
screenshots/q5-ghaymah-service.png
Normal file
ملف ثنائي غير معروض.
|
بعد العرض: | الارتفاع: | الحجم: 63 KiB |
المرجع في مشكلة جديدة
حظر مستخدم