前端工程师也应该了解的 docker compose

深入了解 Docker Compose:简化容器化应用部署的 unity和C++客户端都投了,只有C++岗位有笔试笔试题4道,具体记不太清了1,是个归并排序合并链。二本传媒生一枚从2月底开始投春招,已经一个月了,进面试的都很少,到现在还0offer想投视频岗或者运。昨天一面,今下午收到二面邀请,点进去选择时间的时候犹豫了一会,再点确定时候就提示链接失效了,然后重新。阳了两天,迷迷糊糊的一天就刷了一道题,八股也没看,毕设也没做,笔试不想做,明天还有几场面试,已经开摆。现在有两个offer,两个地方薪资都是一样的,想看看各位大佬的意见1.小米,base武汉,软件开发工。 阅读详情

docker

海面上,一艘满载集装箱的货轮正在驶离港口……

 

 

1. 前言

一个月前,我写了一篇《前端工程师也应该了解的docker》,之后就不断有小伙伴千呼万唤!

催更

 

催更

 

这次我们的目标是部署一个全栈项目,而这一篇涉及的内容有:

  • docker-compose.yml 容器编排配置文件
  • volume 数据卷持久化
  • network 网络(bridge 模式)
  • nginx 反向代理

这一部分的内容还是很难的,但是没关系,看到 3.1 节,你不可能不会。

对了,这次我在 github 上准备了源码,按照顺序分成了多个 tag 版本的代码,方便大家参考:github.com/Knight174/d…

注意:本文我并不打算解释服务端代码,如果你想要实践成功的话,强烈建议下载源码。

2. docker compose

2.1 什么是 docker compose?

上篇说到利用 docker 可以实现单个容器的部署,当遇到相互有联系的容器呢?比如一个 Web 应用,不仅仅有客户端,还有服务器端和数据库需要部署。在这种生产环境级别的情况下,如果一个一个服务启动起来,未免太麻烦了,那么应该如何应对?部署多容器的应用,就要用到 docker 官方提供的容器编排工具 —— docker compose。

2.2 需求设计

设计一个很简单的需求:

  • 统计首页访问量
  • 访问首页可以看到所有人员信息

2.3 编排设计

现在,整个应用的编排设计大体如下:

  • 创建四个容器,分别启动 postgres、redis、express、nginx 服务。
  • postgres 暴露 5432 端口、redis 暴露 6379 端口,让 express 可以访问数据;express 暴露 3000 端口让 nginx 进行反向代理;最后,用户通过访问 nginx 的 80 端口进入网站。
  • 数据库的数据通过 volume 实现持久化。
  • 定义 network 实现服务间的通信,避免占用过多端口。

compose design

 

3. docker 单容器部署

docker compose 的下载安装:略。

在使用 docker compose 进行部署之前,我们先用 docker 单容器的方式去部署,然后再过渡到 docker compose。如果只对 docker compose 感兴趣,请直接去第 4 节。

在此之前,请在本地准备好以下镜像:

  • node:18-alpine
  • postgres:14-alpine
  • redis:6.0.20-alpine
  • nginx:stable-alpine

相关指令:docker pull <image_name>:<image_tag>

3.1 构建网络

如果想让容器之间能够通信,那么就需要构建一个虚拟网络:

bash复制代码# docker network create <network_name>
docker network create network1

如果不构建,后面运行容器时就会报错:docker: Error response from daemon: network network1 not found.

这种网络模式实际上就是 bridge 模式(桥接模式)。当容器启动时,docker 会为容器分配一个 IP 地址,并将容器连接到默认的桥接网络。通过桥接网络,容器可以相互通信,也可以与宿主机上的其他服务进行通信。

大概可以理解为——牛郎织女鹊桥相会,在这段感人的神话传说里,好在有鹊桥,牛郎织女一家人才得以见面团聚。Nginx 容器代表织女、Express App 代表牛郎、PostgreSQL 和 Redis 分别代表一儿一女,而 network1 代表鹊桥。

颐和园长廊彩绘-鹊桥相会

 

记住这个故事,继续往下看。

3.2 PostgreSQL 服务器

3.2.1 启动容器

在数据库服务中将用到 volume 数据卷(可以理解为本地的一个文件夹,服务启动后会用这个本地文件夹里的数据,这样即使容器被干掉了,数据还在,这就做到了持久化。),同样也要用到 network。

使用镜像 postgres:14-alpine 启动一个 Postgres 数据库服务:

bash复制代码docker run -d --name my-postgres -v "$PWD/db-data":/var/lib/postgresql/data --network=network1 -p 5432:5432 -e POSTGRES_USER=myuser -e POSTGRES_PASSWORD=mypassword postgres:14-alpine
  • -d:以“分离模式”启动容器,允许容器在后台运行。
  • --name:指定容器名称,这里名称为 my-postgres。
  • -v "$PWD/db-data":/var/lib/postgresql/data:将主机的文件或目录与容器内的文件或目录进行挂载。在这里,$PWD/db-data 是主机上的当前工作目录下的 "db-data" 目录,/var/lib/postgresql/data 是容器内的 PostgreSQL 数据目录。这样做的目的是使数据库的数据持久化,方便在容器重新启动后保留数据。
  • --network network1:指定容器连接的网络。在这里,容器将连接到名为 "network1" 的网络中,这样可以与其他容器或主机进行通信。
  • -p 5432:5432:将主机的端口与容器的端口进行映射。在这里,主机的 5432 端口将映射到容器的 5432 端口。这样做是为了允许在主机上通过 5432 端口访问运行在容器内的 PostgreSQL 数据库。
  • -e POSTGRES_USER=myuser -e POSTGRES_PASSWORD=mypassword:指定在容器内创建的 PostgreSQL 数据库的用户名和密码。在这里,用户名为 myuser,密码为 mypassword。这些参数将被用于在容器启动时设置数据库的访问凭据。

3.2.2 创建并连接数据库

进入容器,创建并连接数据库 dev。(生产环境用 prod)

bash复制代码docker exec -it my-postgres bash # 进入容器 my-postgres
psql -U myuser # 登录数据库
CREATE DATABASE dev; # 创建数据库 dev
# CREATE DATABASE prod;
\c dev; # 连接数据库 dev
# \c prod;

如果数据库不是首次创建,直接使用 psql -U myuser -d dev 连接即可。

3.2.3 创建表

sql复制代码CREATE TABLE IF NOT EXISTS users (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(100) NOT NULL,
  deleted BOOLEAN DEFAULT false
);

一开始 users 表里是没有数据的,需要数据播种。

3.2.4 数据播种

创建好数据库后,就可以运行 express 服务了,首次进入会进行数据播种。我使用了 @faker-js/faker 这个包来实现,具体可以查看 db/seed.ts 里的代码内容。

3.3 Redis 服务器

使用镜像 redis:6.0.20-alpine 启动一个 Redis 服务:

bash复制代码docker run -d --name my-redis -v "$PWD/redis-data":/data --network network1 -p 6379:6379 redis:6.0.20-alpine redis-server --appendonly yes --requirepass 12345678
  • -name my-redis:指定容器名称,这里名称为 my-redis。
  • v "$PWD/redis-data":/data:创建数据卷。"$PWD/redis-data" 表示当前目录下的 "redis-data" 目录,将其映射到容器内的 "/data" 目录。这样可以持久化存储 Redis 数据,即使容器被删除或重新创建,数据仍然可用。
  • -network network1:指定容器连接的网络。在这里,容器将连接到名为 "network1" 的网络中,这样可以与其他容器或主机进行通信。
  • redis-server --appendonly yes --requirepass 12345678:在容器内运行的命令。redis-server 是 Redis 服务器启动命令,-appendonly yes 启用了 AOF 持久化,-requirepass 12345678 设置了 Redis 的访问密码为 "12345678"。

到这里,我们可以通过 docker ps 指令看到当前正在运行的容器:

正在运行的容器

 

在这里,眼睛雪亮的朋友可以发现容器列表中的 PORTS 还是分别将端口映射出来了,这是为了方便在本地开发,直接连接端口。如果是生产环境,创建容器时则不建议加上 -p 参数,容器间直接通过 network1 以及对应的服务名称进行连接即可,具体可以看 3.4.2 节的 .env 文件。

3.4 Express App 服务

数据库准备好后,开始创建一个 express + ts 项目,前端部分使用 react + ts,并完成相关需求:略。

直接下载运行这个 tag 版本的代码即可:

github.com/Knight174/d…

v1.0.0

 

后端接口 /api/users 我写了增删改查,前端比较繁琐,就写了 users 的列表获取,大家可以 fork 后帮我贡献代码。

image.png

 

3.4.1 package.json

package.json

json复制代码{
    "scripts": {
      "build": "npx tsc",
      "start": "node dist/index.js",
      "dev": "concurrently \"npx tsc --watch\" \"nodemon -q dist/index.js\"",
      "start:prod": "npm run build && npm run start"
    }
}

3.4.2 .env

.env 文件存放了需要使用的环境参数。在开发环境下,记得把这里的 NODE_ENV 对应的值改为 dev,至于环境切换配置可以查看源码中的 /server/config/config.ts。

如果不暴露端口,所有服务处于 network1 网络下,使用启动容器时指定的 name 名称作为 host 地址,因为 docker 会通过这个 name 将容器内部的 host 和容器内部 ip 做关联。例如,PSQL_HOST 和 REDIS_HOST 的值分别为 "my-postgres" 和 "my-redis"。

.env复制代码NODE_ENV=production # 环境,开发环境时改成 dev
PORT=3000 # express 暴露端口

PSQL_DB=prod # postgres 数据库
PSQL_USER=myuser # 数据库服务管理员
PSQL_PASS=mypassword # 数据库服务密码
PSQL_HOST=my-postgres # 数据库服务主机
PSQL_PORT=5432 # 数据库服务端口

REDIS_HOST=my-redis # redis 数据库服务主机
REDIS_PASS=12345678 # 密码
REDIS_PORT=6379 # 端口

3.4.3 构建 express 服务

在 server 目录下新建生产环境的 Dockerfile:

Dockerfile复制代码# 使用 Node.js 18 作为基础镜像
FROM node:18-alpine

# 设置工作目录
WORKDIR /app

# 复制 package.json 和 package-lock.json 到容器中
COPY package*.json ./

# 安装应用程序依赖
RUN npm install

# 复制应用程序代码到容器中
COPY . .

# 暴露应用程序的端口
EXPOSE 3000

# 启动应用程序,对用 package.json 中的指令
CMD ["npm", "run", "start:prod"]

以当前目录下的 Dockerfile 为基础打镜像:

bash复制代码docker build -t express-app .

以 express-app 镜像来启动一个容器服务:

bash复制代码docker run -d --name my-express-app --network network1 -p 3000:3000 express-app

同样需要连接网络 network1。

此时,使用 docker ps 查看容器运行状态:

docker ps

 

注意:这里的两个数据库服务我用了 prod 的方式进行部署,所以没有 port 映射。

3.5 小结

到这里我们就实现了单容器的部署,按照上面的步骤执行下来,当你访问 http://localhost:3000 时,你应该能够看到这样的页面了:

单容器部署

 

恭喜你,成功了!

对了,当前端访问 http://localhost:3000/api/users 则可以拿到 users 列表的数据:

access /api/users

 

最后,再来整理一下思路:

  • 启动 PostgreSQL 数据库服务 + 初始化数据库 + 连接数据库
  • 启动 Redis 数据库服务
  • 启动 App

这里留了一个坑,就是用户并不能通过访问 80 端口就访问到网站,这需要 Nginx 的反向代理来实现,我放在 docker compose 里说。

4. docker compose 多容器部署

如果说 docker 启动的容器是一个个乐高的组件 🧩,那么 docker compose 就是由这些组件共同构成的一个完整的乐高玩具。

lego

 

docker-compose.yml 是进行 docker 编排任务的配置文件,就类似于 Dockerfile 是 Docker 镜像的配置文件一样,有了这份文件就能根据配置组建对应的服务了。

4.1 常用指令

docker compose 的指令和 docker 的指令差不多。

  • 启动容器

根据 docker-compose.yml 文件中的配置启动所有定义的容器。

bash复制代码docker-compose up
# or
docker-compose up -d #(以后台模式运行)
  • 关闭容器

停止并删除所有相关的容器、网络和卷。

bash复制代码docker-compose down
  • 构建镜像

根据 docker-compose.yml 文件中的配置构建所有定义的镜像。

bash复制代码docker-compose build
  • 查看容器状态

显示正在运行的容器的状态。

bash复制代码docker-compose ps
  • 查看容器日志

显示容器的日志输出。

bash复制代码docker-compose logs
  • 进入容器

在指定的服务中执行给定的命令。

bash复制代码docker-compose exec <service> <command>

4.2 构建服务

在 server 目录下新建配置文件:docker-compose.yml

yaml复制代码version: '3'

# 服务列表
services:
  express-app:
    container_name: express-app
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 3000:3000
    depends_on:
      - my-postgres
      - my-redis
    env_file:
      # 从 .env 文件中读取环境变量
      - .env
    networks:
      - network1
  my-postgres:
    image: postgres:14-alpine
    restart: always # Docker在容器退出时自动重启该服务
    container_name: my-postgres
    environment:
      # 从 .env 文件中读取环境变量,使用 ${变量名} 来使用它们
      - POSTGRES_DB=${PSQL_DB}
      - POSTGRES_USER=${PSQL_USER}
      - POSTGRES_PASSWORD=${PSQL_PASS}
    volumes:
      - ./db-data:/var/lib/postgresql/data
    networks:
      - network1
  my-redis:
    image: redis:6.0.20-alpine
    restart: always
    container_name: my-redis
    env_file: .env
    volumes:
      - ./redis-data:/data
    command: redis-server --appendonly yes --requirepass ${REDIS_PASS}
    networks:
      - network1

# 网络
networks:
  network1:

关键注释:

  • container_name:指定容器的名称。
  • build:指定构建镜像所需的上下文路径。可以是一个包含 Dockerfile 的目录路径,或者一个包含具有构建指令的 URL。
  • ports:定义将容器内部端口映射到主机上的端口。格式为:<host>:<container>,前者表示主机端口,后者表示容器端口。
  • image:指定使用的镜像的名称。
  • depends_on:指定服务之间的依赖关系,这里的服务需要先启动,这样就可以保证服务启动顺序。
  • env_file:指定环境变量文件的路径。该文件中定义的环境变量将传递给容器,使您可以在容器内部使用这些变量。
  • networks:指定容器连接的网络。
  • restart:定义服务的重启策略。可以设置为always(始终重启)、no(不重启)、on-failure(仅在非零退出代码时重启)和unless-stopped(除非手动停止,否则重启)。
  • environment:设置容器的环境变量,通过 ${变量名} 的形式可以访问到 env 文件中的环境变量。可以在此处指定键值对,将环境变量传递给容器。格式为KEY=VALUE。如果不想写这个,也可以通过配置 env_file 直接使用对应变量,不过要注意 key 是否一致。
  • volumes:定义容器与主机之间的文件或目录挂载。可以将主机的路径映射到容器内的路径,实现数据持久化或文件共享。

根据 docker-compose.yml 来构建多容器服务(如果这里运行不起来,请重启 docker):

bash复制代码docker-compose up -d

docker-compose 构建服务

 

4.3 小结

在第 3 节,我们用 docker 分别构建了三个容器服务,这三个服务就对应上面 yml 文件中的 servers 中的三个服务。比如第一个服务 express-app 就对应着上面 3.4.3 节的一系列操作:

express-app

 

my-postgres 和 my-redis 这两个服务同理,由此大家可以发现 docker 到 docker compose 几乎是无缝衔接的。

访问 http://localhost:3000:

多容器部署

 

没问题!

另外,通过指令 docker compose ps 可以查看当前编排任务的容器信息:

docker compose ps

 

如果想移除任务,执行 docker-compose down 即可。

docker-compose down

 

至于其他的 docker compose 指令,和 docker 指令简直如出一辙,大家自行探索吧~

5. Nginx 反向代理

还差最后一步,在访问网站时,我们似乎没有碰到还要用户在域名后面还要加上 3000 端口的说法,一般都是访问默认的 80 端口或者 443 端口。那么如何实现呢?加一个网关。

5.1 添加 nginx 服务

在原有的 docker-compose.yml 中添加 nginx 服务:

yaml复制代码version: '3'

services:
  express-app:
    container_name: express-app
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 3000:3000
    depends_on:
      - my-postgres
      - my-redis
    env_file:
      # 从 .env 文件中读取环境变量
      - .env
    networks:
      - network1
  my-postgres:
    image: postgres:14-alpine
    restart: always
    container_name: my-postgres
    environment:
      # 从 .env 文件中读取环境变量,使用 ${变量名} 来使用它们
      - POSTGRES_DB=${PSQL_DB}
      - POSTGRES_USER=${PSQL_USER}
      - POSTGRES_PASSWORD=${PSQL_PASS}
    volumes:
      - ./db-data:/var/lib/postgresql/data
    networks:
      - network1
  my-redis:
    image: redis:6.0.20-alpine
    restart: always
    container_name: my-redis
    env_file: .env
    volumes:
      - ./redis-data:/data
    command: redis-server --appendonly yes --requirepass ${REDIS_PASS}
    networks:
      - network1
  nginx:
    image: nginx:stable-alpine
    container_name: nginx
    restart: always
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./public:/usr/share/nginx/html
    depends_on:
      - express-app
    networks:
      - network1

networks:
  network1:
  • 在 nginx 服务中使用了两个数据卷来持久化,一个是 nginx 配置文件,一个是本地的静态文件。
  • 暴露 80 端口,供用户访问
  • 暴露 3000 端口,供数据调试

5.2 nginx.conf

在 server 目录下新建 nginx.conf:

nginx复制代码# 全局配置
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

# 事件模块配置
events {
  use epoll; # 多路复用
  worker_connections 1024;
}

# HTTP模块配置
http {
  # MIME类型配置
  include /etc/nginx/mime.types;
  default_type application/octet-stream;

  # 日志格式配置
  log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

  # 访问日志配置
  access_log /var/log/nginx/access.log main;

  # Gzip压缩配置
  gzip on;
  gzip_comp_level 6;
  gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

  # 服务器配置
  server {
      listen 80;
      # localhost 是主机名
      server_name localhost;

      # 根目录配置
      root /usr/share/nginx/html;
      index index.html;

      # 其他路由配置
      location / {
          # 这里 express-app 是 node 容器名
          proxy_pass <http://express-app:3000>;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          try_files $uri $uri/ /index.html;
      }

      # 静态文件缓存配置
      location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
          expires 1d;
      }
  }
}
  • 通过设置 proxy_pass 即可设置反向代理。当用户访问 http://localhost:80 时,就会被代理到 express-app 服务上,实际上就变成了访问 http://localhost:3000,但是用户是无感知的。
  • 通过设置静态文件缓存以及 gzip 压缩等,可以给网站提升性能,具体如下:

performance optimization

 

5.3 重新构建服务

移除之前的服务后,重新执行构建命令:

bash复制代码docker-compose up -d

docker compose 构建服务 - 添加了 nginx

 

除了通过 docker compose ps 来查看容器运行情况,也可以直接打开 docker 去 containers 中查看:

docker containers

 

访问 http://localhost:

加上 nginx,访问 80 端口

 

填坑完毕!

6. 总结

到这里,鹊桥相会的故事就讲完了。现在再去回顾 2.3 节的编排设计,相信你会有更深刻的理解。

与 docker 比起来,docker compose 可以让我们更加快速地上线一个全栈项目。

  • 数据持久化
  • bridge 网络模式的 network
  • 使用 docker 单容器部署
  • 使用 docker compose 编排多容器服务

network 还有其他的模式,比如 host 模式、覆盖网络模式;数据库操作推荐使用 Prisma,可以更加方便地进行 CRUD。这些都可以参考我的另一个仓库:github.com/Knight174/d…

虽然这一篇我拿 express.js 举例,但是其实诸如 next.js、nest.js 等 node 框架也大同小异,数据库也是同理,但这并不是说没有工作量。

至于云端部署,大家可以自己研究一下,把本地主机看成服务器就可以了,或者来群里催更。

以上,如有谬误,还请斧正。

记得三连哦,你的鼓励是我创作的最大动力,感谢您的阅读~

👏 对了,如果你还没有我的好友,加我微信:enjoy_Mr_cat,备注 「掘金」 ,即有机会加入高质量前端交流群,在这里你将会认识更多的朋友;也欢迎关注我的公众号 见嘉 Being Dev,并设置星标,以便第一时间收到更新。

前端工程师必备:Docker 从入门到实战 本文介绍了Docker如何解决前端开发中的环境不一致问题。主要内容包括:Docker的核心概念(镜像、容器、Dockerfile、仓库);与传统虚拟机的对比;安装配置步骤;以及将前端项目容器化的实战教程。通过Docker可以实现开发、测试、生产环境的一致性,简化部署流程,提升开发效率。文章详细讲解了如何编写Dockerfile、配置Nginx,以及一些实用技巧,帮助前端开发者快速掌握Docker的核心用法。 阅读详情

相关推荐

Podman Compose:零权限依赖的 Docker Compose 替代方案

容器编排工具的核心挑战在于安全与易用的平衡。Docker Compose 依赖 root 权限的守护进程模型,导致非 root 用户无法调用 socket、权限配置复杂且存在逃逸风险;而 Podman Compose 基于无守护进程(daemonless)架构和 Linux 用户命名空间(userns),实现真正的 rootless 运行——所有容器进程以当前用户 UID 执行,天然规避 CAP_SYS_ADMIN 和 cgroup 写入权限问题。其技术价值不仅在于兼容 docker-compose.yml

weixin_30530939的博客 685

前端如何获取到宿主机的环境变量?

其实很简单 我记录一下过程,然后再整理 获取系统环境变量 env 查看 然后 $ 对应名字即可,比如 $PATH shell 获取 这里关于变量的设置和使用 #!/bin/bash path=$PWD # 使用也很简单 菜鸟教程 sed 文本替换 这一步就是关键, sed -i "s/arrow/arrow_zb/g" ./master 这样就实现了替换某个文件,自然可以实现,如 sed -i "s/arrow/$path/g" ./master 意思就是把arrow替换后成我们想要的系统变

我是张跑跑 6407

使用helm-compose将Docker Compose配置一键转换为Kubernetes Helm Chart

在云原生应用部署中,容器编排和配置管理是核心基础。Docker Compose以其声明式语法和快速启动能力,成为本地开发和测试的利器,尤其适合定义多服务应用栈。而Kubernetes作为生产环境的标准编排平台,其资源对象如Deployment、Service、ConfigMap等提供了强大的运维能力。Helm作为K8s的包管理工具,通过Chart标准化应用部署,但手动从Compose迁移到Helm往往繁琐易错。helm-compose项目正是为解决这一痛点而生,它充当了声明式配置的桥梁,将熟悉的docker

weixin_30667649的博客 807

docker-compose部署caddy并开启https请求

Caddyfile配置 # 授权认证服务 http://auth-server.jianpeicn.com { reverse_proxy http://172.16.95.146:5000 } https://auth-server.jianpeicn.com { tls internal reverse_proxy http://172.16.95.146:5000 } # 基础服务 http://management-server.jianpeicn.com { reverse_p

qq_18638761的博客 2790

Rocky Linux 8 手动安装 Docker Compose 二进制指南

Docker Compose 是基于 Docker Engine 的容器编排工具,其原生 Go 二进制实现(docker compose)与旧版 Python 实现(docker-compose)在架构、性能和安全机制上存在本质差异。理解 Unix socket 直连、静态链接、SELinux 上下文控制等底层原理,是保障 Rocky Linux 8 等 RHEL 系衍生发行版稳定运行的关键。该方案规避包管理器版本滞后、Python 环境污染及网络依赖等常见风险,适用于金融级 CI/CD、监控栈部署及离线环

weixin_30379531的博客 390

Podman Compose:无需 root 权限的 Docker Compose 兼容编排方案

容器编排是现代应用开发与交付的核心能力,其本质是通过声明式配置实现多容器服务的自动化部署、网络互联与生命周期管理。底层依赖于容器运行时对命名空间、cgroups 和镜像分层等 Linux 内核特性的封装。随着最小权限原则和零信任架构成为企业安全基线,传统 Docker 的 root 依赖守护进程(dockerd)暴露出权限集中、审计困难、多租户隔离弱等工程瓶颈。Podman Compose 作为原生 rootless 编排工具,复用标准 docker-compose.yml 语法,依托 Podman 的用户

weixin_30307921的博客 381

使用Docker搭建Caddy

使用Docker搭建Caddy,可以快速部署一个轻量级的、支持自动HTTPS的web服务器。下面将分别介绍使用Docker CLI和Docker Compose两种方式来搭建Caddy服务器,并给出配置文件示例以及参数解释。

LogicLancer的博客 4505

RHEL 8上使用Docker Compose部署多容器应用实战指南

容器化技术通过Docker等工具实现了应用与环境的解耦,其中Docker Compose作为多容器编排工具,能够通过声明式配置管理复杂应用的依赖关系。其核心原理是通过YAML文件定义服务、网络和存储资源,实现一键式环境部署。在微服务架构中,这种技术能有效解决服务依赖管理、环境一致性等工程难题,特别适用于Web应用+数据库+缓存的典型组合场景。本文以RHEL 8为操作系统基础,详细演示如何利用Docker Compose部署包含React前端、Flask API、PostgreSQL数据库和Redis缓存的全

weixin_34357928的博客 900

Caddy2学习笔记——Caddy2反向代理docker版本的headscale

Caddy 反向代理 docker 版本的 headscale

aplsc的专栏 3290

Ruby on Rails 容器化开发:Docker Compose 实战指南

容器化是现代 Ruby on Rails 应用保障环境一致性的核心技术手段。其核心原理在于通过声明式配置(如 docker-compose.yml)固化 Ruby 版本、Gem 依赖、PostgreSQL 主版本、Redis 协议等运行时契约,消除因操作系统差异、本地工具链冲突(如 Homebrew portable ruby 失败、OpenSSL 版本不兼容)导致的‘环境病’。该技术显著提升团队协作效率与 CI/CD 可靠性,广泛应用于 Rails 开发、测试及预发布环境搭建。本文聚焦 Docker Co

weixin_30522183的博客 414

caddy-docker-proxy:Caddy作为Docker的反向代理

CADDY-DOCKER-PROXY CADDY V2! 此插件已更新到Caddy V2。 Master分支和Docker CI映像现在专用于V2。 介绍 该插件使caddy可用作Docker的反向代理。 它是如何工作的? 它扫描Docker元数据以查找指示该服务或容器应在球童上公开的标签。 然后,它会生成一个内存中的Caddyfile,其中包含指向每个Docker服务DNS名称或容器IP的网站条目和代理指令。 每次docker对象更改时,它都会更新Caddyfile并触发caddy零宕机时间重新加载。 使用docker-compose的基本用法示例: docker network create caddy 球童/docker-compose.yml version: "3.7" services: caddy: image: lucaslorentz/cadd

Caddy部署与使用—踩坑总结

Caddy部署与使用—踩坑总结

mingqing的博客 1万+

【生物识别模组介绍】静脉识别模组

静脉识别技术是依据流动的静脉血液中的血红蛋白对近红外光有所吸收,通过近红外光照射手指、手掌、面部、腕部呈现的分布图像,再使用特定的算法对图像进行特征提取、分析比对,从而进行身份认证识别。静脉结构相同几率为34亿分之一,每个人的静脉结构具有独特性,而且静脉特征图像自成年后终身不变,不受外部环境、疾病等影响,是人体最稳定的生物特征之一。商务合作联系:newmagicmission@gmail.com图1.0。

upupDay's blog 902

React Native Skia 遮罩(Mask)组件完全指南:alpha 与 luminance 两种模式的实现原理与实战用法

本文围绕 [react-native-skia](https://link.gitcode.com/i/21ca201c76779855950840632525c009) 提供的 `Mask` 组件展开,系统讲解它在 Skia 渲染管线中如何通过 `alpha`(透明度通道)与 `luminance`(亮度)两种模式裁剪内容,并结合 `clip` 属性控制遮罩绘制本身的可见性。你将掌握 `Mask

gitblog_00946的博客 751

全志D1s RISC-V开发板硬件设计与Linux启动全流程解析

RISC-V架构是当前国产嵌入式处理器演进的核心方向,其启动流程涵盖从BootROM、SPL到U-Boot及Linux内核的多级引导机制。理解该流程需掌握DDR初始化、设备树适配、电源时序控制等底层原理,技术价值在于构建可追溯、可调试、可量产的最小可行系统(MVS)。典型应用场景包括边缘AI推理终端、工业HMI和轻量级网关等对成本与开源性敏感的领域。本文以全志D1s平台为载体,深入剖析基于玄铁C906内核的RISC-V SoC在真实硬件上的启动验证、电源完整性设计与Linux全链路开源实践。

weixin_32306683的博客 359

Unity 2021 LTS安装避坑指南:从下载到第一个3D项目的完整流程

本文提供了一份详尽的Unity 2021 LTS安装与首个3D项目创建指南。内容涵盖从Unity Hub下载、版本选择、模块安装避坑,到编辑器界面解析、创建旋转立方体脚本的完整流程,旨在帮助初学者快速搭建稳定开发环境并上手核心操作。

mango的博客 310

Docker Compose多文件合并实战(90%工程师忽略的关键细节)

掌握Docker Compose多文件合并技巧,轻松管理复杂环境配置。详解开发、测试、生产环境分离的适用场景,通过extends和override实现高效合并,提升部署灵活性与可维护性。90%工程师忽略的关键细节值得收藏。

BreakVein的博客 1066

PTA 学生信息的那些操作:添加记录(结构体)

这是河南工业大学自主命题的一道基础题,题目如下: 有一学生成绩表,包括学号、姓名、3门课程成绩。已知该成绩表按学号升序排序。请编程实现,添加一个新的学生信息,且使成绩表仍按学号有序;若待添加的学号与已有学号重复,则输出错误信息,拒绝添加。 输入格式: 首先输入一个整数n(1<=n<=100),表示学生人数; 然后输入n行,每行包含一个学生的信息:学号(12位)、姓名(不含空格且不超过20位),以及3个整数,表示3门课成绩,数据之间用空格隔开。 最后一行输入一个待添加的学生信息,包括学号

weixin_63617665的博客 3156

Windows使用docker教程(六):docker compose启动容器

本文介绍了Docker Compose的基本概念和使用方法。Docker Compose通过YAML格式文件定义多容器应用,实现一键配置部署。文章解析了Compose文件的6个顶级元素(name、services、version等)及其作用,并通过MySQL容器示例展示了命令与YAML配置的对应关系。重点说明了volumes和networks在不同层级的配置方式,以及depends_on控制启动顺序的用法。最后演示了编写和启动Compose的完整流程,强调熟悉官方文档的重要性。

海风依旧 1527

GD32F4系列替换STM32F4,HAL库CAN初始化卡死?一个Sleep模式的坑与填坑实录

本文详细解析了GD32F4系列替换STM32F4时,HAL库CAN初始化卡死的问题根源——Sleep模式差异。通过对比两款芯片CAN控制器的默认状态,提出了不修改HAL库源码的解决方案,即在HAL_CAN_MspInit()中清除SLEEP位,并分析了该方法的优势。文章还提供了国产MCU替换的通用建议和调试技巧,帮助开发者高效解决问题。

weixin_29174013的博客 218

告别手动归档:基于Allegro Skill的XTools一键生成Gerber与生产文件实践

本文详细介绍了基于Allegro Skill的XTools工具如何实现一键生成Gerber与生产文件,大幅提升PCB设计效率。通过自动化流程,解决了传统手动归档中的重复劳动、人为失误和标准不统一等问题,特别适合需要频繁输出生产文件的工程师。文章包含安装配置、实战操作、问题排查及进阶技巧,帮助用户快速掌握这一高效工具。

weixin_30505225的博客 461

docker build 变量_写给前端工程师看的Docker教程-实战篇

在上一篇文章里,我们学习了Docker常用的命令和基本操作,现在可以开始实战了。单页应用前端工作中最常见的就是单页应用了。我们首先用create-react-app快速创建一个应用npm i create-react-app -g create-react-app react-app cd react-app npm run start可以看见正常启动的页面。打包试一下npm run build可...

weixin_35995835的博客 492

rk3399开发环境的介绍

由于Bluez的介绍文档有限,以及对Linux 系统/驱动概念、D-Bus 通信和蓝牙协议都有要求,加上网络上其实没有一个完整的介绍Bluez系列的文档,所以不管是蓝牙初学者还是蓝牙从业人员,都有不小的难度,学习曲线也相对较陡,所以我有了这个想法,专门对Bluez做一个系统性的介绍,尽可能的涵盖所有内容。

朝气蓬勃 711

Helm-Compose:用Docker Compose语法驱动Kubernetes部署

容器编排是现代云原生应用部署的核心技术,它通过抽象底层基础设施,实现应用的高效调度与管理。其原理在于将应用及其依赖打包为容器,并通过声明式配置定义服务间关系与资源需求。在技术价值上,容器编排显著提升了部署一致性、可扩展性和资源利用率。常见的应用场景包括微服务架构、持续集成/持续部署流水线以及混合云环境下的应用管理。本文聚焦于Helm-Compose这一创新工具,它巧妙地将开发者熟悉的Docker Compose语法与强大的Helm引擎相结合。通过解析与映射机制,Helm-Compose将Compose文件转

weixin_33739541的博客 681

主题045:四足机器人的运动仿真

四足机器人(Quadruped Robot)是模仿哺乳动物四肢运动设计的机器人系统,具有优异的地形适应性和运动稳定性。与双足机器人相比,四足机器人在静态和动态稳定性方面具有天然优势,能够在复杂地形(如楼梯、斜坡、碎石地面)上稳定行走,因此在野外探索、救援任务、军事应用等领域具有广阔的应用前景。本教程将介绍四足机器人的运动学建模、步态规划、稳定性分析和控制策略,并通过Python仿真验证相关理论。典型的四足机器人每条腿包含3个关节:常见的腿部构型包括:对于单腿,足部位置 pfoot\mathbf{p}_{fo

kkchenjj的博客 682

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

上一篇: 玩转Vue3:计算属性和监视属性深度解析
下一篇: 【d3.js入门】d3-drag介绍和实战
Cipher_Y
博客等级 码龄3年 93粉丝 98原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值