Files
My-Blog/public/network-nginx/index.html
2025-07-05 15:03:43 +08:00

535 lines
20 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<title>Dich&#x27;blog</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
<meta name="robots" content="noodp"/>
<link rel="stylesheet" href="https://blog.dich.bid/style.css">
<link rel="stylesheet" href="https://blog.dich.bid/color/blue.css">
<link rel="stylesheet" href="https://blog.dich.bid/color/background_dark.css">
<link rel="stylesheet" href="https://blog.dich.bid/font-hack-subset.css">
<meta name="description" content="">
<meta property="og:description" content="">
<meta property="og:title" content="Dich'blog">
<meta property="og:type" content="article">
<meta property="og:url" content="https://blog.dich.bid/network-nginx/">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:description" content="">
<meta name="twitter:title" content="Dich'blog">
<meta property="twitter:domain" content="blog.dich.bid">
<meta property="twitter:url" content="https://blog.dich.bid/network-nginx/">
<link rel="alternate" type="application/atom+xml" title="Dich&#x27;blog Atom Feed" href="https://blog.dich.bid/atom.xml" />
<link rel="icon" type="image/png" href=&#x2F;dich.webp />
<!-- ✅ Added center alignment styles -->
<style>
.footer {
text-align: center;
padding: 1rem 0;
}
.footer__inner {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
.copyright {
text-align: center;
}
</style>
</head>
<body class="">
<div class="container">
<header class="header">
<div class="header__inner">
<div class="header__logo">
<a href="https://blog.dich.bid" style="text-decoration: none;">
<div class="logo">
Dich&#x27;blog
</div>
</a>
</div>
</div>
<nav class="menu">
<ul class="menu__inner">
<li class="active"><a href="https://blog.dich.bid">blog</a></li>
<li><a href="https://blog.dich.bid/archive">archive</a></li>
<li><a href="https://blog.dich.bid/tags">tags</a></li>
<li><a href="https://blog.dich.bid/weekly">weekly</a></li>
<li><a href="https://blog.dich.bid/search">search</a></li>
<li><a href="https://blog.dich.bid/about">about me</a></li>
<li><a href="https://blog.dich.bid/links">links</a></li>
<li><a href="https://blog.dich.bid/atom.xml">rss</a></li>
<li><a href="https://github.com/Dichgrem" target="_blank" rel="noopener noreferrer">github</a></li>
</ul>
</nav>
</header>
<div class="content">
<div class="post">
<h1 class="post-title"><a href="https://blog.dich.bid/network-nginx/">网络艺术:Docker建站与反向代理</a></h1>
<div class="post-meta-inline">
<span class="post-date">
2024-07-14
</span>
</div>
<span class="post-tags-inline">
:: tags:&nbsp;
<a class="post-tag" href="https://blog.dich.bid/tags/network/">#Network</a></span>
<div class="post-content">
<p>前言 Docker的出现极大简化了建站流程较过去的LAMP方式优雅了许多配合Nginx反向代理可以快速上线HTTPS站点。</p>
<span id="continue-reading"></span><h2 id="an-zhuang-docker">安装Docker</h2>
<p>这里以Debian12为例</p>
<ul>
<li>官方安装脚本:</li>
</ul>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>curl -fsSL https://get.docker.com -o get-docker.sh
</span><span>sudo sh get-docker.sh
</span></code></pre>
<ul>
<li>使用 Docker 存储库安装</li>
</ul>
<p>使用以下命令安装此方法的先决条件:</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>sudo apt update &amp;&amp; sudo apt install ca-certificates curl gnupg
</span></code></pre>
<p>创建一个目录来存储密钥环:</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>sudo install -m 0755 -d /etc/apt/keyrings
</span></code></pre>
<p>使用给定的命令下载 GPG 密钥并将其存储在 <code>/etc/apt/keyrings/etc/apt/keyrings</code> 目录中:</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
</span></code></pre>
<p>使用 chmod 命令更改 docker.gpg 文件的权限:</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>sudo chmod a+r /etc/apt/keyrings/docker.gpg
</span></code></pre>
<p>使用以下命令为 Docker 设置存储库:</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>echo \
</span><span> &quot;deb [arch=&quot;$(dpkg --print-architecture)&quot; signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
</span><span> &quot;$(. /etc/os-release &amp;&amp; echo &quot;$VERSION_CODENAME&quot;)&quot; stable&quot; | \
</span><span> sudo tee /etc/apt/sources.list.d/docker.list &gt; /dev/null
</span></code></pre>
<p>现在可以使用以下命令更新存储库索引并安装 Docker</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>sudo apt update &amp;&amp; sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
</span></code></pre>
<h2 id="shi-yong-docker-compose">使用Docker-Compose</h2>
<ul>
<li>目标:创建一个<code>Searxng服务</code>并对外开放。</li>
<li>方法:创建两个 docker-compose 文件,并<code>使用同一个外部 Docker 网络</code>使两个服务互联。</li>
</ul>
<ol start="0">
<li>首先<code>创建好工作目录</code>,例如:</li>
</ol>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>.
</span><span>└── docker
</span><span> ├── docker-compose.nginx.yml
</span><span> ├── docker-compose.searxng.yml
</span><span> └── nginx
</span><span> ├── certs
</span><span> │ ├── fullchain.pem
</span><span> │ └── privkey.pem
</span><span> └── searxng.conf
</span></code></pre>
<ol>
<li>在启动服务前,首先创建一个 Docker 外部网络(例如命名为 nginx</li>
</ol>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>docker network create nginx
</span></code></pre>
<p>这样,无论是哪个 docker-compose 项目中的容器,只要加入此网络,就能直接通信。</p>
<ol start="2">
<li>编写 searxng 的 docker-compose 文件</li>
</ol>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>version: &#39;3&#39;
</span><span>
</span><span>services:
</span><span> searxng:
</span><span> image: searxng/searxng
</span><span> container_name: searxng
</span><span> restart: unless-stopped
</span><span> ulimits:
</span><span> nproc: 65535
</span><span> nofile:
</span><span> soft: 65535
</span><span> hard: 65535
</span><span> volumes:
</span><span> - /var/lib/docker/volumes/searxng/_data:/etc/searxng
</span><span> networks:
</span><span> - nginx
</span><span> ports:
</span><span> # 如果希望 searxng 只对内部服务开放,则可不映射外部端口
</span><span> - &quot;127.0.0.1:18080:8080&quot;
</span><span>
</span><span>networks:
</span><span> nginx:
</span><span> external: true
</span></code></pre>
<ol start="3">
<li>编写 Nginx 的 docker-compose 文件</li>
</ol>
<p>创建 nginx 的 docker-compose 文件,例如:</p>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>version: &#39;3&#39;
</span><span>
</span><span>services:
</span><span> nginx:
</span><span> image: nginx:latest
</span><span> container_name: nginx
</span><span> restart: unless-stopped
</span><span> ports:
</span><span> - &quot;80:80&quot;
</span><span> # 如需要 HTTPS请映射 443 端口并挂载证书目录
</span><span> #- &quot;443:443&quot;
</span><span> volumes:
</span><span> - ./nginx/searxng.conf:/etc/nginx/conf.d/default.conf:ro
</span><span> #- ./nginx/certs:/etc/nginx/certs:ro
</span><span> networks:
</span><span> - nginx
</span><span>
</span><span>networks:
</span><span> nginx:
</span><span> external: true
</span></code></pre>
<ol start="4">
<li>编写 Nginx 配置文件</li>
</ol>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>server {
</span><span> listen 80;
</span><span> server_name searxng.dich.bid;
</span><span>
</span><span> client_max_body_size 10M;
</span><span>
</span><span> location / {
</span><span> proxy_pass http://searxng:8080;
</span><span> proxy_set_header Host $host;
</span><span> proxy_set_header X-Real-IP $remote_addr;
</span><span> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
</span><span> proxy_set_header X-Forwarded-Proto $scheme;
</span><span> proxy_http_version 1.1;
</span><span> proxy_set_header Connection &quot;&quot;;
</span><span> }
</span><span>
</span><span> error_page 502 /502.html;
</span><span> location = /502.html {
</span><span> root /usr/share/nginx/html;
</span><span> internal;
</span><span> }
</span><span>}
</span></code></pre>
<ol start="5">
<li>启动服务</li>
</ol>
<ul>
<li>启动 searxng 服务:</li>
</ul>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>docker-compose -f docker-compose.searxng.yml up -d
</span></code></pre>
<ul>
<li>启动 nginx 服务:</li>
</ul>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>docker-compose -f docker-compose.nginx.yml up -d
</span></code></pre>
<p>由于两者都加入了外部网络 nginxnginx 内的<code>proxy_pass http://searxng:8080</code>就能解析到 searxng 容器,实现反向代理效果。现在,访问<code>http://ip:18080</code>就可以访问Searxng搜索引擎。</p>
<h2 id="tian-jia-https">添加HTTPS</h2>
<p>在实际生产环境中我们不能使用IP直接访问因此需要为我们的站点开启SSL证书也就是要申请证书并在配置文件中声明。</p>
<ol>
<li>证书生成</li>
</ol>
<ul>
<li>如果只是用于测试可以生成自签名证书:</li>
</ul>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>mkdir -p /home/dich/docker/nginx/certs
</span><span>openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
</span><span> -keyout /home/dich/docker/nginx/certs/privkey.pem \
</span><span> -out /home/dich/docker/nginx/certs/fullchain.pem \
</span><span> -subj &quot;/CN=your-domain.com&quot;
</span></code></pre>
<ol start="2">
<li>更改searxng.conf:</li>
</ol>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>server {
</span><span> listen 443 ssl;
</span><span> server_name searxng.dich.bid;
</span><span>
</span><span> # SSL 证书配置
</span><span> ssl_certificate /home/dich/docker/nginx/certs/fullchain.pem;
</span><span> ssl_certificate_key /home/dich/docker/nginx/certs/privkey.pem;
</span><span> ssl_protocols TLSv1.2 TLSv1.3;
</span><span> ssl_ciphers HIGH:!aNULL:!MD5;
</span><span>
</span><span> client_max_body_size 10M;
</span><span>
</span><span> location / {
</span><span> proxy_pass http://searxng:8080;
</span><span> proxy_set_header Host $host;
</span><span> proxy_set_header X-Real-IP $remote_addr;
</span><span> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
</span><span> proxy_set_header X-Forwarded-Proto $scheme;
</span><span> proxy_http_version 1.1;
</span><span> proxy_set_header Connection &quot;&quot;;
</span><span> }
</span><span>
</span><span> error_page 502 /502.html;
</span><span> location = /502.html {
</span><span> root /usr/share/nginx/html;
</span><span> internal;
</span><span> }
</span><span>}
</span><span>
</span><span># HTTP 服务器块,将所有流量重定向到 HTTPS
</span><span>server {
</span><span> listen 80;
</span><span> server_name searxng.dich.bid;
</span><span> return 301 https://$host$request_uri;
</span><span>}
</span></code></pre>
<ol start="3">
<li>更改docker-compose.nginx.yml</li>
</ol>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>version: &#39;3&#39;
</span><span>
</span><span>services:
</span><span> nginx:
</span><span> image: nginx:latest
</span><span> container_name: nginx
</span><span> restart: unless-stopped
</span><span> ports:
</span><span> - &quot;80:80&quot;
</span><span> # 如需要 HTTPS请映射 443 端口并挂载证书目录
</span><span> - &quot;443:443&quot;
</span><span> volumes:
</span><span> - ./nginx/searxng.conf:/etc/nginx/conf.d/default.conf:ro
</span><span> - ./nginx/certs:/home/dich/docker/nginx/certs
</span><span> networks:
</span><span> - nginx
</span><span>
</span><span>networks:
</span><span> nginx:
</span><span> external: true
</span></code></pre>
<ol start="4">
<li>启动新配置</li>
</ol>
<ul>
<li>重启容器</li>
</ul>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>sudo docker compose -f docker-compose.nginx.yml up -d
</span></code></pre>
<ul>
<li>查看日志</li>
</ul>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>sudo docker logs searxng
</span></code></pre>
<h2 id="caddy">Caddy</h2>
<blockquote>
<p>Caddy 自 2015 年起用 Go 语言重写,定位为“开箱即用”的现代 Web 服务器,内置自动 Lets Encrypt 证书管理和续期,默认支持 HTTP/2 及 HTTP/3QUIC并通过简洁明了的 Caddyfile 语法极大降低配置成本.</p>
</blockquote>
<ol start="0">
<li>示例结构:</li>
</ol>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>.
</span><span>└── compose
</span><span> ├── certs
</span><span> │ ├── cert.pem
</span><span> │ └── key.pem
</span><span> ├── compose.caddy.yml
</span><span> ├── compose.miniflux.yml
</span><span> ├── compose.searxng.yml
</span><span> └── conf
</span><span> └── Caddyfile
</span></code></pre>
<ol>
<li>同样创建名为Caddy的docker网络</li>
</ol>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>docker network create caddy
</span></code></pre>
<ol start="2">
<li>编写Caddy的compose可以看到caddy可以自带签发证书</li>
</ol>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>version: &#39;3.7&#39;
</span><span>
</span><span># 自动签发模式
</span><span>
</span><span>services:
</span><span> caddy:
</span><span> image: caddy:latest
</span><span> container_name: caddy
</span><span> restart: unless-stopped
</span><span> volumes:
</span><span> - ./conf:/etc/caddy:ro
</span><span> - caddy_data:/data
</span><span> - caddy_config:/config
</span><span> ports:
</span><span> - &quot;80:80&quot;
</span><span> - &quot;443:443&quot;
</span><span> networks:
</span><span> - caddy
</span><span>
</span><span>networks:
</span><span> caddy:
</span><span> external: true
</span><span>
</span><span>volumes:
</span><span> caddy_data:
</span><span> caddy_config:
</span><span>
</span><span>
</span><span># 自备证书模式
</span><span>
</span><span>services:
</span><span> caddy:
</span><span> image: caddy:latest
</span><span> container_name: caddy
</span><span> restart: unless-stopped
</span><span> environment:
</span><span> - CADDYPATH=/etc/caddycerts
</span><span> volumes:
</span><span> - ./conf:/etc/caddy
</span><span> - ./certs:/etc/caddycerts
</span><span> - caddy_data:/data
</span><span> - caddy_config:/config
</span><span> ports:
</span><span> - &quot;80:80&quot;
</span><span> - &quot;443:443&quot;
</span><span> networks:
</span><span> - caddy
</span><span>
</span><span>volumes:
</span><span> caddy_data:
</span><span> caddy_config:
</span><span>networks:
</span><span> caddy:
</span><span> external: true
</span></code></pre>
<ol start="3">
<li>编写Caddyfile可以看到自动开启HTTPS模式</li>
</ol>
<pre style="background-color:#151515;color:#e8e8d3;"><code><span># 自动签发模式
</span><span>searxng.dich.bid {
</span><span> reverse_proxy searxng:8080 {
</span><span> header_up Host {upstream_hostport}
</span><span> }
</span><span>}
</span><span>
</span><span>miniflux.dich.bid {
</span><span> reverse_proxy miniflux:8080 {
</span><span> header_up Host {upstream_hostport}
</span><span> }
</span><span>}
</span><span>
</span><span># 自备证书模式
</span><span>searxng.dich.bid {
</span><span> reverse_proxy searxng:8080
</span><span> tls /etc/caddycerts/cert.pem /etc/caddycerts/key.pem
</span><span>}
</span><span>miniflux.dich.bid {
</span><span> reverse_proxy miniflux:8080
</span><span> tls /etc/caddycerts/cert.pem /etc/caddycerts/key.pem
</span><span>}
</span></code></pre>
<ol start="4">
<li>Docker compose的用法不再赘述。</li>
</ol>
<p><strong>FAQ</strong></p>
<ul>
<li>使用nginx的docker版本而非apt安装的版本</li>
<li>注意相对路径和绝对路径,不同容器可能冲突;</li>
<li>使用网络创建的方法简化了配置;</li>
<li>使用127.0.0.1:port的配置增加了安全性无法ip访问</li>
<li>conf中的服务端口是compose中的portport的后一个</li>
<li>更改配置后需要删除现有的容器再生成;</li>
<li>version字段可以不需要</li>
<li>注意加上container_name</li>
<li>每增加一个服务需要在nginx中更新volume</li>
</ul>
<hr />
<p><strong>Done.</strong></p>
</div>
<div class="pagination">
<div class="pagination__title">
<span class="pagination__title-h">Thanks for reading! Read other posts?</span>
<hr />
</div>
<div class="pagination__buttons">
<span class="button previous">
<a href="https://blog.dich.bid/about-server-set/">
<span class="button__icon"></span>&nbsp;
<span class="button__text">乱七八糟:服务器初始化与安全设置</span>
</a>
</span>
<span class="button next">
<a href="https://blog.dich.bid/about-2024/">
<span class="button__text">乱七八糟:2024年度总结</span>&nbsp;
<span class="button__icon"></span>
</a>
</span>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="footer__inner">
<div class="copyright">
<span>©
2025
Dichgrem</span>
<span class="copyright-theme">
<span class="copyright-theme-sep"> :: CC BY-SA 4.0 :: A friend comes from distant lands</span>
</a>
</span>
</div>
</div>
</footer>
</div>
</body>
</html>