mirror of
https://github.com/Dichgrem/Blog.git
synced 2025-07-31 17:09:30 -04:00
535 lines
20 KiB
HTML
535 lines
20 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
|
||
<head>
|
||
<title>Dich'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'blog Atom Feed" href="https://blog.dich.bid/atom.xml" />
|
||
|
||
|
||
<link rel="icon" type="image/png" href=/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'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:
|
||
<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 && 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> "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
|
||
</span><span> "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
|
||
</span><span> sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||
</span></code></pre>
|
||
<p>现在可以使用以下命令更新存储库索引并安装 Docker:</p>
|
||
<pre style="background-color:#151515;color:#e8e8d3;"><code><span>sudo apt update && 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: '3'
|
||
</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> - "127.0.0.1:18080:8080"
|
||
</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: '3'
|
||
</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> - "80:80"
|
||
</span><span> # 如需要 HTTPS,请映射 443 端口并挂载证书目录
|
||
</span><span> #- "443:443"
|
||
</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 "";
|
||
</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>由于两者都加入了外部网络 nginx,nginx 内的<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 "/CN=your-domain.com"
|
||
</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 "";
|
||
</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: '3'
|
||
</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> - "80:80"
|
||
</span><span> # 如需要 HTTPS,请映射 443 端口并挂载证书目录
|
||
</span><span> - "443:443"
|
||
</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 服务器,内置自动 Let’s Encrypt 证书管理和续期,默认支持 HTTP/2 及 HTTP/3(QUIC),并通过简洁明了的 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: '3.7'
|
||
</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> - "80:80"
|
||
</span><span> - "443:443"
|
||
</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> - "80:80"
|
||
</span><span> - "443:443"
|
||
</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中的port:port的后一个;</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>
|
||
<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>
|
||
<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>
|
||
|