In this post, I’ll walk you through how I built a Go Playground REPL clone from scratch — powered by a Go backend that compiles user-submitted code securely in Docker, deployed with GitHub Actions to AWS Elastic Beanstalk, and paired with a beautiful frontend using Vue.js, Pinia, Tailwind CSS, and Monaco Editor.

Tech Stack

  • Backend: Go (Golang), Docker, Gin, os/exec
  • Frontend: Vue 3, Pinia, Tailwind CSS, Monaco Editor
  • DevOps: GitHub Actions, DockerHub, AWS Elastic Beanstalk

What I Built

  • An interactive code editor for writing and executing Go programs.
  • A secure backend that:
  • Runs code inside a Docker container
  • Enforces timeouts to prevent infinite loops
  • Handles malicious input gracefully
  • A responsive frontend with live theme switching, program examples, and output panels.

Backend Setup

I used the os/exec package in Go to compile and run user code inside a Docker container, isolated from the host.

Sample Go run handler:

func RunCode(c *gin.Context) {
    var payload struct {
        Code string `json:"code"`
    }

    if err := c.ShouldBindJSON(&payload); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request format"})
        return
    }

    output, err := runInDocker(payload.Code)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }

    c.JSON(http.StatusOK, gin.H{"output": output, "error": ""})
}

Sample Dockerfile:

FROM golang:1.24-alpine
WORKDIR /app
COPY . .
RUN go build -o repl-server ./cmd
CMD [ "./repl-server" ]

GitHub Actions Deployment

I set up GitHub Actions to automatically build our Docker image, push to ECR, and deploy to AWS Elastic Beanstalk.

Key CI/CD steps:

- name: Build Docker Image
  run: docker build -t repl-api .

- name: Push to ECR
  run: |
    aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin ${{ secrets.ECR_URL }}
    docker tag repl-api:latest ${{ secrets.ECR_URL }}/repl-api:latest
    docker push ${{ secrets.ECR_URL }}/repl-api:latest

- name: Deploy to EBS
  run: |
    eb init -p docker go-repl --region us-west-2
    eb deploy

Frontend Setup

Used Vue 3 with Pinia to manage state and Monaco Editor for code editing.

Vue + Monaco Editor integration (sample):

import MonacoEditor from '@monaco-editor/vue'
const code = ref(`package main\n\nimport "fmt"\n\nfunc main() {\n fmt.Println("Hello, world!")\n}`)

Sample UI with Tailwind CSS:

Go Playground REPL

Program Examples Dropdown

Added dropdown support with built-in Go examples like

  • Fibonacci
  • Peano Integers
  • Prime Checker
  • Bubble Sort
  • Pi Calculation

Securing Execution

Used these techniques to sandbox the code:

  • Timeout using context.WithTimeout
  • Docker resource constraints (--memory, --cpus)
  • Output/error size limits
  • Validated JSON input structure

Future Improvements

This setup is built with extensibility in mind.

  • Add support for JavaScript, Java, Python, etc.
  • Enable stdin support in Docker for user input
  • Add user accounts and save session history
  • Use WebSocket for real-time compile streams

🌐 Live Demo

Go Playground

📝 Final Thoughts

This project was a fun blend of backend performance, frontend UX, and DevOps automation. It’s a perfect playground for experimenting with Go and building a polished, full-stack developer tool.

Feel free to fork and extend it further. Hope this helps you in your learning journey!

Repo
Github Repo