Skip to content
Open

Lab03 #2429

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Python CI - DevOps Info Service

on:
push:
branches: [ "**" ]
tags:
- "v*.*.*"
paths:
- "app_python/**"
- ".github/workflows/python-ci.yml"

pull_request:
branches: [ "main" ]
paths:
- "app_python/**"

jobs:
test:
name: Lint & Test
runs-on: ubuntu-latest

defaults:
run:
working-directory: app_python

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: "pip"
cache-dependency-path: |
app_python/requirements.txt
app_python/requirements-dev.txt

- name: Install dependencies
run: |
pip install -r requirements.txt
pip install -r requirements-dev.txt

- name: Run linter (ruff)
run: |
pip install ruff
ruff check .

- name: Run tests with coverage
run: |
pytest --cov=. --cov-report=term-missing --cov-fail-under=60

- name: Install Bandit
run: pip install bandit

- name: Run Bandit security scan
run: bandit -r . -ll -s B101,B104

docker:
name: Build & Push Docker Image
needs: test
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Extract version
id: vars
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push image
uses: docker/build-push-action@v5
with:
context: ./app_python
push: true
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/devops-info-service:${{ steps.vars.outputs.VERSION }}
${{ secrets.DOCKERHUB_USERNAME }}/devops-info-service:latest
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
![CI](https://github.com/essence-666/DevOps-Core-Course/actions/workflows/python-ci.yml/badge.svg)


# DevOps Engineering: Core Practices

[![Labs](https://img.shields.io/badge/Labs-18-blue)](#labs)
Expand Down
Empty file added app_go/.gitignore
Empty file.
24 changes: 24 additions & 0 deletions app_go/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# -------- Build stage --------
FROM golang:1.25-alpine AS builder

WORKDIR /app
COPY go.mod ./
RUN go mod download

COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app

# -------- Runtime stage --------
FROM alpine:latest

RUN addgroup -S appgroup && adduser -S appuser -G appgroup

WORKDIR /app
COPY --from=builder /app/app .

RUN chown appuser:appgroup /app/app

USER appuser

EXPOSE 5000
CMD ["./app"]
58 changes: 58 additions & 0 deletions app_go/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# DevOps Info Service (Go)

## Overview

DevOps Info Service is a Go-based web application that provides detailed
information about the service itself, system environment, runtime status, and
incoming HTTP requests.

The application is implemented in a single source file for simplicity.

---

## Prerequisites

- Go 1.22+
- Docker (optional)

---

## Running Locally

```bash
go run main.go
````

### Custom Configuration

```bash
PORT=8080 go run main.go
HOST=127.0.0.1 PORT=3000 go run main.go
```

---

## API Endpoints

| Method | Path | Description |
| ------ | ------- | ------------------------------ |
| GET | / | Service and system information |
| GET | /health | Health check |

---

## Configuration

| Variable | Default | Description |
| -------- | ------- | ---------------- |
| HOST | 0.0.0.0 | Bind address |
| PORT | 5000 | Application port |

---

## Docker Build (Multi-Stage)

```bash
docker build -t devops-info-go .
docker run -p 5000:5000 devops-info-go
```
180 changes: 180 additions & 0 deletions app_go/docs/LAB01.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# Lab 01 – DevOps Info Service (Go)

## Framework Selection

### Chosen Language and Framework: Go (net/http)

The Go programming language with the standard `net/http` package was chosen
for this laboratory work. Go is widely used in DevOps and cloud-native
environments due to its performance, static compilation, simplicity, and
excellent support for concurrent workloads.

Using the standard library avoids unnecessary dependencies and keeps the
service lightweight and predictable.

### Comparison with Alternatives

| Option | Pros | Cons | Reason Not Chosen |
|------|------|------|-------------------|
| Go (net/http) | Fast, static binary, no dependencies | Less abstraction | Chosen |
| Gin | Simple routing, middleware | External dependency | Not required |
| Echo | High performance | External dependency | Overkill |
| Python (FastAPI) | Rapid development, async | Interpreted, slower startup | Language diversity |

---

## Best Practices Applied

### 1. Minimal Dependency Usage

Only the Go standard library is used.

**Example:**
```go
import "net/http"
````

**Importance:**
Reduces attack surface, simplifies builds, and improves reliability.

---

### 2. Single Responsibility Structure

Although the application is implemented in a single file, logical separation
is maintained through clearly defined functions.

**Example:**

```go
func healthHandler(w http.ResponseWriter, r *http.Request)
```

**Importance:**
Keeps the code readable while remaining suitable for small services.

---

### 3. Environment-Based Configuration

Runtime configuration is handled via environment variables.

**Example:**

```go
port := os.Getenv("PORT")
```

**Importance:**
Allows flexible deployment across environments without code changes.

---

### 4. Structured JSON Responses

All responses are returned in structured JSON format.

**Example:**

```go
json.NewEncoder(w).Encode(response)
```

**Importance:**
Ensures API consistency and ease of integration.

---

### 5. Health Check Endpoint

A dedicated health check endpoint is implemented.

**Example:**

```go
http.HandleFunc("/health", healthHandler)
```

**Importance:**
Required for monitoring systems and container orchestration platforms.

---

## API Documentation

### GET /

**Description:**
Returns service metadata, system information, runtime statistics, and request
details.

**Example Response:**

```json
{
"service": {
"name": "devops-info-service",
"language": "go"
}
}
```

---

### GET /health

**Description:**
Returns application health status.

**Example Response:**

```json
{
"status": "healthy"
}
```

---

### Testing Commands

```bash
curl http://localhost:5000/
curl http://localhost:5000/health
```

---

## Testing Evidence

The following screenshots are provided:

* Main endpoint (`/`) showing full JSON response
* Health check endpoint (`/health`)
* Pretty-printed JSON output in terminal

---

## Challenges & Solutions

### Problem 1: Balancing simplicity and structure

**Issue:**
Splitting the application into multiple files was unnecessary for the scope of
the laboratory work.

**Solution:**
Implemented all logic in a single file while preserving logical separation via
functions.

---

### Problem 2: Container image size optimization

**Issue:**
Default Go images produce relatively large containers.

**Solution:**
Implemented a multi-stage Docker build to produce a minimal runtime image.

````
Loading