Most computers on the internet run Linux. Not one Linux — many. Each one is called a distribution, and each one puts its files in slightly different places and installs programs with a different command. Two families cover most of the world: the Debian family, where Ubuntu lives, and the Red Hat family, where Rocky Linux lives. 互联网上大多数计算机跑的是 Linux。不是一个 Linux,而是很多个。 每一个叫做一个发行版,各自把文件放在略微不同的地方,安装程序也用不同的命令。 两大家族覆盖了世界上大部分:Debian 家族(Ubuntu 在里面)和 Red Hat 家族(Rocky Linux 在里面)。 คอมพิวเตอร์ส่วนใหญ่บนอินเทอร์เน็ตรัน Linux ไม่ใช่ Linux ตัวเดียว แต่มีหลายตัว แต่ละตัวเรียกว่า distribution และแต่ละตัววางไฟล์ไว้ต่างกันเล็กน้อย และติดตั้งโปรแกรมด้วยคำสั่งที่ต่างกัน สองตระกูลครอบคลุมเกือบทั้งโลก: ตระกูล Debian ที่มี Ubuntu อยู่ และตระกูล Red Hat ที่มี Rocky Linux อยู่
Learning both used to mean two computers. Now it means two commands. Docker gives you a clean Ubuntu and a clean Rocky in about one second each, and you can throw them away when you break them. That is the best way to learn Linux that has ever existed. 以前想两个都学,得有两台电脑;现在只要两条命令。 Docker 大约一秒钟就给你一个干净的 Ubuntu 和一个干净的 Rocky,弄坏了直接扔掉。 这是有史以来学 Linux 最好的方式。 เมื่อก่อนจะเรียนทั้งสองตัวต้องมีคอมสองเครื่อง ตอนนี้ใช้แค่สองคำสั่ง Docker ให้ Ubuntu สะอาด ๆ และ Rocky สะอาด ๆ ในเวลาประมาณหนึ่งวินาทีต่อตัว พังแล้วก็ทิ้งได้เลย นี่คือวิธีเรียน Linux ที่ดีที่สุดที่เคยมีมา
🐳 You need Docker first. This page assumes Docker is installed and the whale is green. If it is not, the Docker Lab installs it on Windows or a Mac in about fifteen minutes.Today you will learn the words, drive four machines, run both Linuxes side by side, learn the command line, keep files that survive, make two containers talk to each other, and finally leave vim — with a real vim you can practise right here in the page. 今天你会学词、玩四台机器、把两个 Linux 并排跑起来、学命令行、 保住那些不该丢的文件、让两个容器互相通话,最后学会退出 vim —— 页面里就有一个真的 vim 让你练。 วันนี้คุณจะเรียนคำศัพท์ เล่นเครื่องมือสี่ตัว รัน Linux ทั้งสองตัวเทียบกัน เรียนคอมมานด์ไลน์ เก็บไฟล์ให้อยู่รอด ทำให้สองคอนเทนเนอร์คุยกัน และสุดท้ายออกจาก vim ให้ได้ — มี vim จริงให้ฝึกในหน้านี้เลย
Twenty-two words. These are the words a Linux job is done in. They are the same on Ubuntu and on Rocky, even when the commands are different. You will type nearly all of them today. Tap say it to hear one word. Tap tell me more to read a long answer.
二十二个词。做 Linux 这份工作就是用这些词。就算命令不同,这些词在 Ubuntu 和 Rocky 上是一样的。今天你几乎都会亲手敲一遍。点 say it 听发音,点 tell me more 读详细解释。
ยี่สิบสองคำ นี่คือคำที่ใช้ทำงาน Linux คำเหล่านี้เหมือนกันทั้งบน Ubuntu และ Rocky แม้ว่าคำสั่งจะต่างกัน วันนี้คุณจะได้พิมพ์เกือบทุกคำ แตะ say it เพื่อฟังหนึ่งคำ แตะ tell me more เพื่ออ่านคำอธิบายยาว
Each machine shows a real command on the left and what it does on the right. Click the chips. Press the buttons. Every command here was run in a real container before it went on this page. 每台机器左边是真实命令,右边是它做的事。点小标签、按按钮。 这页上每一条命令,都先在真实容器里跑过才写上来。 แต่ละเครื่องแสดงคำสั่งจริงทางซ้าย และผลของมันทางขวา กดชิป กดปุ่ม ทุกคำสั่งในหน้านี้ถูกรันในคอนเทนเนอร์จริงมาก่อนแล้ว
Ubuntu and Rocky do the same jobs with different words. Ubuntu uses apt and packages called deb. Rocky uses dnf, or the older yum, and packages called rpm. Once you know the pairs, you can work on either one. Click a job and read both commands.
Ubuntu 和 Rocky 做同样的事,用的词不一样。Ubuntu 用 apt,包叫 deb;Rocky 用 dnf(或者老一点的 yum),包叫 rpm。你把这些对子记住了,两边都能干活。点一个任务,把两条命令都读一遍。
Ubuntu กับ Rocky ทำงานเดียวกันด้วยคำที่ต่างกัน Ubuntu ใช้ apt แพ็กเกจชื่อ deb ส่วน Rocky ใช้ dnf หรือ yum ตัวเก่ากว่า แพ็กเกจชื่อ rpm พอคุณรู้ว่าคำไหนคู่กับคำไหน คุณก็ทำงานได้ทั้งสองฝั่ง คลิกงานหนึ่งงานแล้วอ่านทั้งสองคำสั่ง
Pick the job you want to do. 选一个你想做的事。 เลือกงานที่คุณต้องการทำ
Open two terminal windows. Put Ubuntu in one and Rocky in the other. Now you can run the same job twice and watch the difference with your own eyes. This is the fastest way to learn both. Each container starts in about one second, and you can delete it without fear.
开两个终端窗口,一个放 Ubuntu,一个放 Rocky。现在同一件事你可以做两遍,亲眼看差别。这是同时学会两个最快的办法。每个容器大约一秒就起来,删掉也不用心疼。
เปิดหน้าต่างเทอร์มินัลสองบาน ใส่ Ubuntu ไว้บานหนึ่ง Rocky อีกบานหนึ่ง ตอนนี้คุณทำงานเดียวกันสองครั้งและเห็นความต่างด้วยตาตัวเองได้ นี่คือวิธีเรียนทั้งสองตัวที่เร็วที่สุด แต่ละคอนเทนเนอร์เริ่มในเวลาประมาณหนึ่งวินาที และลบทิ้งได้โดยไม่ต้องกลัว
Two terminal windows. One command in each. -it means "let me type in it".
两个终端窗口,各敲一条命令。-it 的意思是“让我能在里面打字”。
หน้าต่างเทอร์มินัลสองบาน บานละหนึ่งคำสั่ง -it แปลว่า "ให้ฉันพิมพ์ในนั้นได้"
The prompt changes. You are inside now. The name after the @ is the
container's id.
提示符变了,你已经在里面了。@ 后面那串就是容器的 id。
พรอมต์เปลี่ยนไป คุณอยู่ข้างในแล้ว ข้อความหลัง @ คือ id ของคอนเทนเนอร์
root@id:/#. Rocky writes [root@id /]# with square brackets.
That tiny difference is often the fastest way to tell which window you are typing in.
看这两个提示符:Ubuntu 写成 root@id:/#,
Rocky 写成带方括号的 [root@id /]#。
这个小差别常常是最快分辨你正在哪个窗口打字的办法。
ดูพรอมต์สองอันนี้ Ubuntu เขียนว่า root@id:/#
Rocky เขียนว่า [root@id /]# มีวงเล็บเหลี่ยม
ความต่างเล็ก ๆ นี้มักเป็นวิธีที่เร็วที่สุดในการบอกว่าคุณกำลังพิมพ์อยู่ในหน้าต่างไหนTry to open a file with vim. Try to ping something. Both say command not found. Container images are stripped down to stay small. What surprises people is that the two distributions strip different things out. This table was made by asking both images the same question: 试着用 vim 打开文件、试着 ping 一下——两边都会说 command not found。 容器镜像为了小,被削得很干净。让人意外的是:两个发行版削掉的东西不一样。 下面这张表是向两个镜像问同一个问题得到的: ลองเปิดไฟล์ด้วย vim ลอง ping ดู ทั้งสองฝั่งจะขึ้นว่า command not found อิมเมจคอนเทนเนอร์ถูกตัดให้เล็กที่สุด สิ่งที่ทำให้คนแปลกใจคือสองดิสโทรตัดของคนละอย่าง ตารางนี้ได้มาจากการถามอิมเมจทั้งสองด้วยคำถามเดียวกัน
| Is it there? | ubuntu:24.04 | rockylinux:9 |
|---|---|---|
vim | ✖ no | ✖ no |
vi | ✖ no | ✔ yes |
curl | ✖ no | ✔ yes |
less | ✖ no | ✔ yes |
ps | ✔ yes | ✖ no |
which | ✔ yes | ✖ no |
ping · ip · nano · sudo | ✖ no | ✖ no |
vi and start work immediately. On Ubuntu there is no editor at all — not even
vi — so the very first thing you do is install one. Neither image has
sudo, and neither has ping.
Rocky 自带编辑器,Ubuntu 没有。在 Rocky 上你敲 vi
就能立刻干活;在 Ubuntu 上一个编辑器都没有,连 vi 都没有,
所以你要做的第一件事就是装一个。两边都没有 sudo,也都没有 ping。
Rocky ให้เอดิเตอร์มาด้วย Ubuntu ไม่ให้ บน Rocky พิมพ์ vi
แล้วเริ่มทำงานได้ทันที บน Ubuntu ไม่มีเอดิเตอร์เลย แม้แต่ vi
สิ่งแรกที่คุณต้องทำจึงคือติดตั้งสักตัว ทั้งสองฝั่งไม่มี sudo และไม่มี pingOn Ubuntu you must fetch the shop list first. On Rocky you do not — dnf
refreshes by itself.
在 Ubuntu 上你必须先取回商店清单;在 Rocky 上不用——dnf 会自己刷新。
บน Ubuntu คุณต้องไปเอารายการสินค้ามาก่อน บน Rocky ไม่ต้อง —
dnf รีเฟรชเอง
Three package names are different for the same three programs. That is most of what "knowing two distributions" really means. 同样三个程序,包名有三个不一样。所谓“懂两个发行版”,大部分就是这种事。 โปรแกรมสามตัวเดียวกัน แต่ชื่อแพ็กเกจต่างกันสามชื่อ นั่นคือความหมายส่วนใหญ่ของคำว่า "รู้สองดิสโทร"
update on Ubuntu and install will
fail. apt-get install reads a shop list that a fresh image does not have
yet. The error says Unable to locate package, which sounds like the package
does not exist. It does exist. You just never asked for the list.
在 Ubuntu 上忘了 update,install 就会失败。
apt-get install 要读一份商店清单,而新镜像里还没有。
报错写着 Unable to locate package,听起来像这个包不存在——它存在,
只是你没先取清单。
ถ้าลืม update บน Ubuntu แล้ว install จะล้มเหลว
apt-get install ต้องอ่านรายการสินค้าที่อิมเมจใหม่ยังไม่มี
ข้อความผิดพลาดเขียนว่า Unable to locate package
ซึ่งฟังเหมือนว่าไม่มีแพ็กเกจนี้ มันมีอยู่ คุณแค่ยังไม่ได้ขอรายการYou will write scripts that must work on both. Do not guess from the name — read
/etc/os-release, which every modern distribution has. The useful line is
ID_LIKE: it names the family, so your script keeps working on Alma,
Fedora or Debian too. This is real output from both containers:
你会写需要在两边都能跑的脚本。不要靠名字猜——读 /etc/os-release,
每个现代发行版都有。有用的是 ID_LIKE 那一行:它写的是家族,
所以你的脚本在 Alma、Fedora 或 Debian 上也照样能用。下面是两个容器的真实输出:
คุณจะเขียนสคริปต์ที่ต้องทำงานได้ทั้งสองฝั่ง อย่าเดาจากชื่อ —
ให้อ่าน /etc/os-release ซึ่งทุกดิสโทรสมัยใหม่มี บรรทัดที่มีประโยชน์คือ
ID_LIKE มันบอกตระกูล สคริปต์ของคุณจึงยังทำงานได้บน Alma, Fedora
หรือ Debian ด้วย นี่คือผลลัพธ์จริงจากทั้งสองคอนเทนเนอร์
Notice that Rocky still says centos in its family list, and that
/etc/redhat-release exists on Rocky and reads
Rocky Linux release 9.3 (Blue Onyx). That is deliberate: old scripts written
for Red Hat and CentOS keep working without a single change.
注意 Rocky 的家族列表里仍然写着 centos,
而且 Rocky 上有 /etc/redhat-release,内容是
Rocky Linux release 9.3 (Blue Onyx)。这是故意的:
为 Red Hat 和 CentOS 写的老脚本一行都不用改,照样能跑。
สังเกตว่า Rocky ยังเขียนว่า centos ในรายการตระกูลของมัน
และบน Rocky มี /etc/redhat-release ซึ่งเขียนว่า
Rocky Linux release 9.3 (Blue Onyx) นี่เป็นความตั้งใจ:
สคริปต์เก่าที่เขียนให้ Red Hat และ CentOS ยังทำงานได้โดยไม่ต้องแก้แม้แต่บรรทัดเดียว
| The job | Ubuntu · Debian family | Rocky Linux · Red Hat family |
|---|---|---|
| Which Linux is this? | cat /etc/os-release | cat /etc/redhat-release |
| Refresh the shop list | apt-get update | dnf check-update |
| Install a program | apt-get install -y vim | dnf install -y vim-enhanced |
| Remove a program | apt-get remove -y vim | dnf remove -y vim-enhanced |
| Search for a program | apt-cache search editor | dnf search editor |
| What is installed? | dpkg -l | rpm -qa |
| Which package owns this file? | dpkg -S /usr/bin/vim | rpm -qf /usr/bin/vim |
| The package file itself | something.deb | something.rpm |
| Where the shop list lives | /etc/apt/sources.list.d/ | /etc/yum.repos.d/ |
| Network tools package | iproute2 · iputils-ping | iproute · iputils |
| Add a normal user | adduser ploy | useradd ploy |
| The group that grants sudo | sudo | wheel |
| Read the system log | /var/log/syslog | /var/log/messages |
systemctl does not work in a container, on either
distribution. A container runs one program, not a whole booted system, so there is no
service manager listening. You will see Failed to get D-Bus connection. That is
normal and it is not broken. In a container you start programs yourself, or you let the
image's own start command do it.
在容器里,systemctl 两个发行版都用不了。
容器跑的是一个程序,不是一整套启动好的系统,所以没有服务管理器在听。
你会看到 Failed to get D-Bus connection。这是正常的,没坏。
在容器里你自己启动程序,或者交给镜像自带的启动命令。
systemctl ใช้ไม่ได้ในคอนเทนเนอร์ ทั้งสองดิสโทร
คอนเทนเนอร์รันโปรแกรมเดียว ไม่ใช่ระบบที่บูตครบ จึงไม่มีตัวจัดการเซอร์วิสคอยฟังอยู่
คุณจะเห็นข้อความ Failed to get D-Bus connection นี่เป็นเรื่องปกติ ไม่ได้พัง
ในคอนเทนเนอร์คุณเริ่มโปรแกรมเอง หรือให้คำสั่งเริ่มต้นของอิมเมจทำให้The shell reads one line and does one thing. It looks old, but it is faster than any window, and it is the only way into most servers. About twenty commands cover almost every day. Learn those twenty and four keys, and Linux stops being frightening.
Shell 读一行、做一件事。它看着很老,但比任何窗口都快,而且大多数服务器只能这样进去。大约二十条命令就能覆盖几乎每一天。学会这二十条加四个按键,Linux 就不吓人了。
เชลล์อ่านหนึ่งบรรทัดแล้วทำหนึ่งอย่าง มันดูเก่า แต่เร็วกว่าหน้าต่างใด ๆ และเป็นทางเดียวที่เข้าเซิร์ฟเวอร์ส่วนใหญ่ได้ ประมาณยี่สิบคำสั่งครอบคลุมเกือบทุกวัน เรียนยี่สิบคำสั่งนี้กับปุ่มสี่ปุ่ม แล้ว Linux จะไม่น่ากลัวอีก
In a container you are usually root already, so
you almost never need sudo here. On a real server you are not root, and you put
sudo in front of anything that changes the system.
在容器里你通常已经是 root,所以这里几乎不需要 sudo。
在真实服务器上你不是 root,凡是要改动系统的命令前面都要加 sudo。
ในคอนเทนเนอร์คุณมักเป็น root อยู่แล้ว จึงแทบไม่ต้องใช้ sudo ที่นี่
บนเซิร์ฟเวอร์จริงคุณไม่ใช่ root และต้องใส่ sudo ข้างหน้าทุกคำสั่งที่เปลี่ยนระบบ
exit.
Ctrl+D —— 我这儿完事了。
在容器里按它就是退出,跟输入 exit 一样。
Ctrl+D — ฉันเสร็จแล้ว
ในคอนเทนเนอร์ การกดปุ่มนี้คือออกจากมัน เหมือนพิมพ์ exitThe shell writes down every command you type. That list is the history, and it is numbered. Going back through it is the biggest speed-up available to you, and it is free. Shell 会把你输入的每一条命令记下来,这份清单就是历史记录,而且是带编号的。 回头去用它,是你能得到的最大提速,而且免费。 เชลล์จดทุกคำสั่งที่คุณพิมพ์ไว้ รายการนั้นเรียกว่า history และมีเลขกำกับ การย้อนกลับไปใช้มันคือการเร่งความเร็วที่ใหญ่ที่สุดที่คุณหาได้ และฟรี
Now you can run any of them again by number. This is what the exclamation mark is for. The shell prints the command first, so you always see what you are about to run. 然后你就可以按编号再跑其中任何一条——感叹号就是干这个的。 Shell 会先把命令打出来,所以你总能看到自己要跑的是什么。 ทีนี้คุณรันอันไหนซ้ำก็ได้ด้วยเลขของมัน — เครื่องหมายตกใจมีไว้เพื่อสิ่งนี้ เชลล์จะพิมพ์คำสั่งออกมาก่อน คุณจึงเห็นเสมอว่ากำลังจะรันอะไร
!$ is the quiet favourite. You type
ls /var/log/nginx/error.log, it is there, and now you want to read it. Type
less !$ and the shell fills in that long path for you. No copying, no retyping,
no typo.
!$ 是低调的最爱。你敲了
ls /var/log/nginx/error.log,文件在,现在你想读它——
敲 less !$,shell 会把那条长路径替你填进去。不用复制、不用重打、不会打错。
!$ คือของโปรดแบบเงียบ ๆ คุณพิมพ์
ls /var/log/nginx/error.log ไฟล์อยู่จริง ตอนนี้คุณอยากอ่านมัน
พิมพ์ less !$ แล้วเชลล์จะเติมพาธยาว ๆ นั้นให้เอง
ไม่ต้องคัดลอก ไม่ต้องพิมพ์ใหม่ ไม่พิมพ์ผิด~/.bash_history, and it is written when the
shell closes — not as you go. That is why a terminal you killed loses its history.
这份清单存在哪里:~/.bash_history,
而且是在 shell 关闭时才写进去,不是边打边写。所以被强制杀掉的终端会丢历史。
รายการเก็บไว้ที่ไหน: ~/.bash_history
และเขียนตอนเชลล์ปิด ไม่ใช่เขียนไปเรื่อย ๆ
จึงเป็นเหตุผลที่เทอร์มินัลที่ถูกฆ่าทิ้งจะเสียประวัติไป!! and !42 only work in an interactive shell. Inside a
script, or after bash -c, history expansion is switched off. This is the real
error:
关于历史记录,有两点常让人踩坑:!! 和 !42 只在交互式 shell 里有效。
在脚本里,或者用 bash -c 之后,历史展开是关闭的。这是真实的报错:
สองเรื่องเกี่ยวกับ history ที่ทำให้คนสะดุด!! และ !42 ใช้ได้แค่ในเชลล์แบบอินเทอร์แอกทีฟ
ในสคริปต์ หรือหลัง bash -c การขยาย history จะถูกปิด นี่คือข้อผิดพลาดจริง:On a real server you do not work as root.
You work as yourself and put sudo in front of the commands that change the
machine. It asks for your password, does one thing with full power, and hands the
power straight back.
在真实服务器上你不用 root 干活。你用自己的身份,
在要改动机器的命令前面加 sudo。它会问你自己的密码,
用完整权限做一件事,然后立刻把权限交回去。
บนเซิร์ฟเวอร์จริง คุณไม่ทำงานเป็น root
คุณทำงานเป็นตัวคุณเอง และใส่ sudo ข้างหน้าคำสั่งที่เปลี่ยนเครื่อง
มันจะถามรหัสผ่านของคุณ ทำหนึ่งอย่างด้วยอำนาจเต็ม แล้วคืนอำนาจทันที
sudo !! — the most loved two-word command in Linux.
You type a command, you forget sudo, and it says
Permission denied. Do not retype it. sudo !! takes the last
command out of the history and runs it again with root. This is history and sudo working
together, and you will use it for the rest of your life.
sudo !! —— Linux 里最受喜爱的两个词。
你敲了一条命令,忘了加 sudo,它回你 Permission denied。
别重打——sudo !! 会把历史里的上一条命令取出来,用 root 再跑一遍。
这是历史记录和 sudo 联手,你会用它一辈子。
sudo !! — คำสั่งสองคำที่คนรักที่สุดใน Linux
คุณพิมพ์คำสั่ง ลืมใส่ sudo แล้วมันตอบว่า Permission denied
อย่าพิมพ์ใหม่ sudo !! จะดึงคำสั่งล่าสุดจากประวัติมารันซ้ำด้วยสิทธิ์ root
นี่คือ history กับ sudo ทำงานร่วมกัน และคุณจะใช้มันไปตลอดชีวิตYou are allowed to use sudo because you
are in a special group — and the two families named that group differently. This is a real
difference that costs people time, and it is easy to check.
你能用 sudo,是因为你在一个特殊的组里——
而两大家族给这个组起了不同的名字。这是一个会浪费时间的真实差别,好在很容易查。
คุณใช้ sudo ได้เพราะคุณอยู่ในกลุ่มพิเศษ —
และสองตระกูลตั้งชื่อกลุ่มนั้นไม่เหมือนกัน นี่คือความต่างจริงที่ทำให้คนเสียเวลา และตรวจง่าย
sudo is not installed in any of these container
images. Not in ubuntu:24.04
and not in rockylinux:9. You will see bash: sudo: command not found, and that is
correct — you are already root in a container, so there is nothing to borrow. Install it only
if you want to practise being a normal user.
这三个容器镜像里都没有装 sudo:
ubuntu:24.04 没有,rockylinux:9 也没有。
你会看到 bash: sudo: command not found——这是对的:
在容器里你本来就是 root,没什么可借的。只有当你想练习“当普通用户”时才需要装它。
sudo ไม่ได้ติดตั้งในอิมเมจคอนเทนเนอร์เหล่านี้เลย
ไม่มีใน ubuntu:24.04 และไม่มีใน rockylinux:9
คุณจะเห็น bash: sudo: command not found ซึ่งถูกต้อง —
คุณเป็น root อยู่แล้วในคอนเทนเนอร์ จึงไม่มีอะไรต้องยืม
ติดตั้งมันเฉพาะเมื่อคุณอยากฝึกเป็นผู้ใช้ธรรมดา/etc/sudoers with a normal editor. Use
visudo. It opens the same file, but it checks the file makes sense before it
saves. One bad line in that file and nobody can use sudo any more, including you —
on a remote server that means you are locked out for good.
绝不要用普通编辑器改 /etc/sudoers。
用 visudo:它打开的是同一个文件,但会在保存前检查语法。
那个文件里写错一行,所有人都用不了 sudo,包括你——
在远程服务器上,这意味着你被永久锁在外面。
อย่าแก้ /etc/sudoers ด้วยเอดิเตอร์ธรรมดาเด็ดขาด
ให้ใช้ visudo มันเปิดไฟล์เดียวกัน แต่ตรวจว่าไฟล์ถูกต้องก่อนบันทึก
ผิดบรรทัดเดียวในไฟล์นั้น ไม่มีใครใช้ sudo ได้อีก รวมทั้งคุณเอง —
บนเซิร์ฟเวอร์ระยะไกลนั่นหมายถึงคุณถูกล็อกออกอย่างถาวรtail -f is how the job is really done. When something is
broken on a server, you open the log with tail -f in one window, then make the
problem happen in another window, and watch the error arrive. Learn this one properly.
tail -f 才是真正干活的方式。服务器出问题时,
在一个窗口用 tail -f 打开日志,在另一个窗口把问题重现一遍,
看着错误自己出现。这一条要好好学。
tail -f คือวิธีทำงานจริง
เวลามีอะไรพังบนเซิร์ฟเวอร์ ให้เปิดล็อกด้วย tail -f ในหน้าต่างหนึ่ง
แล้วไปทำให้ปัญหาเกิดในอีกหน้าต่าง และดูข้อผิดพลาดโผล่มา เรียนอันนี้ให้ดีrm is final. There is no
"are you sure?", no undo, and no undelete. Before any rm -r, run the same path
with ls first and read what it prints. This one habit will save you one very
bad afternoon. And never type rm -rf / — it means "delete everything".
没有回收站。rm 是不可逆的:不会问“你确定吗”,
没有撤销,也没有恢复。每次要 rm -r 之前,先用 ls
跑一遍同样的路径,把它列出来的东西读一遍。这个习惯能救你一个很糟糕的下午。
永远不要输入 rm -rf /——那是“删掉一切”。
ไม่มีถังขยะ rm คือจบเลย ไม่มีคำถามว่า "แน่ใจไหม"
ไม่มีการย้อนกลับ และกู้คืนไม่ได้ ก่อนใช้ rm -r ทุกครั้ง
ให้รัน ls กับพาธเดียวกันก่อน แล้วอ่านสิ่งที่มันแสดง
นิสัยข้อเดียวนี้จะช่วยคุณจากบ่ายวันที่แย่มากหนึ่งวัน
และอย่าพิมพ์ rm -rf / เด็ดขาด — มันหมายถึง "ลบทุกอย่าง"This is the idea that makes Linux powerful. Each
command is small. The pipe | sends the answer of one into the next.
这就是让 Linux 强大的那个想法:每条命令都很小,
管道 | 把一条命令的答案送进下一条。
นี่คือแนวคิดที่ทำให้ Linux ทรงพลัง แต่ละคำสั่งเล็ก ๆ
ไปป์ | ส่งคำตอบของคำสั่งหนึ่งเข้าไปในคำสั่งถัดไป
> or two changes everything. One
> empties the file first. Two >> add to the bottom. People
overwrite a good file with one arrow and no warning at all.
一个 > 还是两个,结果完全不同。
一个 > 会先把文件清空;两个 >> 追加到末尾。
很多人就是用一个箭头,把一个好文件无声无息地覆盖掉了。
> อันเดียวหรือสองอัน เปลี่ยนทุกอย่าง
> อันเดียวจะล้างไฟล์ก่อน สองอัน >> จะต่อท้าย
หลายคนเขียนทับไฟล์ดี ๆ ด้วยลูกศรอันเดียว โดยไม่มีคำเตือนอะไรเลยdrwxr-xr-x644 means owner 6, group 4, everyone 4. That is the most common number you
will ever type.
那些数字是怎么来的?读是 4,写是 2,执行是 1,
三组各自相加。所以 6 是读加写,7 是三样全有。
644 就是拥有者 6、组 4、其他人 4——这是你最常敲的一个数字。
ทำไมเป็นตัวเลข? อ่านคือ 4 เขียนคือ 2 รันคือ 1
บวกกันในแต่ละกลุ่มทั้งสามกลุ่ม ดังนั้น 6 คืออ่านบวกเขียน และ 7 คือครบทั้งสาม
644 คือเจ้าของ 6 กลุ่ม 4 คนอื่น 4 นี่คือตัวเลขที่คุณจะพิมพ์บ่อยที่สุดA container forgets everything when you delete it. That is on purpose, and it is good. But your database and your work must not be forgotten. There are two ways to keep files: a volume, which Docker looks after, and a bind mount, which is a folder from your own computer. Learn when to use each.
容器被删掉时会忘掉一切。这是故意设计的,而且是好事。但你的数据库和你的工作不能被忘掉。保住文件有两种办法:数据卷(Docker 替你保管)和绑定挂载(就是你自己电脑上的一个文件夹)。要学会什么时候用哪个。
คอนเทนเนอร์ลืมทุกอย่างเมื่อคุณลบมัน นั่นเป็นความตั้งใจ และเป็นเรื่องดี แต่ฐานข้อมูลและงานของคุณต้องไม่ถูกลืม มีสองวิธีเก็บไฟล์: วอลลุมที่ Docker ดูแลให้ และไบนด์เมาต์ซึ่งคือโฟลเดอร์จากเครื่องของคุณเอง เรียนรู้ว่าเมื่อไรควรใช้อันไหน
Docker makes it and looks after it. You never need to know where it is on the disk. Best for data a program owns: databases, uploads, caches. Docker 建它、管它,你不用知道它在硬盘哪里。 最适合程序自己拥有的数据:数据库、上传文件、缓存。 Docker สร้างและดูแลให้ คุณไม่ต้องรู้ว่ามันอยู่ที่ไหนบนดิสก์ เหมาะที่สุดกับข้อมูลที่โปรแกรมเป็นเจ้าของ: ฐานข้อมูล ไฟล์อัปโหลด แคช
A real folder from your computer, appearing inside the container. Best for files you edit: your code, a settings file. Edit on your computer, the container sees it at once. 你电脑上一个真实的文件夹,出现在容器里面。 最适合你要编辑的文件:你的代码、配置文件。你在电脑上改,容器立刻就看到。 โฟลเดอร์จริงจากเครื่องคุณ ที่ไปปรากฏอยู่ข้างในคอนเทนเนอร์ เหมาะที่สุดกับไฟล์ที่คุณแก้: โค้ดของคุณ ไฟล์ตั้งค่า แก้บนเครื่องคุณ คอนเทนเนอร์เห็นทันที
Run these four commands in order. They are exactly the commands used to test this section, and the output below is the real output. 按顺序跑这四条命令。它们就是用来验证这一节的那几条,下面的输出是真实输出。 รันสี่คำสั่งนี้ตามลำดับ นี่คือคำสั่งที่ใช้ทดสอบหัวข้อนี้จริง ๆ และผลลัพธ์ข้างล่างคือผลลัพธ์จริง
The volume kept the file. The container's own file died with the container. That is the whole lesson, and it cost somebody a database to learn. 数据卷把文件留住了;容器自己的文件跟着容器一起死了。 这就是全部要点——曾经有人是丢了一个数据库才学到的。 วอลลุมเก็บไฟล์ไว้ได้ ไฟล์ในตัวคอนเทนเนอร์เองตายไปพร้อมคอนเทนเนอร์ นี่คือบทเรียนทั้งหมด และมีคนต้องเสียฐานข้อมูลไปหนึ่งก้อนเพื่อเรียนรู้มัน
docker volume prune is the dangerous one. It deletes
every volume that no container is using right now. A stopped project's database
counts as "not in use". Read the list it offers you before you say yes.
docker volume prune 是危险的那个。
它会删掉此刻没有容器在用的每一个数据卷——一个停掉的项目的数据库也算“没在用”。
在你点“是”之前,先把它列出来的清单读一遍。
docker volume prune คืออันที่อันตราย
มันลบทุกวอลลุมที่ไม่มีคอนเทนเนอร์ใช้อยู่ในขณะนั้น
ฐานข้อมูลของโปรเจกต์ที่หยุดอยู่ก็นับว่า "ไม่ได้ใช้" อ่านรายการที่มันเสนอให้ก่อนตอบตกลงThe syntax for "this folder, here" is different on the two systems, because the way they write a folder name is different. “这个文件夹,放到这里”的写法在两种系统上不同,因为它们写文件夹名字的方式不同。 ไวยากรณ์ของ "โฟลเดอร์นี้ ไปไว้ที่นี่" ต่างกันในสองระบบ เพราะวิธีเขียนชื่อโฟลเดอร์ต่างกัน
/etc, the container's real /etc is not deleted — it is
covered up, like putting a rug over a floor. Take the mount away and the floor is still
there. Mounting over a folder the program needs is a very confusing way to break it.
绑定挂载会盖住原来的东西。如果你把一个文件夹挂到 /etc 上,
容器里真正的 /etc 并没有被删掉——只是被盖住了,像地板上铺了块地毯。
把挂载去掉,地板还在。挂到程序需要的目录上,是一种非常令人困惑的弄坏方式。
ไบนด์เมาต์ปิดทับสิ่งที่มีอยู่เดิม
ถ้าคุณเมาต์โฟลเดอร์ทับ /etc ตัว /etc จริงในคอนเทนเนอร์ไม่ได้ถูกลบ
แต่ถูกปิดทับ เหมือนปูพรมทับพื้น เอาเมาต์ออกแล้วพื้นก็ยังอยู่
การเมาต์ทับโฟลเดอร์ที่โปรแกรมต้องใช้เป็นวิธีทำให้พังที่ทำให้สับสนมาก$PWD is only a shortcut for "the folder I am standing in". You can name any
folder on your computer instead, and that is how you reach a big external disk, a photo
library, or a project that lives somewhere else.
$PWD 只是“我现在所在的文件夹”的简写。
你可以换成你电脑上任何一个文件夹——外接大硬盘、照片库,或者放在别处的项目,就是这样接进来的。
$PWD เป็นแค่ทางย่อของ "โฟลเดอร์ที่ฉันยืนอยู่"
คุณใส่ชื่อโฟลเดอร์ไหนบนเครื่องก็ได้ และนั่นคือวิธีเข้าถึงฮาร์ดดิสก์ภายนอกตัวใหญ่
คลังรูปภาพ หรือโปรเจกต์ที่อยู่ที่อื่น
C:/Users/Admin/projects, not C:\Users\Admin\projects. Docker
understands the forward-slash form on every system, and the backslash form causes strange
errors that do not name the real problem. If the path has a space in it, keep the whole
thing in quotes.
Windows:请用正斜杠。写 C:/Users/Admin/projects,
不要写 C:\Users\Admin\projects。正斜杠形式在所有系统上 Docker 都认,
反斜杠会引出一些看不出真正原因的怪错误。路径里有空格时,整个用引号括起来。
Windows: ให้ใช้ขีดทับไปหน้า เขียน C:/Users/Admin/projects
ไม่ใช่ C:\Users\Admin\projects Docker เข้าใจแบบขีดทับไปหน้าในทุกระบบ
ส่วนแบบขีดทับกลับหลังทำให้เกิดข้อผิดพลาดแปลก ๆ ที่ไม่บอกสาเหตุจริง
ถ้าพาธมีช่องว่าง ให้ครอบทั้งหมดด้วยเครื่องหมายคำพูดAdd :ro at the end and the container can look but not touch. Use this for
anything you would be sad to lose: your photos, your only copy of something, a folder you
are only letting a program read.
在末尾加 :ro,容器就只能看不能动。
任何你丢了会心疼的东西都该这样挂:你的照片、某个唯一的副本、
或者只是让程序读一读的文件夹。
เติม :ro ท้ายสุด แล้วคอนเทนเนอร์จะดูได้แต่แตะไม่ได้
ใช้กับอะไรที่คุณจะเสียใจถ้าหาย: รูปถ่ายของคุณ สำเนาชิ้นเดียวที่มี
หรือโฟลเดอร์ที่คุณให้โปรแกรมอ่านอย่างเดียว
You do not have to share a whole folder. One file works, which is the neat way to drop a settings file into a container without rebuilding the image. 不一定要共享整个文件夹,一个文件也行—— 这是把配置文件塞进容器而不用重建镜像的漂亮做法。 คุณไม่จำเป็นต้องแชร์ทั้งโฟลเดอร์ ไฟล์เดียวก็ได้ ซึ่งเป็นวิธีสวย ๆ ในการยัดไฟล์ตั้งค่าเข้าไปในคอนเทนเนอร์โดยไม่ต้องสร้างอิมเมจใหม่
Real projects often use --mount instead of -v. It is more
typing, but every part is named, so you can read it a year later and still know what it
does. It also fails loudly if the folder does not exist, while -v silently
creates an empty one — which is the cause of a lot of "where did my files go?".
真实项目里常用 --mount 代替 -v。
字打得多一点,但每一部分都有名字,一年后再看也知道它在干什么。
而且如果文件夹不存在,它会明确报错;-v 会悄悄建一个空的——
这正是很多“我的文件哪去了?”的来源。
โปรเจกต์จริงมักใช้ --mount แทน -v
พิมพ์มากกว่า แต่ทุกส่วนมีชื่อกำกับ อ่านอีกทีในอีกหนึ่งปีก็ยังรู้ว่ามันทำอะไร
และมันจะแจ้งข้อผิดพลาดชัดเจนถ้าโฟลเดอร์ไม่มีอยู่ ขณะที่ -v
จะสร้างโฟลเดอร์เปล่าให้เงียบ ๆ ซึ่งเป็นต้นเหตุของคำถาม "ไฟล์ฉันหายไปไหน" จำนวนมาก
Useful when you only need one file and cannot be bothered with a volume. 只需要传一个文件、又懒得弄数据卷的时候很好用。 มีประโยชน์เวลาคุณต้องการแค่ไฟล์เดียวและไม่อยากยุ่งกับวอลลุม
Every container gets its own address, and that address changes. So you never use addresses. You make your own network and then containers can find each other by name. On the network Docker gives you by default, names do not work, and that costs beginners a whole evening. One extra command fixes it for ever.
每个容器都有自己的地址,而地址会变,所以你永远不用地址。你自己建一个网络,容器就能靠名字找到彼此。在 Docker 默认给你的网络里,名字不管用——这会让新手浪费一整个晚上。多敲一条命令就永久解决了。
คอนเทนเนอร์แต่ละตัวมีที่อยู่ของตัวเอง และที่อยู่นั้นเปลี่ยนได้ คุณจึงไม่ใช้ที่อยู่เลย ให้สร้างเน็ตเวิร์กของคุณเอง แล้วคอนเทนเนอร์จะหากันด้วยชื่อได้ บนเน็ตเวิร์กที่ Docker ให้มาโดยปริยาย ชื่อใช้ไม่ได้ และเรื่องนี้ทำให้มือใหม่เสียเวลาไปทั้งเย็น คำสั่งเพิ่มอันเดียวแก้ได้ตลอดไป
Now put every container that must talk to the others on labnet.
现在把所有需要互相通话的容器都放到 labnet 上。
ตอนนี้เอาทุกคอนเทนเนอร์ที่ต้องคุยกันไปไว้บน labnet
Inside app, ask for web by name. On labnet it
answers. On the default network it does not. Both of these were run for real:
在 app 里面用名字找 web。
在 labnet 上它会回答,在默认网络上不会。下面两个都是真的跑过的:
ข้างใน app ให้ถามหา web ด้วยชื่อ
บน labnet มันตอบ บนเน็ตเวิร์กปริยายมันไม่ตอบ ทั้งสองอันนี้รันจริงมาแล้ว
Once names work, you can talk to it properly. web here is a real web server,
so ask it for a page:
名字能用之后就可以正常通话了。这里的 web 是一个真的网页服务器,
去要一个页面看看:
พอชื่อใช้ได้แล้ว คุณก็คุยกับมันได้จริง ๆ web ที่นี่คือเว็บเซิร์ฟเวอร์จริง
ลองขอหน้าเว็บจากมันดู
Remember that ip is not installed in the Ubuntu image. There is a way that
always works, in every image, with nothing installed:
记住 Ubuntu 镜像里没装 ip。有一个办法在任何镜像里、
什么都不用装就永远好用:
จำไว้ว่าอิมเมจ Ubuntu ไม่ได้ติดตั้ง ip
มีวิธีที่ใช้ได้เสมอในทุกอิมเมจ โดยไม่ต้องติดตั้งอะไรเลย
localhost inside a container means the container itself — not
your computer. A program looking for a database on localhost inside a
container will never find one running next door. Use the other container's
name.
容器里的 localhost 指的是这个容器本身,
不是你的电脑。容器里的程序去 localhost 找数据库,
永远找不到隔壁那个。要用另一个容器的名字。
localhost ข้างในคอนเทนเนอร์หมายถึงตัวคอนเทนเนอร์เอง
ไม่ใช่เครื่องคุณ โปรแกรมที่หาฐานข้อมูลที่ localhost ข้างในคอนเทนเนอร์
จะไม่เจอตัวที่รันอยู่ข้าง ๆ เลย ให้ใช้ชื่อของคอนเทนเนอร์อีกตัวhost.docker.internal. It works on Docker Desktop for Windows and Mac.
要从容器里访问你自己的电脑,用
host.docker.internal。在 Windows 和 Mac 的 Docker Desktop 上有效。
ถ้าจะเข้าถึงเครื่องของคุณเองจากในคอนเทนเนอร์
ให้ใช้ host.docker.internal ใช้ได้บน Docker Desktop ทั้ง Windows และ Mac| What you want | What you write | Who can reach it |
|---|---|---|
| Container to container | --network labnet, then use the name | only containers on that network |
| You, in your browser | -p 8080:80 | anything on your computer |
-p is only for you and your browser. Containers talking to each other do
not need -p at all — a very common piece of extra typing.
-p 只是为了你和你的浏览器。容器之间互相通话完全不需要
-p——这是很常见的多余输入。
-p มีไว้สำหรับคุณกับเบราว์เซอร์ของคุณเท่านั้น
คอนเทนเนอร์ที่คุยกันเองไม่ต้องใช้ -p เลย
นี่คือการพิมพ์เกินที่พบบ่อยมาก
One day you will open vim by accident and not be able to leave. Everybody has done it. vim is strange for one reason only: the keys do different things at different times. That is called a mode. Learn the modes and vim becomes the fastest editor you have. Practise on the real editor below, in this page.
总有一天你会不小心打开 vim,然后出不来。每个人都经历过。vim 之所以奇怪只有一个原因:同一个按键在不同时候做不同的事,这叫“模式”。把模式学会,vim 就是你手上最快的编辑器。就在下面这个真的编辑器里练。
วันหนึ่งคุณจะเปิด vim โดยไม่ได้ตั้งใจ แล้วออกไม่ได้ ทุกคนเคยเจอ vim แปลกเพราะเหตุผลเดียว คือปุ่มเดียวกันทำงานต่างกันในเวลาต่างกัน สิ่งนั้นเรียกว่าโหมด เรียนโหมดให้เข้าใจ แล้ว vim จะเป็นเอดิเตอร์ที่เร็วที่สุดที่คุณมี ฝึกกับเอดิเตอร์จริงข้างล่างในหน้านี้ได้เลย
:q! and press Enter. That leaves and throws away your changes.
It always works. Memorise it now and the fear is gone.
先给你逃生出口:按 Esc,输入 :q!,按
Enter。这会退出并丢掉你的改动。它永远有效。现在就背下来,恐惧就没了。
ทางออกฉุกเฉิน ก่อนอย่างอื่นทั้งหมด กด Esc
แล้วพิมพ์ :q! และกด Enter นั่นคือออกและทิ้งการแก้ไขทั้งหมด
ใช้ได้เสมอ จำไว้เดี๋ยวนี้ แล้วความกลัวก็หมดไปBecause vim is on every Linux server, always, with nothing installed. One day you will be fixing a broken machine over a slow connection with no graphical screen, and vim will be the only editor there. That day, ten minutes of practice today is worth a great deal. 因为 vim 在每一台 Linux 服务器上都有,永远都有,什么都不用装。 总有一天你会在一条很慢的连接上修一台坏机器、没有图形界面,而 vim 是那里唯一的编辑器。 到那天,今天这十分钟的练习会非常值钱。 เพราะ vim มีอยู่บนเซิร์ฟเวอร์ Linux ทุกเครื่อง เสมอ โดยไม่ต้องติดตั้งอะไร วันหนึ่งคุณจะต้องซ่อมเครื่องที่พังผ่านการเชื่อมต่อที่ช้าและไม่มีหน้าจอกราฟิก และ vim จะเป็นเอดิเตอร์เดียวที่นั่น วันนั้น การฝึกสิบนาทีในวันนี้จะมีค่ามาก
vi. On a real Ubuntu server vim is
there. In the container you install it first.
但在新的 Ubuntu 容器里例外。还记得第 3 节吗——
官方 Ubuntu 镜像里没有 vim,连 vi 都没有。真实的 Ubuntu 服务器上是有的;
在容器里你得先装。
ยกเว้นในคอนเทนเนอร์ Ubuntu ใหม่ จำหัวข้อ 3 ได้ไหม —
อิมเมจ Ubuntu ทางการไม่มี vim และไม่มีแม้แต่ vi
บนเซิร์ฟเวอร์ Ubuntu จริงมี vim อยู่ ในคอนเทนเนอร์คุณต้องติดตั้งก่อนw to write, q to quit.
COMMAND(命令模式)—— 按 : 进来。
底部会出现一行,你在那里输入完整的词:w 是保存,q 是退出。
COMMAND — กด : เพื่อเข้ามา
จะมีบรรทัดเปิดขึ้นด้านล่าง แล้วคุณพิมพ์เป็นคำ: w คือบันทึก
q คือออกClick the black box, then type. It behaves like the real thing: the keys do nothing until you understand the mode you are in. Nothing here can break anything. 点一下那个黑框,然后开始打字。它的行为和真的一样: 在你搞清楚自己在哪个模式之前,按键什么也不会做。这里怎么弄都弄不坏东西。 คลิกกล่องสีดำ แล้วพิมพ์ มันทำงานเหมือนของจริง ปุ่มจะไม่ทำอะไรจนกว่าคุณจะเข้าใจว่าคุณอยู่โหมดไหน ที่นี่ทำอะไรก็ไม่พัง
vimtutor and press Enter. It takes
thirty minutes and it is the best half hour you can spend on this.
准备好玩真的时候:每台 Linux 机器上都已经装好了一门免费完整教程。
输入 vimtutor 回车。三十分钟,这是你能花在这件事上最值的半小时。
เมื่อคุณพร้อมสำหรับของจริง มีคอร์สฟรีเต็มรูปแบบติดตั้งอยู่บนเครื่อง Linux ทุกเครื่องแล้ว
พิมพ์ vimtutor แล้วกด Enter ใช้เวลาสามสิบนาที
และเป็นครึ่งชั่วโมงที่คุ้มค่าที่สุดที่คุณจะใช้กับเรื่องนี้Both of those use --rm, so the container
deletes itself when you leave. You can do this as many times as you like and your computer
stays clean.
这两条都用了 --rm,你一退出容器就自己删掉了。
你想练几次都行,电脑还是干干净净。
ทั้งสองอันใช้ --rm คอนเทนเนอร์จะลบตัวเองเมื่อคุณออก
คุณทำซ้ำกี่ครั้งก็ได้ และเครื่องของคุณยังสะอาดอยู่
SSH is how you get a shell on a computer that is somewhere else. You do not normally need it for a container, because docker exec is faster and safer. But building one container with a real SSH server is the best way to practise SSH itself, and it costs nothing. Learn both, and learn when each one is right.
SSH 是你在另一台电脑上拿到一个 shell 的方式。对容器来说通常并不需要它,因为 docker exec 更快也更安全。但搭一个带真 SSH 服务的容器,是练 SSH 本身最好的办法,而且不花钱。两个都学会,并且分清什么时候该用哪个。
SSH คือวิธีเข้าไปได้เชลล์บนคอมพิวเตอร์ที่อยู่ที่อื่น ปกติคุณไม่ต้องใช้มันกับคอนเทนเนอร์ เพราะ docker exec เร็วกว่าและปลอดภัยกว่า แต่การสร้างคอนเทนเนอร์หนึ่งตัวที่มีเซิร์ฟเวอร์ SSH จริง เป็นวิธีฝึก SSH ที่ดีที่สุด และไม่ต้องเสียเงิน เรียนทั้งสองอย่าง และรู้ว่าเมื่อไรควรใช้อันไหน
No password, no keys, no extra program running, nothing
to attack. Use docker exec every day. So why learn SSH at all? Because the
moment you leave your own laptop — a rented server, a Raspberry Pi, the school's machine —
SSH is the only door.
不用密码、不用密钥、不用多跑一个程序,也没有多出来的攻击面。
docker exec 是你每天该用的。那还学 SSH 干什么?因为一旦离开你自己的笔记本——
租的服务器、树莓派、学校那台机器——SSH 是唯一的门。
ไม่ต้องมีรหัสผ่าน ไม่ต้องมีคีย์ ไม่ต้องมีโปรแกรมเพิ่ม และไม่มีช่องให้โจมตี
ใช้ docker exec ทุกวัน แล้วจะเรียน SSH ไปทำไม?
เพราะทันทีที่คุณออกจากแล็ปท็อปของตัวเอง — เซิร์ฟเวอร์เช่า Raspberry Pi เครื่องของโรงเรียน —
SSH คือประตูเดียว
SSH can use a password, but a key is better: nothing to type, nothing to guess, nothing to
forget. You get two files. The one without .pub is secret and never
leaves your computer. The one with .pub you give away freely.
SSH 可以用密码,但密钥更好:不用打字、猜不出来、也忘不了。
你会得到两个文件:没有 .pub 的那个是私密的,永远不离开你的电脑;
带 .pub 的那个可以随便给人。
SSH ใช้รหัสผ่านได้ แต่คีย์ดีกว่า: ไม่ต้องพิมพ์ เดาไม่ได้ และลืมไม่ได้
คุณจะได้ไฟล์สองไฟล์ ไฟล์ที่ไม่มี .pub เป็นความลับและไม่ออกจากเครื่องคุณเลย
ไฟล์ที่มี .pub แจกได้อย่างอิสระ
UNPROTECTED PRIVATE KEY FILE. Fix it with one command.
这里权限很重要,SSH 对此很严格。
如果你的私钥别人也能读,SSH 会拒绝使用它,并打印
UNPROTECTED PRIVATE KEY FILE。一条命令就能修好。
สิทธิ์ไฟล์สำคัญตรงนี้ และ SSH เข้มงวดเรื่องนี้
ถ้าคีย์ลับของคุณคนอื่นอ่านได้ SSH จะไม่ยอมใช้มัน และพิมพ์ว่า
UNPROTECTED PRIVATE KEY FILE แก้ด้วยคำสั่งเดียวMake a file called Dockerfile next to your keys. Every line here is needed —
the /run/sshd folder in particular, because sshd refuses to start without it
and the error does not say so clearly.
在密钥旁边新建一个 Dockerfile。这里每一行都是必需的——
特别是 /run/sshd 这个文件夹:没有它 sshd 根本起不来,
而报错并不会说清楚原因。
สร้างไฟล์ชื่อ Dockerfile ไว้ข้าง ๆ คีย์ของคุณ
ทุกบรรทัดที่นี่จำเป็น — เฉพาะอย่างยิ่งโฟลเดอร์ /run/sshd
เพราะ sshd ไม่ยอมเริ่มถ้าไม่มีมัน และข้อความผิดพลาดไม่ได้บอกชัด
-D means "do not go into the
background". A container lives only as long as its main program, so a service that
helpfully disappears into the background kills the container instantly. -e
sends the log to the screen, where docker logs can find it.
看最后一行:-D 的意思是“不要转到后台”。
容器的寿命就是它主程序的寿命,所以一个“贴心地”跑到后台去的服务,会立刻把容器杀掉。
-e 把日志送到屏幕上,这样 docker logs 才找得到。
อ่านบรรทัดสุดท้าย -D แปลว่า "อย่าไปอยู่เบื้องหลัง"
คอนเทนเนอร์มีชีวิตอยู่เท่ากับโปรแกรมหลักของมัน
ดังนั้นเซอร์วิสที่หลบไปอยู่เบื้องหลังอย่างมีน้ำใจ จะฆ่าคอนเทนเนอร์ทันที
-e ส่งล็อกไปที่หน้าจอ ที่ซึ่ง docker logs หาเจอssh-keygen -A makes the server's own host keys. Ubuntu's package does that
for you; Rocky's does not, and without it sshd will not start.
ssh-keygen -A 生成服务器自己的主机密钥。
Ubuntu 的包会替你做,Rocky 的不会——没有它 sshd 起不来。
ssh-keygen -A สร้างโฮสต์คีย์ของเซิร์ฟเวอร์เอง
แพ็กเกจของ Ubuntu ทำให้ ของ Rocky ไม่ทำ และถ้าไม่มีมัน sshd จะไม่เริ่ม
Port 22 is SSH's own door. On your computer port 22 may already be busy, so we knock on 2222 instead and Docker passes it through. 端口 22 是 SSH 自己的门。你电脑上的 22 端口可能已经被占用, 所以我们敲 2222,由 Docker 转进去。 พอร์ต 22 คือประตูของ SSH เอง บนเครื่องคุณพอร์ต 22 อาจถูกใช้อยู่แล้ว เราจึงเคาะที่ 2222 แทน แล้ว Docker ส่งต่อเข้าไป
This is the real output from doing exactly that: 下面是真的这样做以后得到的输出: นี่คือผลลัพธ์จริงจากการทำแบบนั้นเป๊ะ ๆ
Once SSH works, two more programs come free. They use the same key and the same port. SSH 一通,另外两个程序就免费送你了。它们用同一个密钥、同一个端口。 พอ SSH ใช้ได้ ก็ได้อีกสองโปรแกรมมาฟรี ๆ ใช้คีย์เดียวกันและพอร์ตเดียวกัน
ssh and
rsync use -p for the port. scp uses
-P. Everybody gets this wrong at least once, and the error is unhelpful.
大小写不是笔误:ssh 和 rsync 用小写
-p 指端口,scp 用大写 -P。
每个人至少弄错一次,而报错也帮不上忙。
ตัวพิมพ์ใหญ่ไม่ใช่ความผิดพลาด ssh และ rsync
ใช้ -p สำหรับพอร์ต ส่วน scp ใช้ -P
ทุกคนพลาดข้อนี้อย่างน้อยหนึ่งครั้ง และข้อความผิดพลาดก็ไม่ช่วยอะไรDelete the container, build it again, and SSH will shout at you in capital letters. Nothing is wrong. The new container made itself brand new host keys, so the machine answering on port 2222 really is a different machine than the one you met yesterday — and SSH is doing its job by telling you. 删掉容器再重建,SSH 会用大写字母冲你喊。其实没出事: 新容器给自己生成了全新的主机密钥,所以现在在 2222 端口应答的确实是另一台机器, 跟你昨天见的那台不一样——SSH 提醒你,正是它在尽责。 ลบคอนเทนเนอร์แล้วสร้างใหม่ SSH จะตะโกนใส่คุณเป็นตัวพิมพ์ใหญ่ ไม่มีอะไรผิด คอนเทนเนอร์ใหม่สร้างโฮสต์คีย์ใหม่หมดให้ตัวเอง เครื่องที่ตอบอยู่บนพอร์ต 2222 จึงเป็นเครื่องอื่นจริง ๆ ไม่ใช่เครื่องที่คุณเจอเมื่อวาน — และ SSH กำลังทำหน้าที่ของมันด้วยการบอกคุณ
Because you know why, the fix is safe here. Forget the old key for that port: 既然你知道原因,在这里修它是安全的。把那个端口的旧密钥忘掉: เพราะคุณรู้สาเหตุ การแก้ตรงนี้จึงปลอดภัย ให้ลืมคีย์เก่าของพอร์ตนั้น
For a throwaway lab container you can also tell SSH not to keep a record at all. Never do this to a real server — that check is what stops somebody pretending to be your machine. 对于用完就扔的实验容器,你也可以叫 SSH 干脆不要记录。 千万不要对真实服务器这样做——那个检查正是防止别人假冒你的机器的东西。 สำหรับคอนเทนเนอร์ทดลองที่ใช้แล้วทิ้ง คุณจะบอก SSH ให้ไม่ต้องจดบันทึกเลยก็ได้ อย่าทำแบบนี้กับเซิร์ฟเวอร์จริงเด็ดขาด — การตรวจนั้นคือสิ่งที่กันคนอื่นจากการปลอมเป็นเครื่องของคุณ
| What you see | What it means | Do this |
|---|---|---|
Connection refused |
Nothing is listening. sshd never started, or the container has already stopped. | docker ps then docker logs sshbox. Nine times out of ten
it is the missing /run/sshd. |
Permission denied (publickey) |
The server does not accept your key. | Check authorized_keys holds the .pub file and that
/root/.ssh is 700. |
UNPROTECTED PRIVATE KEY FILE |
Other people can read your secret key. | chmod 600 ./labkey |
REMOTE HOST IDENTIFICATION HAS CHANGED |
A rebuilt container has new host keys. Expected. | ssh-keygen -R "[localhost]:2222" |
| It asks for a password you never set | Your key was not offered or not accepted, so it fell back. | Add -v to ssh and read which key it tried. |
docker exec and kubectl exec. Build the SSH container to
learn SSH, then delete it.
不要在真实容器里装 SSH 服务。一个容器应该只跑一个程序。
加上 sshd 就意味着多一个程序、多一份要保管的密码或密钥、一个开着的端口,
以及一条没人盯着的进入系统的路。真实团队用 docker exec 和
kubectl exec。搭这个 SSH 容器是为了学 SSH,学完就删掉。
อย่าใส่เซิร์ฟเวอร์ SSH ในคอนเทนเนอร์จริง
คอนเทนเนอร์หนึ่งตัวควรรันโปรแกรมเดียว การเพิ่ม sshd หมายถึงโปรแกรมที่สอง
รหัสผ่านหรือคีย์อีกชุดที่ต้องดูแล พอร์ตที่เปิดอยู่ และทางเข้าระบบที่ไม่มีใครเฝ้า
ทีมจริงใช้ docker exec และ kubectl exec
สร้างคอนเทนเนอร์ SSH เพื่อเรียน SSH แล้วลบทิ้ง| docker exec | ssh | |
|---|---|---|
| Set-up needed | none | a server, a key, a port |
| Works on | containers on this machine | any machine, anywhere |
| Copy files | docker cp | scp · rsync |
| Extra risk | none | an open door to guard |
| Use it for | everyday container work | real servers, and practice |
You have made containers, a volume and a network today. Here is how to leave no mess. Do this before you close the laptop. 今天你造了容器、一个数据卷和一个网络。下面是怎么不留垃圾。 合上笔记本之前做一遍。 วันนี้คุณสร้างคอนเทนเนอร์ วอลลุม และเน็ตเวิร์กไว้ นี่คือวิธีเก็บให้ไม่เหลือความรุงรัง ทำก่อนปิดเครื่อง
ubuntu:24.04 is under 80 MB. Deleting containers is the housekeeping that
matters; deleting images only makes tomorrow slower.
镜像留着。它们占硬盘,但下次省下载。ubuntu:24.04
不到 80 MB。真正该收拾的是容器;删镜像只会让明天变慢。
เก็บอิมเมจไว้ มันกินพื้นที่ แต่ช่วยคุณประหยัดการดาวน์โหลดครั้งหน้า
ubuntu:24.04 เล็กกว่า 80 MB การลบคอนเทนเนอร์คือการเก็บบ้านที่สำคัญ
การลบอิมเมจแค่ทำให้วันพรุ่งนี้ช้าลงapt and .deb.
Rocky says dnf and .rpm. Everything else is nearly
the same.
两个家族,同一份活:Ubuntu 说 apt 和 .deb,
Rocky 说 dnf 和 .rpm,其他几乎一样。
สองตระกูล งานเดียวกัน Ubuntu พูดว่า apt และ .deb
Rocky พูดว่า dnf และ .rpm อย่างอื่นเกือบเหมือนกันหมดapt-get update first, always.
新的 Ubuntu 镜像里几乎什么都没有:没有 vim、没有 ping、没有 ip、没有 curl。
永远先 apt-get update。
อิมเมจ Ubuntu ใหม่แทบไม่มีอะไรเลย ไม่มี vim ไม่มี ping ไม่มี ip ไม่มี curl
ให้ apt-get update ก่อนเสมอlocalhost in a container is the container. Not your computer, and
not the container next door.
容器里的 localhost 就是这个容器:不是你的电脑,也不是隔壁那个容器。
localhost ในคอนเทนเนอร์คือตัวคอนเทนเนอร์นั้น
ไม่ใช่เครื่องคุณ และไม่ใช่คอนเทนเนอร์ข้าง ๆrm has no recycle bin. ls the path first. Every time.
rm 没有回收站:先用 ls 看一遍那个路径,每次都要。
rm ไม่มีถังขยะ ให้ ls ดูพาธก่อน ทุกครั้งsudo !! and Ctrl+R. Never retype a command.
The history is numbered, and !42 runs number 42 again.
sudo !! 和 Ctrl+R:命令永远不要重打。
历史记录是带编号的,!42 就是再跑一遍第 42 条。
sudo !! และ Ctrl+R อย่าพิมพ์คำสั่งซ้ำ
ประวัติมีเลขกำกับ และ !42 คือรันอันที่ 42 อีกครั้งdocker exec, not SSH, for containers. Build an SSH container to
learn SSH, then delete it.
对容器要用 docker exec,不要用 SSH。
搭 SSH 容器是为了学 SSH,学完就删。
กับคอนเทนเนอร์ให้ใช้ docker exec ไม่ใช่ SSH
สร้างคอนเทนเนอร์ SSH เพื่อเรียน SSH แล้วลบทิ้ง:q!
在 vim 里迷路了就按 Esc;想不保存直接走::q!
ถ้าหลงทางใน vim ให้กด Esc ถ้าจะออกโดยไม่เก็บอะไร: :q!Thank you for learning with us today.
Break a container on purpose before you go — type rm somewhere silly, watch it
go wrong, then throw the whole thing away and start a clean one. Nothing is lost, and that
freedom is the whole reason we are learning Linux in Docker. See you in the next lab.
感谢今天和我们一起学习。走之前故意弄坏一个容器吧——
在某个奇怪的地方敲个 rm,看它出错,然后把整个东西扔掉,重开一个干净的。
什么都不会丢,而这份自由就是我们在 Docker 里学 Linux 的全部理由。下个实验室见。
ขอบคุณที่เรียนกับเราวันนี้ ก่อนไป ลองตั้งใจทำคอนเทนเนอร์ให้พังดู —
พิมพ์ rm ในที่ที่ไม่ควร ดูมันผิดพลาด แล้วทิ้งทั้งอันไป เริ่มอันใหม่ที่สะอาด
ไม่มีอะไรหาย และอิสระนั้นคือเหตุผลทั้งหมดที่เราเรียน Linux ใน Docker แล้วเจอกันในแล็บหน้า