Lesson 1 · 18 min read
Linux Fundamentals: Shell, SSH, Users, Permissions
Every EC2 server is a Linux box with no screen. Filesystem, permissions, users, processes — and the fix for “my app dies when I close the terminal”.
What you'll learn in this lesson
- Concept: four things to be comfortable with
- Why this matters — 2am on EC2
- Architecture — the Linux filesystem
- Real example — deploying your Next.js app manually
- Part A: Navigation
- Part B: Files and folders
- Part C: Permissions — the most important part
- Part D: Users and sudo
- Part E: Processes — why your app dies
- Part F: Disk and system health
- Part G: Editing files
- Practice task before Lesson 2
- Follow-up: let one user read a file, but not another
- Conclusion
Concept
A typical EC2 server runs Linux and has no screen, no mouse and no GUI (no windows or buttons). Your only way in is a text terminal over SSH. SSH (Secure Shell) is a way to log in to another computer over the network and type commands on it. A terminal is a text window where you type commands. Before EC2 makes sense, you need to be comfortable with four things: navigating the filesystem, permissions, users, and processes.
As a Next.js developer, you already use a terminal every day (npm run dev, git push). You are not starting from zero. You are learning the system that those commands run on.
Why this matters
When your Next.js app breaks on EC2 at 2am, there is no Vercel dashboard to help you. You will ask questions like: “why is the process dead?”, “is port 3000 actually listening?”, “did the disk fill up?”, “why can't Node read this file?” Each of these is a Linux question, not an AWS question. Vercel hides this layer. AWS shows it to you.
Architecture — the Linux filesystem
Windows has separate drives (C:\, D:\). Linux has one single tree that starts at / (called the “root” folder). Everything lives somewhere in this one tree: your app, your settings, even your devices.
- /root — the single starting point of everything
- ├─ home/one folder per user
- │ ├─ ubuntu/your user on EC2 — your Next.js code sits here
- ├─ var/data that changes while the system runs
- │ ├─ log/where you go when things break
- ├─ etc/system config — nginx, ssh, users
- ├─ usr/installed programs — node, git, npm
- ├─ tmp/scratch files, wiped on reboot
- ├─ root/home folder of the root user
- ├─ dev/your hardware, shown as files — disks, terminals
- ├─ proc/live view of running processes
You will use two folders most. /home/ubuntu is where your Next.js code sits. /var/log is where you look when things break.
Real example — deploying your Next.js app manually
Here are the steps you will run in Lesson 7. They show why each Linux skill matters:
SSH into the server
needs: SSH and key file permissions
Install Node.js
needs: a package manager (a tool that installs software, such as apt) and sudo
Clone your repo into
/home/ubuntu/myappneeds: filesystem navigation
Create a
.envfile with your DB passwordneeds: file editing and permissions
Run
npm run build && npm startneeds: process management
It crashes when you close the terminal
needs: understanding background processes
Most people get stuck at step 6. This lesson shows the proper fix.
Part A: Moving around and reading files
A terminal is always “standing” in one folder. You ask where you are, list what is there, and step into another folder. It is like clicking through folders in Finder, but you type. ~ is a shortcut for your home folder. .. means “one folder up”.
You will read files a lot on a server, because that is how you read logs. A log is a file where a program writes what it is doing. You can print a whole file, page through a big one, or see only the last few lines. The most useful way is following a file. The terminal stays open, and new lines appear as soon as your app writes them. This live view lets you watch a bug happen.
Part B: Files and folders
Creating, copying, moving and deleting files works as you expect. But remember: Linux has no recycle bin. A recursive delete (rm -r) removes a folder and everything inside it at once and for ever. It does not ask “are you sure?”.
Before you delete anything recursively, check which folder you are in. Running it one level too high is a common way to wipe a server.
Part C: Permissions — the most important part
Permissions are rules about who may read, change or run a file. Every file has permissions for three kinds of people: the owner, a group (a named set of users) and others (everyone else). Each kind can have read (4), write (2) and execute (1, which means run it as a program). A file listing shows them as nine letters, for example rw-r--r--. This means the owner can read and write, the group can only read, and others can only read.
Add the numbers to get one digit. Write three digits in this order: owner, group, others. For example, read + write = 4 + 2 = 6. Three values cover almost everything you will do:
| Value | Meaning | Use it for |
|---|---|---|
644 | you read and write, everyone else only reads | normal files, public web files |
600 | you read and write, nobody else can do anything | .env, passwords, API keys |
400 | you can only read, nobody else can do anything | SSH private keys (SSH needs this) |
You will meet this error in Lesson 7: SSH prints “UNPROTECTED PRIVATE KEY FILE! Permissions 0644 ... are too open” and refuses to connect. SSH will not use a key that another user on the machine could read. Setting the key to 400 fixes it.
Part D: Users and sudo
You log in as a normal user. On an Ubuntu EC2 server that user is ubuntu. Some commands need admin power, such as installing software or changing system settings. For those, type sudo in front of the command. sudo means “superuser do”: it runs that one command as the admin (the root user). After the command ends, you are a normal user again.
Rule: do not switch to the root user and stay there. As root, one wrong delete can destroy the server, and nothing stops you.
Part E: Processes — why your app dies
A process is a program that is running right now. Each process has a number called its PID (process ID). You can list processes, filter the list for node, watch live CPU and memory use, and stop a process by its number. You can also ask “which process is using port 3000?”. A port is a numbered door on the server (Lesson 2 explains it). Ask this first when your app “starts” but nothing answers.
The | character is a pipe. It sends the output of one command into the next command. So “list everything, then keep only the lines with node” fits in one line.
Solving “my app dies when I close the terminal”
When you run npm start over SSH, the app is a child of your terminal session. When you close the session, Linux stops its children too. There are three levels of fix:
- Detach it from the terminal (for example with
nohupor&). It survives when you disconnect, but if it crashes it stays dead. This is fine for a quick test. - Run it inside a terminal session that keeps living (a tool like tmux). You can come back and look at it later. It still does not restart after a crash.
- Use a process manager (PM2). A process manager is a program that keeps other programs running. PM2 restarts the app when it crashes, starts it again when the server reboots, and keeps its logs. This is the right answer for production. You will set it up in Lesson 7 (later, Docker takes over this job).
Part F: Disk and system health
A full disk is a common cause of outages. npm run build fails with a confusing error, and logs quietly stop being written. So when something seems wrong, check free disk space first. Then check memory (RAM). Then check how busy the CPU is.
Part G: Editing files
A server has no VS Code. Start with nano, a simple text editor in the terminal. It shows its shortcuts at the bottom of the screen (Ctrl+O saves, Ctrl+X exits). vim is more powerful but hard to learn. You can learn it later.
The five commands you will actually use
Try to understand everything above. But memorise these five. They answer the 2am questions from the top of this lesson.
tail -f app.logwatch a log live: new lines appear as they happen
chmod 600 .envonly you can read your secrets
chmod 400 key.pemthe fix SSH demands for your key in Lesson 7
ps aux | grep nodeis my app actually running?
df -his the disk full? check this first when something seems wrong
Practice task before Lesson 2
Do not launch an EC2 instance yet. On Mac or Linux your terminal already works in a similar way. On Windows, install WSL (Windows Subsystem for Linux). Run wsl --install in an administrator PowerShell, then restart. You then have real Ubuntu.
mkdir ~/practice && cd ~/practice
touch .env && chmod 600 .env
ls -la # .env should show -rw-------
df -hThen, without looking anything up, do these: create a file, read it page by page, delete it, and find any running node process. If you can, you are ready for servers.
Follow-up: let one user read a file, but not another
Say you want Rahul to read report.txt, and Amit to have no access. This is where the owner / group / others model becomes useful.
- Create a group for the people who may read the file. Add Rahul, not Amit.
- Give the file to that group. You stay the owner.
- Set it to
640: you read and write, the group reads, and everyone else gets nothing.
Now Rahul can read it, and Amit gets “Permission denied”. Rahul must log out and log in again before his new group counts.
A readable file inside a locked folder is still out of reach. On a folder, x means “can enter” and r means “can list what is inside”. If the group does not have x on the folder, Rahul cannot reach the file, even though the file allows it. Many beginners get confused by this.
Linux also has ACLs (access control lists). An ACL gives or blocks access for one named user without using a group. ACLs work, but a normal file listing hides them (you only see a small +). The next person cannot tell why access behaves as it does. On real servers, prefer groups.
Where this matters on AWS
On your EC2 server this matters at once. Nginx is a web server program that sits in front of your app. It must read your built Next.js files but must never write them. So the build folder belongs to your user, and Nginx's group may read and enter it. Your .env file holds the RDS (database) password, so it is 600: nobody else, ever. If it were 644, any user or hacked process on that machine could read your database password.
Conclusion
An EC2 server has no screen and no mouse, only a terminal. That is why Linux is a must in this course. What you learned today comes down to five ideas:
- Filesystem: everything lives in one tree starting at
/. Your app goes in/home/ubuntu, logs go in/var/log. - Permissions:
600on.envmeans only you can read it. Use it for any file that holds a password. SSH refuses to use your key until it is400. - sudo: run one command as admin, then go back to being a normal user. Never stay logged in as root. One typo can take down the whole server.
- Processes: if you close the terminal, your app dies with it. That is why you use PM2. It keeps the app running and restarts it after a crash.
- The commands you will use most:
tail -f(watch live logs),df -h(is the disk full?),ps aux | grep node(is the app running?).
You do not need EC2 to practise any of this. The terminal on Mac/Linux, or WSL on Windows, runs the same commands.
End of Lesson 1. Next: Lesson 2 — Networking Basics.
Want to know what PM2 and Nginx are before their lessons? The Pieces You Keep Hearing About →
Published by Jainik · Last updated · How these lessons are made
Keep learning
Part of the study guide
Related series