Running Amazon Q Developer Locally on Amazon Linux

It was 2 AM, and I was staring at a permission denied error in my /var/log/messages file that just wouldn’t quit. I had three terminal windows open: one tailing logs, one with vim open trying to hack a configuration file, and a third running htop to make sure I hadn’t stalled the CPU. Usually, this is the part where I context-switch out of my terminal, open a browser, log into the AWS console, and start asking the AI assistant for help. But the disconnect always bugs me. I lose my flow. I lose my terminal history. I wanted the AI right there in the trenches with me, but with the persistence of a web session.

That’s when I decided to shift my workflow. Instead of treating the AI as an external consultant living in a distant browser tab, I started running Amazon Q Developer directly on my Amazon Linux instance, wrapped in a local web interface. This setup allows me to maintain full session management and persistence without leaving my secure environment. If you work in Linux DevOps or System Administration, you know that context is everything. Here is how I set up this workflow on AWS Linux and why I think it beats the standard console experience.

The Environment: Amazon Linux 2023

I run most of my workloads on Amazon Linux 2023 (AL2023). It’s optimized for AWS, secure by default, and stripped of unnecessary bloat. For this setup, I am using a standard t3.medium instance. While you can replicate this on Ubuntu Tutorial guides or Red Hat Linux, AL2023 gives me the native integration with AWS CLI v2 that simplifies the authentication process.

First, I ensure my system is up to date. I don’t like surprises when I start installing Python libraries.

sudo dnf update -y
sudo dnf install python3-pip git -y

I also verify my AWS CLI version. The Amazon Q integration relies on the latest features, so running an old version from 2024 won’t cut it here in late 2025.

aws --version

Building the Bridge: Python and the CLI

The core of this workflow is a Python wrapper. I use Python Scripting to bridge the gap between the raw CLI output and a browser-based UI. This isn’t just about pretty colors; it’s about state. When I use a standard CLI tool, the session dies when the command finishes. By wrapping the interaction in a Python web service, I can keep the conversation history alive in a database (like SQLite) on the Linux File System.

I set up a virtual environment to keep my system Python clean. As a rule of thumb in Linux System Administration, never pollute your global site-packages.

python3 -m venv q-dev-env
source q-dev-env/bin/activate
pip install flask boto3

Here is a simplified version of how I handle the request processing. I use subprocess to interact with the system, capturing the context of my current Linux Users and environment variables.

import subprocess
import json
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/chat', methods=['POST'])
def chat_handler():
    data = request.json
    user_input = data.get('message')
    
    # In a real scenario, this connects to the Amazon Q CLI interface
    # ensuring the session token persists across requests
    try:
        # Simulating the CLI call
        result = subprocess.run(
            ['q', 'chat', '--message', user_input], 
            capture_output=True, 
            text=True
        )
        return jsonify({
            'response': result.stdout,
            'status': 'success'
        })
    except Exception as e:
        return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=8000)

This Python Automation script is basic, but it illustrates the point. I run the logic locally. The persistence layer (saving the chat history) writes to a local JSON file or a lightweight Linux Database like SQLite. This means if I restart my browser, the context of my debugging session remains intact on the server.

Persistence with Systemd

Developer coding at night with multiple terminals - Software developer coding database on multiple monitors to program ...
Developer coding at night with multiple terminals – Software developer coding database on multiple monitors to program …

Running the script manually in a terminal is fine for testing, but for a true “always-on” experience, I treat this interface as a Linux Service. I create a systemd unit file. This ensures that if my instance reboots or the process crashes, it comes right back up. This is standard Linux Administration practice, but it’s often overlooked by developers who just run things in a screen or tmux session.

I create the file at /etc/systemd/system/q-webui.service:

[Unit]
Description=Amazon Q Developer Web Interface
After=network.target

[Service]
User=ec2-user
WorkingDirectory=/home/ec2-user/q-dev-web
ExecStart=/home/ec2-user/q-dev-web/q-dev-env/bin/python app.py
Restart=always
Environment=PATH=/usr/bin:/usr/local/bin

[Install]
WantedBy=multi-user.target

Then I enable and start it:

sudo systemctl daemon-reload
sudo systemctl enable q-webui
sudo systemctl start q-webui

Now, I can check the status using systemctl status q-webui. If I notice high resource usage, I check top command or htop to see if the Python process is eating up memory, though it usually stays very lean.

Security: The Critical Piece

Here is where many people get lazy. I never, ever open port 8000 to the world in my Security Group. Exposing a development tool that has access to your AWS credentials to the public internet is a disaster waiting to happen. I don’t care if it’s a test box; Linux Security is not optional.

Instead of messing with complex Linux Firewall rules or iptables chains to restrict IPs, I use SSH Tunneling. It allows me to access the local web server running on the EC2 instance from my laptop’s browser as if it were running on localhost.

On my local machine, I run:

ssh -i my-key.pem -L 8000:127.0.0.1:8000 ec2-user@my-instance-ip

Now, I open my browser to http://localhost:8000. The traffic is encrypted through SSH. The Linux Server sees the connection coming from localhost. No extra ports open, no complex VPN setup. It’s simple and secure.

Real-World Workflow: DevOps and Troubleshooting

So, what does this actually look like in practice? Let’s go back to my initial problem: the 2 AM debugging session.

I was struggling with an Nginx configuration on a CentOS-based container. I pasted the error log into my local web UI. Because the session is persistent, I could iterate on the solution.

AI code assistant on screen - Code editor screen window app with ai chatbot copilot coding ...
AI code assistant on screen – Code editor screen window app with ai chatbot copilot coding …

Me: “I’m getting a 403 Forbidden on my assets directory. Here is the ls -laZ output.”

Q (via WebUI): “The SELinux context is incorrect for web content. You need to change the file type context to httpd_sys_content_t.”

It gave me the exact command:

sudo chcon -R -t httpd_sys_content_t /var/www/html/assets

I ran it in my terminal. Fixed. But here is the cool part: I didn’t close the tab. Two days later, I had a similar issue with a different directory. I scrolled up in the web UI, found the previous conversation, and applied the same logic. If I had used the standard AWS console chat, that session would have likely timed out or been cleared.

Automating Infrastructure Generation

I also use this for generating boilerplate code. I often need to write Python DevOps scripts to clean up old EBS snapshots or manage Linux Disk Management tasks like extending LVM volumes.

I can ask the interface: “Write a Python script using Boto3 to list all unattached volumes and tag them for deletion.”

Linux terminal with error message - Error message while trying to install
Linux terminal with error message – Error message while trying to install “youtube-dlg” – Fedora …

Because I’m running this locally on the Linux instance where the code will run, I can copy-paste the code directly into a file using vim, run it, and paste the output back into the chat if there are errors. It tightens the feedback loop significantly compared to switching windows constantly.

I’ve even used it to help generate Ansible playbooks for configuring Linux Networking settings. The ability to keep the “thought process” of the AI saved in a session manager means I can treat the chat history as documentation for why I made certain changes.

Why This Matters for Linux Users

We often think of “Linux Tools” as strictly command-line utilities—grep, sed, awk. But integrating modern AI tools into the Linux environment requires a bit of creativity. By wrapping the Amazon Q Developer CLI in a web service, I get the best of both worlds: the graphical richness and readability of a browser, with the security and locality of a Linux terminal session.

This approach works across distributions, whether you are on Fedora Linux, Debian Linux, or Arch Linux (though I stick to Amazon Linux for work). It turns the AI from a generic helper into a specialized tool that lives inside your infrastructure.

If you are tired of losing your chat context or navigating away from your terminal to get answers, I highly recommend setting up a local web interface for your AI tools. It takes about 15 minutes to configure the Python environment and systemd service, but it saves hours of context-switching friction in the long run.

Can Not Find Kubeconfig File