<?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>Docker on heyaohua's Blog</title><link>https://blog.heyaohua.com/tags/docker/</link><description>Recent content in Docker on heyaohua's Blog</description><image><title>heyaohua's Blog</title><url>https://blog.heyaohua.com/og-image.png</url><link>https://blog.heyaohua.com/og-image.png</link></image><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Thu, 09 Oct 2025 12:30:00 +0800</lastBuildDate><atom:link href="https://blog.heyaohua.com/tags/docker/index.xml" rel="self" type="application/rss+xml"/><item><title>Dify + Cloudflare Tunnel 部署指南</title><link>https://blog.heyaohua.com/posts/2025/10/dify-cloudflare-tunnel-deployment/</link><pubDate>Thu, 09 Oct 2025 12:30:00 +0800</pubDate><guid>https://blog.heyaohua.com/posts/2025/10/dify-cloudflare-tunnel-deployment/</guid><description>本指南详细介绍如何使用 Docker 部署 Dify，并通过 Cloudflare Tunnel 实现安全的外网访问。</description><content:encoded><![CDATA[<p>本指南详细介绍如何使用 Docker 部署 Dify，并通过 Cloudflare Tunnel 实现安全的外网访问。</p>
<h2 id="前置条件">前置条件</h2>
<ul>
<li>macOS 系统</li>
<li>已安装 Docker 和 Docker Compose</li>
<li>拥有 Cloudflare 账户</li>
<li>拥有一个域名并托管在 Cloudflare</li>
</ul>
<h2 id="第一步部署-dify">第一步：部署 Dify</h2>
<h3 id="11-克隆-dify-仓库">1.1 克隆 Dify 仓库</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">cd</span> /Users/heyaohua/Server
</span></span><span style="display:flex;"><span>git clone https://github.com/langgenius/dify.git
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">cd</span> dify/docker
</span></span></code></pre></div><h3 id="12-配置环境变量">1.2 配置环境变量</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 复制环境变量模板</span>
</span></span><span style="display:flex;"><span>cp .env.example .env
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 编辑环境变量文件</span>
</span></span><span style="display:flex;"><span>vim .env
</span></span></code></pre></div><p>关键配置项：</p>
<ul>
<li><code>SECRET_KEY</code>: 生成一个安全的密钥</li>
<li><code>DB_USERNAME</code>, <code>DB_PASSWORD</code>: 数据库用户名和密码</li>
<li><code>REDIS_PASSWORD</code>: Redis 密码</li>
</ul>
<h3 id="13-启动-dify-服务">1.3 启动 Dify 服务</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 启动所有服务</span>
</span></span><span style="display:flex;"><span>docker-compose up -d
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 检查服务状态</span>
</span></span><span style="display:flex;"><span>docker-compose ps
</span></span></code></pre></div><p>确保以下服务正常运行：</p>
<ul>
<li><code>docker-nginx-1</code>: 端口 80, 443</li>
<li><code>docker-api-1</code>: 端口 5001</li>
<li><code>docker-web-1</code>: 端口 3000</li>
<li><code>docker-plugin_daemon-1</code>: 端口 5003</li>
</ul>
<h2 id="第二步安装-cloudflare-tunnel">第二步：安装 Cloudflare Tunnel</h2>
<h3 id="21-安装-cloudflared">2.1 安装 cloudflared</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 使用 Homebrew 安装
</span></span><span style="display:flex;"><span>brew install cloudflared
</span></span></code></pre></div><h3 id="22-登录-cloudflare">2.2 登录 Cloudflare</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>cloudflared tunnel login
</span></span></code></pre></div><p>这会打开浏览器，选择要使用的域名进行授权。</p>
<h2 id="第三步创建和配置-tunnel">第三步：创建和配置 Tunnel</h2>
<h3 id="31-创建-tunnel">3.1 创建 Tunnel</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 创建名为 dify-tunnel 的隧道
</span></span><span style="display:flex;"><span>cloudflared tunnel create dify-tunnel
</span></span></code></pre></div><p>记录返回的 Tunnel ID，例如：<code>e5e75674-d270-4201-ab9e-ea858c091d91</code></p>
<h3 id="32-创建配置文件">3.2 创建配置文件</h3>
<p>在 Dify docker 目录下创建 <code>config.yaml</code>：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>tunnel: e5e75674-d270-4201-ab9e-ea858c091d91
</span></span><span style="display:flex;"><span>credentials-file: /Users/heyaohua/.cloudflared/e5e75674-d270-4201-ab9e-ea858c091d91.json
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>ingress:
</span></span><span style="display:flex;"><span>  - hostname: dify.yourdomain.com
</span></span><span style="display:flex;"><span>    service: http://127.0.0.1:80
</span></span><span style="display:flex;"><span>  - service: http_status:404
</span></span></code></pre></div><p><strong>重要说明：</strong></p>
<ul>
<li>将 <code>tunnel</code> 值替换为你的实际 Tunnel ID</li>
<li>将 <code>credentials-file</code> 路径中的 ID 替换为你的实际 Tunnel ID</li>
<li>将 <code>dify.yourdomain.com</code> 替换为你的实际域名</li>
</ul>
<h3 id="33-配置-dns-记录">3.3 配置 DNS 记录</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 为域名创建 DNS 记录（如果不存在）
</span></span><span style="display:flex;"><span>cloudflared tunnel route dns dify-tunnel dify.yourdomain.com
</span></span></code></pre></div><p>如果提示记录已存在，可以跳过此步骤。</p>
<h2 id="第四步测试-tunnel-连接">第四步：测试 Tunnel 连接</h2>
<h3 id="41-手动测试">4.1 手动测试</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 设置 DNS 解析并启动隧道</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">cd</span> /Users/heyaohua/Server/Dify/docker
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">GODNS</span><span style="color:#ff79c6">=</span>1.1.1.1 cloudflared tunnel --config config.yaml run
</span></span></code></pre></div><h3 id="42-验证连接">4.2 验证连接</h3>
<p>在浏览器中访问 <code>https://dify.yourdomain.com</code>，确认可以正常访问 Dify 界面。</p>
<h2 id="第五步配置系统服务后台运行">第五步：配置系统服务（后台运行）</h2>
<h3 id="51-安装基础服务">5.1 安装基础服务</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>cloudflared service install
</span></span></code></pre></div><h3 id="52-创建自定义服务配置">5.2 创建自定义服务配置</h3>
<p>创建 <code>com.cloudflare.cloudflared.plist</code> 文件：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#ff79c6">&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">&lt;!DOCTYPE plist PUBLIC &#34;-//Apple//DTD PLIST 1.0//EN&#34; &#34;http://www.apple.com/DTDs/PropertyList-1.0.dtd&#34;&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">&lt;plist</span> <span style="color:#50fa7b">version=</span><span style="color:#f1fa8c">&#34;1.0&#34;</span><span style="color:#ff79c6">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#ff79c6">&lt;dict&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;key&gt;</span>Label<span style="color:#ff79c6">&lt;/key&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;string&gt;</span>com.cloudflare.cloudflared<span style="color:#ff79c6">&lt;/string&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;key&gt;</span>ProgramArguments<span style="color:#ff79c6">&lt;/key&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;array&gt;</span>
</span></span><span style="display:flex;"><span>                        <span style="color:#ff79c6">&lt;string&gt;</span>/opt/homebrew/bin/cloudflared<span style="color:#ff79c6">&lt;/string&gt;</span>
</span></span><span style="display:flex;"><span>                        <span style="color:#ff79c6">&lt;string&gt;</span>tunnel<span style="color:#ff79c6">&lt;/string&gt;</span>
</span></span><span style="display:flex;"><span>                        <span style="color:#ff79c6">&lt;string&gt;</span>--config<span style="color:#ff79c6">&lt;/string&gt;</span>
</span></span><span style="display:flex;"><span>                        <span style="color:#ff79c6">&lt;string&gt;</span>/Users/heyaohua/Server/Dify/docker/config.yaml<span style="color:#ff79c6">&lt;/string&gt;</span>
</span></span><span style="display:flex;"><span>                        <span style="color:#ff79c6">&lt;string&gt;</span>run<span style="color:#ff79c6">&lt;/string&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;/array&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;key&gt;</span>RunAtLoad<span style="color:#ff79c6">&lt;/key&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;true/&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;key&gt;</span>StandardOutPath<span style="color:#ff79c6">&lt;/key&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;string&gt;</span>/Users/heyaohua/Library/Logs/com.cloudflare.cloudflared.out.log<span style="color:#ff79c6">&lt;/string&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;key&gt;</span>StandardErrorPath<span style="color:#ff79c6">&lt;/key&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;string&gt;</span>/Users/heyaohua/Library/Logs/com.cloudflare.cloudflared.err.log<span style="color:#ff79c6">&lt;/string&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;key&gt;</span>KeepAlive<span style="color:#ff79c6">&lt;/key&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;dict&gt;</span>
</span></span><span style="display:flex;"><span>                        <span style="color:#ff79c6">&lt;key&gt;</span>SuccessfulExit<span style="color:#ff79c6">&lt;/key&gt;</span>
</span></span><span style="display:flex;"><span>                        <span style="color:#ff79c6">&lt;false/&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;/dict&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;key&gt;</span>ThrottleInterval<span style="color:#ff79c6">&lt;/key&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;integer&gt;</span>5<span style="color:#ff79c6">&lt;/integer&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;key&gt;</span>EnvironmentVariables<span style="color:#ff79c6">&lt;/key&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;dict&gt;</span>
</span></span><span style="display:flex;"><span>                        <span style="color:#ff79c6">&lt;key&gt;</span>GODNS<span style="color:#ff79c6">&lt;/key&gt;</span>
</span></span><span style="display:flex;"><span>                        <span style="color:#ff79c6">&lt;string&gt;</span>1.1.1.1<span style="color:#ff79c6">&lt;/string&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#ff79c6">&lt;/dict&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#ff79c6">&lt;/dict&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">&lt;/plist&gt;</span>
</span></span></code></pre></div><p><strong>注意：</strong> 将配置文件路径替换为你的实际路径。</p>
<h3 id="53-安装和启动服务">5.3 安装和启动服务</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 复制配置文件到 LaunchAgents 目录</span>
</span></span><span style="display:flex;"><span>cp com.cloudflare.cloudflared.plist /Users/heyaohua/Library/LaunchAgents/
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 卸载旧服务（如果存在）</span>
</span></span><span style="display:flex;"><span>launchctl unload /Users/heyaohua/Library/LaunchAgents/com.cloudflare.cloudflared.plist
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 加载新服务</span>
</span></span><span style="display:flex;"><span>launchctl bootstrap gui/<span style="color:#ff79c6">$(</span>id -u<span style="color:#ff79c6">)</span> /Users/heyaohua/Library/LaunchAgents/com.cloudflare.cloudflared.plist
</span></span></code></pre></div><h3 id="54-验证服务状态">5.4 验证服务状态</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 检查服务是否运行
</span></span><span style="display:flex;"><span>launchctl list | grep cloudflared
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 查看服务日志
</span></span><span style="display:flex;"><span>tail -f /Users/heyaohua/Library/Logs/com.cloudflare.cloudflared.err.log
</span></span></code></pre></div><h2 id="服务管理命令">服务管理命令</h2>
<h3 id="启动服务">启动服务</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>launchctl bootstrap gui/$(id -u) /Users/heyaohua/Library/LaunchAgents/com.cloudflare.cloudflared.plist
</span></span></code></pre></div><h3 id="停止服务">停止服务</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>launchctl bootout gui/$(id -u) /Users/heyaohua/Library/LaunchAgents/com.cloudflare.cloudflared.plist
</span></span></code></pre></div><h3 id="查看服务状态">查看服务状态</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>launchctl list | grep cloudflared
</span></span></code></pre></div><h3 id="查看实时日志">查看实时日志</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 查看输出日志
</span></span><span style="display:flex;"><span>tail -f /Users/heyaohua/Library/Logs/com.cloudflare.cloudflared.out.log
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 查看错误日志
</span></span><span style="display:flex;"><span>tail -f /Users/heyaohua/Library/Logs/com.cloudflare.cloudflared.err.log
</span></span></code></pre></div><h2 id="故障排除">故障排除</h2>
<h3 id="1-dns-解析问题">1. DNS 解析问题</h3>
<p>如果遇到 DNS 解析错误：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 临时使用 Cloudflare DNS
</span></span><span style="display:flex;"><span>GODNS=1.1.1.1 cloudflared tunnel --config config.yaml run
</span></span></code></pre></div><h3 id="2-端口冲突">2. 端口冲突</h3>
<p>确保本地 80 端口没有被其他服务占用：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 检查端口占用</span>
</span></span><span style="display:flex;"><span>lsof -i :80
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 检查 Docker 服务状态</span>
</span></span><span style="display:flex;"><span>docker-compose ps
</span></span></code></pre></div><h3 id="3-权限问题">3. 权限问题</h3>
<p>确保 cloudflared 有足够的权限访问配置文件和日志目录。</p>
<h3 id="4-服务无法启动">4. 服务无法启动</h3>
<p>检查配置文件路径是否正确，Tunnel ID 是否匹配。</p>
<h2 id="安全建议">安全建议</h2>
<ol>
<li><strong>定期更新</strong>: 保持 Dify 和 cloudflared 为最新版本</li>
<li><strong>访问控制</strong>: 在 Cloudflare 控制台配置访问策略</li>
<li><strong>监控日志</strong>: 定期检查服务日志，监控异常访问</li>
<li><strong>备份配置</strong>: 备份重要的配置文件和数据库</li>
</ol>
<h2 id="总结">总结</h2>
<p>完成以上步骤后，你将拥有：</p>
<ul>
<li>✅ 完全部署的 Dify 服务</li>
<li>✅ 通过 HTTPS 的安全外网访问</li>
<li>✅ 自动启动的后台服务</li>
<li>✅ 完整的日志记录和监控</li>
</ul>
<p>现在你可以通过 <code>https://dify.yourdomain.com</code> 安全地访问你的 Dify 服务，无需担心服务器重启或网络中断的问题。</p>
<hr>
<p><strong>创建时间</strong>: 2025年10月9日
<strong>适用版本</strong>: Dify latest, cloudflared 2025.9.1
<strong>系统要求</strong>: macOS with Docker</p>
]]></content:encoded></item><item><title>PostgreSQL Docker 部署常见问题与解决方案</title><link>https://blog.heyaohua.com/posts/2025/10/postgresql-docker-faq/</link><pubDate>Thu, 09 Oct 2025 12:05:00 +0800</pubDate><guid>https://blog.heyaohua.com/posts/2025/10/postgresql-docker-faq/</guid><description>汇总在使用 Docker 部署 PostgreSQL（含 PostGIS、pgvector、TimescaleDB）过程中常见的问题及可操作的解决方案，涵盖构建、扩展、连接、权限、性能与数据等方面。</description><content:encoded><![CDATA[<p>汇总在使用 Docker 部署 PostgreSQL（含 PostGIS、pgvector、TimescaleDB）过程中常见的问题及可操作的解决方案，涵盖构建、扩展、连接、权限、性能与数据等方面。</p>
<hr>
<h2 id="目录">目录</h2>
<ul>
<li>构建问题</li>
<li>扩展问题</li>
<li>连接问题</li>
<li>权限问题</li>
<li>性能问题</li>
<li>数据问题</li>
<li>调试技巧</li>
<li>预防措施</li>
<li>获取帮助</li>
</ul>
<hr>
<h2 id="构建问题">构建问题</h2>
<h3 id="q1-docker-构建时出现-lsb_release-command-not-found">Q1: Docker 构建时出现 &ldquo;lsb_release: command not found&rdquo;</h3>
<p>问题描述：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>/bin/sh: 1: lsb_release: command not found
</span></span><span style="display:flex;"><span>/bin/sh: 1: apt-key: command not found
</span></span></code></pre></div><p>原因分析：
在 Debian/Ubuntu 基础镜像中，<code>lsb_release</code> 和 <code>apt-key</code> 命令可能不存在或已被弃用。</p>
<p>解决方案：改用从源码编译的方式安装 TimescaleDB：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 不使用包管理器安装，改为源码编译</span>
</span></span><span style="display:flex;"><span>RUN <span style="color:#8be9fd;font-style:italic">cd</span> /tmp <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    git clone https://github.com/timescale/timescaledb.git <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">cd</span> timescaledb <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    git checkout 2.13.0 <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    ./bootstrap <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">cd</span> build <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    make <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    make install
</span></span></code></pre></div><h3 id="q2-编译时出现-gssapigssapih-no-such-file-or-directory">Q2: 编译时出现 &ldquo;gssapi/gssapi.h: No such file or directory&rdquo;</h3>
<p>问题描述：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>fatal error: gssapi/gssapi.h: No such file or directory
</span></span></code></pre></div><p>原因分析：缺少 GSSAPI 开发库，TimescaleDB 编译需要 Kerberos 相关依赖。</p>
<p>解决方案：在 Dockerfile 中添加必要的依赖包：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>RUN apt-get update <span style="color:#ff79c6">&amp;&amp;</span> apt-get install -y <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    build-essential <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    postgresql-server-dev-15 <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    cmake <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    git <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    wget <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    ca-certificates <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    libkrb5-dev <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    libgssapi-krb5-2 <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">&amp;&amp;</span> rm -rf /var/lib/apt/lists/*
</span></span></code></pre></div><hr>
<h2 id="扩展问题">扩展问题</h2>
<h3 id="q3-pgvector-出现段错误-segmentation-fault">Q3: pgvector 出现段错误 (Segmentation Fault)</h3>
<p>问题描述：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>server closed the connection unexpectedly
</span></span><span style="display:flex;"><span>This probably means the server terminated abnormally
</span></span><span style="display:flex;"><span>before or while processing the request.
</span></span></code></pre></div><p>原因分析：</p>
<ul>
<li>pgvector 最新版本可能与 PostgreSQL 15 存在兼容性问题</li>
<li>编译环境或依赖版本不匹配</li>
</ul>
<p>解决方案：使用稳定的预编译版本：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 使用 pgvector 0.5.1 版本，避免段错误</span>
</span></span><span style="display:flex;"><span>RUN <span style="color:#8be9fd;font-style:italic">cd</span> /tmp <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    wget https://github.com/pgvector/pgvector/archive/v0.5.1.tar.gz <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    tar -xzf v0.5.1.tar.gz <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">cd</span> pgvector-0.5.1 <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    make <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    make install
</span></span></code></pre></div><h3 id="q4-timescaledb-扩展创建失败">Q4: TimescaleDB 扩展创建失败</h3>
<p>问题描述：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#ff79c6">ERROR</span>: could not load library &#34;timescaledb&#34;:
</span></span><span style="display:flex;"><span>shared_preload_libraries not configured
</span></span></code></pre></div><p>原因分析：TimescaleDB 需要在 PostgreSQL 启动时预加载。</p>
<p>解决方案：在 Dockerfile 中配置预加载库：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>RUN echo &#34;shared_preload_libraries = &#39;timescaledb&#39;&#34; &gt;&gt; /usr/share/postgresql/postgresql.conf.sample
</span></span></code></pre></div><h3 id="q5-postgis-扩展版本不匹配">Q5: PostGIS 扩展版本不匹配</h3>
<p>问题描述：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#ff79c6">ERROR</span>: extension &#34;postgis&#34; has no installation candidate
</span></span></code></pre></div><p>原因分析：PostgreSQL 版本与 PostGIS 包版本不匹配。</p>
<p>解决方案：明确指定对应版本的包：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>RUN apt-get install -y \
</span></span><span style="display:flex;"><span>    postgresql-15-postgis-3 \
</span></span><span style="display:flex;"><span>    postgresql-15-postgis-3-scripts
</span></span></code></pre></div><hr>
<h2 id="连接问题">连接问题</h2>
<h3 id="q6-ide-连接提示-connection-refused">Q6: IDE 连接提示 &ldquo;Connection refused&rdquo;</h3>
<p>问题描述：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>connection to server at &#34;localhost&#34; (::1), port 5432 failed: Connection refused
</span></span></code></pre></div><p>原因分析：</p>
<ul>
<li>端口映射不正确</li>
<li>服务未完全启动</li>
<li>防火墙阻止连接</li>
</ul>
<p>解决方案：</p>
<ol>
<li>检查端口映射：</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker port postgres-all-extensions
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 应该显示: 5432/tcp -&gt; 0.0.0.0:5432</span>
</span></span></code></pre></div><ol>
<li>确认服务状态：</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker ps
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 检查容器是否正常运行</span>
</span></span></code></pre></div><ol>
<li>等待服务完全启动：</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker logs postgres-all-extensions
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 查看启动日志，确认数据库已就绪</span>
</span></span></code></pre></div><h3 id="q7-密码认证失败">Q7: 密码认证失败</h3>
<p>问题描述：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#ff79c6">FATAL</span>: password authentication failed for user &#34;postgres&#34;
</span></span></code></pre></div><p>原因分析：</p>
<ul>
<li>数据目录已存在，使用了旧密码初始化</li>
<li>环境变量未正确加载</li>
<li>pg_hba.conf 配置问题</li>
</ul>
<p>解决方案：</p>
<ol>
<li>清理旧数据重新初始化：</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker-compose down
</span></span><span style="display:flex;"><span>sudo rm -rf ./data/pgdata/*
</span></span><span style="display:flex;"><span>docker-compose up -d
</span></span></code></pre></div><ol>
<li>检查环境变量：</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> postgres-all-extensions env | grep POSTGRES
</span></span></code></pre></div><ol>
<li>验证 .env 文件格式：</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 确保 .env 文件在正确位置且格式正确
</span></span><span style="display:flex;"><span>POSTGRES_PASSWORD=your_password
</span></span></code></pre></div><hr>
<h2 id="权限问题">权限问题</h2>
<h3 id="q8-数据目录权限错误">Q8: 数据目录权限错误</h3>
<p>问题描述：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>initdb: error: could not create directory &#34;/var/lib/postgresql/data&#34;: Permission denied
</span></span></code></pre></div><p>原因分析：宿主机目录权限不正确，PostgreSQL 容器无法写入。</p>
<p>解决方案：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 修改目录权限</span>
</span></span><span style="display:flex;"><span>sudo chown -R 999:999 ./data/pgdata
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 或者删除目录让 Docker 自动创建</span>
</span></span><span style="display:flex;"><span>sudo rm -rf ./data/pgdata
</span></span></code></pre></div><h3 id="q9-配置文件权限问题">Q9: 配置文件权限问题</h3>
<p>问题描述：容器启动时无法读取配置文件。</p>
<p>解决方案：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 确保配置文件可读
</span></span><span style="display:flex;"><span>chmod 644 config/postgresql.conf
</span></span><span style="display:flex;"><span>chmod 644 config/pg_hba.conf
</span></span></code></pre></div><hr>
<h2 id="性能问题">性能问题</h2>
<h3 id="q10-容器启动缓慢">Q10: 容器启动缓慢</h3>
<p>问题描述：Docker 容器启动时间过长。</p>
<p>原因分析：</p>
<ul>
<li>数据库初始化需要时间</li>
<li>扩展安装和配置耗时</li>
<li>系统资源不足</li>
</ul>
<p>解决方案：</p>
<ol>
<li>增加启动等待时间：</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 等待更长时间再进行连接测试
</span></span><span style="display:flex;"><span>sleep 15 &amp;&amp; docker exec postgres-all-extensions psql -U postgres -c &#34;SELECT 1;&#34;
</span></span></code></pre></div><ol>
<li>优化 Docker 资源分配：</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 在 docker-compose.yml 中添加资源限制
</span></span><span style="display:flex;"><span>deploy:
</span></span><span style="display:flex;"><span>  resources:
</span></span><span style="display:flex;"><span>    limits:
</span></span><span style="display:flex;"><span>      memory: 2G
</span></span><span style="display:flex;"><span>    reservations:
</span></span><span style="display:flex;"><span>      memory: 1G
</span></span></code></pre></div><h3 id="q11-查询性能差">Q11: 查询性能差</h3>
<p>问题描述：数据库查询响应缓慢。</p>
<p>解决方案：</p>
<ol>
<li>调整 PostgreSQL 配置：</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#6272a4">-- 增加共享缓冲区
</span></span></span><span style="display:flex;"><span><span style="color:#ff79c6">ALTER</span> <span style="color:#ff79c6">SYSTEM</span> <span style="color:#ff79c6">SET</span> shared_buffers <span style="color:#ff79c6">=</span> <span style="color:#f1fa8c">&#39;256MB&#39;</span>;
</span></span><span style="display:flex;"><span><span style="color:#6272a4">-- 调整工作内存
</span></span></span><span style="display:flex;"><span><span style="color:#ff79c6">ALTER</span> <span style="color:#ff79c6">SYSTEM</span> <span style="color:#ff79c6">SET</span> work_mem <span style="color:#ff79c6">=</span> <span style="color:#f1fa8c">&#39;4MB&#39;</span>;
</span></span><span style="display:flex;"><span><span style="color:#6272a4">-- 重载配置
</span></span></span><span style="display:flex;"><span><span style="color:#ff79c6">SELECT</span> pg_reload_conf();
</span></span></code></pre></div><ol>
<li>创建适当的索引：</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#6272a4">-- 为向量查询创建索引
</span></span></span><span style="display:flex;"><span><span style="color:#ff79c6">CREATE</span> <span style="color:#ff79c6">INDEX</span> <span style="color:#ff79c6">ON</span> items <span style="color:#ff79c6">USING</span> ivfflat (embedding vector_cosine_ops);
</span></span><span style="display:flex;"><span><span style="color:#6272a4">-- 为时序数据创建索引
</span></span></span><span style="display:flex;"><span><span style="color:#ff79c6">CREATE</span> <span style="color:#ff79c6">INDEX</span> <span style="color:#ff79c6">ON</span> sensor_data (time <span style="color:#ff79c6">DESC</span>);
</span></span></code></pre></div><hr>
<h2 id="数据问题">数据问题</h2>
<h3 id="q12-数据持久化失败">Q12: 数据持久化失败</h3>
<p>问题描述：容器重启后数据丢失。</p>
<p>原因分析：</p>
<ul>
<li>卷映射配置错误</li>
<li>数据目录路径不正确</li>
</ul>
<p>解决方案：确认 docker-compose.yml 中的卷配置：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>volumes:
</span></span><span style="display:flex;"><span>  - ./data/pgdata:/var/lib/postgresql/data
</span></span></code></pre></div><h3 id="q13-数据库版本不兼容">Q13: 数据库版本不兼容</h3>
<p>问题描述：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#ff79c6">FATAL</span>: database files are incompatible with server
</span></span></code></pre></div><p>原因分析：数据目录由不同版本的 PostgreSQL 创建。</p>
<p>解决方案：</p>
<ol>
<li>备份数据：</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> postgres-old pg_dumpall -U postgres &gt; backup.sql
</span></span></code></pre></div><ol>
<li>清理数据目录：</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo rm -rf ./data/pgdata/*
</span></span></code></pre></div><ol>
<li>重新启动并恢复：</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker-compose up -d
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 等待启动完成后</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> -i postgres-all-extensions psql -U postgres &lt; backup.sql
</span></span></code></pre></div><hr>
<h2 id="调试技巧">调试技巧</h2>
<h3 id="查看详细日志">查看详细日志</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 查看容器日志</span>
</span></span><span style="display:flex;"><span>docker logs postgres-all-extensions -f
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 查看 PostgreSQL 日志</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> postgres-all-extensions tail -f /var/log/postgresql/postgresql.log
</span></span></code></pre></div><h3 id="进入容器调试">进入容器调试</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 进入容器</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> -it postgres-all-extensions bash
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 查看进程状态</span>
</span></span><span style="display:flex;"><span>ps aux | grep postgres
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 检查扩展安装</span>
</span></span><span style="display:flex;"><span>psql -U postgres -c <span style="color:#f1fa8c">&#34;\dx&#34;</span>
</span></span></code></pre></div><h3 id="网络连接测试">网络连接测试</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 测试端口连通性</span>
</span></span><span style="display:flex;"><span>telnet localhost <span style="color:#bd93f9">5432</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 使用 Docker 网络测试</span>
</span></span><span style="display:flex;"><span>docker run --rm --network host postgres:15 pg_isready -h localhost -p <span style="color:#bd93f9">5432</span>
</span></span></code></pre></div><hr>
<h2 id="预防措施">预防措施</h2>
<ol>
<li>定期备份：建立自动化备份策略</li>
<li>监控日志：定期检查错误日志</li>
<li>版本管理：记录使用的具体版本号</li>
<li>测试环境：在生产部署前充分测试</li>
<li>文档更新：及时更新配置和问题解决方案</li>
</ol>
<hr>
<h2 id="获取帮助">获取帮助</h2>
<p>如遇到本文未涵盖的问题：</p>
<ol>
<li>查看官方文档：</li>
<li>PostgreSQL 官方文档</li>
<li>PostGIS 文档</li>
<li>pgvector GitHub</li>
<li></li>
</ol>
<p>TimescaleDB 文档</p>
<ol start="6">
<li></li>
</ol>
<p>社区支持：</p>
<ol start="7">
<li>PostgreSQL 邮件列表</li>
<li>Stack Overflow</li>
<li></li>
</ol>
<p>GitHub Issues</p>
<ol start="10">
<li></li>
</ol>
<p>日志分析：</p>
<ol start="11">
<li>详细记录错误信息</li>
<li>提供完整的错误日志</li>
<li>说明环境配置信息</li>
</ol>
]]></content:encoded></item><item><title>PostgreSQL Docker 部署指南</title><link>https://blog.heyaohua.com/posts/2025/10/postgresql-docker-deployment-guide/</link><pubDate>Thu, 09 Oct 2025 12:00:00 +0800</pubDate><guid>https://blog.heyaohua.com/posts/2025/10/postgresql-docker-deployment-guide/</guid><description>本指南详细介绍如何使用 Docker 部署一个包含 PostGIS、pgvector 和 TimescaleDB 扩展的 PostgreSQL 15 数据库。该方案解决了扩展兼容性问题，特别是 pgvector 的段错误问题。</description><content:encoded><![CDATA[<p>本指南详细介绍如何使用 Docker 部署一个包含 PostGIS、pgvector 和 TimescaleDB 扩展的 PostgreSQL 15 数据库。该方案解决了扩展兼容性问题，特别是 pgvector 的段错误问题。</p>
<h2 id="项目结构">项目结构</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>PgSQL/
</span></span><span style="display:flex;"><span>├── .env                          # 环境变量配置
</span></span><span style="display:flex;"><span>├── Dockerfile                    # PostgreSQL 镜像构建文件
</span></span><span style="display:flex;"><span>├── docker-compose.yml            # Docker Compose 配置
</span></span><span style="display:flex;"><span>├── README.md                     # 项目说明
</span></span><span style="display:flex;"><span>├── config/                       # 配置文件目录
</span></span><span style="display:flex;"><span>│   ├── pg_hba.conf              # 客户端认证配置
</span></span><span style="display:flex;"><span>│   └── postgresql.conf          # PostgreSQL 主配置
</span></span><span style="display:flex;"><span>├── data/                        # 数据持久化目录
</span></span><span style="display:flex;"><span>│   └── pgdata/                  # PostgreSQL 数据目录
</span></span><span style="display:flex;"><span>├── init-scripts/                # 初始化脚本
</span></span><span style="display:flex;"><span>│   └── 01-install-extensions.sql # 扩展安装脚本
</span></span><span style="display:flex;"><span>├── logs/                        # 日志目录
</span></span><span style="display:flex;"><span>└── test-examples.sql            # 测试示例
</span></span></code></pre></div><h2 id="快速开始">快速开始</h2>
<h3 id="1-环境准备">1. 环境准备</h3>
<p>确保系统已安装：</p>
<ul>
<li>Docker</li>
<li>Docker Compose</li>
</ul>
<h3 id="2-克隆或创建项目目录">2. 克隆或创建项目目录</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>mkdir -p ~/Server/PgSQL
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">cd</span> ~/Server/PgSQL
</span></span></code></pre></div><h3 id="3-配置环境变量">3. 配置环境变量</h3>
<p>创建 <code>.env</code> 文件：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># PostgreSQL 数据库配置
</span></span><span style="display:flex;"><span>POSTGRES_DB=devdb
</span></span><span style="display:flex;"><span>POSTGRES_USER=postgres
</span></span><span style="display:flex;"><span>POSTGRES_PASSWORD=your_secure_password
</span></span><span style="display:flex;"><span>POSTGRES_PORT=5432
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 注意：请修改 POSTGRES_PASSWORD 为您的实际密码
</span></span><span style="display:flex;"><span># 建议使用强密码，包含大小写字母、数字和特殊字符
</span></span></code></pre></div><h3 id="4-构建镜像">4. 构建镜像</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker build -t postgres-all-extensions:latest .
</span></span></code></pre></div><h3 id="5-启动服务">5. 启动服务</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker-compose up -d
</span></span></code></pre></div><h3 id="6-验证安装">6. 验证安装</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 检查容器状态</span>
</span></span><span style="display:flex;"><span>docker ps
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 连接数据库验证扩展</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> postgres-all-extensions psql -U postgres -d devdb -c <span style="color:#f1fa8c">&#34;SELECT extname, extversion FROM pg_extension WHERE extname IN (&#39;timescaledb&#39;, &#39;postgis&#39;, &#39;vector&#39;) ORDER BY extname;&#34;</span>
</span></span></code></pre></div><h2 id="详细配置说明">详细配置说明</h2>
<h3 id="dockerfile-解析">Dockerfile 解析</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>FROM postgres:15
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 安装系统依赖</span>
</span></span><span style="display:flex;"><span>RUN apt-get update <span style="color:#ff79c6">&amp;&amp;</span> apt-get install -y <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    build-essential <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    postgresql-server-dev-15 <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    cmake <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    git <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    wget <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    ca-certificates <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    postgresql-15-postgis-3 <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    postgresql-15-postgis-3-scripts <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    libkrb5-dev <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    libgssapi-krb5-2 <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">&amp;&amp;</span> rm -rf /var/lib/apt/lists/*
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 安装 pgvector (预编译版本，避免段错误)</span>
</span></span><span style="display:flex;"><span>RUN <span style="color:#8be9fd;font-style:italic">cd</span> /tmp <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    wget https://github.com/pgvector/pgvector/archive/v0.5.1.tar.gz <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    tar -xzf v0.5.1.tar.gz <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">cd</span> pgvector-0.5.1 <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    make <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    make install
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 安装 TimescaleDB (从源码编译)</span>
</span></span><span style="display:flex;"><span>RUN <span style="color:#8be9fd;font-style:italic">cd</span> /tmp <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    git clone https://github.com/timescale/timescaledb.git <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">cd</span> timescaledb <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    git checkout 2.13.0 <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    ./bootstrap <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">cd</span> build <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    make <span style="color:#ff79c6">&amp;&amp;</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>    make install
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 配置 PostgreSQL</span>
</span></span><span style="display:flex;"><span>RUN <span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;shared_preload_libraries = &#39;timescaledb&#39;&#34;</span> &gt;&gt; /usr/share/postgresql/postgresql.conf.sample
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 复制初始化脚本</span>
</span></span><span style="display:flex;"><span>COPY init-scripts/ /docker-entrypoint-initdb.d/
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>EXPOSE <span style="color:#bd93f9">5432</span>
</span></span></code></pre></div><h3 id="docker-compose-配置">Docker Compose 配置</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#ff79c6">version</span>: <span style="color:#f1fa8c">&#39;3.8&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">services</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#ff79c6">postgres-all-extensions</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">image</span>: postgres-all-extensions:latest
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">container_name</span>: postgres-all-extensions
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">environment</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">POSTGRES_DB</span>: ${POSTGRES_DB}
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">POSTGRES_USER</span>: ${POSTGRES_USER}
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">POSTGRES_PASSWORD</span>: ${POSTGRES_PASSWORD}
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">ports</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#f1fa8c">&#34;5432:5432&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">volumes</span>:
</span></span><span style="display:flex;"><span>      - ./data/pgdata:/var/lib/postgresql/data
</span></span><span style="display:flex;"><span>      - ./config/postgresql.conf:/etc/postgresql/postgresql.conf
</span></span><span style="display:flex;"><span>      - ./config/pg_hba.conf:/etc/postgresql/pg_hba.conf
</span></span><span style="display:flex;"><span>      - ./logs:/var/log/postgresql
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">networks</span>:
</span></span><span style="display:flex;"><span>      - postgres-network
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">restart</span>: unless-stopped
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">healthcheck</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">test</span>: [<span style="color:#f1fa8c">&#34;CMD-SHELL&#34;</span>, <span style="color:#f1fa8c">&#34;pg_isready -U postgres&#34;</span>]
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">interval</span>: 30s
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">timeout</span>: 10s
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">retries</span>: <span style="color:#bd93f9">3</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">networks</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#ff79c6">postgres-network</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">driver</span>: bridge
</span></span></code></pre></div><h2 id="扩展功能测试">扩展功能测试</h2>
<h3 id="postgis-测试">PostGIS 测试</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#6272a4">-- 创建几何数据
</span></span></span><span style="display:flex;"><span><span style="color:#ff79c6">SELECT</span> ST_AsText(ST_MakePoint(<span style="color:#ff79c6">-</span><span style="color:#bd93f9">71</span>.<span style="color:#bd93f9">064544</span>, <span style="color:#bd93f9">42</span>.<span style="color:#bd93f9">28787</span>));
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">-- 空间查询示例
</span></span></span><span style="display:flex;"><span><span style="color:#ff79c6">CREATE</span> <span style="color:#ff79c6">TABLE</span> locations (
</span></span><span style="display:flex;"><span>    id <span style="color:#8be9fd;font-style:italic">SERIAL</span> <span style="color:#ff79c6">PRIMARY</span> <span style="color:#ff79c6">KEY</span>,
</span></span><span style="display:flex;"><span>    name <span style="color:#8be9fd;font-style:italic">VARCHAR</span>(<span style="color:#bd93f9">100</span>),
</span></span><span style="display:flex;"><span>    geom GEOMETRY(POINT, <span style="color:#bd93f9">4326</span>)
</span></span><span style="display:flex;"><span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">INSERT</span> <span style="color:#ff79c6">INTO</span> locations (name, geom) <span style="color:#ff79c6">VALUES</span>
</span></span><span style="display:flex;"><span>(<span style="color:#f1fa8c">&#39;Boston&#39;</span>, ST_SetSRID(ST_MakePoint(<span style="color:#ff79c6">-</span><span style="color:#bd93f9">71</span>.<span style="color:#bd93f9">0589</span>, <span style="color:#bd93f9">42</span>.<span style="color:#bd93f9">3601</span>), <span style="color:#bd93f9">4326</span>));
</span></span></code></pre></div><h3 id="pgvector-测试">pgvector 测试</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#6272a4">-- 创建向量表
</span></span></span><span style="display:flex;"><span><span style="color:#ff79c6">CREATE</span> <span style="color:#ff79c6">TABLE</span> items (
</span></span><span style="display:flex;"><span>    id <span style="color:#8be9fd;font-style:italic">SERIAL</span> <span style="color:#ff79c6">PRIMARY</span> <span style="color:#ff79c6">KEY</span>,
</span></span><span style="display:flex;"><span>    embedding VECTOR(<span style="color:#bd93f9">3</span>)
</span></span><span style="display:flex;"><span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">-- 插入向量数据
</span></span></span><span style="display:flex;"><span><span style="color:#ff79c6">INSERT</span> <span style="color:#ff79c6">INTO</span> items (embedding) <span style="color:#ff79c6">VALUES</span>
</span></span><span style="display:flex;"><span>(<span style="color:#f1fa8c">&#39;[1,2,3]&#39;</span>),
</span></span><span style="display:flex;"><span>(<span style="color:#f1fa8c">&#39;[4,5,6]&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">-- 向量相似度查询
</span></span></span><span style="display:flex;"><span><span style="color:#ff79c6">SELECT</span> <span style="color:#ff79c6">*</span> <span style="color:#ff79c6">FROM</span> items <span style="color:#ff79c6">ORDER</span> <span style="color:#ff79c6">BY</span> embedding <span style="color:#ff79c6">&lt;-&gt;</span> <span style="color:#f1fa8c">&#39;[3,1,2]&#39;</span> <span style="color:#ff79c6">LIMIT</span> <span style="color:#bd93f9">5</span>;
</span></span></code></pre></div><h3 id="timescaledb-测试">TimescaleDB 测试</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#6272a4">-- 创建时序表
</span></span></span><span style="display:flex;"><span><span style="color:#ff79c6">CREATE</span> <span style="color:#ff79c6">TABLE</span> sensor_data (
</span></span><span style="display:flex;"><span>    time TIMESTAMPTZ <span style="color:#ff79c6">NOT</span> <span style="color:#ff79c6">NULL</span>,
</span></span><span style="display:flex;"><span>    sensor_id <span style="color:#8be9fd;font-style:italic">INTEGER</span>,
</span></span><span style="display:flex;"><span>    temperature DOUBLE <span style="color:#ff79c6">PRECISION</span>,
</span></span><span style="display:flex;"><span>    humidity DOUBLE <span style="color:#ff79c6">PRECISION</span>
</span></span><span style="display:flex;"><span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">-- 转换为超表
</span></span></span><span style="display:flex;"><span><span style="color:#ff79c6">SELECT</span> create_hypertable(<span style="color:#f1fa8c">&#39;sensor_data&#39;</span>, <span style="color:#f1fa8c">&#39;time&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">-- 插入时序数据
</span></span></span><span style="display:flex;"><span><span style="color:#ff79c6">INSERT</span> <span style="color:#ff79c6">INTO</span> sensor_data <span style="color:#ff79c6">VALUES</span>
</span></span><span style="display:flex;"><span>(NOW(), <span style="color:#bd93f9">1</span>, <span style="color:#bd93f9">23</span>.<span style="color:#bd93f9">5</span>, <span style="color:#bd93f9">65</span>.<span style="color:#bd93f9">2</span>),
</span></span><span style="display:flex;"><span>(NOW() <span style="color:#ff79c6">-</span> <span style="color:#8be9fd;font-style:italic">INTERVAL</span> <span style="color:#f1fa8c">&#39;1 hour&#39;</span>, <span style="color:#bd93f9">1</span>, <span style="color:#bd93f9">22</span>.<span style="color:#bd93f9">8</span>, <span style="color:#bd93f9">64</span>.<span style="color:#bd93f9">1</span>);
</span></span></code></pre></div><h2 id="连接配置">连接配置</h2>
<h3 id="ide-连接参数">IDE 连接参数</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>Host: localhost
</span></span><span style="display:flex;"><span>Port: 5432
</span></span><span style="display:flex;"><span>Database: devdb (或 postgres)
</span></span><span style="display:flex;"><span>Username: postgres
</span></span><span style="display:flex;"><span>Password: [您在.env中设置的密码]
</span></span></code></pre></div><h3 id="命令行连接">命令行连接</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 使用 Docker 容器内的 psql</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> -it postgres-all-extensions psql -U postgres -d devdb
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 使用外部 psql (需要安装 PostgreSQL 客户端)</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">PGPASSWORD</span><span style="color:#ff79c6">=</span>your_password psql -h localhost -p <span style="color:#bd93f9">5432</span> -U postgres -d devdb
</span></span></code></pre></div><h2 id="管理命令">管理命令</h2>
<h3 id="启动停止服务">启动/停止服务</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 启动服务</span>
</span></span><span style="display:flex;"><span>docker-compose up -d
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 停止服务</span>
</span></span><span style="display:flex;"><span>docker-compose down
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 重启服务</span>
</span></span><span style="display:flex;"><span>docker-compose restart
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 查看日志</span>
</span></span><span style="display:flex;"><span>docker-compose logs -f
</span></span></code></pre></div><h3 id="数据备份与恢复">数据备份与恢复</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 备份数据库</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> postgres-all-extensions pg_dump -U postgres devdb &gt; backup.sql
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 恢复数据库</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> -i postgres-all-extensions psql -U postgres devdb &lt; backup.sql
</span></span></code></pre></div><h3 id="性能监控">性能监控</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 查看容器资源使用</span>
</span></span><span style="display:flex;"><span>docker stats postgres-all-extensions
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 查看数据库连接</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> postgres-all-extensions psql -U postgres -c <span style="color:#f1fa8c">&#34;SELECT * FROM pg_stat_activity;&#34;</span>
</span></span></code></pre></div><h2 id="安全建议">安全建议</h2>
<ol>
<li>修改默认密码：确保在 <code>.env</code> 文件中设置强密码</li>
<li>网络安全：生产环境中限制 <code>pg_hba.conf</code> 的访问范围</li>
<li>数据加密：考虑启用 SSL/TLS 连接</li>
<li>定期备份：建立自动化备份策略</li>
<li>更新维护：定期更新 PostgreSQL 和扩展版本</li>
</ol>
<h2 id="版本信息">版本信息</h2>
<ul>
<li>PostgreSQL: 15.14</li>
<li>PostGIS: 3.6.0</li>
<li>pgvector: 0.5.1</li>
<li>TimescaleDB: 2.13.0</li>
</ul>
<h2 id="许可证">许可证</h2>
<p>本项目遵循 MIT 许可证。各个扩展遵循其各自的许可证条款。</p>
]]></content:encoded></item><item><title>Docker Hue 时区修改完整指南</title><link>https://blog.heyaohua.com/posts/2025/09/docker-hue-timezone/</link><pubDate>Mon, 08 Sep 2025 10:00:00 +0800</pubDate><guid>https://blog.heyaohua.com/posts/2025/09/docker-hue-timezone/</guid><description>使用Docker启动Hue后，发现时区不正确，显示UTC时间而不是中国标准时间(CST)。具体表现为： - HDFS文件时间显示为UTC时间（如06:00-06:01） - 实际文件创建时间为中国时间（如14:00-14:01） - Hue日志时间格式混乱</description><content:encoded><![CDATA[<h2 id="问题描述">问题描述</h2>
<p>使用Docker启动Hue后，发现时区不正确，显示UTC时间而不是中国标准时间(CST)。具体表现为：</p>
<ul>
<li>HDFS文件时间显示为UTC时间（如06:00-06:01）</li>
<li>实际文件创建时间为中国时间（如14:00-14:01）</li>
<li>Hue日志时间格式混乱</li>
</ul>
<h2 id="解决方案概述">解决方案概述</h2>
<p>需要从多个层面修改时区设置：</p>
<ol>
<li>容器系统时区设置</li>
<li>Hue配置文件时区设置</li>
<li>Django时区设置</li>
<li>文件浏览器模块时区处理</li>
</ol>
<h2 id="详细修改步骤">详细修改步骤</h2>
<h3 id="1-检查当前容器状态">1. 检查当前容器状态</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 查看运行中的Hue容器</span>
</span></span><span style="display:flex;"><span>docker ps -a | grep hue
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 检查容器时区</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> &lt;container_name&gt; date
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 检查Hue日志时间格式</span>
</span></span><span style="display:flex;"><span>docker logs &lt;container_name&gt; --tail <span style="color:#bd93f9">10</span>
</span></span></code></pre></div><h3 id="2-备份原始配置">2. 备份原始配置</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 备份Hue配置文件</span>
</span></span><span style="display:flex;"><span>cp /data/server/hue-server/config/hue.ini /data/server/hue-server/config/hue.ini.backup.<span style="color:#ff79c6">$(</span>date +%Y%m%d_%H%M%S<span style="color:#ff79c6">)</span>
</span></span><span style="display:flex;"><span>cp /data/server/hue-server/config/z-hue-overrides.ini /data/server/hue-server/config/z-hue-overrides.ini.backup.<span style="color:#ff79c6">$(</span>date +%Y%m%d_%H%M%S<span style="color:#ff79c6">)</span>
</span></span></code></pre></div><h3 id="3-修改hue配置文件中的时区设置">3. 修改Hue配置文件中的时区设置</h3>
<h4 id="31-修改主配置文件">3.1 修改主配置文件</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 修改 hue.ini 中的时区设置
</span></span><span style="display:flex;"><span>sed -i &#39;s/time_zone=America\/Los_Angeles/time_zone=Asia\/Shanghai/g&#39; /data/server/hue-server/config/hue.ini
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 添加Django时区设置
</span></span><span style="display:flex;"><span>sed -i &#39;/time_zone=Asia\/Shanghai/a use_tz=true&#39; /data/server/hue-server/config/hue.ini
</span></span></code></pre></div><h4 id="32-修改覆盖配置文件">3.2 修改覆盖配置文件</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 修改 z-hue-overrides.ini 中的时区设置
</span></span><span style="display:flex;"><span>sed -i &#39;s/time_zone=America\/Los_Angeles/time_zone=Asia\/Shanghai/g&#39; /data/server/hue-server/config/z-hue-overrides.ini
</span></span></code></pre></div><h3 id="4-重新创建容器包含时区和dns设置">4. 重新创建容器（包含时区和DNS设置）</h3>
<h4 id="41-停止并删除旧容器">4.1 停止并删除旧容器</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker stop &lt;old_container_name&gt;
</span></span><span style="display:flex;"><span>docker rm &lt;old_container_name&gt;
</span></span></code></pre></div><h4 id="42-创建新容器">4.2 创建新容器</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker run -d --name hue_new <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>  -p 8888:8888 <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>  -e <span style="color:#8be9fd;font-style:italic">TZ</span><span style="color:#ff79c6">=</span>Asia/Shanghai <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>  -v /etc/localtime:/etc/localtime:ro <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>  -v /usr/share/zoneinfo/Asia/Shanghai:/etc/timezone:ro <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>  -v /data/server/hue-server/config:/usr/share/hue/desktop/conf <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>  --dns<span style="color:#ff79c6">=</span>100.100.2.136 <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>  --dns<span style="color:#ff79c6">=</span>8.8.8.8 <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>  gethue/hue:latest
</span></span></code></pre></div><h3 id="5-修改文件浏览器模块时区处理">5. 修改文件浏览器模块时区处理</h3>
<h4 id="51-备份原始文件">5.1 备份原始文件</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> hue_new cp /usr/share/hue/apps/filebrowser/src/filebrowser/views.py /usr/share/hue/apps/filebrowser/src/filebrowser/views.py.backup
</span></span></code></pre></div><h4 id="52-修改时区处理代码">5.2 修改时区处理代码</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 添加Django时区导入</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> hue_new sed -i <span style="color:#f1fa8c">&#34;s/from datetime import datetime/from datetime import datetime, timezone, timedelta\nfrom django.utils import timezone as django_timezone/g&#34;</span> /usr/share/hue/apps/filebrowser/src/filebrowser/views.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 修改时间格式化代码</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> hue_new sed -i <span style="color:#f1fa8c">&#34;s/datetime.fromtimestamp(stats.mtime).strftime(&#39;%B %d, %Y %I:%M %p&#39;)/django_timezone.make_aware(datetime.fromtimestamp(stats.mtime)).strftime(&#39;%B %d, %Y %I:%M %p&#39;)/g&#34;</span> /usr/share/hue/apps/filebrowser/src/filebrowser/views.py
</span></span></code></pre></div><h4 id="53-清除python缓存">5.3 清除Python缓存</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> hue_new find /usr/share/hue -name <span style="color:#f1fa8c">&#34;*.pyc&#34;</span> -path <span style="color:#f1fa8c">&#34;*/filebrowser/*&#34;</span> -delete
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> hue_new find /usr/share/hue -name <span style="color:#f1fa8c">&#34;__pycache__&#34;</span> -path <span style="color:#f1fa8c">&#34;*/filebrowser/*&#34;</span> -exec rm -rf <span style="color:#ff79c6">{}</span> <span style="color:#f1fa8c">\;</span> 2&gt;/dev/null <span style="color:#ff79c6">||</span> <span style="color:#8be9fd;font-style:italic">true</span>
</span></span></code></pre></div><h3 id="6-重启容器应用修改">6. 重启容器应用修改</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker restart hue_new
</span></span></code></pre></div><h3 id="7-验证修改结果">7. 验证修改结果</h3>
<h4 id="71-检查系统时区">7.1 检查系统时区</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 检查容器系统时间</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> hue_new date
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 检查时区环境变量</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> hue_new env | grep TZ
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 检查时区文件</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> hue_new cat /etc/timezone
</span></span></code></pre></div><h4 id="72-检查hue应用时区">7.2 检查Hue应用时区</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#6272a4"># 查看Hue日志，确认时间格式</span>
</span></span><span style="display:flex;"><span>docker logs hue_new <span style="color:#ff79c6">--</span>tail <span style="color:#bd93f9">10</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 检查Django时区设置</span>
</span></span><span style="display:flex;"><span>docker exec hue_new <span style="color:#ff79c6">/</span>usr<span style="color:#ff79c6">/</span>share<span style="color:#ff79c6">/</span>hue<span style="color:#ff79c6">/</span>build<span style="color:#ff79c6">/</span>env<span style="color:#ff79c6">/</span><span style="color:#8be9fd;font-style:italic">bin</span><span style="color:#ff79c6">/</span>python3 <span style="color:#ff79c6">-</span>c <span style="color:#f1fa8c">&#34;import os; os.environ.setdefault(&#39;DJANGO_SETTINGS_MODULE&#39;, &#39;desktop.settings&#39;); import django; django.setup(); from django.utils import timezone; print(&#39;Django timezone:&#39;, timezone.get_current_timezone())&#34;</span>
</span></span></code></pre></div><h4 id="73-检查文件浏览器时间显示">7.3 检查文件浏览器时间显示</h4>
<p>访问Hue文件浏览器，查看HDFS文件的时间显示是否正确。</p>
<h2 id="关键配置说明">关键配置说明</h2>
<h3 id="1-环境变量设置">1. 环境变量设置</h3>
<ul>
<li><code>TZ=Asia/Shanghai</code>: 设置容器系统时区</li>
<li><code>-v /etc/localtime:/etc/localtime:ro</code>: 挂载主机时区文件</li>
<li><code>-v /usr/share/zoneinfo/Asia/Shanghai:/etc/timezone:ro</code>: 挂载时区信息文件</li>
</ul>
<h3 id="2-dns设置">2. DNS设置</h3>
<ul>
<li><code>--dns=100.100.2.136</code>: 内网DNS服务器</li>
<li><code>--dns=8.8.8.8</code>: 公共DNS服务器</li>
</ul>
<h3 id="3-配置文件修改">3. 配置文件修改</h3>
<ul>
<li><code>hue.ini</code>: 主配置文件中的 <code>time_zone=Asia/Shanghai</code> 和 <code>use_tz=true</code></li>
<li><code>z-hue-overrides.ini</code>: 覆盖配置文件中的 <code>time_zone=Asia/Shanghai</code></li>
</ul>
<h3 id="4-代码修改">4. 代码修改</h3>
<ul>
<li>文件：<code>/usr/share/hue/apps/filebrowser/src/filebrowser/views.py</code></li>
<li>修改：使用Django的时区设置处理文件时间显示</li>
</ul>
<h2 id="完整的一键脚本">完整的一键脚本</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#ff79c6">#!/bin/bash
</span></span></span><span style="display:flex;"><span><span style="color:#6272a4"># Hue时区修改完整脚本</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">CONTAINER_NAME</span><span style="color:#ff79c6">=</span><span style="color:#f1fa8c">&#34;hue_new&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">CONFIG_PATH</span><span style="color:#ff79c6">=</span><span style="color:#f1fa8c">&#34;/data/server/hue-server/config&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;开始修改Hue时区设置...&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 1. 备份配置</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;备份原始配置...&#34;</span>
</span></span><span style="display:flex;"><span>cp <span style="color:#8be9fd;font-style:italic">$CONFIG_PATH</span>/hue.ini <span style="color:#8be9fd;font-style:italic">$CONFIG_PATH</span>/hue.ini.backup.<span style="color:#ff79c6">$(</span>date +%Y%m%d_%H%M%S<span style="color:#ff79c6">)</span>
</span></span><span style="display:flex;"><span>cp <span style="color:#8be9fd;font-style:italic">$CONFIG_PATH</span>/z-hue-overrides.ini <span style="color:#8be9fd;font-style:italic">$CONFIG_PATH</span>/z-hue-overrides.ini.backup.<span style="color:#ff79c6">$(</span>date +%Y%m%d_%H%M%S<span style="color:#ff79c6">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 2. 修改配置文件</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;修改时区配置...&#34;</span>
</span></span><span style="display:flex;"><span>sed -i <span style="color:#f1fa8c">&#39;s/time_zone=America\/Los_Angeles/time_zone=Asia\/Shanghai/g&#39;</span> <span style="color:#8be9fd;font-style:italic">$CONFIG_PATH</span>/hue.ini
</span></span><span style="display:flex;"><span>sed -i <span style="color:#f1fa8c">&#39;s/time_zone=America\/Los_Angeles/time_zone=Asia\/Shanghai/g&#39;</span> <span style="color:#8be9fd;font-style:italic">$CONFIG_PATH</span>/z-hue-overrides.ini
</span></span><span style="display:flex;"><span>sed -i <span style="color:#f1fa8c">&#39;/time_zone=Asia\/Shanghai/a use_tz=true&#39;</span> <span style="color:#8be9fd;font-style:italic">$CONFIG_PATH</span>/hue.ini
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 3. 停止旧容器</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;停止旧容器...&#34;</span>
</span></span><span style="display:flex;"><span>docker stop <span style="color:#8be9fd;font-style:italic">$CONTAINER_NAME</span> 2&gt;/dev/null <span style="color:#ff79c6">||</span> <span style="color:#8be9fd;font-style:italic">true</span>
</span></span><span style="display:flex;"><span>docker rm <span style="color:#8be9fd;font-style:italic">$CONTAINER_NAME</span> 2&gt;/dev/null <span style="color:#ff79c6">||</span> <span style="color:#8be9fd;font-style:italic">true</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 4. 创建新容器</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;创建新容器...&#34;</span>
</span></span><span style="display:flex;"><span>docker run -d --name <span style="color:#8be9fd;font-style:italic">$CONTAINER_NAME</span> <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>  -p 8888:8888 <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>  -e <span style="color:#8be9fd;font-style:italic">TZ</span><span style="color:#ff79c6">=</span>Asia/Shanghai <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>  -v /etc/localtime:/etc/localtime:ro <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>  -v /usr/share/zoneinfo/Asia/Shanghai:/etc/timezone:ro <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>  -v <span style="color:#8be9fd;font-style:italic">$CONFIG_PATH</span>:/usr/share/hue/desktop/conf <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>  --dns<span style="color:#ff79c6">=</span>100.100.2.136 <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>  --dns<span style="color:#ff79c6">=</span>8.8.8.8 <span style="color:#f1fa8c">\
</span></span></span><span style="display:flex;"><span>  gethue/hue:latest
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 5. 等待启动</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;等待容器启动...&#34;</span>
</span></span><span style="display:flex;"><span>sleep <span style="color:#bd93f9">20</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 6. 修改文件浏览器代码</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;修改文件浏览器时区处理...&#34;</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> <span style="color:#8be9fd;font-style:italic">$CONTAINER_NAME</span> cp /usr/share/hue/apps/filebrowser/src/filebrowser/views.py /usr/share/hue/apps/filebrowser/src/filebrowser/views.py.backup
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> <span style="color:#8be9fd;font-style:italic">$CONTAINER_NAME</span> sed -i <span style="color:#f1fa8c">&#34;s/from datetime import datetime/from datetime import datetime, timezone, timedelta\nfrom django.utils import timezone as django_timezone/g&#34;</span> /usr/share/hue/apps/filebrowser/src/filebrowser/views.py
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> <span style="color:#8be9fd;font-style:italic">$CONTAINER_NAME</span> sed -i <span style="color:#f1fa8c">&#34;s/datetime.fromtimestamp(stats.mtime).strftime(&#39;%B %d, %Y %I:%M %p&#39;)/django_timezone.make_aware(datetime.fromtimestamp(stats.mtime)).strftime(&#39;%B %d, %Y %I:%M %p&#39;)/g&#34;</span> /usr/share/hue/apps/filebrowser/src/filebrowser/views.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 7. 清除缓存</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;清除Python缓存...&#34;</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> <span style="color:#8be9fd;font-style:italic">$CONTAINER_NAME</span> find /usr/share/hue -name <span style="color:#f1fa8c">&#34;*.pyc&#34;</span> -path <span style="color:#f1fa8c">&#34;*/filebrowser/*&#34;</span> -delete
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> <span style="color:#8be9fd;font-style:italic">$CONTAINER_NAME</span> find /usr/share/hue -name <span style="color:#f1fa8c">&#34;__pycache__&#34;</span> -path <span style="color:#f1fa8c">&#34;*/filebrowser/*&#34;</span> -exec rm -rf <span style="color:#ff79c6">{}</span> <span style="color:#f1fa8c">\;</span> 2&gt;/dev/null <span style="color:#ff79c6">||</span> <span style="color:#8be9fd;font-style:italic">true</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 8. 重启容器</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;重启容器应用修改...&#34;</span>
</span></span><span style="display:flex;"><span>docker restart <span style="color:#8be9fd;font-style:italic">$CONTAINER_NAME</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 9. 等待重启</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;等待容器重启...&#34;</span>
</span></span><span style="display:flex;"><span>sleep <span style="color:#bd93f9">25</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 10. 验证结果</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;验证时区设置...&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;系统时间:&#34;</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> <span style="color:#8be9fd;font-style:italic">$CONTAINER_NAME</span> date
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;Hue日志时间格式:&#34;</span>
</span></span><span style="display:flex;"><span>docker logs <span style="color:#8be9fd;font-style:italic">$CONTAINER_NAME</span> --tail <span style="color:#bd93f9">3</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;Django时区设置:&#34;</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> <span style="color:#8be9fd;font-style:italic">$CONTAINER_NAME</span> /usr/share/hue/build/env/bin/python3 -c <span style="color:#f1fa8c">&#34;import os; os.environ.setdefault(&#39;DJANGO_SETTINGS_MODULE&#39;, &#39;desktop.settings&#39;); import django; django.setup(); from django.utils import timezone; print(&#39;Django timezone:&#39;, timezone.get_current_timezone())&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;时区修改完成！&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">echo</span> <span style="color:#f1fa8c">&#34;请访问 http://localhost:8888 查看文件浏览器中的时间显示是否正确。&#34;</span>
</span></span></code></pre></div><h2 id="常见问题排查">常见问题排查</h2>
<h3 id="1-dns解析问题">1. DNS解析问题</h3>
<p>如果出现 <code>Name or service not known</code> 错误：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 检查DNS配置</span>
</span></span><span style="display:flex;"><span>docker inspect &lt;container_name&gt; | grep -A <span style="color:#bd93f9">5</span> -B <span style="color:#bd93f9">5</span> -i dns
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 确保容器有正确的DNS设置</span>
</span></span><span style="display:flex;"><span>--dns<span style="color:#ff79c6">=</span>100.100.2.136 --dns<span style="color:#ff79c6">=</span>8.8.8.8
</span></span></code></pre></div><h3 id="2-时区仍然不正确">2. 时区仍然不正确</h3>
<p>检查所有配置文件中的时区设置：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>grep -r -i &#34;time_zone\|timezone&#34; /data/server/hue-server/config/ | grep -v &#34;.backup&#34;
</span></span></code></pre></div><h3 id="3-文件浏览器时间显示不正确">3. 文件浏览器时间显示不正确</h3>
<p>检查代码修改是否正确：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> &lt;container_name&gt; grep -n -A <span style="color:#bd93f9">2</span> -B <span style="color:#bd93f9">2</span> <span style="color:#f1fa8c">&#34;mtime.*datetime&#34;</span> /usr/share/hue/apps/filebrowser/src/filebrowser/views.py
</span></span></code></pre></div><h3 id="4-容器无法启动">4. 容器无法启动</h3>
<p>检查挂载路径是否正确：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 确保配置文件路径存在
</span></span><span style="display:flex;"><span>ls -la /data/server/hue-server/config/
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 检查挂载权限
</span></span><span style="display:flex;"><span>ls -la /data/server/hue-server/config/hue.ini
</span></span></code></pre></div><h2 id="验证成功标志">验证成功标志</h2>
<ul>
<li>容器系统时间显示：<code>Mon Sep  8 15:08:02 Asia 2025</code></li>
<li>Hue日志时间格式：<code>[08/Sep/2025 15:08:02 +0800]</code></li>
<li>环境变量：<code>TZ=Asia/Shanghai</code></li>
<li>Django时区：<code>Asia/Shanghai</code></li>
<li>HDFS文件时间显示：正确的中国时间（如14:00-14:01）</li>
<li>HDFS连接正常，无DNS解析错误</li>
</ul>
<h2 id="注意事项">注意事项</h2>
<ol>
<li><strong>备份重要</strong>: 修改前务必备份原始配置文件和代码文件</li>
<li><strong>DNS设置</strong>: 确保容器有正确的DNS配置，否则无法连接HDFS</li>
<li><strong>配置文件</strong>: 需要修改两个配置文件：<code>hue.ini</code> 和 <code>z-hue-overrides.ini</code></li>
<li><strong>代码修改</strong>: 需要修改文件浏览器模块的时区处理代码</li>
<li><strong>重启生效</strong>: 修改配置和代码后需要重启容器才能生效</li>
<li><strong>权限检查</strong>: 确保挂载的配置文件有正确的读写权限</li>
<li><strong>缓存清理</strong>: 修改Python代码后需要清除缓存</li>
</ol>
<h2 id="回滚方法">回滚方法</h2>
<p>如果修改后出现问题，可以按以下步骤回滚：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 1. 恢复配置文件</span>
</span></span><span style="display:flex;"><span>cp /data/server/hue-server/config/hue.ini.backup.* /data/server/hue-server/config/hue.ini
</span></span><span style="display:flex;"><span>cp /data/server/hue-server/config/z-hue-overrides.ini.backup.* /data/server/hue-server/config/z-hue-overrides.ini
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 2. 恢复代码文件</span>
</span></span><span style="display:flex;"><span>docker <span style="color:#8be9fd;font-style:italic">exec</span> &lt;container_name&gt; cp /usr/share/hue/apps/filebrowser/src/filebrowser/views.py.backup /usr/share/hue/apps/filebrowser/src/filebrowser/views.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 3. 重启容器</span>
</span></span><span style="display:flex;"><span>docker restart &lt;container_name&gt;
</span></span></code></pre></div>]]></content:encoded></item><item><title>Redis Docker开发环境配置指南</title><link>https://blog.heyaohua.com/posts/2024/03/redis-docker-development-guide/</link><pubDate>Tue, 19 Mar 2024 12:00:00 +0800</pubDate><guid>https://blog.heyaohua.com/posts/2024/03/redis-docker-development-guide/</guid><description>本文档详细介绍如何使用Docker搭建Redis开发环境，包括环境配置、启动方式、维护方法等内容。</description><content:encoded><![CDATA[<h1 id="redis-docker开发环境配置指南">Redis Docker开发环境配置指南</h1>
<p>本文档详细介绍如何使用Docker搭建Redis开发环境，包括环境配置、启动方式、维护方法等内容。</p>
<h2 id="目录结构">目录结构</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>Redis_Docker/
</span></span><span style="display:flex;"><span>├── .env                # 环境变量配置文件
</span></span><span style="display:flex;"><span>├── README.md          # 项目说明文档
</span></span><span style="display:flex;"><span>├── config/            # 配置文件目录
</span></span><span style="display:flex;"><span>│   └── redis.conf    # Redis配置文件
</span></span><span style="display:flex;"><span>├── data/             # 数据存储目录
</span></span><span style="display:flex;"><span>└── logs/             # 日志文件目录
</span></span></code></pre></div><h2 id="配置文件说明">配置文件说明</h2>
<h3 id="1-docker-composeyml">1. docker-compose.yml</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#ff79c6">version</span>: <span style="color:#f1fa8c">&#39;3.8&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">services</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#ff79c6">redis</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">container_name</span>: redis-server
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">image</span>: redis:7.2
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">ports</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#f1fa8c">&#34;${REDIS_PORT}:6379&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">volumes</span>:
</span></span><span style="display:flex;"><span>      - ./data:/data
</span></span><span style="display:flex;"><span>      - ./logs:/var/log/redis
</span></span><span style="display:flex;"><span>      - ./config/redis.conf:/usr/local/etc/redis/redis.conf
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">command</span>: redis-server /usr/local/etc/redis/redis.conf
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">environment</span>:
</span></span><span style="display:flex;"><span>      - TZ=Asia/Shanghai
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">networks</span>:
</span></span><span style="display:flex;"><span>      - redis-network
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">healthcheck</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">test</span>: [<span style="color:#f1fa8c">&#34;CMD&#34;</span>, <span style="color:#f1fa8c">&#34;redis-cli&#34;</span>, <span style="color:#f1fa8c">&#34;ping&#34;</span>]
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">interval</span>: 10s
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">timeout</span>: 5s
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">retries</span>: <span style="color:#bd93f9">5</span>
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">start_period</span>: 5s
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">networks</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#ff79c6">redis-network</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">driver</span>: bridge
</span></span></code></pre></div><h3 id="2-env-环境变量配置">2. .env 环境变量配置</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># Redis 配置环境变量
</span></span><span style="display:flex;"><span>REDIS_PORT=6379           # Redis端口映射
</span></span><span style="display:flex;"><span>REDIS_PASSWORD=your_password  # Redis访问密码
</span></span></code></pre></div><h3 id="3-redisconf-主要配置">3. redis.conf 主要配置</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 网络设置
</span></span><span style="display:flex;"><span>bind 0.0.0.0
</span></span><span style="display:flex;"><span>port 6379
</span></span><span style="display:flex;"><span>protected-mode yes
</span></span><span style="display:flex;"><span>tcp-keepalive 300
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 基本设置
</span></span><span style="display:flex;"><span>databases 16
</span></span><span style="display:flex;"><span>loglevel notice
</span></span><span style="display:flex;"><span>logfile &#34;/var/log/redis/redis.log&#34;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 内存设置
</span></span><span style="display:flex;"><span>maxmemory 256mb
</span></span><span style="display:flex;"><span>maxmemory-policy allkeys-lru
</span></span><span style="display:flex;"><span>maxmemory-samples 5
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 持久化设置
</span></span><span style="display:flex;"><span>save 900 1      # 900秒内至少1个键被修改
</span></span><span style="display:flex;"><span>save 300 10     # 300秒内至少10个键被修改
</span></span><span style="display:flex;"><span>save 60 10000   # 60秒内至少10000个键被修改
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># AOF设置
</span></span><span style="display:flex;"><span>appendonly yes
</span></span><span style="display:flex;"><span>appendfilename &#34;appendonly.aof&#34;
</span></span><span style="display:flex;"><span>appendfsync everysec
</span></span></code></pre></div><h2 id="使用说明">使用说明</h2>
<h3 id="1-启动服务">1. 启动服务</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 启动服务</span>
</span></span><span style="display:flex;"><span>docker-compose up -d
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 查看服务状态</span>
</span></span><span style="display:flex;"><span>docker-compose ps
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 查看日志</span>
</span></span><span style="display:flex;"><span>docker-compose logs redis
</span></span></code></pre></div><h3 id="2-连接redis">2. 连接Redis</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 使用容器内的redis-cli</span>
</span></span><span style="display:flex;"><span>docker-compose <span style="color:#8be9fd;font-style:italic">exec</span> redis redis-cli -a your_password
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 使用主机的redis-cli（如果已安装）</span>
</span></span><span style="display:flex;"><span>redis-cli -h localhost -p <span style="color:#bd93f9">6379</span> -a your_password
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 测试连接</span>
</span></span><span style="display:flex;"><span>redis-cli -h localhost -p <span style="color:#bd93f9">6379</span> -a your_password ping
</span></span></code></pre></div><h3 id="3-停止服务">3. 停止服务</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 停止服务</span>
</span></span><span style="display:flex;"><span>docker-compose down
</span></span></code></pre></div><h2 id="数据持久化">数据持久化</h2>
<p>Redis配置了双重持久化机制：</p>
<h3 id="1-rdb持久化">1. RDB持久化</h3>
<ul>
<li>文件位置：data/dump.rdb</li>
<li>自动保存策略：</li>
<li>900秒内至少1个键被修改</li>
<li>300秒内至少10个键被修改</li>
<li>60秒内至少10000个键被修改</li>
</ul>
<h3 id="2-aof持久化">2. AOF持久化</h3>
<ul>
<li>文件位置：data/appendonly.aof</li>
<li>同步策略：everysec（每秒同步）</li>
<li>重写策略：auto-aof-rewrite-percentage 100</li>
</ul>
<h2 id="性能优化">性能优化</h2>
<h3 id="1-内存配置">1. 内存配置</h3>
<ul>
<li>maxmemory：设置为256MB</li>
<li>maxmemory-policy：使用allkeys-lru策略</li>
<li>maxmemory-samples：设置为5</li>
</ul>
<h3 id="2-网络优化">2. 网络优化</h3>
<ul>
<li>tcp-keepalive：300秒</li>
<li>tcp-backlog：511</li>
</ul>
<h3 id="3-持久化优化">3. 持久化优化</h3>
<ul>
<li>appendfsync：everysec</li>
<li>no-appendfsync-on-rewrite：no</li>
</ul>
<h2 id="安全配置">安全配置</h2>
<h3 id="1-网络安全">1. 网络安全</h3>
<ul>
<li>protected-mode：启用</li>
<li>bind：0.0.0.0（允许所有IP访问）</li>
<li>requirepass：设置访问密码</li>
</ul>
<h3 id="2-客户端限制">2. 客户端限制</h3>
<ul>
<li>maxclients：10000</li>
<li>timeout：0（不自动断开空闲连接）</li>
</ul>
<h2 id="监控和维护">监控和维护</h2>
<h3 id="1-性能监控">1. 性能监控</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 查看服务器信息
</span></span><span style="display:flex;"><span>redis-cli -a your_password INFO
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 监控命令执行
</span></span><span style="display:flex;"><span>redis-cli -a your_password MONITOR
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 查看慢查询日志
</span></span><span style="display:flex;"><span>redis-cli -a your_password SLOWLOG GET
</span></span></code></pre></div><h3 id="2-内存分析">2. 内存分析</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 查看内存使用情况
</span></span><span style="display:flex;"><span>redis-cli -a your_password INFO memory
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 查看大键
</span></span><span style="display:flex;"><span>redis-cli -a your_password --bigkeys
</span></span></code></pre></div><h3 id="3-数据备份">3. 数据备份</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 手动触发RDB备份
</span></span><span style="display:flex;"><span>redis-cli -a your_password SAVE
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 异步触发RDB备份
</span></span><span style="display:flex;"><span>redis-cli -a your_password BGSAVE
</span></span></code></pre></div><h2 id="常见问题处理">常见问题处理</h2>
<h3 id="1-连接失败">1. 连接失败</h3>
<ul>
<li>检查密码是否正确</li>
<li>确认端口映射是否正确</li>
<li>验证Redis服务是否正常运行</li>
</ul>
<h3 id="2-内存问题">2. 内存问题</h3>
<ul>
<li>检查maxmemory设置</li>
<li>查看内存使用情况</li>
<li>考虑调整内存策略</li>
</ul>
<h3 id="3-持久化问题">3. 持久化问题</h3>
<ul>
<li>检查磁盘空间</li>
<li>查看AOF/RDB文件状态</li>
<li>确认写入权限</li>
</ul>
<h2 id="最佳实践">最佳实践</h2>
<h3 id="1-安全建议">1. 安全建议</h3>
<ul>
<li>使用强密码</li>
<li>限制可访问的IP</li>
<li>定期更新Redis版本</li>
</ul>
<h3 id="2-性能建议">2. 性能建议</h3>
<ul>
<li>合理设置内存上限</li>
<li>选择适当的持久化策略</li>
<li>监控慢查询</li>
</ul>
<h3 id="3-运维建议">3. 运维建议</h3>
<ul>
<li>定期备份数据</li>
<li>监控系统资源</li>
<li>保持日志分析</li>
</ul>
]]></content:encoded></item><item><title>PostgreSQL Docker开发环境配置指南</title><link>https://blog.heyaohua.com/posts/2024/03/postgresql-docker-development-guide/</link><pubDate>Tue, 19 Mar 2024 11:30:00 +0800</pubDate><guid>https://blog.heyaohua.com/posts/2024/03/postgresql-docker-development-guide/</guid><description>本文档详细介绍如何使用Docker搭建PostgreSQL开发环境，包括环境配置、启动方式、维护方法等内容。</description><content:encoded><![CDATA[<h1 id="postgresql-docker开发环境配置指南">PostgreSQL Docker开发环境配置指南</h1>
<p>本文档详细介绍如何使用Docker搭建PostgreSQL开发环境，包括环境配置、启动方式、维护方法等内容。</p>
<h2 id="目录结构">目录结构</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>PgSQL_Docker/
</span></span><span style="display:flex;"><span>├── .env                  # 环境变量配置文件
</span></span><span style="display:flex;"><span>├── README.md            # 项目说明文档
</span></span><span style="display:flex;"><span>├── config/              # 配置文件目录
</span></span><span style="display:flex;"><span>│   ├── pg_hba.conf     # 访问控制配置
</span></span><span style="display:flex;"><span>│   └── postgresql.conf  # PostgreSQL主配置文件
</span></span><span style="display:flex;"><span>├── data/               # 数据存储目录
</span></span><span style="display:flex;"><span>└── logs/               # 日志文件目录
</span></span></code></pre></div><h2 id="配置文件说明">配置文件说明</h2>
<h3 id="1-docker-composeyml">1. docker-compose.yml</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#ff79c6">version</span>: <span style="color:#f1fa8c">&#39;3.8&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">services</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#ff79c6">postgres</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">container_name</span>: postgres-server
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">image</span>: postgres:15
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">environment</span>:
</span></span><span style="display:flex;"><span>      - POSTGRES_DB=${POSTGRES_DB}
</span></span><span style="display:flex;"><span>      - POSTGRES_USER=${POSTGRES_USER}
</span></span><span style="display:flex;"><span>      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">ports</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#f1fa8c">&#34;${POSTGRES_PORT}:5432&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">volumes</span>:
</span></span><span style="display:flex;"><span>      - ./data:/var/lib/postgresql/data
</span></span><span style="display:flex;"><span>      - ./logs:/var/log/postgresql
</span></span><span style="display:flex;"><span>      - ./config/postgresql.conf:/etc/postgresql/postgresql.conf
</span></span><span style="display:flex;"><span>      - ./config/pg_hba.conf:/etc/postgresql/pg_hba.conf
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">command</span>: postgres -c &#39;config_file=/etc/postgresql/postgresql.conf&#39;
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">networks</span>:
</span></span><span style="display:flex;"><span>      - postgres-network
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">healthcheck</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">test</span>: [<span style="color:#f1fa8c">&#34;CMD-SHELL&#34;</span>, <span style="color:#f1fa8c">&#34;pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}&#34;</span>]
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">interval</span>: 10s
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">timeout</span>: 5s
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">retries</span>: <span style="color:#bd93f9">5</span>
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">start_period</span>: 10s
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">networks</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#ff79c6">postgres-network</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">driver</span>: bridge
</span></span></code></pre></div><h3 id="2-env-环境变量配置">2. .env 环境变量配置</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># PostgreSQL 配置环境变量
</span></span><span style="display:flex;"><span>POSTGRES_DB=test_db           # 数据库名称
</span></span><span style="display:flex;"><span>POSTGRES_USER=data           # 默认超级用户
</span></span><span style="display:flex;"><span>POSTGRES_PASSWORD=your_password  # 用户密码
</span></span><span style="display:flex;"><span>POSTGRES_PORT=5432          # 端口映射
</span></span></code></pre></div><h3 id="3-postgresqlconf-主要配置">3. postgresql.conf 主要配置</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># 连接设置
</span></span><span style="display:flex;"><span>listen_addresses = &#39;*&#39;
</span></span><span style="display:flex;"><span>port = 5432
</span></span><span style="display:flex;"><span>max_connections = 100
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 内存设置
</span></span><span style="display:flex;"><span>shared_buffers = 128MB
</span></span><span style="display:flex;"><span>work_mem = 4MB
</span></span><span style="display:flex;"><span>maintenance_work_mem = 64MB
</span></span><span style="display:flex;"><span>effective_cache_size = 512MB
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 写入设置
</span></span><span style="display:flex;"><span>wal_level = replica
</span></span><span style="display:flex;"><span>max_wal_size = 1GB
</span></span><span style="display:flex;"><span>min_wal_size = 80MB
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 日志设置
</span></span><span style="display:flex;"><span>log_destination = &#39;stderr&#39;
</span></span><span style="display:flex;"><span>logging_collector = on
</span></span><span style="display:flex;"><span>log_directory = &#39;/var/log/postgresql&#39;
</span></span><span style="display:flex;"><span>log_filename = &#39;postgresql-%Y-%m-%d_%H%M%S.log&#39;
</span></span><span style="display:flex;"><span>log_rotation_age = 1d
</span></span><span style="display:flex;"><span>log_rotation_size = 10MB
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 区域设置
</span></span><span style="display:flex;"><span>datestyle = &#39;iso, mdy&#39;
</span></span><span style="display:flex;"><span>timezone = &#39;UTC&#39;
</span></span><span style="display:flex;"><span>lc_messages = &#39;en_US.utf8&#39;
</span></span></code></pre></div><h3 id="4-pg_hbaconf-访问控制配置">4. pg_hba.conf 访问控制配置</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># TYPE  DATABASE        USER            ADDRESS                 METHOD
</span></span><span style="display:flex;"><span>local   all            all                                     trust
</span></span><span style="display:flex;"><span>host    all            all             127.0.0.1/32           scram-sha-256
</span></span><span style="display:flex;"><span>host    all            all             ::1/128                scram-sha-256
</span></span><span style="display:flex;"><span>host    all            all             0.0.0.0/0              scram-sha-256
</span></span></code></pre></div><h2 id="使用说明">使用说明</h2>
<h3 id="1-启动服务">1. 启动服务</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 启动服务</span>
</span></span><span style="display:flex;"><span>docker-compose up -d
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 查看服务状态</span>
</span></span><span style="display:flex;"><span>docker-compose ps
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 查看日志</span>
</span></span><span style="display:flex;"><span>docker-compose logs postgres
</span></span></code></pre></div><h3 id="2-连接数据库">2. 连接数据库</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 使用超级用户连接</span>
</span></span><span style="display:flex;"><span>docker-compose <span style="color:#8be9fd;font-style:italic">exec</span> postgres psql -U data -d test_db
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 查看用户列表和权限</span>
</span></span><span style="display:flex;"><span><span style="color:#f1fa8c">\d</span>u
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 查看数据库列表</span>
</span></span><span style="display:flex;"><span><span style="color:#f1fa8c">\l</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 退出psql</span>
</span></span><span style="display:flex;"><span><span style="color:#f1fa8c">\q</span>
</span></span></code></pre></div><h3 id="3-停止服务">3. 停止服务</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 停止服务</span>
</span></span><span style="display:flex;"><span>docker-compose down
</span></span></code></pre></div><h2 id="用户和权限管理">用户和权限管理</h2>
<p>PostgreSQL使用角色（Role）概念来管理用户权限。在我们的配置中：</p>
<ol>
<li>通过<code>POSTGRES_USER</code>环境变量创建的用户（本例中为&quot;data&quot;）是超级用户，具有所有权限：</li>
<li>Superuser（超级用户权限）</li>
<li>Create role（创建角色权限）</li>
<li>Create DB（创建数据库权限）</li>
<li>Replication（复制权限）</li>
<li></li>
</ol>
<p>Bypass RLS（绕过行级安全性）</p>
<ol start="7">
<li></li>
</ol>
<p>创建新用户示例：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#ff79c6">CREATE</span> <span style="color:#ff79c6">ROLE</span> username <span style="color:#ff79c6">WITH</span> LOGIN PASSWORD <span style="color:#f1fa8c">&#39;password&#39;</span>;
</span></span></code></pre></div><ol>
<li>授予权限示例：</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>GRANT ALL PRIVILEGES ON DATABASE dbname TO username;
</span></span></code></pre></div><h2 id="数据备份和恢复">数据备份和恢复</h2>
<h3 id="备份数据">备份数据</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 备份整个数据库</span>
</span></span><span style="display:flex;"><span>docker-compose <span style="color:#8be9fd;font-style:italic">exec</span> postgres pg_dump -U data test_db &gt; backup.sql
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 备份特定表</span>
</span></span><span style="display:flex;"><span>docker-compose <span style="color:#8be9fd;font-style:italic">exec</span> postgres pg_dump -U data -t table_name test_db &gt; table_backup.sql
</span></span></code></pre></div><h3 id="恢复数据">恢复数据</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 恢复数据</span>
</span></span><span style="display:flex;"><span>docker-compose <span style="color:#8be9fd;font-style:italic">exec</span> -T postgres psql -U data test_db &lt; backup.sql
</span></span></code></pre></div><h2 id="性能优化建议">性能优化建议</h2>
<ol>
<li>内存配置</li>
<li><code>shared_buffers</code>: 建议设置为系统内存的25%</li>
<li><code>effective_cache_size</code>: 建议设置为系统内存的50%</li>
<li></li>
</ol>
<p><code>work_mem</code>: 根据并发连接数调整</p>
<ol start="5">
<li></li>
</ol>
<p>写入性能</p>
<ol start="6">
<li><code>wal_buffers</code>: 建议设置为16MB</li>
<li><code>checkpoint_timeout</code>: 可根据写入压力调整</li>
<li></li>
</ol>
<p><code>max_wal_size</code>: 根据磁盘空间调整</p>
<ol start="9">
<li></li>
</ol>
<p>连接池</p>
<ol start="10">
<li>建议使用pgBouncer等连接池管理工具</li>
<li>避免频繁创建新连接</li>
</ol>
<h2 id="常见问题处理">常见问题处理</h2>
<ol>
<li>容器无法启动</li>
<li>检查端口占用：<code>lsof -i :5432</code></li>
<li>检查配置文件权限</li>
<li></li>
</ol>
<p>查看错误日志：<code>docker-compose logs postgres</code></p>
<ol start="5">
<li></li>
</ol>
<p>连接失败</p>
<ol start="6">
<li>确认用户名和密码正确</li>
<li>检查pg_hba.conf配置</li>
<li></li>
</ol>
<p>验证网络连接</p>
<ol start="9">
<li></li>
</ol>
<p>性能问题</p>
<ol start="10">
<li>检查慢查询日志</li>
<li>使用EXPLAIN分析查询计划</li>
<li>优化索引和查询语句</li>
</ol>
<h2 id="安全建议">安全建议</h2>
<ol>
<li>密码安全</li>
<li>使用强密码</li>
<li>定期更换密码</li>
<li></li>
</ol>
<p>避免在命令行中明文输入密码</p>
<ol start="5">
<li></li>
</ol>
<p>网络安全</p>
<ol start="6">
<li>限制访问IP</li>
<li>使用SSL连接</li>
<li></li>
</ol>
<p>定期更新PostgreSQL版本</p>
<ol start="9">
<li></li>
</ol>
<p>权限控制</p>
<ol start="10">
<li>遵循最小权限原则</li>
<li>使用角色管理权限</li>
<li>启用行级安全性（RLS）</li>
</ol>
<h2 id="维护建议">维护建议</h2>
<ol>
<li>定期维护</li>
<li>执行VACUUM操作</li>
<li>更新统计信息</li>
<li></li>
</ol>
<p>检查日志文件大小</p>
<ol start="5">
<li></li>
</ol>
<p>监控</p>
<ol start="6">
<li>监控连接数</li>
<li>监控磁盘使用</li>
<li></li>
</ol>
<p>监控查询性能</p>
<ol start="9">
<li></li>
</ol>
<p>备份策略</p>
<ol start="10">
<li>定期备份</li>
<li>测试恢复流程</li>
</ol>
]]></content:encoded></item><item><title>MySQL Docker开发环境配置指南</title><link>https://blog.heyaohua.com/posts/2024/03/mysql-docker-development-guide/</link><pubDate>Tue, 19 Mar 2024 11:00:00 +0800</pubDate><guid>https://blog.heyaohua.com/posts/2024/03/mysql-docker-development-guide/</guid><description>重要配置说明： - - 容器异常退出时自动重启 - - 环境变量配置，支持从.env文件读取 - - 数据持久化配置，确保数据安全 - - 端口映射，允 …</description><content:encoded><![CDATA[<h1 id="如何使用docker启动mysql开发环境">如何使用Docker启动MySQL开发环境</h1>
<h2 id="目录结构">目录结构</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>MySQL_Docker/
</span></span><span style="display:flex;"><span>├── docker-compose.yml    # Docker Compose 配置文件
</span></span><span style="display:flex;"><span>├── .env                 # 环境变量配置
</span></span><span style="display:flex;"><span>├── config/
</span></span><span style="display:flex;"><span>│   └── my.cnf          # MySQL 配置文件
</span></span><span style="display:flex;"><span>├── data/               # MySQL 数据目录 (挂载)
</span></span><span style="display:flex;"><span>└── logs/               # MySQL 日志目录 (挂载)
</span></span></code></pre></div><h2 id="配置文件说明">配置文件说明</h2>
<h3 id="1-docker-composeyml-配置要点">1. docker-compose.yml 配置要点</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#ff79c6">version</span>: <span style="color:#f1fa8c">&#39;3.8&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">services</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#ff79c6">mysql</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">image</span>: mysql:8.0
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">container_name</span>: mysql-server
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">restart</span>: unless-stopped
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">environment</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">MYSQL_ROOT_PASSWORD</span>: ${MYSQL_ROOT_PASSWORD:-root123}
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">MYSQL_DATABASE</span>: ${MYSQL_DATABASE:-testdb}
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">MYSQL_USER</span>: ${MYSQL_USER:-testuser}
</span></span><span style="display:flex;"><span>      <span style="color:#ff79c6">MYSQL_PASSWORD</span>: ${MYSQL_PASSWORD:-testpass}
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">ports</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#f1fa8c">&#34;${MYSQL_PORT:-3306}:3306&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">volumes</span>:
</span></span><span style="display:flex;"><span>      - ./data:/var/lib/mysql
</span></span><span style="display:flex;"><span>      - ./logs:/var/log/mysql
</span></span><span style="display:flex;"><span>      - ./config/my.cnf:/etc/mysql/conf.d/my.cnf
</span></span></code></pre></div><p><strong>重要配置说明：</strong></p>
<ul>
<li><code>restart: unless-stopped</code> - 容器异常退出时自动重启</li>
<li><code>environment</code> - 环境变量配置，支持从.env文件读取</li>
<li><code>volumes</code> - 数据持久化配置，确保数据安全</li>
<li><code>ports</code> - 端口映射，允许外部访问</li>
</ul>
<h3 id="2-mysql配置文件-mycnf-要点">2. MySQL配置文件 (my.cnf) 要点</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>[mysqld]
</span></span><span style="display:flex;"><span># 基本设置
</span></span><span style="display:flex;"><span>port = <span style="color:#bd93f9">3306</span>
</span></span><span style="display:flex;"><span>bind-address = <span style="color:#bd93f9">0.0</span>.<span style="color:#bd93f9">0.0</span>
</span></span><span style="display:flex;"><span>default-storage-engine = InnoDB
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 字符集设置（重要）
</span></span><span style="display:flex;"><span>character-set-server = utf<span style="color:#bd93f9">8</span>mb<span style="color:#bd93f9">4</span>
</span></span><span style="display:flex;"><span>collation-server = utf<span style="color:#bd93f9">8</span>mb<span style="color:#bd93f9">4</span>_unicode_ci
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 连接设置
</span></span><span style="display:flex;"><span>max_connections = <span style="color:#bd93f9">200</span>
</span></span><span style="display:flex;"><span>max_connect_errors = <span style="color:#bd93f9">10</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 缓冲区设置
</span></span><span style="display:flex;"><span>innodb_buffer_pool_size = <span style="color:#bd93f9">256</span>M
</span></span><span style="display:flex;"><span>innodb_log_file_size = <span style="color:#bd93f9">64</span>M
</span></span><span style="display:flex;"><span>innodb_log_buffer_size = <span style="color:#bd93f9">16</span>M
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># 日志设置
</span></span><span style="display:flex;"><span>log-error = /var/log/mysql/error.log
</span></span><span style="display:flex;"><span>slow_query_log = <span style="color:#bd93f9">1</span>
</span></span><span style="display:flex;"><span>slow_query_log_file = /var/log/mysql/slow.log
</span></span><span style="display:flex;"><span>long_query_time = <span style="color:#bd93f9">2</span>
</span></span></code></pre></div><p><strong>配置注意事项：</strong></p>
<ol>
<li>字符集必须设置为utf8mb4，以支持完整的Unicode字符集</li>
<li>根据服务器内存调整缓冲区大小</li>
<li>开启慢查询日志便于性能优化</li>
<li>MySQL 8.0已不支持查询缓存（query_cache）相关配置</li>
</ol>
<h3 id="3-环境变量配置-env">3. 环境变量配置 (.env)</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>MYSQL_ROOT_PASSWORD=your_root_password
</span></span><span style="display:flex;"><span>MYSQL_DATABASE=your_database
</span></span><span style="display:flex;"><span>MYSQL_USER=your_user
</span></span><span style="display:flex;"><span>MYSQL_PASSWORD=your_password
</span></span><span style="display:flex;"><span>MYSQL_PORT=3306
</span></span></code></pre></div><p><strong>安全注意事项：</strong></p>
<ul>
<li>生产环境必须修改默认密码</li>
<li>.env文件不要提交到版本控制系统</li>
<li>定期更换密码</li>
<li>避免使用弱密码</li>
</ul>
<h2 id="启动和维护">启动和维护</h2>
<h3 id="启动服务">启动服务</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker-compose up -d
</span></span></code></pre></div><h3 id="查看服务状态">查看服务状态</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker-compose ps
</span></span></code></pre></div><h3 id="查看日志">查看日志</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#6272a4"># 查看容器日志</span>
</span></span><span style="display:flex;"><span>docker-compose logs mysql
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 查看错误日志</span>
</span></span><span style="display:flex;"><span>tail -f logs/error.log
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4"># 查看慢查询日志</span>
</span></span><span style="display:flex;"><span>tail -f logs/slow.log
</span></span></code></pre></div><h3 id="停止服务">停止服务</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker-compose down
</span></span></code></pre></div><h2 id="常见问题处理">常见问题处理</h2>
<h3 id="1-容器无法启动或反复重启">1. 容器无法启动或反复重启</h3>
<ul>
<li>检查数据目录权限</li>
<li>查看错误日志（logs/error.log）</li>
<li>确认配置文件语法正确</li>
<li>验证端口是否被占用</li>
</ul>
<h3 id="2-连接失败">2. 连接失败</h3>
<ul>
<li>确认容器运行状态</li>
<li>检查端口映射</li>
<li>验证用户名密码</li>
<li>检查防火墙设置</li>
</ul>
<h3 id="3-性能问题">3. 性能问题</h3>
<ul>
<li>检查慢查询日志</li>
<li>调整缓冲区大小</li>
<li>优化索引</li>
<li>监控资源使用情况</li>
</ul>
<h2 id="数据备份建议">数据备份建议</h2>
<h3 id="1-使用docker-compose执行备份">1. 使用docker-compose执行备份</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker-compose <span style="color:#8be9fd;font-style:italic">exec</span> mysql mysqldump -u root -p database_name &gt; backup.sql
</span></span></code></pre></div><h3 id="2-自动备份脚本示例">2. 自动备份脚本示例</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#ff79c6">#!/bin/bash
</span></span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">backup_dir</span><span style="color:#ff79c6">=</span><span style="color:#f1fa8c">&#34;backups&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">date_format</span><span style="color:#ff79c6">=</span><span style="color:#ff79c6">$(</span>date +%Y%m%d_%H%M%S<span style="color:#ff79c6">)</span>
</span></span><span style="display:flex;"><span>docker-compose <span style="color:#8be9fd;font-style:italic">exec</span> -T mysql mysqldump -u root -p database_name &gt; <span style="color:#f1fa8c">&#34;</span><span style="color:#f1fa8c">${</span><span style="color:#8be9fd;font-style:italic">backup_dir</span><span style="color:#f1fa8c">}</span><span style="color:#f1fa8c">/backup_</span><span style="color:#f1fa8c">${</span><span style="color:#8be9fd;font-style:italic">date_format</span><span style="color:#f1fa8c">}</span><span style="color:#f1fa8c">.sql&#34;</span>
</span></span></code></pre></div><h2 id="安全建议">安全建议</h2>
<ol>
<li>网络安全</li>
<li>限制端口访问</li>
<li>使用专用网络</li>
<li></li>
</ol>
<p>启用SSL/TLS加密</p>
<ol start="5">
<li></li>
</ol>
<p>账户安全</p>
<ol start="6">
<li>定期更换密码</li>
<li>限制用户权限</li>
<li></li>
</ol>
<p>删除未使用的账户</p>
<ol start="9">
<li></li>
</ol>
<p>数据安全</p>
<ol start="10">
<li>定期备份</li>
<li>加密敏感数据</li>
<li>监控异常访问</li>
</ol>
<h2 id="性能优化建议">性能优化建议</h2>
<ol>
<li>硬件资源</li>
<li>适当分配内存</li>
<li>使用SSD存储</li>
<li></li>
</ol>
<p>监控CPU使用率</p>
<ol start="5">
<li></li>
</ol>
<p>配置优化</p>
<ol start="6">
<li>调整缓冲池大小</li>
<li>优化日志设置</li>
<li></li>
</ol>
<p>配置合适的连接数</p>
<ol start="9">
<li></li>
</ol>
<p>查询优化</p>
<ol start="10">
<li>建立合适的索引</li>
<li>优化SQL语句</li>
<li>定期维护统计信息</li>
</ol>
]]></content:encoded></item></channel></rss>