Linux Terminal Playground
A safe Linux shell in your browser, with ready-made scenarios from the articles: services, logs, disks, permissions, firewalls, SSH and more.
● Runs 100% in your browser — nothing you type leaves this page.
Starting the terminal…
The address bar updates as you go, so you can bookmark or share the result.
What is this?
A Linux shell that runs entirely in your browser. It emulates a small server — with a home directory, logs, nginx and SSH configuration — in two flavours: Ubuntu 24.04 (Debian family) and Rocky Linux 9 (RHEL-compatible: RHEL, Rocky, AlmaLinux). Switch between them to see where they differ: /var/log/auth.log vs /var/log/secure, sudo vs wheel, sites-available vs conf.d. You can practice commands without a VM, a cloud account, or the fear of breaking something. Nothing is sent to a server, and Reset brings the machine back to its starting state.
What you can do
- Navigate and manage files:
ls -la,cd,tree,mkdir -p,cp -r,mv,rm -r, symbolic links withln -sandreadlink - Read and search:
cat,head,tail,grep -rn,find(with-Land-type lfor links),sed,wc,xargs - Combine commands with pipes, redirections and command substitution:
grep error app.log | sort | uniq -c > summary.txt,sudo chown $(id -u):$(id -g) file - Work with permissions:
chmod 640,chmod u+x,chown,sudo,sudo -i - Manage services and read their logs:
systemctl status,systemctl restart,systemctl list-unit-files(to find a service’s name on each distribution),journalctl -u nginx,journalctl -k,dmesg - Check ports and test services:
ss -tlnp,lsof -i :80,curl -I http://localhost,nginx -t,pg_isready - Use git in the scenarios that have a repository:
git status,add,commit,log,diff,stash,pull,push,switch,.gitignorerules withcheck-ignoreandrm --cached,safe.directoryand more, with a simulated GitHub as the remote - Use Docker in the scenarios that have it:
docker ps,run(with--memoryand--platform),start,stop,kill,rm,logs --tail,pull,inspect -f,image inspect,stats --no-stream, with thedockerservice insystemctland thedockergroup (usermod -aG,newgrp,groups); a container over its memory limit is killed with exit code 137, an image built for another CPU fails withexec format error, and a program the image doesn’t have (bashon Alpine) withexecutable file not found in $PATH; Docker Compose readscompose.yaml(up -d,down [-v],ps,ls,logs,config,exec,-p NAME, healthchecks anddepends_on), with its YAML errors, container name conflicts, ports held by another project, and a PostgreSQL database in a named volume that keeps the password it was created with and lacks aPOSTGRES_DBadded later (psql -cinside the container) - Use kubectl in the scenarios that have a Kubernetes cluster:
kubectl get,describe pod,logs --previous,rollout status|restart|undo,set image,set env,create secret,apply -f,config viewand more. Pods follow the clock (image pulls, restarts and back-off), the scheduler places them by what they request (describe node,top,set resources,scale), RBAC decides what--asmay do (auth can-i, Roles and RoleBindings), the kubelet checksrunAsNonRootagainst the image (patch,exec … -- id) and evicts pods from a node under pressure, and a Service only gets the ready pods its selector matches (get endpointslices,describe svc|ingress,set selector). kubectl reads its config from~/.kube/configor$KUBECONFIG, as the real one does - Reach the other machines of a scenario:
ssh app01(andexitto come back),curl http://app01:8080,nc -zv app01 8080,ssh -G,ssh-add -l— with~/.ssh/config, keys and the ssh-agent - Open and close ports in the firewall:
ufwon Ubuntu,firewall-cmdon Rocky Linux — and see the difference from outside: a dropped packet times out, a rejected one says “No route to host” - Check disks and mounts:
df -h,du -sh,lsblk -f,blkid,findmnt,mount(a partition on a folder, ormount -afrom/etc/fstab),umount,fsck,free -h - On Rocky Linux: SELinux with
getenforce,getseboolandsetsebool
Type help inside the terminal for the full list, and man <command> for the options each one supports.
Scenarios
Many OhSudo articles come with a scenario: the terminal opens with the files, services and logs of a real problem — nginx that won’t start, a disk that went read-only, a 502 Bad Gateway — so you can find the cause and fix it step by step. Look for the “Practice this in the terminal” box at the end of an article, or the “Try it in the terminal” links under code blocks.
Note
This is an emulator, not a real Linux machine. Commands and their output follow GNU/Linux (and differ between Ubuntu and Rocky where the real systems do), but only the options listed by man <command> are supported. Connections only reach the machines of the current scenario — there is no internet. Package installs, HTTPS and editors like vim aren’t available. Docker works only in the scenarios that have it, without building images, and Compose without build; kubectl too, with Deployments, Pods, Services, EndpointSlices, Ingresses, Secrets, ConfigMaps and RBAC.
FAQ
Is it safe to try rm -rf here?
Yes. Everything happens in a pretend filesystem in your browser tab. Try sudo rm -rf /var/log and see what happens — then hit Reset. (It’s still a terrible idea on a real server.)
Why do some commands say “Permission denied”?
Just like on a real server, you’re logged in as a normal user, guest. Files like /etc/shadow or /var/log/auth.log need root: put sudo in front of the command, or run sudo -i to get a root shell (exit to leave it).
Will my files still be there tomorrow?
Not yet — the machine starts fresh every time you open the page. Saving your progress is planned.
Is there a guided way to learn this?
Yes: the Terminal Lessons take you through it step by step, and check your work as you go.
Articles
Learn more
Git "Your local changes would be overwritten by merge": keep them, or throw them away
Fix git "Your local changes to the following files would be overwritten by merge" or checkout: commit, stash, or discard them, plus untracked files and servers.
Beginner · 3 min read
Kubernetes "Forbidden: User cannot list resource": give exactly the rights it needs with RBAC
Fix Kubernetes "Forbidden: User cannot list resource": read who and what is missing, test with kubectl auth can-i, then add a Role and RoleBinding.
Intermediate · 4 min read
kubectl "x509: certificate signed by unknown authority": your kubeconfig doesn't trust this cluster
Fix kubectl "x509: certificate signed by unknown authority": get a fresh kubeconfig for a recreated cluster, compare the CA, and handle proxies that inspect TLS.
Intermediate · 3 min read
"No route to host": usually a firewall saying no, sometimes a machine that isn't there
Fix "No route to host" from ssh, curl or nc: check the firewall on the other machine (firewalld rejects by default), then whether the host is up.
Beginner · 4 min read
Docker "pull access denied": the repository doesn't exist, or you're not logged in
Fix Docker "pull access denied, repository does not exist or may require docker login": check the image name and tag, log in to the right registry, handle rate limits.
Beginner · 4 min read
Docker "exec format error": the wrong CPU architecture, or a script with no shebang
Fix Docker "exec /app: exec format error": an image built for another architecture (arm64 vs amd64) or a script with no shebang. Check it, then build with buildx.
Intermediate · 4 min read
Docker "port is already allocated" and "ports are not available": find who has the port
Fix Docker "Bind for 0.0.0.0:8080 failed: port is already allocated" and "Ports are not available": find the container or process using it, and Windows reserved ports.
Beginner · 4 min read
Git "error: src refspec main does not match any": commit first, or use the right branch name
Fix Git "error: src refspec main does not match any" on push: you have no commits yet, or your branch is called master. Check with git branch, then commit or rename it.
Beginner · 4 min read
Kubernetes CreateContainerConfigError: a missing Secret or ConfigMap, and how to find it
Fix Kubernetes CreateContainerConfigError: kubectl describe names the missing Secret, ConfigMap or key. Check the namespace and the key, then let the pod restart.
Beginner · 4 min read
Kubernetes pods "Evicted": find the pressure on the node, and stop it from coming back
Fix Kubernetes pods with status Evicted: read why with describe, handle DiskPressure and MemoryPressure on the node, clean up, set requests and limits, delete old pods.
Intermediate · 4 min read
"umount: target is busy": find what holds the filesystem, and when umount -l is safe
Fix "umount: target is busy" on Linux: find the process with lsof or fuser, leave the folder, stop services, handle NFS and bind mounts, and know when umount -l is safe.
Beginner · 4 min read
"Cannot connect to the Docker daemon. Is the docker daemon running?": every cause
Fix "Cannot connect to the Docker daemon. Is the docker daemon running?": start the service, read why it failed, check DOCKER_HOST, contexts, Docker Desktop and WSL.
Beginner · 5 min read
Git "fatal: refusing to merge unrelated histories": when the flag is safe, and when it isn't
Fix Git "fatal: refusing to merge unrelated histories": why it happens, how to use --allow-unrelated-histories safely, and how to spot a wrong remote or shallow clone.
Beginner · 4 min read
kubectl "The connection to the server localhost:8080 was refused": your kubeconfig is missing
Fix kubectl "The connection to the server localhost:8080 was refused": kubectl has no kubeconfig. Set it up for kubeadm, k3s, minikube, EKS, GKE or AKS, and under sudo.
Beginner · 3 min read
MySQL "ERROR 2003: Can't connect to MySQL server": read the number in brackets
Fix MySQL ERROR 2003 "Can't connect to MySQL server": the number in brackets says if it's a stopped server, bind-address, a firewall or the wrong host in Docker.
Beginner · 4 min read
"Connection timed out" vs "Connection refused": what each one tells you, and how to fix it
Timed out means a firewall dropped the packets; refused means nothing listens there. Tell them apart with nc and curl, then fix ufw, firewalld or the bind address.
Beginner · 5 min read
.gitignore not working: why Git still tracks the file, and how to fix it
.gitignore is ignored because the file is already tracked, the pattern is wrong or the file has the wrong encoding. Find the cause with git check-ignore -v.
Beginner · 4 min read
Kubernetes "container has runAsNonRoot and image will run as root": fix the image or the pod
CreateContainerConfigError with runAsNonRoot: the image runs as root or has a non-numeric USER. Fix the Dockerfile, set runAsUser, and keep restricted security.
Intermediate · 4 min read
SSH "Too many authentication failures": your agent offers too many keys
Fix SSH "Received disconnect … Too many authentication failures": the agent offers every key before the right one. Use IdentitiesOnly and IdentityFile.
Beginner · 4 min read
"Argument list too long": delete or move thousands of files on Linux
Fix "Argument list too long" for rm, mv, cp or grep with a wildcard: why the kernel refuses, and how find -delete, find -exec + and xargs handle any number of files.
Beginner · 3 min read
Docker: "permission denied while trying to connect to the Docker daemon socket"
Fix Docker "permission denied" on /var/run/docker.sock: add your user to the docker group, make it take effect, and know why chmod 666 is a bad idea.
Beginner · 3 min read
Git "fatal: detected dubious ownership in repository": fix it without turning the check off
Fix Git "detected dubious ownership in repository": run Git as the owner, fix the ownership, or trust one path with safe.directory, on servers, Docker and CI.
Beginner · 3 min read
Git "! [rejected] main -> main (fetch first)": why the push failed and how to fix it safely
Fix git push "rejected (fetch first)" and "non-fast-forward": pull with rebase or merge, use --force-with-lease instead of --force, and handle protected branches.
Beginner · 4 min read
"Job for nginx.service failed because the control process exited with error code": how to find the cause
Fix "Job for X.service failed because the control process exited with error code": read systemctl status and journalctl, test the config, and fix the usual causes.
Beginner · 5 min read
Kubernetes ImagePullBackOff and ErrImagePull: find out why the image won’t pull
Fix ImagePullBackOff: read the pull error in kubectl describe, then fix the image name or tag, registry credentials, Docker Hub rate limits, network or architecture.
Beginner · 4 min read
Kubernetes pod stuck in Pending: "0/3 nodes are available: Insufficient cpu"
Fix pods stuck in Pending: read the FailedScheduling event, then fix CPU and memory requests, taints, node selectors, volumes or the cluster size.
Intermediate · 4 min read
Linux process "Killed" with no error: find the OOM killer and stop it happening again
A process that just prints "Killed" (exit code 137) was usually stopped by the Linux OOM killer. Find it in the kernel log, see what used the memory, and fix it.
Intermediate · 4 min read
PostgreSQL "Connection refused … Is the server running?": find out why nothing answers on 5432
Fix PostgreSQL "connection refused": check that it runs, read why it did not start, then fix listen_addresses, the port, the firewall or Docker.
Beginner · 3 min read
PostgreSQL "FATAL: password authentication failed for user": find the real reason
Fix PostgreSQL "password authentication failed" and "Peer authentication failed": read the server log, check pg_hba.conf, reset the password, and handle Docker.
Beginner · 6 min read
"Read-only file system" on Linux: why the disk went read-only, and how to fix it safely
Fix "Read-only file system" errors: find the read-only mount, read dmesg to see why the kernel did it, then repair with fsck — and check whether the disk is failing.
Intermediate · 4 min read
"sudo: unable to resolve host": fix /etc/hosts after a hostname change
Fix "sudo: unable to resolve host … Name or service not known" on Ubuntu and Debian: add the hostname to /etc/hosts, and keep cloud-init from undoing it.
Beginner · 3 min read
"Address already in use": find who is using port 80 (or any port)
Fix "bind() failed (98: Address already in use)": find the process holding the port with ss or lsof, then stop it, move it, or change your port.
Beginner · 5 min read
Docker "exited with code 137": OOM kill or a stop that took too long
Exit code 137 means the container was killed with SIGKILL. Find out if it ran out of memory or ignored docker stop, and fix each case.
Intermediate · 6 min read
Kubernetes CrashLoopBackOff: 7 causes and how to find yours
CrashLoopBackOff means the container keeps exiting. Read the exit code and the previous logs, then fix the crash, OOM kill, probe or command.
Intermediate · 6 min read
Nginx "502 Bad Gateway": find the cause in the error log
Fix nginx 502 Bad Gateway: read error.log, then fix the backend that is down, the wrong address or socket, the crashing app, or SELinux on RHEL.
Intermediate · 5 min read
No space left on device: find what is filling your Linux disk
Fix "No space left on device" on Linux: find the biggest directories and files, free space safely, and handle the cases where df says there is space.
Beginner · 4 min read
"Permission denied" when running a script: 5 causes and fixes
Fix "bash: ./script.sh: Permission denied" and "bad interpreter" on Linux: execute bits, noexec mounts, directory permissions, Windows line endings and shebangs.
Beginner · 4 min read
SSH "Permission denied (publickey)": how to find the real cause
Fix SSH "Permission denied (publickey)": read the server log, fix ~/.ssh permissions, check the key and sshd_config, and handle SELinux on RHEL.
Intermediate · 4 min read