Agus Makmun

I'm Programmer for Python & Django. I've made quite a few web apps, especially on Django.

Real-Time EC2 WebSocket Terminal with Django, Channels, and OpenTelemetry

23 Apr 2024 » python, django, observability, websocket

Are you looking to build a real-time, browser-based terminal that streams interactive shell sessions from an AWS EC2 instance, with full observability and distributed tracing? In this post, I’ll walk you through a modern Django stack that does exactly that—leveraging Django Channels, xterm.js, Celery, Redis, and OpenTelemetry for a seamless developer and monitoring experience.

Why Real-Time WebSocket Terminals Matter

Web-based terminals are invaluable for cloud management, remote debugging, and DevOps workflows. By streaming an SSH session from EC2 directly to your browser, you can securely manage infrastructure from anywhere, with full auditability and performance monitoring.

The Stack: Django, Channels, xterm.js, and More

This project combines:

  • Django + Channels for WebSocket support
  • xterm.js for a beautiful, interactive frontend terminal
  • Celery for background tasks and periodic health checks
  • Redis as cache and message broker
  • OpenTelemetry, Jaeger, and Grafana for distributed tracing and service performance monitoring

All services are orchestrated with Docker Compose for easy local development and deployment.

Key Features

  • WebSocket Terminal: Real-time, interactive shell in your browser
  • EC2 SSH Integration: Backend logic ready to stream from AWS EC2 (just add your credentials)
  • Distributed Tracing: End-to-end observability for HTTP, WebSocket, Celery, and Redis
  • Health Check API: /health-check/ endpoint and periodic Celery task
  • Grafana Dashboards: Visualize traces and service performance

Getting Started

1. Clone and Set Up

git clone git@github.com:agusmakmun/django-aws-terminal-websocket.git
cd django-aws-terminal-websocket/
pip install -r requirements.txt

2. Run the Full Stack

docker-compose up --build

3. Access the Terminal

Open http://localhost:8000/ in your browser. You’ll see a live terminal powered by xterm.js.

EC2 SSH Configuration

To connect to your EC2 instance:

  • Set environment variables:
    export AWS_HOSTNAME=your-ec2-public-dns
    export AWS_USERNAME=ec2-user
    
  • Place your SSH private key as terminal/aws.pem (chmod 600, not tracked by git)

The backend will use these to establish an SSH session for the WebSocket terminal.

Observability: Tracing Everything

  • OpenTelemetry: Traces HTTP, WebSocket, Celery, and Redis operations
  • Jaeger: Visualize traces and debug performance bottlenecks
  • Grafana: Build dashboards for service monitoring

Class-Level Tracing

Decorators like @traced_class and @traced_async_class automatically trace all methods in a class, reducing boilerplate and ensuring consistent observability.

Redis Tracing

All Redis and Django cache operations are automatically traced and enriched with context—no manual instrumentation needed.

Health Checks and Periodic Tasks

  • /health-check/ endpoint for monitoring
  • Celery task runs every minute, calling the health check and logging results (fully traced)

Customization

  • Frontend: Edit terminal/templates/terminal/terminal.html
  • Backend: Extend TerminalConsumer for authentication, EC2 connection, and streaming logic

Running the Slidev Presentation

Want to demo or learn more? Run the included Slidev presentation:

npm install --save-dev @slidev/cli
npx slidev

This opens an interactive presentation in your browser using slides.md.

Final Thoughts

This project is a great starting point for building secure, observable, and scalable web-based terminals for cloud infrastructure. With full tracing and monitoring out of the box, you can focus on features—not plumbing.

Check out the GitHub repo for the full code and documentation!