写点东西《使用 Docker 构建本地开发环境:运行带有 PostgreSQL 和 Minio S3 的 Next.js 全栈应用程序》

写点东西《使用 Docker 构建本地开发环境:运行带有 PostgreSQL 和 Minio S3 的 Next.js 全栈应用程序》


简介

作为从事全栈应用程序开发的开发人员,您需要拥有一个尽可能接近生产环境的本地开发环境。这将允许您在将应用程序部署到生产环境之前在本地测试和调试应用程序。

几乎每个全栈应用程序都需要一个数据库和一个文件存储,因此,让我们构建一个基本的全栈应用程序,该应用程序可以保存和检索数据库中的数据,以及上传和下载文件存储中的文件。

您可以在本地运行自己的 PostgreSQL 和 Minio S3 服务器,甚至可以使用 AWS RDS 和 S3 等云服务。但这需要一些时间来设置和配置。使用 docker-compose 可以非常轻松地为您的全栈应用程序设置本地开发环境。在本地对其进行测试后,您需要切换到生产环境所做的全部工作就是更改环境变量。

此外,您可以在尽可能接近生产环境的本地环境中端到端测试您的应用程序(例如,使用 Cypress)。预先配置的 docker-compose 文件将使设置 GitHub Actions 或 GitLab CI 等 CI/CD 管道变得容易。

一旦你拥有一个 docker-compose 文件,你和你团队就可以使用它在任何机器上用一个命令在几分钟内设置相同的本地开发环境。总体而言,它将为你节省大量时间,让你的生活更轻松。

在本文中,我们将研究如何使用 Docker-Compose 为一个完整的 Next.js 应用程序构建一个本地开发环境,该应用程序使用 Prisma ORM 连接到 PostgreSQL 作为数据库,并使用 Minio S3 作为文件存储。

您可以在 GitHub 上找到本教程的完整源代码

当您准备好将应用程序部署到生产环境时,可以使用任何类型的数据库:

  • Supabase(我喜欢这个)
  • Vercel Postgres
  • AWS RDS
  • Google Cloud SQL
  • Azure Database for PostgreSQL
  • Heroku Postgres
  • DigitalOcean Managed Databases
  • ScaleGrid

文件存储也是如此,您需要一个兼容 S3 协议的文件存储:

  • AWS S3
  • Google Cloud Storage(我测试过,它有效)
  • Wasabi(最便宜的选择之一)
  • Backblaze B2
  • DigitalOcean Spaces

先决条件

要按照本教程进行操作,您需要在计算机上安装 Docker 和 Docker-Compose。您可以在 Docker 官方网站上找到有关如何安装 Docker 和 Docker-Compose 的说明。

当我第一次面临为 Next.js、Prisma 和 PostgreSQL 设置本地开发环境的任务时,我尝试使用 T3 Docker 教程,但它对我不起作用。不过,我将其用作本教程的起点。


构建本地开发环境

1. 创建一个 Next.js 应用程序

让我们从创建一个 Next.js 应用程序开始。在本教程中,我们将使用 T3 堆栈(TypeScript、TailwindCSS 和 Prisma ORM)来跳过安装和配置所有依赖项,这超出了本文的范围。您可以在此处找到有关 T3 堆栈的更多信息。

运行以下命令以创建一个新的 Next.js:

npm create t3-app@latest

运行命令后,系统会询问您几个问题:

   ___ ___ ___   __ _____ ___   _____ ____    __   ___ ___
  / __| _ \ __| /  \_   _| __| |_   _|__ /   /  \ | _ \ _ \
 | (__|   / _| / /\ \| | | _|    | |  |_ \  / /\ \|  _/  _/
  \___|_|_\___|_/‾‾\_\_| |___|   |_| |___/ /_/‾‾\_\_| |_|

◇  What will your project be called?
│  local-nextjs-postgres-s3
│
◇  Will you be using TypeScript or JavaScript?
│  TypeScript
│
◇  Will you be using Tailwind CSS for styling?
│  Yes
│
◇  Would you like to use tRPC?
│  No
│
◇  What authentication provider would you like to use?
│  None
│
◇  What database ORM would you like to use?
│  Prisma
│
◇   EXPERIMENTAL  Would you like to use Next.js App Router?
│  No
│
◇  Should we initialize a Git repository and stage the changes?
│  Yes
│
◇  Should we run 'npm install' for you?
│  Yes
│
◇  What import alias would you like to use?
│  ~/

2. 配置 Next.js 以配合 Docker 使用

根据 Next.js 文档

Next.js 可以自动创建一个独立文件夹,其中仅复制生产部署所需的必要文件,包括 node_modules 中的选定文件。

为了减小图像大小,我们需要在 next.config.js 文件中添加 output: "standalone"

next.config.js 文件应如下所示:

const config = {
  reactStrictMode: true,
  output: "standalone",
  // ...
};

3. 添加 .dockerignore 文件

我更喜欢为 docker 文件单独创建一个文件夹,因此我在项目的根目录中创建了一个名为 compose 的文件夹。我们需要向此文件夹中添加一个 .dockerignore 文件,以从 Docker 镜像中排除不必要的文件。 .dockerignore 文件应如下所示:

.env
Dockerfile
.dockerignore
.next
.git
.gitignore
node_modules
npm-debug.log
README.md

4. 配置 Prisma 以配合 Docker 使用

prisma/schema.prisma 文件中,我们需要

  • 将提供商从 sqlite 更改为 postgresql
  • binaryTargets 添加到生成器块。这将允许我们在 Docker 容器内使用 Prisma CLI。您需要将 binaryTargets 指定为特定于您的操作系统和架构。例如,对于 M1 Mac,我使用 "linux-musl-arm64-openssl-3.0.x" 。要支持其他操作系统和架构,您需要将它们添加到 binaryTargets 数组中。有关 Prisma 文档中的 binaryTargets 的更多信息。

我想在具有不同操作系统和架构的机器上用于本地开发以及在 GitHub Actions 上用于 CI/CD 管道的 schema.prisma 文件相同。因此,在我的情况下, prisma/schema.prisma 文件如下所示:

generator client {
    provider      = "prisma-client-js"
    binaryTargets = ["native", "linux-musl-arm64-openssl-3.0.x", "linux-musl-openssl-3.0.x", "rhel-openssl-1.0.x"]
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

5. 为 Next.js 应用程序创建一个 Dockerfile

compose 文件夹中,创建一个名为 web.Dockerfile 的文件,内容如下:

FROM node:18-alpine

RUN mkdir app
COPY ../prisma  ./app
COPY ../package.json ../package-lock.json ./app
WORKDIR /app

RUN npm ci

CMD ["npm", "run", "dev"]

我们将使用 node:18-alpine 镜像作为基础镜像。这是一个轻量级镜像,包含 Node.js 18 和 npm。我们将复制 /prisma 文件夹、 package.jsonpackage-lock.json 文件到 /app 文件夹,并运行 npm ci 来安装依赖项。

在 Docker 镜像中使用“clean install”( npm ci )而不是“install”( npm i )是一种好习惯。它将确保依赖项是从 package-lock.json 文件中安装的,而不是从 node_modules 缓存中安装的。这比“install”更快,这对于希望尽可能缩短构建时间的 CI/CD 管道尤为重要。

6. 创建 docker compose 文件

Docker compose 文件用于使用单个命令定义和运行多容器 Docker 应用程序 docker-compose up

此处我们不会详细介绍 docker-compose 文件。通常,我们的 docker-compose 文件创建 3 个服务:web(使用我们的 Dockerfile 构建的 Next.js 应用程序)、db(PostgreSQL 数据库)和 minio(Minio S3 文件存储)。请记住为数据库和文件存储服务添加卷。否则,停止容器时数据将丢失。

通常不建议在 docker-compose 文件中存储环境变量。但是,在这个特定场景中,出于教育目的,并且我们仅将其用于本地开发和测试,这看起来是可以接受的。

如果您不想将机密存储在 docker-compose 文件中,则应使用 .env 文件并使用 ${VARIABLE_NAME} 语法来引用变量。有关 docker-compose 文件中的环境变量的更多信息,请参阅 Docker compose 文件参考。

compose 文件夹中,创建一个名为 docker-compose.yml 的文件,内容如下:

version: "3.9"
name: nextjs-postgres-s3minio
services:
  web:
    container_name: nextjs
    build:
      context: ../
      dockerfile: compose/web.Dockerfile
      args:
        NEXT_PUBLIC_CLIENTVAR: "clientvar"
    ports:
      - 3000:3000
    volumes:
      - ../:/app
    environment:
      - DATABASE_URL=postgresql://postgres:postgres@db:5432/myapp-db?schema=public
      - S3_ENDPOINT=minio
      - S3_PORT=9000
      - S3_ACCESS_KEY=minio
      - S3_SECRET_KEY=miniosecret
      - S3_BUCKET_NAME=s3bucket
    depends_on:
      - db
      - minio
  db:
    image: postgres:15.3
    container_name: postgres
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: myapp-db
    volumes:
      - postgres-data:/var/lib/postgresql/data
    restart: unless-stopped
  minio:
    container_name: s3minio
    image: bitnami/minio:latest
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - minio_storage:/data
volumes:
  postgres-data:
  minio_storage:


运行应用程序

根据 docker-compose 文件的位置和要使用的选项,

您需要运行以下命令:

# If you have docker files in the root of the project
docker-compose up

# In our case, we have dockerfile and docker-compose file in the compose folder, so we need to run:
docker-compose -f compose/docker-compose.yml up

# --- Optional ---
# For running the application with secrets ${VARIABLE_NAME} stored in the .env file, we would need to run:
docker-compose -f compose/docker-compose.yml --env-file .env up

# If you want to run the application in the background, you can use the -d flag:
docker-compose -f compose/docker-compose.yml up -d

它将运行构建 Next.js 应用程序并在端口 3000 上运行它。它还将下载 PostgreSQL 和 Minio S3 docker 镜像,并在端口 5432 和 9000 上分别运行它们。

应用程序构建完毕并下载完镜像后,您将看到以下输出:

您可以在 http://localhost:3000 访问应用程序,在 http://localhost:5432 访问 PostgreSQL 数据库(登录名:postgres,密码:postgres),在 http://localhost:9000 访问 Minio S3(登录名:minio,密码:miniosecret)。

数据库和文件存储的凭据存储在 docker-compose 文件中。如果您愿意,可以更改它们。

结论

在本文中,我们研究了如何为一个完整的 Next.js 应用程序构建一个本地开发环境,其中 Prisma ORM 连接到 PostgreSQL 作为数据库,Minio S3 作为文件存储,使用 Docker-Compose。


参考资料和进一步阅读:

  • 将 T3 堆栈容器化并使用 Docker 将其部署为单个容器
  • Next.js 部署文档
  • 官方 Next.js Docker 示例
  • Docker Compose 文件参考
  • 如何使用 .dockerignore 及其重要性
  • 保护 Docker 构建:.dockerignore 用法和最佳实践的综合指南
  • Prisma 架构参考
  • Minio S3 Docker 镜像

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/323445.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HCIP-3

重发布、重分布、重分发: ASBR同时工作于不同的路由协议中,然后通过各种的方式学习的条目,再进行共享; 必须存在ASBR----自治系统边界路由器--协议边界路由器需要考虑种子度量 规则: 将A协议发布到B协议&#xff0c…

SpringBoot教程(九) | SpringBoot统一异常处理

SpringBoot教程(九) | SpringBoot统一异常处理 异常大家应该都很清楚,我们的项目总是不可避免的出现异常,那么应该如何优雅的进行异常处理使我们需要关注的一个问题,合理的异常封装既可以方便前端的处理,也能够简化后端的开发。 …

uniap vue3 组件使用uni.createSelectorQuery() 获取dom报错

由于vue3中没有this,所以使用uni.createSelectorQuery().in(this)时,会报错 使用 getCurrentInstance 获取组件实例 使用 uni.createSelectorQuery() 批量查询时,结果是按照查询的顺序返回的 使用示例 import { getCurrentInstance } from…

MySQl导入与导出远程备份

文章目录 一. navicat导入导出 二. mysqldump命令导入导出导入导出 三. load data infile命令导入导出导入导出 四. 远程备份导入导出思维导图 一. navicat 导入 右键——>运行SQL文件 导出 选中要导出的表➡右键➡转储SQL文件➡数据和结构 二. mysqldump命令导入导出…

uniapp 打包成 apk(原生APP-云打包)免费

修改APP配置 根据需求,修改 manifest.json 配置,常见的修改有: 应用名称,应用版本名称,应用版本号 升级版本时,应用版本名称和应用版本号必须高于上一版的值 应用图标 点浏览选择png格式的图片后&#x…

HTML--CSS--超链接样式以及鼠标样式自定义

超链接伪类 再复习一下,超链接的定义方式如下&#xff1a; <!DOCTYPE html> <html> <head> <title>这是一个标题</title><meta charset"utf-8"/><style></style> </head> <body><a href"http…

操作系统概述

概述 文章目录 概述定义功能特征并发共享并发与共享的关系虚拟异步 发展与分类手工操作阶段批处理阶段分时操作系统实时操作系统网络操作系统分布式操作系统个人计算机操作系统 运行机制程序是如何运行的&#xff1f;内核程序应用程序特权指令非特权指令内核态用户态内核态与用…

人力资源智能化管理项目(day01:基础架构拆解)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学&#xff0c;可以点心心支持一下哈 一、基础架构拆解 1.拉取模板代码 git clone GitHub - PanJiaChen/vue-admin-template: a vue2.0 minimal admin template 项目名 2.core-js…

Swift 周报 第四十五期

文章目录 前言新闻和社区苹果或将扩充健康版图&#xff0c;为Apple Watch X铺路更新后的《Apple Developer Program 许可协议》现已发布 提案通过的提案 Swift论坛推荐博文话题讨论关于我们 前言 本期是 Swift 编辑组整理周报的第四十五期&#xff0c;每个模块已初步成型。各位…

概率论与数理统计————古典概型、几何概型和条件概率

一、古典概型 特点 &#xff08;1&#xff09;有限性&#xff1a;试验S的样本空间的有限集合 &#xff08;2&#xff09; 等可能性&#xff1a;每个样本点发生的概率是相等的 公式&#xff1a;P&#xff08;A&#xff09; A为随机事件的样本点数&#xff1b;S是样本…

【OpenCV学习笔记12】- 更改颜色空间

关于 OpenCV 官方文档的核心操作告一段落&#xff0c;接下来开始图像处理的学习。学习笔记中会记录官方给出的例子&#xff0c;也会给出自己根据官方的例子完成的更改代码&#xff0c;同样彩蛋的实现也会结合多个知识点一起实现一些小功能&#xff0c;来帮助我们对学会的知识点…

如何实现本地USB设备共享服务映射到外网实现跨网USB共享通信访问

文章目录 前言1. 安装下载软件1.1 内网安装使用USB Redirector1.2 下载安装cpolar内网穿透 2. 完成USB Redirector服务端和客户端映射连接3. 设置固定的公网地址 前言 USB Redirector是一款方便易用的USB设备共享服务应用程序&#xff0c;它提供了共享和访问本地或互联网上的U…

只要3步,教你搞定网工领导满意的年终总结

你们好&#xff0c;我是老杨。 2024年的总结你们都写完了吗&#xff1f; 早的大厂都已经收了一波总结了&#xff0c;等着大年三十之前再搞个年终述职&#xff0c;这一年就算是齐活了。 老生常谈&#xff0c;但每年又不得不谈的总结&#xff0c;咱们今天就聊聊这个。 不管你是…

树莓派4B +Ubuntu20.04+ROS1的使用(2)

首先确定一下主机与从机的ip地址&#xff08;非常重要&#xff09; 在这次实验中&#xff0c;主机是一台Ubuntu20.04.03系统的台式机&#xff0c;我们间通过这台准备来远程遥控树莓派上的ros1系统&#xff0c;它的ip地址是192.168.230.181 从机是一台搭载Ubuntu20.04桌面版ro…

pod控制器的作用

pod控制器的作用 1、动态pv和pvc deployment是控制器 pod空气器:工作负载&#xff0c;workload用于管理pod的中间层&#xff0c;确保podi资源符合预期的状态 预期状态 1、副本数 2、容器重启策略 3、镜像拉取策略 pod、出现故障时重启等等 pod的控制器类型 1、replic…

Spring MVC文件上传及全局异常处理器

添加依赖 <!--文件上传--> <dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version> </dependency>配置文件上传解析器 <!--配置文件上传解析器-…

mysql复制表的几种常用方法

遇到需要拷贝一个表及其数据的情况,总结了一下几种方法 1.使用 show create table 旧表 将结果拷贝出来,将旧表名换成新表名即可. 注意:该方法仅适用于拷贝表结构,不需要同步数据的情况 show create table 旧表名2.create table 新表 like 旧表 该语句将完全拷贝旧表结构, …

RT-Thread: 控制台调试串口波特率更改

说明&#xff1a;rt_kprintf 函数是RT 的一个调试接口使用的函数&#xff0c;波特率默认是 115200 &#xff0c;本文介绍更改这个波特率。 1.根据截图路径找到文件 serial.h 修改如下代码中关于波特率定义部分。 /* Default config for serial_configure structure */ #defin…

华为设备端口镜像设置

核心代码&#xff1a; observe-port int 编号 int 编号 mirror to observe-port both | inbound | outbound #both:将镜像端口的入和出流量同时复制到观察者端口 #inbound:将镜像端口的入流量复制到观察者端口 #outbound:将镜像端口的出流量复制到观察者端口配置后可使出入端口…

NLP论文阅读记录 - 2021 | WOS HG-News:基于生成式预训练模型的新闻标题生成

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.相关工作三.本文方法四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结果4.6 细粒度分析 五 总结思考 前言 HG-News: News Headline Generation Based on a Generative Pre-…