🐣 Crawl

What Even Is Linux?

Before you can use it, you need to understand what it actually is — and why it's so different from what you're used to.

The simple version
Linux is an operating system — just like Windows. It runs your hardware (CPU, RAM, drives), manages programs, and lets you interact with your computer.

The big difference: Windows hides everything behind pretty buttons. Linux exposes everything, and that exposure is where the power comes from. When something breaks, you can actually see why. When you want to automate something, you can. When you want a server running 24/7 with no desktop wasting RAM, you can do that too.
The real world analogy
Windows
Like a restaurant with a menu. You pick from what they offer. Works great. You can't go in the kitchen or change the recipe.
Linux
Like having your own kitchen. You have to cook, but you can make anything. You can also see exactly what's in every dish.
Why your homelab runs Linux
  • 1
    It's free and runs on anything
    Proxmox, your containers (Nextcloud, Navidrome, Pi-hole), Debian inside those CTs — all Linux. Zero licensing cost. Your whole homelab runs on it for $0 in software.
  • 2
    Servers don't need a desktop
    Windows wastes RAM running a full visual interface even when no one's looking at it. Linux can run everything through text commands, so 100% of your hardware goes to actual work.
  • 3
    Docker basically requires it
    Docker was built for Linux. Every container you'll ever run — Jellyfin, Nextcloud, Frigate — was designed and tested on Linux first.
💡
You already know more than you think Your Proxmox host (192.168.1.200) and every CT you've set up — CT100 through CT107 — is running Debian Linux right now. Every command you've ever typed in Proxmox shell is Linux.
🐣 Crawl

The Filesystem Tree

This is the most important concept in Linux. Everything — files, devices, network connections, settings — is a file inside a tree of folders. Once this clicks, everything else makes sense.

It's one big tree, starting from /
On Windows, you have C:\, D:\, E:\ — separate drive letters for separate storage devices.

Linux has one root, written as just / (a forward slash). Everything branches off from there. Drives, USB sticks, network shares — they all get mounted somewhere inside that single tree.
/ ← the root. everything starts here. ├── etc/ ← all system config files live here ├── home/ ← personal folders for each user │ └── justin/ ← your home folder (shown as ~) ├── var/ ← logs, databases, runtime data │ └── log/ ├── usr/ ← installed programs and libraries ├── tmp/ ← temporary files (wiped on reboot) ├── mnt/ ← where you mount external drives/shares │ └── hamster-storage/ ← your SSHFS mount to the gaming PC └── root/ ← home folder for the root (admin) user
Key folders you'll actually use
PathWhat it isYour homelab example
/etc/Config files for everything on the systemPi-hole config, Nextcloud settings, systemd services
/var/log/Log files — what happened and whenWhere you read error logs when something breaks
/mnt/Mount point for drives and sharesYour SSHFS gaming PC mount lives at /mnt/hamster-storage
/home/User home directoriesWhere personal files live for non-root users
/root/Home folder for the root userYour SSH keys live at /root/.ssh/hamsterpc
/tmp/Temporary filesCleared on reboot. Good for scratch work.
/usr/bin/Programs you can runWhere nano, ffmpeg, etc. are stored
🔑
The tilde shortcut The ~ symbol is a shortcut for your home directory. If you're logged in as root (which you are in Proxmox and your CTs), ~ means /root. So ~/scripts is the same as /root/scripts.
🐣 Crawl

Why a Terminal Exists

You said you hate having to remember commands just to navigate. That's fair. Here's why it works this way, and why you'll actually come to appreciate it.

The honest reason
A terminal is just a text interface to give instructions. That's it. You type an instruction, Linux executes it, and shows you the result.

GUIs (graphical interfaces) are great for humans browsing around. But they can't do everything, and on a server — where no one's sitting there clicking around — a terminal running over SSH is way more efficient. No screen required. No mouse required. You can manage your server from across the house, or across the planet.
Why commands instead of clicking
GUI (clicking)
Open folder → right-click → New Folder → type name → press Enter. Every step requires you to be there, watching, clicking. Can't repeat it 100 times automatically.
Terminal (typing)
mkdir myfolder — done in 2 seconds. You can also write it in a script and run it on 50 machines at once. Or schedule it every night at midnight.
The secret about "remembering" commands
You don't have to memorize everything. Nobody does. Real sysadmins Google stuff constantly. The goal isn't memorization — it's understanding what you're looking at so you know when something is working, when it's broken, and roughly what kind of command you need.

That's exactly what this tutorial is for. You're building pattern recognition, not a command dictionary.
⌨️
Tab autocomplete — the single biggest quality-of-life tip Start typing a path or command, then press Tab. Linux will fill in the rest, or show you the options if there are multiple matches. You almost never have to type a full directory path. Type the first few letters and hit Tab. This single habit will cut your typing by 60%.
Other tricks that make life easier
  • Up arrow = previous command
    Press ↑ to scroll through your command history. Press ↑ twice to go further back. You'll reuse commands constantly — no retyping.
  • !!
    !! = repeat last command
    Type !! and press Enter to run whatever you just ran. Super useful when you forgot to add sudo — just type sudo !!
  • Ctrl
    Ctrl+C = stop whatever is running
    If a command is running and won't stop, or you started the wrong thing, press Ctrl+C to cancel it immediately. This is your escape key in the terminal.
  • Ctrl
    Ctrl+L = clear the screen
    Same as typing clear. Wipes the visible terminal output so you have a clean view. Your history still works, nothing is deleted.
🐣 Crawl

Reading the Prompt

Before you type a single command, there's information right in front of you. The prompt tells you who you are, where you are, and whether you have power.

Anatomy of a prompt
Your Proxmox host shell
root@pve:~# _
Who
root
The username. root = admin, full power. If it shows your name, you're a regular user.
At symbol
@
Just separates who from where. Read it as "at".
Machine
pve
The hostname. pve = Proxmox VE host. Changes when you SSH into a CT.
Where
~
Your current folder. ~ = home directory. Changes as you navigate.
Power level
#
# = you are root (god mode). $ = regular user. This one symbol tells you everything about your permission level.
Real examples you'll see in your setup
# On Proxmox host shell: root@pve:~# # After SSH-ing into your Nextcloud CT (101): root@nextcloud:~# # After going into /etc directory: root@nextcloud:/etc# # As a regular user on your future R720xd: justin@r720:~$
⚠️
The # symbol is a warning sign When you see # in a prompt, you have root privileges. There's no "are you sure?" dialog box. One wrong command can delete critical files with no undo. When you're working as root, slow down and read before pressing Enter.
🐣 Crawl

Root vs. Your User

Every Linux system has a concept of permissions. Not everyone can do everything. Here's how it works and why it matters for your homelab.

Who is root?
Root is the superuser — the administrator account that can do anything on the system. Delete any file. Start or stop any service. Change any setting.

In your current setup, you log into Proxmox as root and drop into CT shells as root. This is fine for a personal homelab — it's simpler. Just be careful.
File permissions — who can do what
Every file in Linux has an owner and permissions. When you run ls -la you'll see something like this:
# Output of ls -la -rw-r--r-- 1 root root 4096 May 20 12:30 config.txt drwxr-xr-x 2 root root 4096 May 18 09:00 scripts/ -rwx------ 1 root root 512 May 15 16:45 run.sh
The first column (-rw-r--r--) is the permission string. For now, just know: if Linux says "permission denied" when you run something, you probably need to use sudo or switch to root.
The ownership concept
Windows equivalent
The Administrator account. "Run as Administrator" when something needs elevated access.
Linux root
The root user. sudo command runs something with root power from a regular account. If you're already root, you don't need sudo.
💡
You're already comfortable with this When you ran commands like pct set 101 --mp0 from the Proxmox host shell — that's you being root. That's why it worked without asking for a password. In your CT shells, same thing: you're root inside the container.
🏁
Crawl phase complete! You now understand what Linux is, how the filesystem is structured, why terminals exist, how to read the prompt, and what root means. You've been using this stuff the whole time — now you know what you were looking at. Move to Walk to learn how to actually navigate.
🚶 Walk

pwd — Where Am I?

The first command every Linux user learns. It stands for Print Working Directory. It just tells you where you currently are in the filesystem.

The command
Terminal
root@pve:~# pwd /root
That's it. Type pwd, press Enter, and it prints the full path of where you are. No options needed, no arguments. Just pwd.

When to use it: Whenever you're not sure where you are. You'll get lost sometimes — that's normal. Just type pwd to get your bearings.
What it looks like in your actual setup
# On Proxmox host, just logged in: root@pve:~# pwd /root # After entering Nextcloud CT and moving around: root@nextcloud:/etc/nginx# pwd /etc/nginx
🚶 Walk

ls — What's Here?

ls stands for list. It shows you what files and folders exist in the current directory. It's like opening a folder in Windows Explorer but faster.

Basic usage
Terminal
root@pve:~# ls scripts backups notes.txt setup.sh
The useful flags
CommandWhat it doesWhen to use
lsBasic list. Just names.Quick glance at what's there.
ls -lLong format: shows permissions, owner, size, date.When you need details about files.
ls -aShows hidden files too (files starting with a dot).When config files seem "missing".
ls -laBoth: long format + hidden files.This is what you'll use most.
ls /etcList a specific path without going there first.Peek into a folder from anywhere.
ls -la example output
root@pve:~# ls -la total 28 drwx------ 4 root root 4096 May 25 08:00 . drwxr-xr-x 19 root root 4096 May 20 14:00 .. -rw------- 1 root root 512 May 25 08:01 .bash_history ← hidden file (starts with .) drwxr-xr-x 2 root root 4096 May 18 09:00 scripts -rw-r--r-- 1 root root 128 May 20 11:30 notes.txt
🎨
Colors have meaning In most terminals: blue = directory (folder), white/grey = regular file, green = executable (a program), red = broken symlink. Your eyes will learn to read these automatically.
🚶 Walk

cd — Moving Around

cd = Change Directory. This is the one you already know. Here's how to use it without having to type full paths every time.

The core commands
# Go into a folder root@pve:~# cd scripts root@pve:~/scripts# ← prompt changed to show where you are # Go back up one level root@pve:~/scripts# cd .. root@pve:~# # Go straight to your home folder from anywhere root@pve:/etc/nginx/conf.d# cd root@pve:~# ← cd with no argument = go home # Go back to previous directory (like clicking back) root@pve:~# cd - /etc/nginx/conf.d root@pve:/etc/nginx/conf.d#
⭐ The Tab key — your most important habit
You said you hate typing long directory names. Tab autocomplete is the fix.
  • Tab
    Type the first few letters, then Tab
    Type cd /etc/ng then press Tab → fills in to cd /etc/nginx. You only typed 2 letters of "nginx".
  • Tab
    Double-Tab shows all options
    If there are multiple matches, press Tab twice and Linux lists all possibilities. Then type one more letter to narrow it down, Tab again.
  • Tab
    Works for commands too, not just paths
    Type sys and press Tab → completes to systemctl. Type doc Tab → docker. This works for any installed program.
Chaining with Tab: the real technique You can Tab through multiple levels at once. Type cd /e Tab → /etc/, then ng Tab → /etc/nginx/, then co Tab Tab to see what's inside. Full path built in seconds with almost no typing.
🚶 Walk

Absolute vs. Relative Paths

Understanding paths is what separates confused typing from confident navigation. There are two ways to describe any location in Linux.

Absolute path — the full address
An absolute path starts from the root / and gives the complete address. Like a street address — it works no matter where you currently are.
# Absolute paths always start with / /etc/nginx/nginx.conf /mnt/hamster-storage/Music /root/.ssh/hamsterpc /var/log/syslog
Relative path — directions from where you are
A relative path doesn't start with /. It's directions from your current location. Like "turn left at the corner" vs. giving a full address.
# You're currently in /etc/nginx/ root@pve:/etc/nginx# cat nginx.conf ← relative: nginx.conf in HERE root@pve:/etc/nginx# cat ../hosts ← relative: go up, then hosts root@pve:/etc/nginx# cat /etc/hosts ← absolute: same file, full path
The . and .. shortcuts
SymbolMeaningExample
.Current directory (where you are right now)./run.sh = run the script that's right here
..Parent directory (one level up)cd .. = go up one folder
../..Two levels upcd ../.. = go up two folders
~Your home directorycd ~/scripts = always goes to /root/scripts
💡
Rule of thumb Use absolute paths in scripts and config files (so they work regardless of where the script is run from). Use relative paths when typing interactively — less to type, and Tab helps.
🚶 Walk

Reading Files: cat & less

Half of troubleshooting is reading the right file. Here's how to look inside files without a GUI.

cat — print a file to screen
cat stands for "concatenate" but you'll mostly use it to just dump a file's contents to the screen. Best for short files (config files, small scripts, etc.).
root@pve:~# cat /etc/hostname pve root@nextcloud:~# cat /etc/hosts 127.0.0.1 localhost 127.0.1.1 nextcloud 192.168.1.200 pve
less — read long files with scrolling
less opens a file in a scrollable reader. Use this for long log files, big config files — anything that would fly off the screen with cat.
root@pve:~# less /var/log/syslog ... file opens in reader mode ...
Key in lessWhat it does
↑ ↓Scroll up and down line by line
SpacePage down (big jump)
GJump to the end of the file
gJump to the beginning
/wordSearch for "word" in the file
qQuit and return to the terminal
tail — see just the end of a file
tail is often more useful than cat or less for logs because you usually want to see what just happened, not the whole history.
# Show last 20 lines root@pve:~# tail -n 20 /var/log/syslog # Follow a log in real time (Ctrl+C to stop) root@pve:~# tail -f /var/log/syslog ... new lines appear as they're written ...
🚶 Walk

Editing Files: nano

nano is the beginner-friendly text editor. Unlike vim (which has a learning curve that breaks people), nano works like you'd expect — just type to edit.

Opening a file
root@pve:~# nano /etc/hosts ... file opens in editor ...
The file opens and you can immediately start typing. Arrow keys move your cursor. No modes, no commands to enter edit mode. Just edit.
The controls — shown at the bottom of nano
📌
The ^ symbol means Ctrl When nano shows ^X at the bottom, it means press Ctrl+X. This trips people up constantly — it's not the caret character, it's Control.
ShortcutWhat it does
Ctrl+XExit nano. Will ask if you want to save.
Ctrl+OSave (write Out) without exiting.
Ctrl+WSearch for text (Where is).
Ctrl+KCut the entire current line.
Ctrl+UPaste what you cut.
Ctrl+GHelp menu.
The save workflow
# 1. You're done editing. Press: Ctrl+X # 2. nano asks: Save modified buffer? Save modified buffer? Y Yes N No ^C Cancel # 3. Press Y Y # 4. nano shows the filename, press Enter to confirm File Name to Write: /etc/hosts Enter # Done. You're back at the terminal.
🚶 Walk

🖥️ Practice Terminal

This is a simulated terminal. Type real commands and see how Linux responds. It won't break anything — it's a fake filesystem for practice. Try the hints below or freestyle it.

Interactive simulator
root@hamsterlab:~ — practice terminal
Welcome to the Hamster Lab practice terminal.
Type commands below. Try: pwd, ls, cd, cat, clear, help
 
root@hamsterlab:~#
TRY THESE COMMANDS:
pwd ls ls -la cd documents cd .. cd (home) cat readme.txt cat /etc/hostname ls /mnt mkdir testfolder clear help
🏁
Walk phase complete! You can now navigate Linux: know where you are, list what's there, move around, read files, and edit them. Head to Run to learn how to actually do things — services, permissions, logs, and more.
🏃 Run

sudo — Why You Need Permission

Most of the time in your homelab you're already root, so you don't need sudo. But you'll see it everywhere, and understanding it matters.

What sudo does
sudo stands for Super User Do. It runs a single command as root, even if you're logged in as a regular user. It's like "Run as Administrator" on Windows but for one command at a time.

In your CT shells and Proxmox, you're already root — so you won't need sudo. But on your future R720xd, if you create a personal user account, you'll need sudo to do admin things.
# Regular user trying to install something: justin@server:~$ apt install nginx E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied) # Same command with sudo: justin@server:~$ sudo apt install nginx [sudo] password for justin: Reading package lists... Done ... installs successfully ...
The "forgot sudo" fix
# You ran a command and it failed with permission denied. # Instead of retyping the whole thing, just: justin@server:~$ sudo !! # !! = "the last command I ran" — sudo runs it again with permission
ℹ️
In your current setup: already root everywhere Your Proxmox host shell = root. Your LXC CT shells = root. You never need sudo in your current setup. This lesson is for when you eventually create normal user accounts on the R720xd.
🏃 Run

Services — systemctl

On Linux, programs that run in the background (like your SSHFS mounts, Pi-hole, web servers) are called services. systemctl is how you control them.

The analogy
Think of services like apps that run in the background on your phone. You can start them, stop them, see if they're crashed, and set them to auto-start when the phone turns on. systemctl does all of that for Linux services.
The commands you'll actually use
# Check if a service is running (and see recent logs) root@pve:~# systemctl status sshfs-mounts ● sshfs-mounts.service - SSHFS Mount Service Loaded: loaded (/etc/systemd/system/sshfs-mounts.service) Active: active (running) since Mon 2026-05-25 09:00:01 # Start a stopped service root@pve:~# systemctl start sshfs-mounts # Stop a running service root@pve:~# systemctl stop sshfs-mounts # Restart a service (stop + start) root@pve:~# systemctl restart sshfs-mounts # Enable: make it start automatically on boot root@pve:~# systemctl enable sshfs-mounts # Disable: stop it from starting on boot root@pve:~# systemctl disable sshfs-mounts
Reading the status output
● sshfs-mounts.service - SSHFS Mount Service ← service name Loaded: loaded (/etc/systemd/system/sshfs-mounts.service; enabled) ← enabled = survives reboot Active: active (running) since Mon 2026-05-25 09:00:01 ← GREEN = all good Active: failed since Mon 2026-05-25 09:00:01 ← RED = broken Active: inactive (dead) ← AMBER = stopped on purpose Main PID: 1234 (mount-sshfs.sh) Tasks: 2 (limit: 4915) May 25 09:00:01 pve systemd[1]: Started SSHFS Mount Service. ← recent log lines
💡
Your real services: sshfs-mounts.service The SSHFS auto-remount service you set up lives at /etc/systemd/system/sshfs-mounts.service. If your music or storage mounts stop working after a reboot, the first thing to check is systemctl status sshfs-mounts.
🏃 Run

Decoding Error Messages

You said you freeze up when something doesn't work. This lesson is specifically for that. Error messages aren't random noise — they're usually telling you exactly what's wrong.

The most common errors you'll see — click to expand
bash: command not found
What it means
Linux can't find a program with that name. Either you typo'd the command, or the program isn't installed.
How to fix it
1. Check your spelling. Did you type docekr instead of docker?
2. If spelled right, install it: apt install <name>
3. If it's a script you made: you might need ./script.sh instead of just script.sh
Permission denied
What it means
You're trying to do something that your current user account doesn't have permission to do.
How to fix it
1. If you need root: prepend sudo to the command. Or switch to root with su -
2. If it's a script: make it executable with chmod +x script.sh then run ./script.sh
3. If it's a file: check ownership with ls -la to see who owns it
No such file or directory
What it means
The path you typed doesn't exist. Linux is very literal — one wrong letter, wrong case, or wrong slash and it can't find it.
How to fix it
1. Check the path with ls at each step. ls /etc, then ls /etc/nginx, etc.
2. Linux paths are case-sensitive. /etc/Nginx and /etc/nginx are different.
3. Use Tab autocomplete — it only completes paths that actually exist
Connection refused / Connection timed out
What it means
Refused: The machine you're connecting to is reachable, but nothing is listening on that port. Timed out: The machine isn't responding at all — firewall, wrong IP, or machine is down.
How to fix it
1. Is the service running? systemctl status <service>
2. Is the IP right? ping 192.168.1.202 to test connectivity
3. Is the port right? Check with ss -tlnp to see what ports are actually open
failed to mount / Transport endpoint is not connected
What it means
A mount point (drive, network share, SSHFS) was disconnected or failed to mount. You'll see this if your SSHFS gaming PC connection drops.
How to fix it
1. Unmount the broken mount: fusermount -u /mnt/hamster-storage
2. Remount it: run your mount script or systemctl restart sshfs-mounts
3. If that fails, check if the gaming PC is on: ping 192.168.1.132
E: dpkg was interrupted / E: Unable to acquire lock
What it means
A previous apt install was interrupted mid-way (maybe you cancelled it), or another package manager process is running.
How to fix it
Run: dpkg --configure -a to fix interrupted installs.
If there's a lock: rm /var/lib/dpkg/lock-frontend then try again.
Wait a moment first — sometimes it's just another process finishing.
The universal troubleshooting process
  • 1
    Read the error message literally
    Don't just see red text and panic. Read it word by word. It usually says exactly what went wrong. "No such file or directory" is not vague — it means the path doesn't exist.
  • 2
    Check status of the related service
    systemctl status <servicename> — this shows you the last few log lines which almost always contain the specific cause.
  • 3
    Check the logs
    journalctl -u servicename -n 50 shows the last 50 log lines for a service. This is where the real details are.
  • 4
    Copy the error message and search it
    Copy the specific error text (without your IP/paths) and paste it into Google or ask here. Most errors have been seen and documented a thousand times.
🏃 Run

Copy, Move, Delete

The file management commands. These are powerful and mostly have no undo — especially delete.

The commands
# COPY — cp source destination root@pve:~# cp config.txt config.txt.backup ← make a backup root@pve:~# cp -r scripts/ /root/scripts-backup/ ← copy entire folder (-r = recursive) # MOVE (also renames) — mv source destination root@pve:~# mv config.txt old-config.txt ← rename a file root@pve:~# mv scripts/ /opt/scripts/ ← move folder to new location # DELETE — rm target root@pve:~# rm old-config.txt ← delete a file (no trash, permanent) root@pve:~# rm -r old-scripts/ ← delete a folder and everything in it # MAKE DIRECTORY root@pve:~# mkdir new-folder root@pve:~# mkdir -p /opt/hamster/data/logs ← -p creates all missing parent folders
☠️
rm has no trash can. Ever. rm -rf /something deletes instantly, permanently, with no confirmation. There is no undo. Double-check your path before pressing Enter. A misplaced space can be catastrophic: rm -rf / opt (with a space) would start deleting the entire root filesystem.
🛡️
Always backup before deleting Before deleting any config file: cp config.conf config.conf.bak. Takes 2 seconds and has saved countless homelab setups.
🏃 Run

Reading Logs

Logs are Linux's black box recorder. When something breaks, logs tell you exactly what happened. This is the most powerful troubleshooting skill you can build.

journalctl — the main log tool
journalctl reads the systemd journal — the central log for all system services. Every service you've set up (sshfs-mounts, etc.) logs here.
# See logs for one service (most useful) root@pve:~# journalctl -u sshfs-mounts # Last 50 lines only root@pve:~# journalctl -u sshfs-mounts -n 50 # Follow in real time (great for watching a service start) root@pve:~# journalctl -u sshfs-mounts -f # Since last boot (see what happened on startup) root@pve:~# journalctl -b # All logs, most recent first root@pve:~# journalctl -r
Docker logs
Docker containers have their own log system, separate from journalctl:
# See logs from a container root@104:~# docker logs open-webui # Last 50 lines root@104:~# docker logs --tail 50 open-webui # Follow in real time root@104:~# docker logs -f open-webui
🔍
Searching logs with grep Pipe logs through grep to find specific keywords: journalctl -u sshfs-mounts | grep -i error. The -i flag makes it case-insensitive. This is how you find the actual error in 200 lines of log output.
🏃 Run

Processes — ps & kill

Every program running on Linux is a process with an ID number. Sometimes you need to find a stuck process and stop it manually.

Listing what's running
# Show your own processes root@pve:~# ps aux USER PID %CPU %MEM VSZ RSS COMMAND root 1 0.0 0.1 19364 1516 /sbin/init root 1234 0.1 0.5 55296 5000 sshfs hamsterpc@192.168.1.132:... root 5678 0.0 0.1 9832 900 -bash # Search for a specific process root@pve:~# ps aux | grep sshfs root 1234 0.1 0.5 55296 5000 sshfs hamsterpc@192.168.1.132:... # Interactive live view (like Task Manager — press q to quit) root@pve:~# top
Killing a stuck process
# Kill a process by PID (get PID from ps output) root@pve:~# kill 1234 ← politely ask it to stop root@pve:~# kill -9 1234 ← force kill (no questions asked) # Kill by name instead of PID root@pve:~# pkill sshfs ← kills all processes named "sshfs"
🏁
Run phase complete! You can now manage services, decode errors, handle files, read logs, and kill stuck processes. These skills cover 90% of day-to-day homelab work. Move to Climb for Proxmox-specific commands and Docker.
🧗 Climb

Proxmox — Shell vs. CT Shell

One of the most important things to keep straight: where are you running commands? The host shell and a container shell are completely different environments.

Two separate environments
Proxmox Host Shell (pve)
The building itself. Controls all the CTs. Can see all hardware. Where you run pct commands and manage the SSHFS service. Root on the whole machine.
CT Shell (nextcloud, navidrome, etc.)
An apartment inside the building. Only sees its own files and services. Commands here only affect that container. Root inside the container only.
How to enter each one
# Method 1: Proxmox Web UI Click on pve node → Shell (host shell, prompt: root@pve) Click on CT 101 → Console (CT shell, prompt: root@nextcloud) # Method 2: SSH into host, then enter a CT root@pve:~# pct enter 101 root@nextcloud:~# ← now you're inside CT 101 # Exit back to host root@nextcloud:~# exit root@pve:~# ← back on host
Your CT map
CT IDHostname / PromptServiceIP
100root@piholePi-hole DNS192.168.1.201
101root@nextcloudNextcloud192.168.1.202
102root@navidromeNavidrome music192.168.1.191
103root@minecraft-bedrockMC Bedrock192.168.1.192
104root@npm-dockerNPM + Docker192.168.1.193
106root@games-siteGames website192.168.1.194
107root@dashboardHome dashboard192.168.1.195
🧗 Climb

Proxmox — Container Commands

pct is the Proxmox Container Toolkit. Run these from the host shell (root@pve) — not from inside a CT.

The pct commands you'll actually use
# List all containers and their status root@pve:~# pct list VMID Status Lock Name 100 running pihole 101 running nextcloud 102 running navidrome # Start / stop / restart a container root@pve:~# pct start 101 root@pve:~# pct stop 101 root@pve:~# pct restart 101 # Enter a container shell root@pve:~# pct enter 101 # Show CT config (RAM, disk, mounts, IPs) root@pve:~# pct config 101 arch: amd64 cores: 2 hostname: nextcloud memory: 2048 mp0: /mnt/hamster-storage,mp=/mnt/hamster-storage net0: name=eth0,bridge=vmbr0,ip=192.168.1.202/24,gw=192.168.1.1 # Run a command inside a CT without entering it root@pve:~# pct exec 101 -- systemctl status apache2 # Copy a file into a CT root@pve:~# pct push 102 /root/.ssh/hamsterpc /root/.ssh/hamsterpc
Resize a CT disk (from host shell)
# Increase CT 101's root disk by 5GB root@pve:~# pct resize 101 rootfs +5G # Then inside the CT, resize the filesystem to use the new space root@pve:~# pct enter 101 root@nextcloud:~# resize2fs /dev/sda
🧗 Climb

Docker — The Mental Model

Docker is confusing at first because it has its own vocabulary. Get the mental model right and the commands become obvious.

The shipping container analogy
Before Docker, if you wanted to run software, you had to install it on your system — and it might conflict with other software. Docker solves this by packaging everything an app needs into a container: the app, its dependencies, its config, all bundled together like a shipping container. Drop it anywhere, it runs the same way.
The key concepts
📦
Image the blueprint
A read-only template. Like an app installer. You download an image (e.g. linuxserver/nextcloud) and use it to create containers. One image, many containers.
🏃
Container the running instance
A running copy of an image. Like a process started from an executable. Your Open WebUI in CT104 is a running container created from the Open WebUI image.
💾
Volume persistent storage
Containers are temporary — if you delete one, its data is gone. Volumes attach external storage so your data survives. Always use volumes for anything important.
🌐
Port Mapping how the outside connects
Containers are isolated. Port mapping punches a hole: -p 3000:3000 means "host port 3000 → container port 3000". That's how your Open WebUI is reachable at :3000.
🔗
Network how containers talk
Docker creates virtual networks. Containers on the same network can find each other by name. External traffic goes through port mappings.
📋
docker-compose multi-container setup
A YAML file that describes a whole stack of containers, their volumes, ports, and networks. One file to rule them all — run docker compose up and everything starts.
Real world
Image = recipe
Container = meal you cooked
Volume = the plate (persists)
Port = the door to serve it through
Proxmox equivalent
Image = CT template
Container = running CT
Volume = mounted storage
Port = port forward in NPM
🧗 Climb

Docker — Core Commands

These are the commands you'll use constantly. Run them from inside CT104 (your Docker CT) or wherever Docker is installed.

Essential Docker commands
────────────────────────────── SEEING WHAT'S RUNNING ────────────────────────────── # List running containers root@104:~# docker ps CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES a1b2c3d4e5f6 open-webui ... Up 2 hours 0.0.0.0:3000->3000 open-webui # List ALL containers (including stopped ones) root@104:~# docker ps -a # List downloaded images root@104:~# docker images ────────────────────────────── STARTING AND STOPPING ────────────────────────────── # Start / stop / restart by name root@104:~# docker start open-webui root@104:~# docker stop open-webui root@104:~# docker restart open-webui ────────────────────────────── LOGS AND DEBUGGING ────────────────────────────── root@104:~# docker logs open-webui root@104:~# docker logs -f --tail 50 open-webui # Open a shell inside a running container root@104:~# docker exec -it open-webui bash root@open-webui:/# ← now inside the container, type exit to leave ────────────────────────────── CLEANUP ────────────────────────────── # Remove a stopped container root@104:~# docker rm open-webui # Remove an image root@104:~# docker rmi ghcr.io/open-webui/open-webui # Clean up everything unused (stopped containers, old images) root@104:~# docker system prune
💡
docker exec -it is powerful Being able to shell into a running container (docker exec -it containername bash) means you can inspect its files, check its internal config, run commands inside it — just like SSH-ing into a CT. Essential for debugging.
🧗 Climb

Docker Compose

Running a single container with docker run works, but real apps need multiple containers working together. Docker Compose describes your whole stack in one file.

What a compose file looks like
This is a docker-compose.yml file. Each service is a container. You write the config once and then just run one command to start everything.
docker-compose.yml — example
services: open-webui: ← name of this container image: ghcr.io/open-webui/open-webui ← which Docker image to use container_name: open-webui restart: unless-stopped ← auto-restart if it crashes ports: - "3000:8080" ← host:container port mapping volumes: - ./open-webui:/app/backend/data ← persist data to ./open-webui folder environment: - OLLAMA_BASE_URL=http://192.168.1.132:11434 ← env variables (settings)
The compose commands
# Navigate to the folder with your compose file first root@104:~# cd /opt/stacks/open-webui/ # Start everything (downloads images if needed) root@104:/opt/stacks/open-webui# docker compose up -d ^ runs in background (detached) # Stop everything root@104:/opt/stacks/open-webui# docker compose down # See status root@104:/opt/stacks/open-webui# docker compose ps # See logs root@104:/opt/stacks/open-webui# docker compose logs -f # Pull new image versions + restart (update) root@104:/opt/stacks/open-webui# docker compose pull && docker compose up -d
📂
Where to keep your compose files on R720xd Convention: one folder per app stack in /opt/stacks/. So: /opt/stacks/jellyfin/docker-compose.yml, /opt/stacks/nextcloud/docker-compose.yml, etc. Then Portainer can find and manage them all through its "Stacks" interface.
🧗 Climb

Portainer — The GUI Layer

Portainer is what makes Docker manageable without memorizing commands. You mentioned it — it's exactly what the name implies: a port (gateway) into your Docker environment.

What Portainer gives you
📋
Containers view
See all running containers at a glance. Start, stop, restart with a click. No docker ps needed.
📦
Stacks
Manage your docker-compose files through the UI. Paste the compose YAML into Portainer and it handles the rest.
📜
Logs
Click any container → Logs. Scrollable, searchable. Same as docker logs -f but visual.
💻
Console
Open a shell inside any container from the browser. Same as docker exec -it bash but without typing it.
💾
Volumes
See all Docker volumes, where they're mounted, how big they are.
🖼️
Images
See downloaded images, pull new ones, delete old ones — all without CLI.
The relationship: CLI ↔ Portainer
Portainer doesn't replace knowing Docker — it translates it into buttons. When something breaks and the UI isn't showing you enough, you'll drop into the shell and use the commands from the previous lessons. Portainer is the 90% case. CLI is the escape hatch.

This is exactly like how Proxmox's web UI handles 90% of your work, but sometimes you drop into the host shell for the detailed stuff.
The plan for R720xd
R720xd Proxmox → Docker VM → Portainer installed first Then deploy all stacks through Portainer Stacks interface: • Jellyfin • Navidrome • Nextcloud • Open WebUI + Ollama • Pi-hole • Nginx Proxy Manager • Frigate NVR • Minecraft / game servers Each stack = one folder in /opt/stacks/ + one compose file Portainer = the Proxmox UI equivalent for all of these
🏆
You've climbed the whole mountain. You now understand Linux fundamentals, can navigate the filesystem without freezing, manage services, decode errors, work with Proxmox containers, understand Docker's mental model, use core Docker commands, and know where Portainer fits. The $1,000 setup is going to make a lot more sense when you're building it.