Esta es la placa completa de la pila construida alrededor de la última pila Next.js. Se compone de las mejores prácticas descritas en documentos oficiales combinados con mis decisiones derivadas de mi propia experiencia y conocimiento que he reunido para trabajar con otras personas.
No pase los próximos 3 meses tomando decisiones arquitectónicas, eligiendo bibliotecas, la configuración de entornos de desarrollo y prod y tuberías de CI/CD, escribiendo código de horario básico, instale esta caldera en 15 minutos y comience a trabajar en sus funciones hoy .
Si la aplicación está destrozada, solo use el enlace
Reseeden el lado derecho del pie de página para volver a calificar la base de datos.
Necesita una cuenta GitPod y tal vez una URL de la base de datos de Postgres si mi base de datos de demostración está destrozada. Puede crear uno en Elephantsql.com, consulte la sección de entorno GITPOD para más detalles.















next-auth , etc.) React 18.2.0 , Next.js 12.2.0 , Node.js 16.13.1 , Prisma 4 , Postgres 14.3 , TypeScript 4.7.4 , React Consult 4-beta , Axios, React Hook Form 8-alpha , React Dropzone, Zod, MSW, Tailwindcss 3 , Jest 28 , Testing Biblioteca, Cypress 9.6.1 .
next-auth y Facebook, Google y Credenciales.env* ...pages estructura de componentes escalables y desacoplables -> layouts -> views -> components!important en el código completo)next-connect con middleware para validación y rutas protegidasgetServerSideProps con clase de error personalizadotesting-library/react para las pruebas de la unidad y de integraciónjest-preview , imágenes burladas con Blob Polyfill, archivos separados .env.test*Sin ningún ajuste especial, hay espacio para una mejora adicional.

Este proyecto tiene 3 entornos de desarrollo disponibles:
Puedes elegir el entorno que prefieras.
¿Cuál para elegir? Si le gusta el enfoque convencional, elija local, si trabaja en un equipo y desea tener entornos consistentes con colegas para reproducir fácilmente los errores y a bordo rápidamente los nuevos miembros eligen Docker, y si desea hacer que Sandbox reproduce un error y solicite ayuda públicamente elegir GitPod.
Repositorio de clones e instalación de dependencias.
# clone repository
git clone [email protected]:nemanjam/nextjs-prisma-boilerplate.git
cd nextjs-prisma-boilerplate
# install dependencies
yarn installCuando abra la carpeta del proyecto por primera vez VS Código, le pedirá que instale extensiones recomendadas, debe aceptarlas todas, son necesarias para resaltar, el código de la pelusa y el formato, ejecutar pruebas, administrar contenedores.
Complete las variables de entorno público requeridos en .env.development . La forma más rápida es ejecutar la aplicación con el servidor http .
Necesita
httpslocalmente solo para el inicio de sesión de Facebook OAuth. Para eso, necesitamkcertpara instalar certificados paralocalhost, instrucciones para que pueda encontrar en la carpetadocs.
Deje PORT como 3001, está codificado en varios lugares, si desea cambiarlo, debe editarlos todos (es decir, todo Dockerfile.* Y docker-compose.*.yml )
# .env.development
SITE_PROTOCOL=http
SITE_HOSTNAME=localhost
PORT=3001
# don't touch these two variables
APP_ENV=local
NEXTAUTH_URL= ${SITE_PROTOCOL} :// ${SITE_HOSTNAME} : ${PORT} Crear .env.development.local File.
# create local file form example file
cp .env.development.local.example .env.development.local
En todos los entornos, el contenedor de Postgres está configurado para ejecutarse como un usuario no root actual en una máquina host de Linux. Esto es importante para que los archivos de base de datos en volúmenes se creen con la propiedad y los permisos correctos. Para esto debes definir MY_UID y MY_GID . El mejor lugar para establecerlos es en ~/.bashrc .
# ~/.bashrc
export MY_UID= $( id -u )
export MY_GID= $( id -g )Complete las variables de entorno privado requeridas. Las únicas variables requeridas son para la conexión de la base de datos Postgres y JWT Secret.
Las credenciales de Facebook y Google son opcionales y se usan solo para el inicio de sesión de OAuth. El inicio de sesión de Facebook requiere
httpspara la URL de redirección. Puede establecer cualquier valor paraPOSTGRES_USER,POSTGRES_PASSWORDyPOSTGRES_DB.
# .env.development.local
# set database connection
POSTGRES_HOSTNAME=localhost
POSTGRES_PORT=5432
POSTGRES_USER=postgres_user
POSTGRES_PASSWORD=password
POSTGRES_DB=npb-db-dev
# don't edit this expanded variable
DATABASE_URL=postgresql:// ${POSTGRES_USER} : ${POSTGRES_PASSWORD} @ ${POSTGRES_HOSTNAME} : ${POSTGRES_PORT} / ${POSTGRES_DB} ? schema=public
# jwt secret
SECRET=some-long-random-string
# OAuth logins (optional)
# Facebook (you need https for this)
FACEBOOK_CLIENT_ID=
FACEBOOK_CLIENT_SECRET=
# Google
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET= Después de que se establezcan todas las variables, puede ejecutar la base de datos Postgres dentro del contenedor Docker, ejecutar migraciones de prisma que creen tablas SQL a partir de schema.prisma y base de datos de semillas con datos.
# run database container
yarn docker:db:dev:up
# run Prisma migrations (this will create sql tables, database must be running)
yarn prisma:migrate:dev:env
# seed database with data
yarn prisma:seed:dev:env En este punto, todo está listo, ahora puede comenzar la aplicación. Abra http://localhost:3001 en el navegador para ver la aplicación en ejecución.
# start the app in dev mode
yarn devDespués de que clonó el contenedor de aplicaciones de compilación del repositorio.
# terminal on host
yarn docker:dev:build Docker Environment leerá variables de la carpeta envs/development-docker . Cree un archivo ENV local a partir del archivo de ejemplo. Ya tiene todas las variables configuradas.
# terminal on host
cp envs/development-docker/.env.development.docker.local.example envs/development-docker/.env.development.docker.local Ejecute la aplicación, la base de datos y los contenedores de administrador. Eso es todo. La carpeta del proyecto está montada en la carpeta de /app dentro del contenedor, puede editar la fuente directamente en el host o abrir la pestaña de extensión de contenedores remotos y hacer clic con el botón derecho npb-app-dev y seleccionar Attach to Container y abrir /app Carpeta en la instancia de código remoto vs. Abra http://localhost:3001 en el navegador en el host para ver la aplicación en ejecución.
# terminal on host
yarn docker:dev:up Abra un nuevo terminal dentro del contenedor y sembra la base de datos, docker-compose.dev.yml ya pasa archivos ENV correctos.
# terminal inside the container
yarn prisma:seedNota: Git ya existirá en Container con su cuenta para que pueda confirmar y presionar los cambios directamente desde el contenedor.
# check that git config is already set inside the container
git config --list --show-originLe sugiero que instale contenedores de Portainer Community Edition localmente para obtener contenedores de gestión y depuración más fácil, es una herramienta gratuita y muy útil.
Vaya a Elephantsql.com Cree una cuenta gratuita y cree una base de datos Postgres de 20 MB gratuita. Vaya a GitPod.io, inicie sesión con GitHub. Abra su repositorio bifurcado en GITPOD abriendo el siguiente enlace (reemplace your-username con uno real):
https://gitpod.io/#https://github.com/your-username/nextjs-prisma-boilerplate
El entorno GITPOD leerá variables de la carpeta envs/development-gitpod . Cree un archivo ENV local a partir del archivo de ejemplo.
# terminal on Gitpod
cp envs/development-gitpod/.env.development.gitpod.local.example envs/development-gitpod/.env.development.gitpod.local En ese archivo local, establece la URL de la base de datos de elephantsql.com . Otras variables se establecen automáticamente.
# envs/development-gitpod/.env.development.gitpod.local
DATABASE_URL=postgres://something:[email protected]/somethingAhora migra y sembra la base de datos.
Nota: La base de datos
elephantsql.comno tiene todos los privilegios, por lo que debe usar el comandoprisma pushen lugar delprisma migrate devhabitual. Lea más detalles sobre la base de datos de Shadow en Docs/Demo-Environments.md.
# terminal on Gitpod
# migrate db
yarn gitpod:push:env
# seed db
yarn gitpod:seed:envTodo está configurado, ahora puede ejecutar la aplicación en modo Dev y abrirla en la nueva pestaña del navegador.
yarn gitpod:dev:envEste proyecto tiene 4 configuraciones de prueba separadas más la configuración de cobertura de código. Todas las pruebas pueden ejecutarse localmente, en Docker y en acciones de Github.
NOTA: También puede ejecutar y depurar todas las pruebas de Jest con la extensión
orta.vscode-jestque ya está incluida en la lista recomendada.
Ejecutando localmente.
yarn test:clientCorriendo en Docker.
yarn docker:test:clientEjecutando localmente.
yarn test:server:unitCorriendo en Docker.
yarn docker:test:server:unitAsegúrese de que la base de datos de pruebas esté arriba y migra. No necesitas sembrarlo.
# run database container
yarn docker:db:test:up
# migrate test database
yarn prisma:migrate:test:envEjecutando localmente.
yarn test:server:integrationCorriendo en Docker.
yarn docker:test:server:integrationNecesita ejecutar la base de datos de prueba, igual que en el paso anterior.
Ejecutando localmente.
yarn test:coverageCorriendo en Docker.
yarn docker:test:coverageEjecutando localmente:
Debe ejecutar y migrar la base de datos de prueba (sin necesidad de semillas), crear una aplicación para la producción, ejecutar la aplicación y ejecutar Cypress.
# run database container
yarn docker:db:test:up
# migrate test database
yarn prisma:migrate:test:envEntonces necesita crear una aplicación para la producción.
# build the app for prod
yarn buildLuego debe iniciar APP y Cypress al mismo tiempo. Esto abrirá Cypress GUI.
# starts the app and Cypress GUI
yarn test:e2e:envTambién puede ejecutar Cypress en modo sin cabeza (sin GUI).
# starts the app and Cypress in headless mode
yarn test:e2e:headless:envCorriendo en Docker:
Cree imágenes de APP y Cypress.
# build testing app image
yarn docker:npb-app-test:build
# build Cypress container
yarn docker:npb-e2e:buildLuego puede ejecutar la base de datos de prueba, probar el contenedor de aplicaciones y el contenedor de ciprés (en modo sin cabeza) a la vez.
# run db, app and Cypress headless
yarn docker:npb-e2e:upHice un repositorio separado Nemanjam/Traefik-Proxy solo para la implementación con un proxy inverso de Traefik que solo necesita variables de entorno e imagen de DockerHub. También hay flujos de trabajo de GitHub Action para construir, presionar y volver a desplegar la última imagen en su servidor. Debe usar eso para la implementación.
En aras de la integridad, describí aquí cómo construir y ejecutar la aplicación de producción localmente y en Docker. Estos dos pueden ser útiles como entornos de estadificación para las pruebas. También describí cómo construir y enviar una imagen en vivo a Dockerhub desde su máquina de desarrollo local.
Al construir y ejecutar la aplicación en modo de producción, leerá variables de .env.production y .env.production.local . En la hora de compilación, la única variable requerida es NEXTAUTH_URL (se usa para URL base en el componente CustomHead responsable del SEO). Si usa getStaticProps (generación de sitios estática), también deberá aprobar DATABASE_URL con los datos correctos. En tiempo de ejecución, debe definir todas las variables públicas y privadas en estos dos archivos.
Para construir y ejecutar la aplicación de producción, ejecute estos dos comandos.
# build app
yarn build
# start app
yarn start Al construir una aplicación de producción dentro de una imagen de Docker nuevamente, debe pasar las mismas variables como localmente ( NEXTAUTH_URL y DATABASE_URL para SSG), esta vez se envían con ARG_NEXTAUTH_URL y ARG_DATABASE_URL en Dockerfile.prod . Esta variables de entorno de tiempo se lee de envs/production-docker/.env.production.docker y envs/production-docker/.env.production.docker.local . En tiempo de ejecución, debe definir todas las variables públicas y privadas en estos dos archivos.
Para construir y ejecutar la imagen de producción de Docker, ejecute esto.
# build production image
yarn docker:prod:build:env
# run production image
yarn docker:prod:up Una vez más, debe establecer NEXTAUTH_URL y DATABASE_URL (para SSG) esta vez en envs/production-live/.env.production.live.build.local . Cree este archivo a partir del archivo de ejemplo.
cp envs/production-live/.env.production.live.build.local.example envs/production-live/.env.production.live.build.localDebe editar este script de hilo y establecer su nombre de usuario y nombre de imagen real DockerHub.
# replace your-dockerhub-username and your-image-name with yours
" docker:live:build " : " dotenv -e ./envs/production-live/.env.production.live.build.local -- bash -c 'docker build -f Dockerfile.prod -t your-dockerhub-username/your-image-name:latest --build-arg ARG_DATABASE_URL= ${DATABASE_URL} --build-arg ARG_NEXTAUTH_URL= ${NEXTAUTH_URL} .' " ,
Ahora puede construir, etiquetar y empujar a Dockerhub su imagen de producción. Para presionar la imagen, primero debe iniciar sesión en Terminal con docker login .
# build and tag production image
yarn docker:live:build
# push image to Dockerhub
yarn docker:live:push Ya hay un flujo de trabajo configurado para construir y impulsar la imagen de producción en acciones de GitHub en .github/workflows/build-docker-image.yml . En la configuración de su repositorio, solo necesita establecer estas variables y ejecutar el flujo de trabajo.
# your dockerhub username
DOCKERHUB_USERNAME
# your dockerhub password
DOCKERHUB_TOKEN
# database url (only for SSG)
NPB_DATABASE_URL
# your live production app url (without trailing '/')
# i.e. https://subdomain.my-domain.com
NPB_NEXTAUTH_URL Solo necesita configurar el nombre de su imagen dentro de docker-compose.live.yml , pasar todas las variables de entorno e implementarlo con docker-compose up -d en su servidor.
# docker-compose.live.yml
services :
npb-app-live :
container_name : npb-app-live
image : your-dockerhub-username/your-image-name:latest Para este propósito, ya hice un repositorio separado Nemanjam/Traefik-Proxy con un proxy inverso de Traefik que le permite alojar múltiples aplicaciones dentro de los contenedores Docker donde cada contenedor expone diferentes puertos y traefik mapas de puertos a subdominios. Para más detalles sobre cómo configurar esto, consulte el archivo README.md y el tutorial vinculado en él. Solo necesita ejecutar el contenedor de su aplicación y Traefik lo recogerá automáticamente sin que necesite reiniciar el contenedor de Traefik manualmente.
Además de Traefik, también ya tiene contenedor portainer para administrar contenedores, un contenedor adminer para administrar una base de datos de producción, uptime-kuma para rastrear el tiempo de actividad del sitio web y otro contenedor postgres configurado para aceptar conexiones de hosts remotos (útil para construir aplicaciones en acciones de GitHub).
Bellow se enumeran en todas las variables de entornos que necesita establecer. En aras de la simplicidad, le mostré aquí cómo configurarlos en el archivo .env local, el archivo docker-compose.yml lo leerá y reenviará todas las variables necesarias en contenedores. Esto está bien para las aplicaciones de demostración, pero para las aplicaciones de producción reales, la forma adecuada de hacerlo es configurarlas en el tablero de su proveedor de la nube o usar una bóveda dedicada.
# create .env file locally and set vars
cp apps/nextjs-prisma-boilerplate/.env.example apps/nextjs-prisma-boilerplate/.env
# copy populated local .env file to server securely with ssh
scp ./apps/nextjs-prisma-boilerplate/.env ubuntu@your-server: ~ /traefik-proxy/apps/nextjs-prisma-boilerplateTodas estas son variables necesarias.
MY_UIDyMY_GIDson ID de su usuario y grupo actual en su servidor Linux. Puede ver sus valores ejecutandoid -ueid -gen el terminal de su servidor. El mejor lugar para establecerlos es globalmente en~/.bashrcporque pueden ser necesarios para múltiples contenedores. Se pasan al contenedor Postgres para que los archivos de datos de volumen se creen con permisos y propiedad correctos (como usuario actual y no usuario root).
# apps/nextjs-prisma-boilerplate/.env
# public vars bellow
APP_ENV=live
# http node server in live, Traefik handles https
SITE_PROTOCOL=http
# real full production public domain (with subdomain), used in app and Traefik
SITE_HOSTNAME=nextjs-prisma-boilerplate.nemanjamitic.com
PORT=3001
# real url is https and doesn't have port, Traefik handles https and port
NEXTAUTH_URL=https:// ${SITE_HOSTNAME}
# private vars bellow
# db container
POSTGRES_HOSTNAME=npb-db-live
POSTGRES_PORT=5432
POSTGRES_USER=postgres_user
POSTGRES_PASSWORD=
POSTGRES_DB=npb-db-live
# don't edit this
DATABASE_URL=postgresql:// ${POSTGRES_USER} : ${POSTGRES_PASSWORD} @ ${POSTGRES_HOSTNAME} : ${POSTGRES_PORT} / ${POSTGRES_DB} ? schema=public
# current host user as non-root user in Postgres container, set it here
MY_UID=1001
MY_GID=1001
# or better globally in ~/.bashrc
# export MY_UID=$(id -u)
# export MY_GID=$(id -g)
# jwt secret
SECRET=some-long-random-string
# Facebook
FACEBOOK_CLIENT_ID=
FACEBOOK_CLIENT_SECRET=
# Google
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET= Para evitar el trabajo manual, ya existe un flujo de trabajo de GitHub Actions en .github/workflows/deploy.yml que eliminará la imagen antigua y extraerá y ejecutará la última imagen de Dockerhub utilizando la acción SSH. Todo lo que necesita hacer es activarlo manualmente o encadenarlo en el flujo de trabajo de construcción y empuje existente.
# .github/workflows/deploy.yml
# trigger redeploy with build workflow
on :
workflow_run :
workflows : ['docker build'] Hay una amplia documentación para este proyecto en la carpeta Docs. Puede encontrar todos los aspectos técnicos cuidadosamente documentados, especialmente partes importantes y difíciles. Allí puede encontrar descripciones de problemas, soluciones, fragmentos de código y referencias vinculadas relacionadas.
Actualmente, la documentación está desnuda en el sentido de que solo contiene información técnica desnuda sobre cómo resolver algo y no está redondeado en artículos amigables para los humanos con contexto adicional.
Aquí está la breve descripción de lo que puede encontrar en él:
next-connect y algunas cosas de reacción comúnmkcert y detalles clave sobre Google y los inicios de sesión de Facebookv4 , componentes de prueba y ganchos, hidratación, principalmente de Docs y Tkdodo Blognext-themes , temas como implementación del complemento de viento de cola personalizado de Daisyuiv4elephantsql.com para fines de demostracióngetServerSideProps , manejo de errores con fondos de error y reaccionando consultas, opciones de typescript y strict strictNullChecksts-jest , las pruebas de async con consulta react, formularios de prueba, la clase de BLOB burlándose en JSDOM para imágenes, migración UserEvent v14 , suspenso y error de error en las pruebas, MSW, burla del prisma en las pruebas unitarias, utilizando los controladores de la prueba, los controladores de la integración de backend con la base de datos de pruebas, la configuración múltiple Jest Setup Inside Tests Tests Tests jest-preview configuración, configuración de cobertura de códigodocker-compose.yml , configuración de contenedores de producción en vivo, imagen de ciprés personalizadoNODE_ENV y APP_ENV , implementación de VPS utilizando la acción SSHgitpod.io , repl.it , codesandbox.io y stackblitz.com , en la carpeta envs and notes/envs que tiene configuración para todos estos entornos, pero solo GitPod tiene suficiente potencia informática para ejecutarla realmenteLas contribuciones son bienvenidas. Puede encontrar más información sobre cómo contribuir en la contribución.
Image Next.js para imágenes alojadas localmenteoutput: 'standalone' en next.config.jsprisma de las dependencias de prod con un contenedor separado para migraciones sin hacer que el flujo de trabajo sea demasiado complicadocypress: 10.x y next-connect: 1.x (tienen cambios de ruptura)Hay muchas conversaciones, teorías, opiniones y zumbidos en torno a los marcos de JavaScript ... pero dejemos de hablar, elija el marco más popular, lea lo que sugieren en la documentación y pruebe en la práctica, verifique cómo funciona y veamos si podemos construir algo útil y significativo con él.
Nemanjam, LinkedIn
Los enlaces de referencias completas se adjuntan en archivos Docs. Las referencias más importantes son:
next-connect , ejemplo de aplicación Hoangvvo/NextJS-MongoDB-AppEste proyecto utiliza la licencia del MIT: licencia