Linux: Git, Containers and Automation for DevOps
Bridge system administration and software engineering. Master command-line Git workflows, Docker containerization, Ansible configuration management, cloud-init provisioning, kernel namespaces and cgroups, and Python automation.
14.1 Git on the Command Line
Git is the industry-standard distributed version control system. Every configuration file, infrastructure playbook, and application codebase on modern Linux servers is tracked through Git repositories.
14.1.1 Core Repository Workflow
Standard operations transition code between the working directory, the staging index, and the permanent Git history:
| Command | Target Stage | Operational Action |
|---|---|---|
| git init / git clone <url> | Repository Init | Initializes a new empty repository or clones an existing remote repository |
| git add <file> (or git add .) | Staging Index | Stages modified file changes into the index ready for commit packaging |
| git commit -m "message" | Local History | Records a snapshot of staged changes with an author signature and hash |
| git push origin <branch> | Remote Sync | Uploads local branch commits to the remote tracking branch |
| git pull | Remote Sync | Fetches remote changes and immediately merges them into the active branch |
14.1.2 Branching, Merging, and Conflict Resolution
Branch Management
- Branch Creation: git checkout -b feature/deploy:Creates and switches to a dedicated feature branch, isolating ongoing work from main.
- Branch Inspection: git branch -v -a:Lists all local and remote tracking branches alongside latest commit hashes.
- Branch Merging: git merge feature/deploy:Integrates changes from feature branch into active branch (fast-forward or three-way commit).
- Conflict Resolution:Edit conflict markers (
<<<<<<<,=======,>>>>>>>), stage resolved files withgit add, and commit.
14.1.3 Authenticating with GitHub and GitLab over SSH
Authenticate Git operations using modern Ed25519 SSH keypairs rather than storing plaintext credentials in script files:
Git SSH key setup
Create a key, print it, test the connection, and switch the remote.
# Generate dedicated Ed25519 keypair for Git operations ssh-keygen -t ed25519 -C "devops@example.com" -f ~/.ssh/id_ed25519_git # Print public key to copy into GitHub/GitLab account settings cat ~/.ssh/id_ed25519_git.pub # Test authenticated SSH connectivity to remote provider ssh -T git@github.com # Configure repository remote URL to use SSH git remote set-url origin git@github.com:organization/infra-repo.git
14.2 Docker on Linux
Docker packages applications and their complete userspace dependencies into lightweight, portable container images that run consistently across development laptops, testing clusters, and cloud production environments.
14.2.1 Installation and Container Lifecycle
Install the official Docker Engine packages and grant local user rights by adding your account to the docker group:
Docker Host Setup
- Repository Installation:Install
docker-ce,docker-ce-cli,containerd.io, anddocker-compose-pluginfrom the official Docker repository. - User Group Delegation:Add current user to docker group:
sudo usermod -aG docker $USERto communicate with the Docker Unix domain socket (/var/run/docker.sock) without sudo. - Daemon Validation:Verify installation with
docker versionand run the test container:docker run hello-world.
Run and inspect a container
Start nginx with a port and volume, then check it.
# Run container in background with port mapping and volume mount docker run -d \ --name webapp \ -p 8080:80 \ -v app_data:/usr/share/nginx/html \ --restart unless-stopped \ nginx:alpine # Review running containers, resource usage, and streaming logs docker ps docker stats --no-stream docker logs -f webapp
14.2.2 Images, Containers, Volumes, and Networks
Core Docker Primitives
- Image vs Container:An image is an immutable read-only template with layers; a container is a running instance with an ephemeral read-write layer.
- Named Volumes (docker volume):Persists data independently of the container lifecycle in
/var/lib/docker/volumes/. - Bridge Networks (docker network):Provides DNS service discovery and IP isolation between sibling containers on the same host.
14.2.3 Dockerfile and Multi-Container Docker Compose
Define reproducible application runtime images with Dockerfile and orchestrate multi-container stacks using compose.yaml:
Docker Compose stack
Write compose.yaml, then validate and start it.
# Write compose.yaml
cat > compose.yaml <<'YAML'
services:
web:
build: .
ports:
- "80:8000"
environment:
- DB_HOST=db
depends_on:
- db
db:
image: postgres:15-alpine
environment:
POSTGRES_PASSWORD: secret
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
YAML
# Validate and start the stack
docker compose config
docker compose up -d14.3 Configuration Management with Ansible
Ansible is an agentless automation engine that configures servers over standard OpenSSH without installing background agents on target nodes. It enforces idempotency: tasks only make changes if the target node is not already in the declared state.
14.3.1 Inventory and Playbook Architecture
Structure infrastructure definitions using declarative YAML playbooks:
Ansible inventory and playbook
Write both files, then run the playbook.
# Write the inventory
cat > hosts.ini <<'INI'
[webservers]
web01.internal ansible_host=10.0.1.10
web02.internal ansible_host=10.0.1.11
INI
# Write the playbook
cat > site.yml <<'YAML'
---
- name: Configure Production Web Servers
hosts: webservers
become: true
tasks:
- name: Ensure Nginx package is installed
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
- name: Ensure deployment user exists
ansible.builtin.user:
name: deployer
shell: /bin/bash
groups: sudo
append: true
- name: Ensure Nginx service is running and enabled at boot
ansible.builtin.service:
name: nginx
state: started
enabled: true
YAML
# Execute playbook against inventory
ansible-playbook -i hosts.ini site.yml14.4 Linux in the Cloud
Deploying virtual machines across AWS EC2, Azure VMs, or Google Cloud Compute Engine relies on standardized cloud initialization mechanisms and cloud-native security controls.
14.4.1 Bootstrapping with cloud-init
Supply #cloud-config user-data during VM creation to automate initial server setup without manual intervention:
cloud-init configuration
Write the user data, then validate it.
# Write the cloud-init user data
cat > user-data.yaml <<'CLOUD'
#cloud-config
package_upgrade: true
packages:
- curl
- git
- ufw
users:
- name: devops
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_authorized_keys:
- ssh-ed25519 AAAAC3NzaC1l... admin@laptop
runcmd:
- ufw default deny incoming
- ufw allow 22/tcp
- ufw --force enable
CLOUD
# Validate the schema
cloud-init schema --config-file user-data.yaml14.4.2 Securing Cloud Virtual Machines
| Architecture Layer | Cloud Hardening Principle | Risk Prevented |
|---|---|---|
| Subnet Placement | Place databases in private subnets with NAT-only outbound routing | Prevents direct internet scans from probing internal database ports |
| Security Groups | Restrict port 22 access to specific office VPN or bastion host IP addresses | Stops brute-force dictionary attacks against SSH |
| Metadata Protection | Enforce AWS IMDSv2 (token-based instance metadata access) | Prevents SSRF vulnerabilities from harvesting IAM role credentials |
| Storage Encryption | Enable KMS encryption on all root EBS and persistent volume disks | Protects physical data at rest against unauthorized snapshot access |
14.5 CI/CD and Kubernetes Overview
Understanding container execution requires looking beneath Docker abstractions at Linux kernel primitives.
14.5.1 Container Internals: Namespaces and cgroups
Containers are standard Linux processes isolated by two distinct kernel subsystems:
| Kernel Subsystem | Isolation Boundary | Container Behavior |
|---|---|---|
| PID Namespace | Process Numbering | Container sees itself as PID 1; cannot see or signal host processes |
| NET Namespace | Network Stack | Container possesses dedicated virtual interface (veth), routing table, and port bindings |
| MNT Namespace | Filesystem Mounts | Isolates directory mount points; container cannot see host paths outside volume mounts |
| Control Groups (cgroups) | Resource Throttling | Enforces hard CPU, memory, and disk I/O quota ceilings per container |
14.5.2 Kubernetes at a Glance
Kubernetes Core Components
- Pod:The smallest deployable unit; contains one or more tightly coupled containers sharing IPC and network namespaces.
- Deployment:Declares desired replica counts and manages automated rolling updates and rollbacks without downtime.
- Service:Provides a stable virtual cluster IP and round-robin load balances traffic across ephemeral Pods.
- Kubelet:Agent running on every Linux worker node communicating with container runtimes (containerd/CRI-O).
14.6 Python for Linux Admins
When bash scripts exceed 100 lines or require parsing complex nested JSON, XML, or interacting with REST APIs, Python provides standard libraries for clean system automation.
14.6.1 Virtual Environments and Administrative Scripting
Modern distributions enforce PEP 668, preventing direct pip install outside virtual environments to protect system libraries. Use venv and the standard subprocess module:
Disk space check in Python
Write the script, run it, and read the exit status.
# Write the disk check script
cat > disk_check.py <<'PY'
#!/usr/bin/env python3
import subprocess
import json
import sys
def check_disk_space(threshold_percent=80):
"""Inspect disk usage and return warning if threshold is breached."""
cmd = ["df", "--output=pcent,target", "/"]
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
# Parse second line (usage percentage)
lines = result.stdout.strip().splitlines()
usage_str = lines[1].split()[0].replace("%", "")
usage = int(usage_str)
if usage >= threshold_percent:
print(f"[ALERT] Root filesystem at {usage}% capacity!")
return 1
print(f"[OK] Root filesystem nominal at {usage}%.")
return 0
if __name__ == "__main__":
sys.exit(check_disk_space())
PY
# Run it and show the exit code
python3 disk_check.py; echo "Exit status: $?"14.7 Interactive Lab: Git Repositories and CLI Automation
Practice initializing a Git repository, creating commits, and running Python administrative scripts with the commands below. Press Load in Terminal to open them in the Linux terminal:
Git Repositories and CLI Automation
Load these in the terminal, then press Enter to run them.
$ git --version$ python3 --version$ mkdir -p /tmp/demo-repo && cd /tmp/demo-repo$ git init$ git status
Knowledge Check: Module 14 DevOps, Containers and Automation
1. Which Git command creates and immediately switches to a new branch?
2. Which Linux kernel technology provides process and network isolation for Docker containers?
3. Which Linux kernel technology enforces resource quotas such as CPU and memory limits on containers?
4. What communication protocol does Ansible use by default to manage remote Linux target nodes?
5. Which multi-distribution tool initializes cloud instances using user-data scripts during first boot?
6. Which built-in Python module executes shell commands and captures their output in administrative scripts?