<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>工程实践 on 三巧小站</title><link>https://3qiao.vip/categories/%E5%B7%A5%E7%A8%8B%E5%AE%9E%E8%B7%B5/</link><description>Recent content in 工程实践 on 三巧小站</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Fri, 18 Jun 2021 00:00:00 +0000</lastBuildDate><atom:link href="https://3qiao.vip/categories/%E5%B7%A5%E7%A8%8B%E5%AE%9E%E8%B7%B5/index.xml" rel="self" type="application/rss+xml"/><item><title>从脚本到服务：用 Docker Compose 管理一个小项目</title><link>https://3qiao.vip/posts/2021-lightweight-deployment/</link><pubDate>Fri, 18 Jun 2021 00:00:00 +0000</pubDate><guid>https://3qiao.vip/posts/2021-lightweight-deployment/</guid><description>记录一次把本地脚本整理成可重复部署服务的过程。</description><content:encoded><![CDATA[<p>很多个人项目最初只有一个脚本：在电脑上可以运行，换一台机器就要重新安装依赖、修改配置，再手动启动。2021 年我给一个小工具做整理时，决定把“运行环境”也作为项目的一部分保存下来。</p>
<h2 id="先把服务边界说清楚">先把服务边界说清楚</h2>
<p>我先把程序拆成三个部分：应用本身、持久化数据、配置文件。应用容器可以随时重建，数据目录需要长期保留，配置则通过环境变量注入。这样做的好处是，升级应用时不必碰数据，迁移服务器时也只需要打包数据目录和 compose 文件。</p>
<p>一个最小的 <code>docker-compose.yml</code> 可以这样写：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">version</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;3.8&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">app</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">example/app:1.0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">unless-stopped</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;8080:8080&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">env_file</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">.env</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./data:/var/lib/app</span><span class="w">
</span></span></span></code></pre></div><p><code>restart: unless-stopped</code> 让机器重启后服务自动恢复；版本号固定则避免“今天能跑、明天突然变样”。开发阶段可以使用 <code>latest</code>，生产环境最好明确写版本。</p>
<h2 id="配置和数据分开">配置和数据分开</h2>
<p>密码、令牌等内容不应该提交到 Git。项目里只保留 <code>.env.example</code>，真正的 <code>.env</code> 放在服务器上，并限制文件权限：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cp .env.example .env
</span></span><span class="line"><span class="cl">chmod <span class="m">600</span> .env
</span></span><span class="line"><span class="cl">docker compose up -d
</span></span></code></pre></div><p>备份也围绕数据目录进行。对小项目来说，每天压缩一次数据并保留最近七份，已经比“只在出问题时想起来备份”可靠很多。</p>
<h2 id="让部署变成一个动作">让部署变成一个动作</h2>
<p>最后我把更新流程固定为：拉取代码、检查配置、构建新镜像、重新创建容器、查看日志。步骤固定之后，部署不再依赖某个人记得哪些命令，也更容易在低配服务器上控制资源。</p>
<p>这个实践让我意识到，轻量化不只是少装软件，更是让每个组件的职责足够单一。服务越小，备份、迁移和排错都越容易。</p>
]]></content:encoded></item></channel></rss>