新闻详情

新闻详情

首页 / 资讯中心 / 详情

Docker实战:用nginx反向代理搭建第一个容器化应用

发布时间:2026/9/20 17:59:45来源:尧图网络
Docker实战:用nginx反向代理搭建第一个容器化应用
写这篇教程的起因很简单我见过太多人在“容器化”这道门槛前卡住而Docker加nginx反向代理这个组合恰恰是最适合新手的第一个实战项目。它把 Docker 最核心的安装、镜像拉取、容器启动、端口映射、数据卷挂载全部串了一遍同时也把你以后在生产环境里天天要打交道的反向代理工具讲透了。我当年第一次在服务器上手动编译安装 nginx 时光处理 PCRE、OpenSSL、zlib 这些依赖就折腾了一下午最后还因为版本不匹配编译失败。后来切到 Docker 一条docker run命令五分钟看到欢迎页那种从“装环境”到“用服务”的转变确实让我眼前一亮。这篇内容就是按我自己的入门路径写的适合完全没碰过 Docker 的新手也适合想快速搭一套反代环境做本地联调的前后端同学。1. 先说结论为什么我坚持用 Docker 跑 nginx先说说传统装 nginx 的痛点。在 Linux 服务器上不同发行版的包管理器版本差异很大Ubuntu 源里的 nginx 和 CentOS 源里的 nginx 版本能差出去好几个大版本如果你要装第三方模块或者编译特定参数那就更头疼了PCRE、zlib、OpenSSL 这些依赖库版本冲突能让人崩溃。最麻烦的是卸载系统里散落的各种配置文件、日志、二进制文件很难清干净下次再装可能就踩到上次残留的坑。Docker 跑 nginx 的思路完全不一样。镜像把 nginx 本体、依赖库、默认配置、运行环境整体打包成一个只读模板容器只是这个模板的一个运行实例。你想换 nginx 版本直接换个镜像 tag 重新 run 一个容器就行不会影响系统里的其他软件。多项目之间想隔离也更简单各自的 nginx 跑在各自容器里互不干扰。还有一个很实际的点一致性。你在自己电脑 Docker Desktop 里测好的配置拿到服务器上只要 Docker 环境一样跑起来的结果就是一样的。我后来在好几台机器上部署同一套前端项目从装 Docker 到 nginx 反代起来十分钟内搞定再也不用担心“本地好好的服务器上怎么就不行”这种问题。有人可能会说Docker 多了一层抽象感觉是多余的。我的观点是这一层抽象换来的是可复制性和环境隔离对个人开发者可能要付出一点学习成本但对整个部署流程来说收益非常大。而且学会这一套之后你后面想跑 MySQL、Redis、GitLab套路全是通的一次学习到处复用。2. 安装这一步的水有多深Windows、macOS、Linux 分开讲Docker 本身是个客户端-服务端架构docker命令是客户端真正干活的是dockerd守护进程。在 Windows 和 macOS 上Docker 官方提供的 Docker Desktop 把守护进程装进了一个轻量级虚拟机里所以你不用自己管理虚拟机在 Linux 上Docker Engine 直接跑在宿主机上。2.1 Windows 上装 Docker DesktopWindows 装 Docker Desktop 有几个前提条件容易踩坑第一系统必须是 Win10 64 位及以上版本专业版、企业版、教育版都行家庭版也可以但要手动启用 WSL2。第二BIOS 里必须开启虚拟化。很多人安装后启动报错 “Virtualization is disabled”就是这一步没做需要在开机进 BIOS 时找到 Intel VT-x 或 AMD-V 选项并启用。第三Windows 功能里的“适用于 Linux 的 Windows 子系统”和“虚拟机平台”要打开装完重启。Docker Desktop 安装包本身是个几百 MB 的 exe官方渠道下载可能比较慢耐心等就好。安装过程中勾选“Use WSL 2 instead of Hyper-V”然后一路下一步。装完打开 Docker Desktop等右下角鲸鱼图标稳定下来打开 PowerShell 或 CMD 输入docker version能正常显示 Client 和 Server 的信息说明安装成功。看到 Server 那一栏有内容而不是只有 Client这点很重要——很多人只看到客户端信息服务端没起来那说明 Docker Desktop 还没真正完成启动。2.2 macOS 上装 Docker DesktopmacOS 上同样是用 Docker Desktop。这里要特别注意芯片架构Apple SiliconM1/M2/M3芯片的 Mac 必须下载对应 arm64 版本的安装包Intel 芯片的 Mac 下载 x86_64 版本。下错了可能能装但跑起来很卡甚至直接报错。装完打开 Docker Desktop等菜单栏图标变绿终端里跑docker version验证就好。2.3 Ubuntu 上装 Docker Engine服务器上没有图形界面直接用命令行装。Ubuntu 最简单的方式是 apt 安装sudo apt update sudo apt install -y docker.io sudo systemctl enable --now docker docker version用系统自带的docker.io包版本可能不是最新的但胜在稳定简单。如果一定要最新版那就用官方源加 apt 仓库安装 docker-ce步骤稍微多一些新手可以先不必纠结。装完还有一个关键操作让当前用户免 sudo 执行 docker 命令。sudo usermod -aG docker $USER加完组之后要退出重新登录或者执行newgrp docker让组权限在当前会话生效。否则每次 docker 命令都要加 sudo用起来很别扭。最后用一个官方最小镜像验证整套环境docker run hello-world能输出 “Hello from Docker!” 就说明客户端、守护进程、镜像拉取链路全部正常。3. 第一步先治“拉不动”镜像加速源配置装好 Docker 之后大部分人遇到的第一个问题不是不会用命令而是拉镜像特别慢。Docker 默认从 Docker Hub 拉镜像国内网络环境下确实非常不稳定几十 MB 的小镜像经常要等半天大一点的镜像直接超时失败。解决办法是配置镜像加速源。所谓加速源就是一些机构提供的 Docker Hub 镜像仓库的镜像服务器你从加速源拉取镜像本质还是从 Docker Hub 同步但网络链路会快很多。Docker Desktop 配置方式打开 Docker Desktop 设置找到 Docker Engine 一栏会看到一段 JSON 配置在里面加上registry-mirrors字段例如{ registry-mirrors: [ https://docker.mirrors.ustc.edu.cn ] }不同云服务商也有各自的专属加速地址阿里云容器镜像服务的控制台会生成一个个人专属地址格式大概是https://xxxxxxxx.mirror.aliyuncs.com复制过来填进去就行。改完点 Apply RestartDocker Desktop 会带着新配置重启。Linux 上的配置方式新建或编辑/etc/docker/daemon.json{ registry-mirrors: [ https://docker.mirrors.ustc.edu.cn ] }保存后重启 Dockersudo systemctl restart docker配置有没有生效用这个命令验证docker info在输出里找Registry Mirrors这一项能看到你填写的地址就说明生效了。如果这里没有那后面拉镜像还是会走默认源。需要提醒的是镜像加速只影响拉取镜像这一层容器跑起来之后访问外部网络的链路还是照常。另外加速源地址可能因为各种原因调整遇到失效就换一个公开镜像站这类信息网上随时能查到最新的。不要迷信某个地址永久可用。4. 动手之前把镜像、容器、数据卷、端口映射这四件事想明白直接上手敲命令之前把这四个概念搞清楚后面就不会老觉得 Docker 很玄。4.1 镜像和容器别混着说镜像是一个只读模板里面打包了运行程序需要的操作系统基础环境、代码、依赖、配置文件相当于一个刚装好系统、所有软件都配置好的“环境快照”。容器是镜像运行起来的实例是一个独立的进程环境拥有自己的网络栈、文件系统视图和进程空间。打个比方镜像就像菜谱容器就是按这份菜谱做出来的一道菜。同一份菜谱可以做很多盘菜同一份镜像可以启动很多个容器彼此之间互不影响。做菜的时候你可以单独往一盘菜里加料但这不会改变菜谱本身容器运行中产生的文件改动也不会写回镜像。4.2 数据卷容器删除后数据怎么保住容器一旦被删除运行期间写在容器文件系统里的所有数据都会没掉。这不是什么诡异的问题而是容器设计如此——容器是无状态的你随时可以杀掉它然后重新启动一个一模一样的新容器。但如果里面跑的是数据库、用户上传文件、项目源码那就必须把数据放到容器外面。数据卷volume就是解决这个问题的。通过-v参数可以把宿主机的一个目录挂载到容器的某个目录比如docker run -d --name my-nginx -v /opt/nginx/html:/usr/share/nginx/html nginx这样宿主机/opt/nginx/html里的文件就相当于容器/usr/share/nginx/html里的文件容器删了宿主机上的文件还在。这个机制在后续配置 nginx 时是核心操作。4.3 端口映射为什么容器里的服务外面访问不到每个容器有自己的网络命名空间容器里监听的端口默认只能在容器内部访问。比如 nginx 容器里监听 80 端口这个 80 是容器自己的宿主机的 80 端口没被占用的话你直接访问http://宿主机IP也是不通的。要让宿主机外面的请求能进到容器里必须做端口映射。-p 8080:80的意思是宿主机的 8080 端口收到流量转发到容器的 80 端口。前一个是宿主机端口后一个是容器端口这个顺序千万别搞反。多个容器用宿主机不同的端口各自就能互相不冲突地对外提供服务。4.4 常用命令的最小集合不用背很多先记住这几条就够命令作用docker pull nginx拉取镜像docker images查看本地已有的镜像docker run -d --name 名称 -p 宿主端口:容器端口 镜像启动容器docker ps查看运行中的容器docker ps -a查看所有容器包括已退出docker logs 容器名查看容器日志排错第一入口docker exec -it 容器名 bash进入容器 shelldocker stop/start/restart 容器名停止/启动/重启容器docker rm 容器名删除容器特别注意run和stop的区别启动容器时如果名字已经存在会报冲突停止容器只是结束进程容器还在随时可以被再次启动。彻底不要了才是rm。删除一个运行中的容器要先stop或者用rm -f强制删除。5. 第一个 nginx 容器从 docker run 到看到欢迎页环境准备好、概念也理清了现在开始真正跑东西。5.1 启动第一个 nginx拉取 nginx 官方镜像docker pull nginx:latest然后启动容器docker run -d --name nginx-test -p 8080:80 nginx这个命令应该拆开理解-d表示后台运行--name nginx-test给容器起个名字-p 8080:80把宿主机的 8080 端口映射到容器的 80 端口nginx是要运行的镜像名。启动之后打开浏览器访问http://localhost:8080看到 “Welcome to nginx!” 页面就说明一切正常。再看一眼容器状态docker psnginx-test 应该显示为 Up 状态端口映射列会显示0.0.0.0:8080-80/tcp说明流量通路已经建立。这里有个细节值得展开。nginx 默认的配置是以前台进程方式运行的具体来说官方镜像的默认启动命令是nginx -g daemon off;。为什么容器里不能像在系统里那样以后台守护进程方式跑 nginx因为 Docker 容器的生命周期绑定的是主进程主进程停了容器就停了。如果 nginx 自己 fork 到后台去跑容器的主进程会立刻退出结果就是容器几秒钟后自动结束。这是新手很容易踩的一个点以后自己去写 Dockerfile 启动其他服务时也会遇到同样的逻辑。5.2 进入容器看看 nginx 里面长什么样对容器内部好奇是很正常的直接进去看docker exec -it nginx-test bash进入容器 shell 后你可以执行nginx -v查看 nginx 版本cat /etc/nginx/nginx.conf查看主配置文件ls /usr/share/nginx/html查看默认网页文件ls /etc/nginx/conf.d查看扩展配置目录看完之后exit退出容器。这里我先提个醒不要在这个阶段直接进容器去改配置。你在容器里改的配置只存在于当前容器一旦容器删掉重建所有改动全部消失。正确做法在下一步全程用宿主机目录挂载来管理配置和静态文件。5.3 用数据卷挂载配置和静态文件先删掉刚才那个临时容器docker stop nginx-test docker rm nginx-test在宿主机上准备一个工作目录mkdir -p /opt/docker/nginx/conf mkdir -p /opt/docker/nginx/html把容器内的默认配置带出来作为后续修改的起点。这里有个技巧直接用 docker cp 把现在运行中的容器里的配置文件复制到宿主机。我刚才删掉了那个容器也完全可以再起一个临时容器复制或者直接从官方镜像解包拿配置。更常见的做法是再起一个一次性容器来复制docker run --rm -d --name nginx-temp nginx docker cp nginx-temp:/etc/nginx/nginx.conf /opt/docker/nginx/conf/nginx.conf docker stop nginx-temp--rm参数表示容器停止后自动删除配合临时容器使用很方便。然后在宿主机的/opt/docker/nginx/html里写一个自己的网页echo Hello from Docker nginx /opt/docker/nginx/html/index.html接着启动一个真正用于日常开发的容器docker run -d --name nginx-mounted \ -p 8080:80 \ -v /opt/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro \ -v /opt/docker/nginx/html:/usr/share/nginx/html \ nginx注意这里-v的用法宿主机路径在前容器路径在后中间用冒号分隔。:ro表示只读挂载容器内部无法修改宿主机上的配置文件避免误改。静态文件目录不需要只读后面可能要通过容器往里面放东西。这时重新访问http://localhost:8080看到的就是你自己写的 “Hello from Docker nginx”而不是默认欢迎页了。到这一步你已经完成了 Docker 最核心的一个工作流镜像启动容器、端口映射、数据卷挂载。6. 反向代理配置从“访问 nginx”到“nginx 帮你转发”nginx 最常用的生产场景不是当静态文件服务器而是做反向代理。6.1 反向代理到底是干什么的正向代理你肯定用过客户端配置代理服务器通过它去访问外部网站外部服务器不知道真正的客户端是谁。反向代理则相反客户端访问的是反向代理服务器reversed 代理服务器再决定把请求转发给后面的哪台真实业务服务器客户端完全感知不到后端服务器的存在。可以这样理解反向代理就像一个公司前台。外部人员来办事只需要对前台说明来意前台再转达给对应的部门。外部人员永远不需要知道具体经办人坐在哪个工位、分机是多少。这样对外只暴露一个入口内部服务都藏起来安全性好管理也方便做负载均衡和水平扩展。6.2 一份能跑通的反向代理配置先说场景本地已经有一个跑在 3000 端口的 Node.js 服务假设它就监听http://127.0.0.1:3000我想通过 nginx 监听 80 端口把访问 nginx 的请求转发到这个 3000 端口服务上。nginx 主配置/opt/docker/nginx/conf/nginx.conf改成这样worker_processes 1; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; server { listen 80; server_name localhost; location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } }这个配置的骨架是http块里包含若干个server块server块里包含若干location块。location /代表匹配所有路径proxy_pass是核心指令指定请求转发到哪个地址。三行proxy_set_header也很重要。Host $host是把客户端请求的原始 Host 头传递给后端服务否则后端看到的不一定是你访问的域名X-Real-IP和X-Forwarded-For是让后端能拿到真实客户端 IP有时候做访问日志、风控、限流必须要用到。X-Forwarded-Proto告诉后端客户端是用 http 还是 https 访问的重定向场景经常会依赖这个头。改完配置先做语法检查然后重载docker exec nginx-mounted nginx -t docker exec nginx-mounted nginx -s reloadnginx -t验证配置文件语法输出syntax is ok才算通过。nginx -s reload是平滑重载配置不中断现有连接这个操作比 restart 更优雅。之后访问http://localhost:8080如果 3000 端口的服务能正常返回内容说明反向代理已经生效。6.3 关键的一坑容器里的 127.0.0.1 不是宿主机上面示例里我写的是proxy_pass http://127.0.0.1:3000;但这句话只在一种情况下成立nginx 和那个 Node.js 服务在同一个网络命名空间里。容器恰好是隔离的网络环境nginx 容器里的127.0.0.1指的是容器自己不是宿主机。所以这个配置在 Docker 场景下大概率要翻车这是新手遇到 502 最常见的根因。那容器里的 nginx 要怎么访问宿主机上的服务Linux 环境下Docker 默认的桥接网络网关一般是172.17.0.1在容器里访问这个地址就相当于访问宿主机。先把proxy_pass改成http://172.17.0.1:3000;试试。在 Windows 和 macOS 的 Docker Desktop 里Docker 预留了一个特殊域名host.docker.internal容器里访问它等价于访问宿主机。所以 Docker Desktop 场景下可以写proxy_pass http://host.docker.internal:3000;。我这里要额外说一句千万不要在一个容器里用127.0.0.1想去访问另一个容器的服务它们之间的localhost完全不互通。不同容器的网络通信有专门的方式。6.4 容器与容器之间怎么通信自定义网络如果后端服务本身也跑在容器里最推荐的方式是让它们加入同一个用户自定义网络通过容器名互相访问。先创建一个网络docker network create my-net然后分别把两个容器加到同一个网络里。假设后端服务镜像叫my-app-imagedocker run -d --network my-net --name app-server -p 3000:3000 my-app-image docker run -d --network my-net --name nginx-proxy -p 80:80 -v /opt/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro nginx两个容器都在my-net网络内Docker 会为它们提供 DNS 解析容器名就是主机名。此时 nginx 配置里的代理目标可以写容器名location / { proxy_pass http://app-server:3000; }这样做的最大好处是不管后端容器 IP 怎么变只要容器名不变nginx 配置就不用改。这比写死 IP 要可靠得多。6.5 用 Docker Compose 管理多容器容器一多手工docker run就变得难维护。这时候用 Docker Compose把容器、网络、数据卷、端口映射写进一个docker-compose.yml文件里一条命令全部拉起来。services: app-server: image: node:18 working_dir: /app command: sh -c npm install node server.js volumes: - ./app:/app ports: - 3000:3000 nginx: image: nginx:latest ports: - 80:80 volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - app-server在这个文件所在目录执行docker compose up -dCompose 会自动创建一个默认网络两个服务通过服务名互相访问nginx 里代理http://app-server:3000就通了。depends_on只保证 app-server 先启动不保证它已经能接受请求业务代码复杂时这其实是个隐患但开发环境用没问题。整个配置用docker compose down一键全部停止并移除。7. 多项目多域名一个 nginx 容器挂载多个站点目录单容器挂单目录只是入门真实场景经常是一台服务器上要跑好几个前端项目有的还要代理到不同的后端服务。有人问过“docker 安装 nginx 并挂载多个项目目录”这就要给同一个 nginx 容器挂多个-v并且在配置里按域名或路径分开处理。7.1 挂载多个目录的启动命令假设宿主机上有两个前端项目的静态文件目录/srv/sites/a项目 A 编译后的文件/srv/sites/b项目 B 编译后的文件启动命令docker run -d --name multi-site \ -p 80:80 \ -v /srv/sites/a:/srv/www/a \ -v /srv/sites/b:/srv/www/b \ -v /opt/nginx/multi.conf:/etc/nginx/nginx.conf:ro \ nginx多个-v参数可以重复出现每个项目目录一个挂载。容器内的路径自己定只要和 nginx 配置里root指令指向的路径对上就行。我习惯统一放在/srv/www下面看起来整洁。7.2 按域名区分两个 server 块如果项目 A 用a.example.com访问项目 B 用b.example.com访问用两个server块实现events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; server { listen 80; server_name a.example.com; root /srv/www/a; index index.html; location /api/ { proxy_pass http://api-a:8080/api/; } } server { listen 80; server_name b.example.com; root /srv/www/b; index index.html; location /api/ { proxy_pass http://api-b:8080/api/; } } }server_name就是 nginx 用来区分不同域名的依据外部请求带哪个 Host 头就落到对应的 server 块。这里因为是演示后端容器名直接用了api-a和api-b实际部署时你可以是同一个后端容器的不同路径也可以是独立的两个服务。7.3 按路径区分同一个域名下分流还有一种情况只有一个域名但想根据 URL 路径分配不同项目比如/a/开头走项目 A/b/开头走项目 B。server { listen 80; server_name example.com; location /a/ { root /srv/www; try_files $uri $uri/ /a/index.html; } location /b/ { root /srv/www; try_files $uri $uri/ /b/index.html; } }这里需要注意root会直接把匹配的 URL 路径拼到目录后面。请求/a/index.html时nginx 去/srv/www/a/index.html找文件所以挂载到/srv/www/a和/srv/www/b正好对得上。try_files $uri $uri/ /a/index.html;这一行解决的是前端路由问题。很多单页应用用的是 history 模式路径可能是/a/login这种磁盘上并不存在login.html这个文件。没有try_files的话 nginx 会直接 404加上之后找不到真实文件就回退到项目的入口index.html由前端路由接管。7.4 验证配置并平滑重载改动配置文件后第一时间在容器内执行docker exec multi-site nginx -t看到syntax is ok之后docker exec multi-site nginx -s reloadreload是平滑重载nginx 会 fork 新的 worker 进程加载新配置处理完旧连接的 worker 慢慢退出整个过程中不会出现服务中断。所以只要不是改了监听端口或者日志路径这类影响全局的配置一般都用 reload 而不是 restart。restart 是彻底重启进程会有短暂的连接断开生产环境里尽量少用。8. 实战中高频出现的故障和排查思路最后这部分是我最想分享的新手很大一部分时间不是花在写配置上而是花在排查问题上。以下四个故障是 nginx 容器化部署里最容易碰到的。8.1 403 Forbidden多半是文件权限问题场景项目目录挂载好了静态文件也放了访问却报 403 Forbidden。先别急着怀疑 nginx 配置。403 说明请求已经到达 nginx但 nginx 没有权限读取文件。最常见原因是挂载目录的权限不对。nginx 容器里的 worker 进程默认以nginx用户运行这个用户在宿主机上的 UID 通常是 101而宿主机/srv/sites/a目录的属主可能是 root权限是 700。容器里的nginx用户读不了自然就 403。解决办法sudo chmod -R 755 /srv/sites/a或者直接把目录属主改成容器内 nginx 用户的 UIDsudo chown -R 101:101 /srv/sites/a改完刷新页面一般就好了。另外如果目录里没有index.html文件nginx 默认又不允许列目录autoindex off也会 403。先确认目录里有没有文件再查权限这个顺序比较合理。8.2 502 Bad Gateway后端服务根本不通502 表示 nginx 成功接收了请求但是无法从上游服务器拿到有效响应。排查思路分三步。第一步确认后端服务有没有起来。如果你代理的是另一个容器用docker ps看它是不是 Up 状态再看它的日志有没有报错docker logs app-server第二步确认 nginx 容器能不能访问到后端。进入 nginx 容器用 curl 测试docker exec -it nginx-proxy bash curl http://app-server:3000/health容器里如果没装 curl用wget也行。这一步能直接暴露网络问题如果提示解析不到app-server说明两个容器不在同一网络如果连接超时检查网络配置和防火墙。第三步验证你写的proxy_pass地址在容器内视角下是否正确。别忘了127.0.0.1在容器里是指容器自己不是宿主机。这也是新手第一次配反代最容易翻车的点。8.3 404 Not Foundlocation 路径拼接逻辑要理清404 里有一部分是静态文件路径没对上有一部分是 location 匹配出问题。特别是proxy_pass后面的路径结尾有没有斜杠结果完全不一样。配置写法请求/api/user时转发到后端的路径proxy_pass http://app-server:3000;/api/user完整 URI 原样转发proxy_pass http://app-server:3000/;/user匹配到的/api/前缀被替换为/这个差异很微妙但实际工程里经常因为这一条踩坑。如果你的后端接口路由是/api/user那 proxy_pass 就不要带结尾斜杠如果后端路由是/user那就要带斜杠把/api前缀剥掉。配置之前先把这个逻辑想清楚能省去很多 404 排查时间。8.4 端口冲突bind: address already in use启动容器时报bind: address already in use说明宿主机上要映射的端口已经被别的进程占用。排查方式sudo lsof -i :8080或者用 ssss -lntp | grep 8080看到占用进程之后确认能不能停掉不能停就换一个宿主机端口映射改-p左边数字就好。还有一种情况是之前启动过的容器没删干净同名容器残留也可能导致新容器启动失败报冲突是因为名字而不是端口。这种就docker rm 旧容器名删掉再启动。8.5 日志是最好的老师无论上面哪种故障第一件事都应该是看日志docker logs -f nginx容器名容器启动失败时看启动日志运行中的问题看访问日志和错误日志。docker logs输出的就是容器主进程的 stdout 和 stderrnginx 容器如果没额外配置默认会把访问日志打到 stdout。很多时候错误信息不会直接报在页面上但一定会在日志里留线索。最后分享一个我自己的习惯所有 nginx 配置文件都放在宿主机上一个固定目录比如/opt/docker/nginx/conf下面配套一个 Docker Compose 文件统一管理。换机器部署时只要把整个目录拷过去docker compose up -d全部搞定。这套玩法学到手之后再去摸索 MySQL、Redis、GitLab 的容器化部署思路完全一致拉镜像、起容器、挂数据卷、配端口和网络。永远记住先想清楚数据放哪里、日志从哪里看就不会在容器化的路上走太偏。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

大学物理波动章节考点精讲:课后习题与答案高效复习指南 2026/9/20 19:29:59

大学物理波动章节考点精讲:课后习题与答案高效复习指南

简介:这份PDF是大学物理(第四版)波动章节的课后习题与答案解析,面向正在学习波动理论的理工科本科生及备考期末的考生。内容以第十四章波动为核心,系统覆盖波动方程、振幅、波速、频率、波长、横波、相位差等基础概念&…

阅读更多 →
Hermes Agent 的 Profile 与 Cron 不走官方模型通道,改走 TaoToken 通道行不行 2026/9/20 19:29:59

Hermes Agent 的 Profile 与 Cron 不走官方模型通道,改走 TaoToken 通道行不行

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
宝塔线指标公式详解:5分钟周期实战源码与参数调优 2026/9/20 19:29:59

宝塔线指标公式详解:5分钟周期实战源码与参数调优

简介:文华财经期货5分钟宝塔线指标公式源码以doc文档形式提供,主要面向期货交易者、文华财经软件用户以及希望学习指标编写的人。文档内含一套完整公式代码,聚焦5分钟周期下的宝塔线及相关多空信号,涵盖均线多空排列、量托价托、金…

阅读更多 →
Matlab实现Transformer-LSTM混合模型用于时间序列预测及GUI设计 2026/9/20 19:29:59

Matlab实现Transformer-LSTM混合模型用于时间序列预测及GUI设计

简介:Matlab实现Transformer-LSTM时间序列预测的完整项目实例,面向深度学习与时间序列预测方向的研究生、科研人员及数据分析从业者。包内为1个docx文档(约55KB),系统阐述了混合模型应对长短期依赖与非线性特征的思路&…

阅读更多 →
计算机网络实验报告写作指南:Wireshark抓包与Socket编程实战 2026/9/20 19:29:59

计算机网络实验报告写作指南:Wireshark抓包与Socket编程实战

简介:西北工业大学软件学院计算机网络实验报告,面向计算机网络课程学习者,系统呈现HTTP协议四大实验的完整分析与答题框架。报告以Wireshark抓包为主线,涵盖基础GET/响应交互、条件GET、长文档检索、HTML嵌入对象等场景&#xff0…

阅读更多 →
为什么 OpenClaw Gateway 一直离线?TaoToken 这样修模型通道 2026/9/20 19:26:59

为什么 OpenClaw Gateway 一直离线?TaoToken 这样修模型通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞