<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: jieke1688</title>
    <description>The latest articles on DEV Community by jieke1688 (@jieke1688).</description>
    <link>https://dev.to/jieke1688</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4127204%2Ff2b85a78-95b9-4cd0-8da0-6d96740ff9d6.png</url>
      <title>DEV Community: jieke1688</title>
      <link>https://dev.to/jieke1688</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jieke1688"/>
    <language>en</language>
    <item>
      <title>Production-Ready Cloud Server: 12 Checks Before You Deploy 云服务器上线前的 12 项检查</title>
      <dc:creator>jieke1688</dc:creator>
      <pubDate>Wed, 16 Sep 2026 06:37:11 +0000</pubDate>
      <link>https://dev.to/jieke1688/production-ready-cloud-server-12-checks-before-you-deployyun-fu-wu-qi-shang-xian-qian-de-12-xiang-jian-cha-b04</link>
      <guid>https://dev.to/jieke1688/production-ready-cloud-server-12-checks-before-you-deployyun-fu-wu-qi-shang-xian-qian-de-12-xiang-jian-cha-b04</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxqhesosxf9hldtam5oa5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxqhesosxf9hldtam5oa5.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
Shipping an application is easy. Proving that the server can survive a reboot, a failed login attempt, a full disk, or a broken backup is the real work.&lt;/p&gt;

&lt;p&gt;把应用部署到云服务器并不难，真正困难的是证明它能经受重启、暴力登录、磁盘写满和备份失效等生产场景。&lt;/p&gt;

&lt;p&gt;This bilingual checklist gives you a vendor-neutral baseline for an Ubuntu/Debian cloud server running Docker and Nginx. Every section includes a command and a verification step—because a configuration is not complete until you can verify it.&lt;/p&gt;

&lt;p&gt;这份中英双语清单适用于运行 Docker 与 Nginx 的 Ubuntu/Debian 云服务器，不绑定任何云厂商。每一项都包含命令和验证方法：&lt;strong&gt;配置完成不等于验证完成。&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Safety note / 安全提示：Keep the current SSH session open while changing SSH or firewall settings. Test a second session before closing the first one. 修改 SSH 或防火墙时保留当前会话，并先用第二个终端验证新连接，避免把自己锁在服务器外。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The target architecture｜目标架构&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff8s5fzsr546pjj3f5x5a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff8s5fzsr546pjj3f5x5a.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;
The public network should reach only the intended entry points. Nginx terminates HTTP/HTTPS traffic, the application stays behind it, the database is not exposed publicly, and backups leave the failure domain of the server.&lt;/p&gt;

&lt;p&gt;公网只应访问必要入口。Nginx 负责 HTTP/HTTPS，应用容器位于其后，数据库不暴露到公网，备份则必须离开本机故障域。&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Patch the operating system｜更新操作系统
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt full-upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt autoremove &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Check whether a reboot is required:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/run/reboot-required &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cat&lt;/span&gt; /var/run/reboot-required &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"No reboot required"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;确认安全更新已经安装，并检查是否需要重启。若生产业务不能立即重启，应创建维护窗口，而不是长期忽略内核更新。&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Use a non-root operator account｜使用非 root 运维账号
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;adduser deploy
&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;deploy
&lt;span class="nb"&gt;id &lt;/span&gt;deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Daily operations should not run as &lt;code&gt;root&lt;/code&gt;. The &lt;code&gt;id&lt;/code&gt; output must show the expected user and &lt;code&gt;sudo&lt;/code&gt; group.&lt;/p&gt;

&lt;p&gt;日常操作不应直接使用 &lt;code&gt;root&lt;/code&gt;。通过 &lt;code&gt;id deploy&lt;/code&gt; 确认用户和 &lt;code&gt;sudo&lt;/code&gt; 组已经生效。&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Verify SSH keys before disabling passwords｜先验证密钥，再关闭密码登录
&lt;/h2&gt;

&lt;p&gt;From your local computer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-a&lt;/span&gt; 64
ssh-copy-id deploy@SERVER_IP
ssh deploy@SERVER_IP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the key login succeeds in a second terminal, create a drop-in configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/ssh/sshd_config.d/99-hardening.conf &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;sshd &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl reload ssh
&lt;span class="nb"&gt;sudo &lt;/span&gt;sshd &lt;span class="nt"&gt;-T&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'permitrootlogin|passwordauthentication|pubkeyauthentication'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;sshd -t&lt;/code&gt; must return no error. Do not close the original session until the second key-based login works.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sshd -t&lt;/code&gt; 必须无报错。第二个终端使用密钥登录成功之前，不要关闭原会话。&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Apply a default-deny firewall｜设置默认拒绝的防火墙
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw default deny incoming
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw default allow outgoing
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow OpenSSH
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 80/tcp
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 443/tcp
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw &lt;span class="nb"&gt;enable
sudo &lt;/span&gt;ufw status verbose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only ports you intentionally expose should appear in the status output. If SSH uses a custom port, allow it before enabling UFW.&lt;/p&gt;

&lt;p&gt;状态中只应出现你明确开放的端口。如果 SSH 使用自定义端口，必须先放行该端口再启用 UFW。&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Audit listening ports｜审计监听端口
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ss &lt;span class="nt"&gt;-lntup&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;lsof &lt;span class="nt"&gt;-nP&lt;/span&gt; &lt;span class="nt"&gt;-iTCP&lt;/span&gt; &lt;span class="nt"&gt;-sTCP&lt;/span&gt;:LISTEN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common public ports are &lt;code&gt;22&lt;/code&gt;, &lt;code&gt;80&lt;/code&gt;, and &lt;code&gt;443&lt;/code&gt;. A database bound to &lt;code&gt;0.0.0.0:3306&lt;/code&gt; or &lt;code&gt;0.0.0.0:5432&lt;/code&gt; deserves immediate investigation.&lt;/p&gt;

&lt;p&gt;常见公网端口为 &lt;code&gt;22&lt;/code&gt;、&lt;code&gt;80&lt;/code&gt; 和 &lt;code&gt;443&lt;/code&gt;。如果数据库监听在 &lt;code&gt;0.0.0.0:3306&lt;/code&gt; 或 &lt;code&gt;0.0.0.0:5432&lt;/code&gt;，应立即检查安全组、防火墙和应用连接方式。&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Do not assume Docker obeys UFW｜不要假设 Docker 自动遵守 UFW
&lt;/h2&gt;

&lt;p&gt;Docker can publish ports through its own iptables/nftables rules. Prefer binding internal services to loopback:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:3000:3000"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then verify locally and externally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://127.0.0.1:3000
&lt;span class="nb"&gt;sudo &lt;/span&gt;ss &lt;span class="nt"&gt;-lntp&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;':3000'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From another machine, &lt;code&gt;SERVER_IP:3000&lt;/code&gt; should be unreachable while Nginx can still proxy to &lt;code&gt;127.0.0.1:3000&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;从外部机器访问 &lt;code&gt;SERVER_IP:3000&lt;/code&gt; 应失败，但 Nginx 仍应能代理到 &lt;code&gt;127.0.0.1:3000&lt;/code&gt;。&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Put Nginx in front of the app｜让 Nginx 作为统一入口
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://127.0.0.1:3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt; &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-Proto&lt;/span&gt; &lt;span class="nv"&gt;$scheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_connect_timeout&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_read_timeout&lt;/span&gt; &lt;span class="s"&gt;60s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nginx &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl reload nginx
curl &lt;span class="nt"&gt;-I&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Host: example.com'&lt;/span&gt; http://127.0.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;example.com&lt;/code&gt; with your real domain. Add TLS only after DNS resolves correctly.&lt;/p&gt;

&lt;p&gt;将 &lt;code&gt;example.com&lt;/code&gt; 替换为真实域名。先确认 DNS 正确解析，再配置 TLS，能减少证书签发失败和错误排查成本。&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Set resource limits｜设置资源限制
&lt;/h2&gt;

&lt;p&gt;Without limits, one container can consume all memory and trigger the OOM killer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;mem_limit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1g&lt;/span&gt;
    &lt;span class="na"&gt;cpus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.0&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the effective limits and recent OOM events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker inspect app &lt;span class="nt"&gt;--format&lt;/span&gt; &lt;span class="s1"&gt;'{{.HostConfig.Memory}} {{.HostConfig.NanoCpus}}'&lt;/span&gt;
journalctl &lt;span class="nt"&gt;-k&lt;/span&gt; &lt;span class="nt"&gt;--since&lt;/span&gt; &lt;span class="s2"&gt;"24 hours ago"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'oom|out of memory'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;没有资源限制时，单个容器可能吃光内存并触发 OOM。限制值应根据真实负载测试调整，而不是照抄示例。&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Watch disk and inode usage｜同时监控磁盘容量和 inode
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-hT&lt;/span&gt;
&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-ih&lt;/span&gt;
&lt;span class="nb"&gt;sudo du&lt;/span&gt; &lt;span class="nt"&gt;-xhd1&lt;/span&gt; /var | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt;
docker system &lt;span class="nb"&gt;df&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A server can fail with free gigabytes remaining if it runs out of inodes. Set alerts for both percentage used and projected growth.&lt;/p&gt;

&lt;p&gt;即使还有可用容量，inode 耗尽也会导致无法创建文件。监控应同时覆盖容量、inode 和增长速度。&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Configure log rotation｜配置日志轮转
&lt;/h2&gt;

&lt;p&gt;For Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"log-driver"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"json-file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"log-opts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"max-size"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"20m"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"max-file"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save this as &lt;code&gt;/etc/docker/daemon.json&lt;/code&gt;, validate it, and restart Docker during a controlled maintenance window:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool /etc/docker/daemon.json
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart docker
docker info &lt;span class="nt"&gt;--format&lt;/span&gt; &lt;span class="s1"&gt;'{{.LoggingDriver}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;日志轮转能避免容器日志无限增长。重启 Docker 会影响正在运行的容器，应安排维护窗口并验证重启策略。&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Back up off-server—and test restore｜异机备份，并验证恢复
&lt;/h2&gt;

&lt;p&gt;A backup on the same server is not disaster recovery. Keep a database dump plus application data in object storage or another host.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /var/backups/app
pg_dump &lt;span class="nt"&gt;-Fc&lt;/span&gt; &lt;span class="nt"&gt;-U&lt;/span&gt; appuser appdb &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /var/backups/app/appdb-&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%F&lt;span class="si"&gt;)&lt;/span&gt;.dump
&lt;span class="nb"&gt;sha256sum&lt;/span&gt; /var/backups/app/appdb-&lt;span class="k"&gt;*&lt;/span&gt;.dump
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test the restore into an isolated database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;createdb &lt;span class="nt"&gt;-U&lt;/span&gt; postgres appdb_restore_test
pg_restore &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-d&lt;/span&gt; appdb_restore_test /var/backups/app/appdb-YYYY-MM-DD.dump
psql &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-d&lt;/span&gt; appdb_restore_test &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'select now();'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;备份成功日志不能证明数据可恢复。至少定期恢复到隔离环境，并记录恢复耗时、数据校验结果和负责人。&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Add monitoring with actionable alerts｜建立可行动的监控告警
&lt;/h2&gt;

&lt;p&gt;At minimum, monitor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU saturation and load average&lt;/li&gt;
&lt;li&gt;Available memory and swap activity&lt;/li&gt;
&lt;li&gt;Disk usage, inode usage, and I/O latency&lt;/li&gt;
&lt;li&gt;HTTP error rate and latency&lt;/li&gt;
&lt;li&gt;Container restart count&lt;/li&gt;
&lt;li&gt;TLS certificate expiry&lt;/li&gt;
&lt;li&gt;Backup age and restore-test status&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;至少监控 CPU、内存、磁盘、I/O 延迟、HTTP 错误率、容器重启、证书到期时间、备份新鲜度和恢复演练状态。告警必须对应明确动作，而不是只产生噪声。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffoayruev40s729e043w1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffoayruev40s729e043w1.png" alt=" " width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final verification script｜最终验证脚本
&lt;/h2&gt;

&lt;p&gt;This read-only snapshot helps you collect evidence before deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'== OS =='&lt;/span&gt;
&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'== Resources =='&lt;/span&gt;
free &lt;span class="nt"&gt;-h&lt;/span&gt;
&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-hT&lt;/span&gt;
&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-ih&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'== Listening ports =='&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ss &lt;span class="nt"&gt;-lntup&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'== Firewall =='&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw status verbose

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'== Failed services =='&lt;/span&gt;
systemctl &lt;span class="nt"&gt;--failed&lt;/span&gt; &lt;span class="nt"&gt;--no-pager&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'== Docker =='&lt;/span&gt;
docker ps &lt;span class="nt"&gt;--format&lt;/span&gt; &lt;span class="s1"&gt;'table {{.Names}}\t{{.Status}}\t{{.Ports}}'&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'== Recent OOM events =='&lt;/span&gt;
journalctl &lt;span class="nt"&gt;-k&lt;/span&gt; &lt;span class="nt"&gt;--since&lt;/span&gt; &lt;span class="s1"&gt;'24 hours ago'&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'oom|out of memory'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The script does not change the server. Save the output with your deployment record and compare it after changes.&lt;/p&gt;

&lt;p&gt;该脚本只读，不修改服务器。可以把输出保存到上线记录中，并在变更后再次执行，用于对比验证。&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this baseline stops｜这套基线的边界
&lt;/h2&gt;

&lt;p&gt;This checklist is suitable for a single cloud server or small production workload. It is not a substitute for high availability, multi-region disaster recovery, compliance controls, or a tested incident-response process.&lt;/p&gt;

&lt;p&gt;这份清单适合单台云服务器或小型生产负载，但不能替代高可用、多地域容灾、合规控制和经过演练的故障响应流程。&lt;/p&gt;

&lt;p&gt;Use real metrics to decide when to add capacity or split services: sustained CPU saturation, memory pressure, disk latency, connection limits, recovery-time targets, and failure-domain requirements are stronger signals than a generic sizing table.&lt;/p&gt;

&lt;p&gt;是否扩容或拆分服务，应依据真实指标：持续 CPU 饱和、内存压力、磁盘时延、连接数限制、恢复时间目标和故障域要求，比通用配置表更可靠。&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR｜总结
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Patch first. 先更新系统。&lt;/li&gt;
&lt;li&gt;Verify key login before disabling passwords. 关闭密码登录前先验证密钥。&lt;/li&gt;
&lt;li&gt;Expose only intended ports. 只开放必要端口。&lt;/li&gt;
&lt;li&gt;Treat Docker networking separately. 单独检查 Docker 网络规则。&lt;/li&gt;
&lt;li&gt;Set resource and log limits. 设置资源与日志限制。&lt;/li&gt;
&lt;li&gt;Back up off-server and test a restore. 异机备份并实际恢复。&lt;/li&gt;
&lt;li&gt;Monitor symptoms that lead to action. 监控必须能触发明确行动。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tags: &lt;code&gt;#devops&lt;/code&gt; &lt;code&gt;#cloud&lt;/code&gt; &lt;code&gt;#linux&lt;/code&gt; &lt;code&gt;#tutorial&lt;/code&gt;&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>devops</category>
      <category>linux</category>
      <category>production</category>
    </item>
  </channel>
</rss>
