├── .gitignore ├── .dockerignore ├── test ├── base │ ├── windows │ │ ├── prisma │ │ │ ├── .keep │ │ │ └── schema.prisma │ │ ├── app │ │ │ ├── tailwind.css │ │ │ ├── root.tsx │ │ │ └── session.server.ts │ │ ├── .dockerignore │ │ ├── tsconfig.json │ │ ├── docker-entrypoint.js │ │ ├── Dockerfile │ │ └── package.json │ ├── litestream-url │ │ ├── prisma │ │ │ ├── migrations │ │ │ │ └── .keep │ │ │ └── schema.prisma │ │ ├── .dockerignore │ │ ├── fly.toml │ │ ├── litestream.yml │ │ ├── package.json │ │ ├── docker-entrypoint.js │ │ └── Dockerfile │ ├── litestream │ │ ├── prisma │ │ │ ├── migrations │ │ │ │ └── .keep │ │ │ └── schema.prisma │ │ ├── .dockerignore │ │ ├── fly.toml │ │ ├── litestream.yml │ │ ├── package.json │ │ ├── docker-entrypoint.js │ │ └── Dockerfile │ ├── instructions │ │ ├── setup.base │ │ ├── setup.build │ │ ├── setup.deploy │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── alpine │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── build │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── bun │ │ ├── .dockerignore │ │ ├── package.json │ │ ├── Dockerfile │ │ └── bun.lock │ ├── defer-build │ │ ├── app │ │ │ ├── tailwind.css │ │ │ ├── root.tsx │ │ │ └── session.server.ts │ │ ├── .dockerignore │ │ ├── package.json │ │ ├── tsconfig.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── docker-entrypoint.js │ │ └── Dockerfile │ ├── dev │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── git │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── litefs │ │ ├── .dockerignore │ │ ├── fly.toml │ │ ├── package.json │ │ ├── Dockerfile │ │ └── litefs.yml │ ├── nginx │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── port │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── swap │ │ ├── .dockerignore │ │ ├── package.json │ │ ├── docker-entrypoint.js │ │ └── Dockerfile │ ├── cache-bun │ │ ├── .dockerignore │ │ ├── bun.lockb │ │ ├── package.json │ │ └── Dockerfile │ ├── cache-npm │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── cache-pnpm │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── cache-yarn │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── distroless │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── envargs │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── no-link │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── packages │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── puppeteer │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── version │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── build-secret │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── cmd-entrypoint │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── fluent-ffmpeg │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── ignore-scripts │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ └── legacy-peer-deps │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile ├── frameworks │ ├── next-npm │ │ ├── pages │ │ │ └── .keep │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── next-pnpm │ │ ├── pages │ │ │ └── .keep │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── next-yarn │ │ ├── pages │ │ │ └── .keep │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── next-yarn4 │ │ ├── pages │ │ │ └── .keep │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── vite │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── remix-pnpm │ │ ├── routes │ │ │ └── .keep │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── remix-blues │ │ ├── prisma │ │ │ ├── migrations │ │ │ │ └── .keep │ │ │ └── schema.prisma │ │ ├── app │ │ │ ├── tailwind.css │ │ │ ├── root.tsx │ │ │ └── session.server.ts │ │ ├── .dockerignore │ │ ├── fly.toml │ │ ├── tsconfig.json │ │ ├── Dockerfile │ │ └── package.json │ ├── remix-indie │ │ ├── prisma │ │ │ ├── migrations │ │ │ │ └── .keep │ │ │ └── schema.prisma │ │ ├── app │ │ │ ├── tailwind.css │ │ │ ├── root.tsx │ │ │ └── session.server.ts │ │ ├── .dockerignore │ │ ├── fly.toml │ │ ├── tsconfig.json │ │ ├── docker-entrypoint.js │ │ ├── Dockerfile │ │ └── package.json │ ├── meteor │ │ ├── .meteor │ │ │ └── release │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── nest │ │ ├── .dockerignore │ │ ├── tsconfig.json │ │ ├── Dockerfile │ │ └── package.json │ ├── nuxt │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── adonisjs │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ └── package.json │ ├── express │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── fastify │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── gatsby │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ ├── next-trpc │ │ ├── .dockerignore │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── package.json │ │ └── Dockerfile │ ├── svelte-bun │ │ ├── .dockerignore │ │ ├── bun.lockb │ │ ├── package.json │ │ ├── Dockerfile │ │ └── node_modules │ │ │ └── .bin │ │ │ └── vite │ ├── nuxt-prisma │ │ ├── .dockerignore │ │ ├── prisma │ │ │ ├── schema.prisma │ │ │ └── seed.js │ │ ├── package.json │ │ ├── docker-entrypoint.js │ │ └── Dockerfile │ ├── remix-epic │ │ ├── .dockerignore │ │ ├── tsconfig.json │ │ ├── docker-entrypoint.js │ │ ├── Dockerfile │ │ └── package.json │ ├── next-standalone │ │ ├── next.config.mjs │ │ ├── .dockerignore │ │ ├── package.json │ │ ├── docker-entrypoint.js │ │ └── Dockerfile │ ├── svelte-prisma │ │ ├── .dockerignore │ │ ├── prisma │ │ │ ├── schema.prisma │ │ │ └── seed.ts │ │ ├── docker-entrypoint.js │ │ ├── package.json │ │ └── Dockerfile │ ├── astro-ssr │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile │ └── astro-static │ │ ├── .dockerignore │ │ ├── package.json │ │ └── Dockerfile ├── fly │ └── sqlite3 │ │ ├── .dockerignore │ │ ├── fly.toml │ │ ├── package.json │ │ └── Dockerfile └── test.js ├── bun.lockb ├── templates ├── .dockerignore.ejs ├── litestream.yml.ejs └── litefs.yml.ejs ├── .eslintrc.cjs ├── package.json └── .github └── workflows └── ci.yml /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /test/base/windows/prisma/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/frameworks/next-npm/pages/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/frameworks/next-pnpm/pages/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/frameworks/next-yarn/pages/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/frameworks/next-yarn4/pages/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/frameworks/vite/.dockerignore: -------------------------------------------------------------------------------- 1 | dist -------------------------------------------------------------------------------- /test/frameworks/remix-pnpm/routes/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/base/litestream-url/prisma/migrations/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/base/litestream/prisma/migrations/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/frameworks/remix-blues/prisma/migrations/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/frameworks/remix-indie/prisma/migrations/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/base/instructions/setup.base: -------------------------------------------------------------------------------- 1 | # base additions 2 | -------------------------------------------------------------------------------- /test/base/instructions/setup.build: -------------------------------------------------------------------------------- 1 | # build additions 2 | -------------------------------------------------------------------------------- /test/base/instructions/setup.deploy: -------------------------------------------------------------------------------- 1 | # deploy additions 2 | -------------------------------------------------------------------------------- /test/frameworks/meteor/.meteor/release: -------------------------------------------------------------------------------- 1 | METEOR@3.0-rc.4 2 | -------------------------------------------------------------------------------- /bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fly-apps/dockerfile-node/HEAD/bun.lockb -------------------------------------------------------------------------------- /test/base/windows/app/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /test/base/alpine/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/build/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/bun/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/defer-build/app/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /test/base/dev/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/git/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/litefs/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/nginx/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/port/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/swap/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/fly/sqlite3/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/frameworks/remix-pnpm/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /test/base/cache-bun/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/cache-bun/bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fly-apps/dockerfile-node/HEAD/test/base/cache-bun/bun.lockb -------------------------------------------------------------------------------- /test/base/cache-npm/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/cache-pnpm/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/cache-yarn/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/distroless/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/envargs/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/git/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "express": "github:expressjs/express" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/base/litestream/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/no-link/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/packages/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/puppeteer/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/version/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/frameworks/nest/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/frameworks/nuxt/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/frameworks/remix-blues/app/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /test/frameworks/remix-indie/app/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /test/base/build-secret/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/cmd-entrypoint/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/fluent-ffmpeg/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/ignore-scripts/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/instructions/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/legacy-peer-deps/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/base/litestream-url/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/frameworks/adonisjs/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/frameworks/express/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/frameworks/fastify/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/frameworks/gatsby/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/frameworks/next-npm/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/frameworks/next-pnpm/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/frameworks/next-trpc/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/frameworks/next-yarn/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/frameworks/next-yarn4/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/frameworks/svelte-bun/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | -------------------------------------------------------------------------------- /test/frameworks/meteor/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | .meteor/local -------------------------------------------------------------------------------- /test/frameworks/svelte-bun/bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fly-apps/dockerfile-node/HEAD/test/frameworks/svelte-bun/bun.lockb -------------------------------------------------------------------------------- /test/frameworks/nuxt-prisma/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | 8 | dev.db 9 | prisma/dev.db 10 | -------------------------------------------------------------------------------- /test/base/windows/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | 8 | /.cache 9 | /build 10 | /public/build 11 | -------------------------------------------------------------------------------- /test/base/defer-build/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | 8 | /.cache 9 | /build 10 | /public/build 11 | -------------------------------------------------------------------------------- /test/frameworks/remix-blues/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | 8 | /.cache 9 | /build 10 | /public/build 11 | -------------------------------------------------------------------------------- /test/frameworks/remix-epic/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | 8 | /.cache 9 | /build 10 | /public/build 11 | -------------------------------------------------------------------------------- /test/frameworks/remix-indie/.dockerignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | 8 | /.cache 9 | /build 10 | /public/build 11 | -------------------------------------------------------------------------------- /test/frameworks/next-standalone/next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | output: "standalone" 4 | }; 5 | 6 | export default nextConfig; 7 | -------------------------------------------------------------------------------- /test/base/litefs/fly.toml: -------------------------------------------------------------------------------- 1 | 2 | [mounts] 3 | source = "data" 4 | destination="/data" 5 | auto_extend_size_threshold = 80 6 | auto_extend_size_increment = "1GB" 7 | auto_extend_size_limit = "10GB" 8 | -------------------------------------------------------------------------------- /test/fly/sqlite3/fly.toml: -------------------------------------------------------------------------------- 1 | 2 | [mounts] 3 | source = "data" 4 | destination="/data" 5 | auto_extend_size_threshold = 80 6 | auto_extend_size_increment = "1GB" 7 | auto_extend_size_limit = "10GB" 8 | -------------------------------------------------------------------------------- /test/base/litestream/fly.toml: -------------------------------------------------------------------------------- 1 | 2 | [mounts] 3 | source = "data" 4 | destination="/data" 5 | auto_extend_size_threshold = 80 6 | auto_extend_size_increment = "1GB" 7 | auto_extend_size_limit = "10GB" 8 | -------------------------------------------------------------------------------- /test/base/litestream-url/fly.toml: -------------------------------------------------------------------------------- 1 | 2 | [mounts] 3 | source = "data" 4 | destination="/data" 5 | auto_extend_size_threshold = 80 6 | auto_extend_size_increment = "1GB" 7 | auto_extend_size_limit = "10GB" 8 | -------------------------------------------------------------------------------- /test/frameworks/svelte-prisma/.dockerignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | 10 | 11 | # sqlite3 database 12 | dev.db 13 | prisma/dev.db 14 | -------------------------------------------------------------------------------- /test/base/bun/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bunserver", 3 | "module": "index.ts", 4 | "type": "module", 5 | "devDependencies": { 6 | "bun-types": "latest" 7 | }, 8 | "peerDependencies": { 9 | "typescript": "^5.0.0" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/fly/sqlite3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node index.js" 7 | }, 8 | "dependencies": { 9 | "express": "^4.18.2", 10 | "sqlite3": "^5.1.6" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/base/litefs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node index.js" 7 | }, 8 | "dependencies": { 9 | "express": "^4.18.2", 10 | "sqlite3": "^5.1.6" 11 | }, 12 | "dockerfile": { 13 | "litefs": true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/frameworks/astro-ssr/.dockerignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | 4 | # generated types 5 | .astro/ 6 | 7 | # dependencies 8 | node_modules/ 9 | 10 | # logs 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | -------------------------------------------------------------------------------- /test/frameworks/astro-static/.dockerignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | 4 | # generated types 5 | .astro/ 6 | 7 | # dependencies 8 | node_modules/ 9 | 10 | # logs 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | -------------------------------------------------------------------------------- /test/frameworks/remix-blues/fly.toml: -------------------------------------------------------------------------------- 1 | 2 | swap_size_mb = 512 3 | 4 | [[http_service.checks]] 5 | grace_period = "10s" 6 | interval = "30s" 7 | method = "GET" 8 | timeout = "5s" 9 | path = "/healthcheck" 10 | 11 | [deploy] 12 | release_command = "npx prisma migrate deploy" 13 | seed_command = "ts-node --require tsconfig-paths/register prisma/seed.ts" 14 | -------------------------------------------------------------------------------- /test/frameworks/next-yarn4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yarn4", 3 | "packageManager": "yarn@4.5.3", 4 | "scripts": { 5 | "dev": "next dev", 6 | "build": "next build", 7 | "start": "next start", 8 | "lint": "next lint" 9 | }, 10 | "dependencies": { 11 | "next": "latest", 12 | "react": "latest", 13 | "react-dom": "latest" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/frameworks/nuxt/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-app", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "nuxt dev", 7 | "build": "nuxt build", 8 | "generate": "nuxt generate" 9 | }, 10 | "dependencies": { 11 | "nuxt": "^3.16.1" 12 | }, 13 | "packageManager": "yarn@1.22.21", 14 | "devDependencies": {} 15 | } 16 | -------------------------------------------------------------------------------- /templates/.dockerignore.ejs: -------------------------------------------------------------------------------- 1 | /.git 2 | /node_modules 3 | .dockerignore 4 | .env 5 | Dockerfile 6 | fly.toml 7 | <% if (remix) { -%> 8 | 9 | /.cache 10 | /build 11 | /public/build 12 | <% } -%> 13 | <% if (meteor) { -%> 14 | 15 | /.meteor/local 16 | <% } -%> 17 | <% if (prismaFile) { -%> 18 | 19 | <%= path.join(prismaFile) %> 20 | <%= path.join("prisma", prismaFile) %> 21 | <% } -%> -------------------------------------------------------------------------------- /test/base/dev/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "express": "^4.18.2" 4 | }, 5 | "devDependencies": { 6 | "@types/express": "^4.17.17", 7 | "@types/node": "^20.5.1", 8 | "typescript": "^5.1.6" 9 | }, 10 | "scripts": { 11 | "build": "tsc", 12 | "start": "node build/server.js" 13 | }, 14 | "dockerfile": { 15 | "dev": true 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/base/cache-bun/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "express": "^4.18.2" 4 | }, 5 | "devDependencies": { 6 | "@types/express": "^4.17.17", 7 | "@types/node": "^20.5.1", 8 | "typescript": "^5.1.6" 9 | }, 10 | "scripts": { 11 | "build": "tsc", 12 | "start": "node build/server.js" 13 | }, 14 | "dockerfile": { 15 | "cache": true 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/base/cache-npm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "express": "^4.18.2" 4 | }, 5 | "devDependencies": { 6 | "@types/express": "^4.17.17", 7 | "@types/node": "^20.5.1", 8 | "typescript": "^5.1.6" 9 | }, 10 | "scripts": { 11 | "build": "tsc", 12 | "start": "node build/server.js" 13 | }, 14 | "dockerfile": { 15 | "cache": true 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/base/cache-pnpm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "express": "^4.18.2" 4 | }, 5 | "devDependencies": { 6 | "@types/express": "^4.17.17", 7 | "@types/node": "^20.5.1", 8 | "typescript": "^5.1.6" 9 | }, 10 | "scripts": { 11 | "build": "tsc", 12 | "start": "node build/server.js" 13 | }, 14 | "dockerfile": { 15 | "cache": true 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/base/cache-yarn/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "express": "^4.18.2" 4 | }, 5 | "devDependencies": { 6 | "@types/express": "^4.17.17", 7 | "@types/node": "^20.5.1", 8 | "typescript": "^5.1.6" 9 | }, 10 | "scripts": { 11 | "build": "tsc", 12 | "start": "node build/server.js" 13 | }, 14 | "dockerfile": { 15 | "cache": true 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/base/build/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "express": "^4.18.2" 4 | }, 5 | "devDependencies": { 6 | "@types/express": "^4.17.17", 7 | "@types/node": "^20.5.1", 8 | "typescript": "^5.1.6" 9 | }, 10 | "scripts": { 11 | "tcs": "tsc", 12 | "start": "node build/server.js" 13 | }, 14 | "dockerfile": { 15 | "build": "npm run tsc" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/frameworks/express/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "cookie-parser": "^1.4.6", 10 | "debug": "^2.6.9", 11 | "express": "^4.18.2", 12 | "http-errors": "^1.8.1", 13 | "jade": "^1.11.0", 14 | "morgan": "^1.10.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | root: true, 4 | env: { 5 | browser: true, 6 | es2021: true, 7 | mocha: true, 8 | }, 9 | extends: ['standard'], 10 | parserOptions: { 11 | ecmaVersion: 'latest', 12 | sourceType: 'module', 13 | }, 14 | rules: { 15 | 'space-before-function-paren': ['error', 'never'], 16 | }, 17 | } -------------------------------------------------------------------------------- /test/frameworks/remix-indie/fly.toml: -------------------------------------------------------------------------------- 1 | 2 | [mounts] 3 | source = "data" 4 | destination="/data" 5 | auto_extend_size_threshold = 80 6 | auto_extend_size_increment = "1GB" 7 | auto_extend_size_limit = "10GB" 8 | 9 | swap_size_mb = 512 10 | 11 | [[http_service.checks]] 12 | grace_period = "10s" 13 | interval = "30s" 14 | method = "GET" 15 | timeout = "5s" 16 | path = "/healthcheck" 17 | -------------------------------------------------------------------------------- /test/base/puppeteer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "cookie-parser": "^1.4.6", 10 | "debug": "^2.6.9", 11 | "express": "^4.18.2", 12 | "http-errors": "^1.8.1", 13 | "jade": "^1.11.0", 14 | "morgan": "^1.10.0", 15 | "puppeteer": "^21.1.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/base/build-secret/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "express": "^4.18.2" 4 | }, 5 | "devDependencies": { 6 | "@types/express": "^4.17.17", 7 | "@types/node": "^20.5.1", 8 | "typescript": "^5.1.6" 9 | }, 10 | "scripts": { 11 | "build": "tsc", 12 | "start": "node build/server.js" 13 | }, 14 | "dockerfile": { 15 | "secrets": [ 16 | "DATABASE_URL" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/base/fluent-ffmpeg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "cookie-parser": "^1.4.6", 10 | "debug": "^2.6.9", 11 | "express": "^4.18.2", 12 | "fluent-ffmpeg": "^2.1.2", 13 | "http-errors": "^1.8.1", 14 | "jade": "^1.11.0", 15 | "morgan": "^1.10.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/frameworks/astro-static/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fly-astro", 3 | "type": "module", 4 | "version": "0.0.1", 5 | "scripts": { 6 | "dev": "astro dev", 7 | "start": "astro dev", 8 | "build": "astro check && astro build", 9 | "preview": "astro preview", 10 | "astro": "astro" 11 | }, 12 | "dependencies": { 13 | "@astrojs/check": "^0.5.1", 14 | "astro": "^4.3.5", 15 | "typescript": "^5.3.3" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/base/litestream/litestream.yml: -------------------------------------------------------------------------------- 1 | # This is the configuration file for litestream. 2 | # 3 | # For more details, see: https://litestream.io/reference/config/ 4 | # 5 | dbs: 6 | - path: /data/dev.db 7 | replicas: 8 | - type: s3 9 | endpoint: $AWS_ENDPOINT_URL_S3 10 | bucket: $BUCKET_NAME 11 | path: litestream/dev.db 12 | access-key-id: $AWS_ACCESS_KEY_ID 13 | secret-access-key: $AWS_SECRET_ACCESS_KEY 14 | -------------------------------------------------------------------------------- /test/base/litestream-url/litestream.yml: -------------------------------------------------------------------------------- 1 | # This is the configuration file for litestream. 2 | # 3 | # For more details, see: https://litestream.io/reference/config/ 4 | # 5 | dbs: 6 | - path: /data/dev.db 7 | replicas: 8 | - type: s3 9 | endpoint: $AWS_ENDPOINT_URL_S3 10 | bucket: $BUCKET_NAME 11 | path: litestream/dev.db 12 | access-key-id: $AWS_ACCESS_KEY_ID 13 | secret-access-key: $AWS_SECRET_ACCESS_KEY 14 | -------------------------------------------------------------------------------- /test/base/port/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "chalk": "^5.3.0", 10 | "cookie-parser": "^1.4.6", 11 | "debug": "^2.6.9", 12 | "express": "^4.18.2", 13 | "http-errors": "^1.8.1", 14 | "jade": "^1.11.0", 15 | "morgan": "^1.10.0" 16 | }, 17 | "dockerfile": { 18 | "port": 4567 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/base/version/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "chalk": "^5.3.0", 10 | "cookie-parser": "^1.4.6", 11 | "debug": "^2.6.9", 12 | "express": "^4.18.2", 13 | "http-errors": "^1.8.1", 14 | "jade": "^1.11.0", 15 | "morgan": "^1.10.0" 16 | }, 17 | "engines": { 18 | "node": ">99" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/base/alpine/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "chalk": "^5.3.0", 10 | "cookie-parser": "^1.4.6", 11 | "debug": "^2.6.9", 12 | "express": "^4.18.2", 13 | "http-errors": "^1.8.1", 14 | "jade": "^1.11.0", 15 | "morgan": "^1.10.0" 16 | }, 17 | "dockerfile": { 18 | "alpine": true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/base/no-link/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "chalk": "^5.3.0", 10 | "cookie-parser": "^1.4.6", 11 | "debug": "^2.6.9", 12 | "express": "^4.18.2", 13 | "http-errors": "^1.8.1", 14 | "jade": "^1.11.0", 15 | "morgan": "^1.10.0" 16 | }, 17 | "dockerfile": { 18 | "link": false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/base/swap/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "chalk": "^5.3.0", 10 | "cookie-parser": "^1.4.6", 11 | "debug": "^2.6.9", 12 | "express": "^4.18.2", 13 | "http-errors": "^1.8.1", 14 | "jade": "^1.11.0", 15 | "morgan": "^1.10.0" 16 | }, 17 | "dockerfile": { 18 | "swap": "512M" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/base/distroless/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "chalk": "^5.3.0", 10 | "cookie-parser": "^1.4.6", 11 | "debug": "^2.6.9", 12 | "express": "^4.18.2", 13 | "http-errors": "^1.8.1", 14 | "jade": "^1.11.0", 15 | "morgan": "^1.10.0" 16 | }, 17 | "dockerfile": { 18 | "distroless": true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/base/nginx/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "cookie-parser": "^1.4.6", 10 | "debug": "^2.6.9", 11 | "express": "^4.18.2", 12 | "http-errors": "^1.8.1", 13 | "foreman": "^3.0.1", 14 | "jade": "^1.11.0", 15 | "morgan": "^1.10.0" 16 | }, 17 | "dockerfile": { 18 | "nginxRoot": "public" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/frameworks/astro-ssr/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fly-astro", 3 | "type": "module", 4 | "version": "0.0.1", 5 | "scripts": { 6 | "dev": "astro dev", 7 | "start": "astro dev", 8 | "build": "astro check && astro build", 9 | "preview": "astro preview", 10 | "astro": "astro" 11 | }, 12 | "dependencies": { 13 | "@astrojs/check": "^0.5.1", 14 | "@astrojs/node": "^8.2.0", 15 | "astro": "^4.3.5", 16 | "typescript": "^5.3.3" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /templates/litestream.yml.ejs: -------------------------------------------------------------------------------- 1 | # This is the configuration file for litestream. 2 | # 3 | # For more details, see: https://litestream.io/reference/config/ 4 | # 5 | dbs: 6 | - path: /data/<%= path.basename(prismaFile) %> 7 | replicas: 8 | - type: s3 9 | endpoint: $AWS_ENDPOINT_URL_S3 10 | bucket: $BUCKET_NAME 11 | path: litestream/<%= path.basename(prismaFile) %> 12 | access-key-id: $AWS_ACCESS_KEY_ID 13 | secret-access-key: $AWS_SECRET_ACCESS_KEY 14 | -------------------------------------------------------------------------------- /test/base/instructions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "express": "^4.18.2" 4 | }, 5 | "devDependencies": { 6 | "@types/express": "^4.17.17", 7 | "@types/node": "^20.5.1", 8 | "typescript": "^5.1.6" 9 | }, 10 | "scripts": { 11 | "build": "tsc", 12 | "start": "node build/server.js" 13 | }, 14 | "dockerfile": { 15 | "instructions": { 16 | "base": "setup.base", 17 | "build": "setup.build", 18 | "deploy": "setup.deploy" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/base/cmd-entrypoint/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "chalk": "^5.3.0", 10 | "cookie-parser": "^1.4.6", 11 | "debug": "^2.6.9", 12 | "express": "^4.18.2", 13 | "http-errors": "^1.8.1", 14 | "jade": "^1.11.0", 15 | "morgan": "^1.10.0" 16 | }, 17 | "dockerfile": { 18 | "cmd": "./bin/www", 19 | "entrypoint": "node" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/base/litestream/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node index.js" 7 | }, 8 | "dependencies": { 9 | "@prisma/client": "5.22.0", 10 | "express": "^4.18.2" 11 | }, 12 | "devDependencies": { 13 | "@types/node": "22.10.2", 14 | "@types/react": "18.3.18", 15 | "@types/react-dom": "18.3.5", 16 | "prisma": "5.22.0", 17 | "ts-node": "10.9.2", 18 | "typescript": "5.7.2" 19 | }, 20 | "dockerfile": { 21 | "litestream": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/base/packages/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "express": "^4.18.2" 4 | }, 5 | "devDependencies": { 6 | "@types/express": "^4.17.17", 7 | "@types/node": "^20.5.1", 8 | "typescript": "^5.1.6" 9 | }, 10 | "scripts": { 11 | "build": "tsc", 12 | "start": "node build/server.js" 13 | }, 14 | "dockerfile": { 15 | "packages": { 16 | "base": [ 17 | "procps" 18 | ], 19 | "build": [ 20 | "libicu-dev" 21 | ], 22 | "deploy": [ 23 | "vim" 24 | ] 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/base/litestream-url/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express", 3 | "version": "0.0.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "start": "node index.js" 8 | }, 9 | "dependencies": { 10 | "@prisma/client": "5.22.0", 11 | "express": "^4.18.2" 12 | }, 13 | "devDependencies": { 14 | "@types/node": "22.10.2", 15 | "@types/react": "18.3.18", 16 | "@types/react-dom": "18.3.5", 17 | "prisma": "5.22.0", 18 | "ts-node": "10.9.2", 19 | "typescript": "5.7.2" 20 | }, 21 | "dockerfile": { 22 | "litestream": true 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/frameworks/next-standalone/.dockerignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /test/frameworks/gatsby/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-gatsby-site", 3 | "version": "1.0.0", 4 | "private": true, 5 | "description": "my-gatsby-site", 6 | "author": "Sam Ruby", 7 | "keywords": [ 8 | "gatsby" 9 | ], 10 | "scripts": { 11 | "develop": "gatsby develop", 12 | "start": "gatsby develop", 13 | "build": "gatsby build", 14 | "serve": "gatsby serve", 15 | "clean": "gatsby clean" 16 | }, 17 | "dependencies": { 18 | "gatsby": "^5.11.0", 19 | "react": "^18.2.0", 20 | "react-dom": "^18.2.0" 21 | }, 22 | "dockerfile": { 23 | "legacyPeerDeps": true 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/frameworks/nest/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "allowSyntheticDefaultImports": true, 9 | "target": "es2017", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true, 14 | "skipLibCheck": true, 15 | "strictNullChecks": false, 16 | "noImplicitAny": false, 17 | "strictBindCallApply": false, 18 | "forceConsistentCasingInFileNames": false, 19 | "noFallthroughCasesInSwitch": false 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/frameworks/next-npm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@types/node": "^20.5.1", 13 | "@types/react": "^18.2.20", 14 | "@types/react-dom": "^18.2.7", 15 | "autoprefixer": "^10.4.15", 16 | "eslint": "^8.47.0", 17 | "eslint-config-next": "^13.4.19", 18 | "next": "^13.5.6", 19 | "postcss": "^8.4.28", 20 | "react": "^18.2.0", 21 | "react-dom": "^18.2.0", 22 | "tailwindcss": "^3.3.3", 23 | "typescript": "^5.1.6" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/frameworks/next-pnpm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@types/node": "^20.5.1", 13 | "@types/react": "^18.2.20", 14 | "@types/react-dom": "^18.2.7", 15 | "autoprefixer": "^10.4.15", 16 | "eslint": "^8.47.0", 17 | "eslint-config-next": "^13.4.19", 18 | "next": "^13.4.19", 19 | "postcss": "^8.4.31", 20 | "react": "^18.2.0", 21 | "react-dom": "^18.2.0", 22 | "tailwindcss": "^3.3.3", 23 | "typescript": "^5.1.6" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/frameworks/next-yarn/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@types/node": "^20.5.1", 13 | "@types/react": "^18.2.20", 14 | "@types/react-dom": "^18.2.7", 15 | "autoprefixer": "^10.4.15", 16 | "eslint": "^8.47.0", 17 | "eslint-config-next": "^13.4.19", 18 | "next": "^13.4.19", 19 | "postcss": "^8.4.31", 20 | "react": "^18.2.0", 21 | "react-dom": "^18.2.0", 22 | "tailwindcss": "^3.3.3", 23 | "typescript": "^5.1.6" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/base/litestream/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | generator client { 2 | provider = "prisma-client-js" 3 | } 4 | 5 | datasource db { 6 | provider = "sqlite" 7 | url = "file:./dev.db" 8 | } 9 | 10 | model User { 11 | id Int @id @default(autoincrement()) 12 | email String @unique 13 | name String? 14 | posts Post[] 15 | } 16 | 17 | model Post { 18 | id Int @id @default(autoincrement()) 19 | createdAt DateTime @default(now()) 20 | updatedAt DateTime @updatedAt 21 | title String 22 | content String? 23 | published Boolean @default(false) 24 | viewCount Int @default(0) 25 | author User? @relation(fields: [authorId], references: [id]) 26 | authorId Int? 27 | } 28 | -------------------------------------------------------------------------------- /test/frameworks/meteor/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-app", 3 | "private": true, 4 | "scripts": { 5 | "start": "meteor run", 6 | "test": "meteor test --once --driver-package meteortesting:mocha", 7 | "test-app": "TEST_WATCH=1 meteor test --full-app --driver-package meteortesting:mocha", 8 | "visualize": "meteor --production --extra-packages bundle-visualizer" 9 | }, 10 | "dependencies": { 11 | "@babel/runtime": "^7.23.5", 12 | "meteor-node-stubs": "^1.2.7" 13 | }, 14 | "meteor": { 15 | "mainModule": { 16 | "client": "client/main.js", 17 | "server": "server/main.js" 18 | }, 19 | "testModule": "tests/main.js" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/frameworks/next-standalone/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "standalone-next-js-test", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "next": "14.2.1", 13 | "react": "^18", 14 | "react-dom": "^18" 15 | }, 16 | "devDependencies": { 17 | "@flydotio/dockerfile": "^0.5.5", 18 | "@types/node": "^20", 19 | "@types/react": "^18", 20 | "@types/react-dom": "^18", 21 | "eslint": "^8", 22 | "eslint-config-next": "14.2.1", 23 | "postcss": "^8", 24 | "tailwindcss": "^3.4.1", 25 | "typescript": "^5" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/base/litestream-url/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | generator client { 2 | provider = "prisma-client-js" 3 | } 4 | 5 | datasource db { 6 | provider = "sqlite" 7 | url = env("DATABASE_URL") 8 | } 9 | 10 | model User { 11 | id Int @id @default(autoincrement()) 12 | email String @unique 13 | name String? 14 | posts Post[] 15 | } 16 | 17 | model Post { 18 | id Int @id @default(autoincrement()) 19 | createdAt DateTime @default(now()) 20 | updatedAt DateTime @updatedAt 21 | title String 22 | content String? 23 | published Boolean @default(false) 24 | viewCount Int @default(0) 25 | author User? @relation(fields: [authorId], references: [id]) 26 | authorId Int? 27 | } 28 | -------------------------------------------------------------------------------- /test/frameworks/nuxt-prisma/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | generator client { 2 | provider = "prisma-client-js" 3 | } 4 | 5 | datasource db { 6 | provider = "sqlite" 7 | url = "file:./dev.db" 8 | } 9 | 10 | model User { 11 | id Int @id @default(autoincrement()) 12 | email String @unique 13 | name String? 14 | posts Post[] 15 | } 16 | 17 | model Post { 18 | id Int @id @default(autoincrement()) 19 | createdAt DateTime @default(now()) 20 | updatedAt DateTime @updatedAt 21 | title String 22 | content String? 23 | published Boolean @default(false) 24 | viewCount Int @default(0) 25 | author User? @relation(fields: [authorId], references: [id]) 26 | authorId Int? 27 | } 28 | -------------------------------------------------------------------------------- /test/frameworks/svelte-prisma/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | generator client { 2 | provider = "prisma-client-js" 3 | } 4 | 5 | datasource db { 6 | provider = "sqlite" 7 | url = "file:./dev.db" 8 | } 9 | 10 | model User { 11 | id Int @id @default(autoincrement()) 12 | email String @unique 13 | name String? 14 | posts Post[] 15 | } 16 | 17 | model Post { 18 | id Int @id @default(autoincrement()) 19 | createdAt DateTime @default(now()) 20 | updatedAt DateTime @updatedAt 21 | title String 22 | content String? 23 | published Boolean @default(false) 24 | viewCount Int @default(0) 25 | author User? @relation(fields: [authorId], references: [id]) 26 | authorId Int? 27 | } 28 | -------------------------------------------------------------------------------- /test/frameworks/fastify/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "myproject", 3 | "version": "1.0.0", 4 | "description": "This project was bootstrapped with Fastify-CLI.", 5 | "main": "app.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "test": "tap \"test/**/*.test.js\"", 11 | "start": "fastify start -l info app.js", 12 | "dev": "fastify start -w -l info -P app.js" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC", 17 | "dependencies": { 18 | "fastify": "^4.21.0", 19 | "fastify-plugin": "^4.5.1", 20 | "@fastify/autoload": "^5.7.1", 21 | "@fastify/sensible": "^5.2.0", 22 | "fastify-cli": "^5.8.0" 23 | }, 24 | "devDependencies": { 25 | "tap": "^16.3.8" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/frameworks/remix-epic/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["**/*.ts", "**/*.tsx"], 3 | "compilerOptions": { 4 | "lib": ["DOM", "DOM.Iterable", "ES2022"], 5 | "isolatedModules": true, 6 | "esModuleInterop": true, 7 | "jsx": "react-jsx", 8 | "module": "nodenext", 9 | "moduleResolution": "nodenext", 10 | "resolveJsonModule": true, 11 | "target": "ES2022", 12 | "strict": true, 13 | "noImplicitAny": true, 14 | "allowJs": true, 15 | "forceConsistentCasingInFileNames": true, 16 | "paths": { 17 | "#*": ["./*"], 18 | "@/icon-name": [ 19 | "./app/components/ui/icons/name.d.ts", 20 | "./types/icon-name.d.ts" 21 | ] 22 | }, 23 | "skipLibCheck": true, 24 | "allowImportingTsExtensions": true, 25 | "noEmit": true 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/base/envargs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "express": "^4.18.2" 4 | }, 5 | "devDependencies": { 6 | "@types/express": "^4.17.17", 7 | "@types/node": "^20.5.1", 8 | "typescript": "^5.1.6" 9 | }, 10 | "scripts": { 11 | "build": "tsc", 12 | "start": "node build/server.js" 13 | }, 14 | "dockerfile": { 15 | "args": { 16 | "base": { 17 | "A1": "V1" 18 | }, 19 | "build": { 20 | "A2": "V2" 21 | }, 22 | "deploy": { 23 | "A3": "V3" 24 | } 25 | }, 26 | "envs": { 27 | "base": { 28 | "E1": "V1" 29 | }, 30 | "build": { 31 | "E2": "V2" 32 | }, 33 | "deploy": { 34 | "E3": "V3" 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/base/defer-build/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@types/node": "^20.5.1", 13 | "@types/react": "^18.2.20", 14 | "@types/react-dom": "^18.2.7", 15 | "@prisma/client": "5.1.1", 16 | "autoprefixer": "^10.4.15", 17 | "eslint": "^8.47.0", 18 | "eslint-config-next": "^13.4.19", 19 | "next": "^13.4.19", 20 | "postcss": "^8.4.28", 21 | "react": "^18.2.0", 22 | "react-dom": "^18.2.0", 23 | "tailwindcss": "^3.3.3", 24 | "typescript": "^5.1.6" 25 | }, 26 | "dockerfile": { 27 | "deferBuild": true 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/base/defer-build/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["./cypress", "./cypress.config.ts"], 3 | "include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"], 4 | "compilerOptions": { 5 | "lib": ["DOM", "DOM.Iterable", "ES2019"], 6 | "types": ["vitest/globals"], 7 | "isolatedModules": true, 8 | "esModuleInterop": true, 9 | "jsx": "react-jsx", 10 | "module": "CommonJS", 11 | "moduleResolution": "node", 12 | "resolveJsonModule": true, 13 | "target": "ES2019", 14 | "strict": true, 15 | "allowJs": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "~/*": ["./app/*"] 20 | }, 21 | "skipLibCheck": true, 22 | 23 | // Remix takes care of building everything in `remix build`. 24 | "noEmit": true 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/base/windows/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["./cypress", "./cypress.config.ts"], 3 | "include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"], 4 | "compilerOptions": { 5 | "lib": ["DOM", "DOM.Iterable", "ES2019"], 6 | "types": ["vitest/globals"], 7 | "isolatedModules": true, 8 | "esModuleInterop": true, 9 | "jsx": "react-jsx", 10 | "module": "CommonJS", 11 | "moduleResolution": "node", 12 | "resolveJsonModule": true, 13 | "target": "ES2019", 14 | "strict": true, 15 | "allowJs": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "~/*": ["./app/*"] 20 | }, 21 | "skipLibCheck": true, 22 | 23 | // Remix takes care of building everything in `remix build`. 24 | "noEmit": true 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/frameworks/remix-blues/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["./cypress", "./cypress.config.ts"], 3 | "include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"], 4 | "compilerOptions": { 5 | "lib": ["DOM", "DOM.Iterable", "ES2019"], 6 | "types": ["vitest/globals"], 7 | "isolatedModules": true, 8 | "esModuleInterop": true, 9 | "jsx": "react-jsx", 10 | "module": "CommonJS", 11 | "moduleResolution": "node", 12 | "resolveJsonModule": true, 13 | "target": "ES2019", 14 | "strict": true, 15 | "allowJs": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "~/*": ["./app/*"] 20 | }, 21 | "skipLibCheck": true, 22 | 23 | // Remix takes care of building everything in `remix build`. 24 | "noEmit": true 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/frameworks/remix-indie/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": ["./cypress", "./cypress.config.ts"], 3 | "include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"], 4 | "compilerOptions": { 5 | "lib": ["DOM", "DOM.Iterable", "ES2019"], 6 | "types": ["vitest/globals"], 7 | "isolatedModules": true, 8 | "esModuleInterop": true, 9 | "jsx": "react-jsx", 10 | "module": "CommonJS", 11 | "moduleResolution": "node", 12 | "resolveJsonModule": true, 13 | "target": "ES2019", 14 | "strict": true, 15 | "allowJs": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "~/*": ["./app/*"] 20 | }, 21 | "skipLibCheck": true, 22 | 23 | // Remix takes care of building everything in `remix build`. 24 | "noEmit": true 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/base/ignore-scripts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "myproject", 3 | "version": "1.0.0", 4 | "description": "This project was bootstrapped with Fastify-CLI.", 5 | "main": "app.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "test": "tap \"test/**/*.test.js\"", 11 | "start": "fastify start -l info app.js", 12 | "dev": "fastify start -w -l info -P app.js" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC", 17 | "dependencies": { 18 | "fastify": "^4.21.0", 19 | "fastify-plugin": "^4.5.1", 20 | "@fastify/autoload": "^5.7.1", 21 | "@fastify/sensible": "^5.2.0", 22 | "fastify-cli": "^5.8.0" 23 | }, 24 | "devDependencies": { 25 | "tap": "^16.3.8" 26 | }, 27 | "dockerfile": { 28 | "ignoreScripts": true 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/base/legacy-peer-deps/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "myproject", 3 | "version": "1.0.0", 4 | "description": "This project was bootstrapped with Fastify-CLI.", 5 | "main": "app.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "test": "tap \"test/**/*.test.js\"", 11 | "start": "fastify start -l info app.js", 12 | "dev": "fastify start -w -l info -P app.js" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC", 17 | "dependencies": { 18 | "fastify": "^4.21.0", 19 | "fastify-plugin": "^4.5.1", 20 | "@fastify/autoload": "^5.7.1", 21 | "@fastify/sensible": "^5.2.0", 22 | "fastify-cli": "^5.8.0" 23 | }, 24 | "devDependencies": { 25 | "tap": "^16.3.8" 26 | }, 27 | "dockerfile": { 28 | "legacyPeerDeps": true 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/frameworks/remix-epic/docker-entrypoint.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { spawn } from 'node:child_process' 4 | 5 | const env = { ...process.env } 6 | 7 | // If running the web server then migrate existing database 8 | if (process.argv.slice(-3).join(' ') === 'npm run start' && process.env.FLY_REGION === process.env.PRIMARY_REGION) { 9 | await exec('npx prisma migrate deploy') 10 | } 11 | 12 | // launch application 13 | await exec(process.argv.slice(2).join(' ')) 14 | 15 | function exec(command) { 16 | const child = spawn(command, { shell: true, stdio: 'inherit', env }) 17 | return new Promise((resolve, reject) => { 18 | child.on('exit', code => { 19 | if (code === 0) { 20 | resolve() 21 | } else { 22 | reject(new Error(`${command} failed rc=${code}`)) 23 | } 24 | }) 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /test/frameworks/next-standalone/docker-entrypoint.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { spawn } = require('node:child_process') 4 | 5 | const env = { ...process.env } 6 | 7 | ;(async() => { 8 | // If running the web server then prerender pages 9 | if (process.argv.slice(-2).join(' ') === 'node server.js') { 10 | await exec('npx next build --experimental-build-mode generate') 11 | } 12 | 13 | // launch application 14 | await exec(process.argv.slice(2).join(' ')) 15 | })() 16 | 17 | function exec(command) { 18 | const child = spawn(command, { shell: true, stdio: 'inherit', env }) 19 | return new Promise((resolve, reject) => { 20 | child.on('exit', code => { 21 | if (code === 0) { 22 | resolve() 23 | } else { 24 | reject(new Error(`${command} failed rc=${code}`)) 25 | } 26 | }) 27 | }) 28 | } 29 | -------------------------------------------------------------------------------- /test/frameworks/svelte-bun/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-app", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "dev": "vite dev", 6 | "build": "vite build", 7 | "preview": "vite preview", 8 | "check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json", 9 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch" 10 | }, 11 | "devDependencies": { 12 | "@flydotio/dockerfile": "^0.5.4", 13 | "@fontsource/fira-mono": "^4.5.10", 14 | "@neoconfetti/svelte": "^1.0.0", 15 | "@sveltejs/adapter-auto": "^3.0.0", 16 | "@sveltejs/kit": "^2.0.0", 17 | "@sveltejs/vite-plugin-svelte": "^3.0.0", 18 | "svelte": "^4.2.7", 19 | "svelte-adapter-bun": "^0.5.2", 20 | "svelte-check": "^3.6.0", 21 | "typescript": "^5.0.0", 22 | "vite": "^5.0.3" 23 | }, 24 | "type": "module" 25 | } 26 | -------------------------------------------------------------------------------- /test/frameworks/remix-pnpm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "sideEffects": false, 4 | "scripts": { 5 | "build": "remix build", 6 | "deploy": "fly deploy --remote-only", 7 | "dev": "remix dev", 8 | "start": "remix-serve build", 9 | "typecheck": "tsc" 10 | }, 11 | "dependencies": { 12 | "@remix-run/css-bundle": "^1.19.3", 13 | "@remix-run/node": "^1.19.3", 14 | "@remix-run/react": "^1.19.3", 15 | "@remix-run/serve": "^1.19.3", 16 | "isbot": "^3.6.8", 17 | "react": "^18.2.0", 18 | "react-dom": "^18.2.0" 19 | }, 20 | "devDependencies": { 21 | "@remix-run/dev": "^1.19.3", 22 | "@remix-run/eslint-config": "^1.19.3", 23 | "@types/react": "^18.2.20", 24 | "@types/react-dom": "^18.2.7", 25 | "eslint": "^8.38.0", 26 | "typescript": "^5.1.6" 27 | }, 28 | "engines": { 29 | "node": ">=14.0.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/base/defer-build/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | datasource db { 2 | provider = "sqlite" 3 | url = "file:./dev.db" 4 | } 5 | 6 | generator client { 7 | provider = "prisma-client-js" 8 | } 9 | 10 | model User { 11 | id String @id @default(cuid()) 12 | email String @unique 13 | 14 | createdAt DateTime @default(now()) 15 | updatedAt DateTime @updatedAt 16 | 17 | password Password? 18 | notes Note[] 19 | } 20 | 21 | model Password { 22 | hash String 23 | 24 | user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade) 25 | userId String @unique 26 | } 27 | 28 | model Note { 29 | id String @id @default(cuid()) 30 | title String 31 | body String 32 | 33 | createdAt DateTime @default(now()) 34 | updatedAt DateTime @updatedAt 35 | 36 | user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade) 37 | userId String 38 | } 39 | -------------------------------------------------------------------------------- /test/base/windows/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | datasource db { 2 | provider = "sqlite" 3 | url = env("DATABASE_URL") 4 | } 5 | 6 | generator client { 7 | provider = "prisma-client-js" 8 | } 9 | 10 | model User { 11 | id String @id @default(cuid()) 12 | email String @unique 13 | 14 | createdAt DateTime @default(now()) 15 | updatedAt DateTime @updatedAt 16 | 17 | password Password? 18 | notes Note[] 19 | } 20 | 21 | model Password { 22 | hash String 23 | 24 | user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade) 25 | userId String @unique 26 | } 27 | 28 | model Note { 29 | id String @id @default(cuid()) 30 | title String 31 | body String 32 | 33 | createdAt DateTime @default(now()) 34 | updatedAt DateTime @updatedAt 35 | 36 | user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade) 37 | userId String 38 | } 39 | -------------------------------------------------------------------------------- /test/frameworks/next-trpc/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | datasource db { 2 | provider = "sqlite" 3 | url = env("DATABASE_URL") 4 | } 5 | 6 | generator client { 7 | provider = "prisma-client-js" 8 | } 9 | 10 | model User { 11 | id String @id @default(cuid()) 12 | email String @unique 13 | 14 | createdAt DateTime @default(now()) 15 | updatedAt DateTime @updatedAt 16 | 17 | password Password? 18 | notes Note[] 19 | } 20 | 21 | model Password { 22 | hash String 23 | 24 | user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade) 25 | userId String @unique 26 | } 27 | 28 | model Note { 29 | id String @id @default(cuid()) 30 | title String 31 | body String 32 | 33 | createdAt DateTime @default(now()) 34 | updatedAt DateTime @updatedAt 35 | 36 | user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade) 37 | userId String 38 | } 39 | -------------------------------------------------------------------------------- /test/base/alpine/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-alpine AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apk update && \ 21 | apk add build-base gyp pkgconfig python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | 31 | # Final stage for app image 32 | FROM base 33 | 34 | # Copy built application 35 | COPY --from=build /app /app 36 | 37 | # Start the server by default, this can be overwritten at runtime 38 | EXPOSE 3000 39 | CMD [ "npm", "run", "start" ] 40 | -------------------------------------------------------------------------------- /test/frameworks/remix-blues/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | datasource db { 2 | provider = "postgresql" 3 | url = env("DATABASE_URL") 4 | } 5 | 6 | generator client { 7 | provider = "prisma-client-js" 8 | } 9 | 10 | model User { 11 | id String @id @default(cuid()) 12 | email String @unique 13 | 14 | createdAt DateTime @default(now()) 15 | updatedAt DateTime @updatedAt 16 | 17 | password Password? 18 | notes Note[] 19 | } 20 | 21 | model Password { 22 | hash String 23 | 24 | user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade) 25 | userId String @unique 26 | } 27 | 28 | model Note { 29 | id String @id @default(cuid()) 30 | title String 31 | body String 32 | 33 | createdAt DateTime @default(now()) 34 | updatedAt DateTime @updatedAt 35 | 36 | user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade) 37 | userId String 38 | } 39 | -------------------------------------------------------------------------------- /test/frameworks/remix-indie/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | datasource db { 2 | provider = "sqlite" 3 | url = env("DATABASE_URL") 4 | } 5 | 6 | generator client { 7 | provider = "prisma-client-js" 8 | } 9 | 10 | model User { 11 | id String @id @default(cuid()) 12 | email String @unique 13 | 14 | createdAt DateTime @default(now()) 15 | updatedAt DateTime @updatedAt 16 | 17 | password Password? 18 | notes Note[] 19 | } 20 | 21 | model Password { 22 | hash String 23 | 24 | user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade) 25 | userId String @unique 26 | } 27 | 28 | model Note { 29 | id String @id @default(cuid()) 30 | title String 31 | body String 32 | 33 | createdAt DateTime @default(now()) 34 | updatedAt DateTime @updatedAt 35 | 36 | user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade) 37 | userId String 38 | } 39 | -------------------------------------------------------------------------------- /test/frameworks/nuxt-prisma/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-prisma", 3 | "version": "2.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "nuxt dev", 7 | "build": "nuxt build", 8 | "start": "node .output/server/index.mjs", 9 | "generate": "nuxt generate" 10 | }, 11 | "dependencies": { 12 | "@prisma/client": "5.22.0", 13 | "nuxt": "3.14.1592" 14 | }, 15 | "devDependencies": { 16 | "@babel/eslint-parser": "7.25.9", 17 | "@flydotio/dockerfile": "github:fly-apps/dockerfile-node", 18 | "@nuxtjs/eslint-config": "12.0.0", 19 | "@nuxtjs/eslint-module": "4.1.0", 20 | "eslint": "8.57.1", 21 | "eslint-config-prettier": "9.1.0", 22 | "eslint-plugin-nuxt": "4.0.0", 23 | "eslint-plugin-prettier": "5.2.1", 24 | "prettier": "3.4.2", 25 | "prisma": "5.22.0" 26 | }, 27 | "prisma": { 28 | "seed": "node prisma/seed.js" 29 | }, 30 | "dockerfile": { 31 | "litestream": true 32 | } 33 | } -------------------------------------------------------------------------------- /test/base/bun/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust BUN_VERSION as desired 4 | ARG BUN_VERSION=xxx 5 | FROM oven/bun:${BUN_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Bun" 8 | 9 | # Bun app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY bun.lock package.json ./ 25 | RUN bun install --ci 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | 31 | # Final stage for app image 32 | FROM base 33 | 34 | # Copy built application 35 | COPY --from=build /app /app 36 | 37 | # Start the server by default, this can be overwritten at runtime 38 | EXPOSE 3000 39 | CMD [ "bun", "index.ts" ] 40 | -------------------------------------------------------------------------------- /test/base/swap/docker-entrypoint.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { spawn } = require('node:child_process') 4 | const { writeFileSync } = require('node:fs') 5 | 6 | const env = { ...process.env } 7 | 8 | ;(async() => { 9 | // allocate swap space 10 | await exec('fallocate -l 512M /swapfile') 11 | await exec('chmod 0600 /swapfile') 12 | await exec('mkswap /swapfile') 13 | writeFileSync('/proc/sys/vm/swappiness', '10') 14 | await exec('swapon /swapfile') 15 | writeFileSync('/proc/sys/vm/overcommit_memory', '1') 16 | 17 | // launch application 18 | await exec(process.argv.slice(2).join(' ')) 19 | })() 20 | 21 | function exec(command) { 22 | const child = spawn(command, { shell: true, stdio: 'inherit', env }) 23 | return new Promise((resolve, reject) => { 24 | child.on('exit', code => { 25 | if (code === 0) { 26 | resolve() 27 | } else { 28 | reject(new Error(`${command} failed rc=${code}`)) 29 | } 30 | }) 31 | }) 32 | } 33 | -------------------------------------------------------------------------------- /test/base/git/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential git node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package.json ./ 25 | RUN npm install 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | 31 | # Final stage for app image 32 | FROM base 33 | 34 | # Copy built application 35 | COPY --from=build /app /app 36 | 37 | # Start the server by default, this can be overwritten at runtime 38 | EXPOSE 3000 39 | CMD [ "node", "index.js" ] 40 | -------------------------------------------------------------------------------- /test/base/port/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | 31 | # Final stage for app image 32 | FROM base 33 | 34 | # Copy built application 35 | COPY --from=build /app /app 36 | 37 | # Start the server by default, this can be overwritten at runtime 38 | EXPOSE 4567 39 | CMD [ "npm", "run", "start" ] 40 | -------------------------------------------------------------------------------- /test/base/no-link/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | 31 | # Final stage for app image 32 | FROM base 33 | 34 | # Copy built application 35 | COPY --from=build /app /app 36 | 37 | # Start the server by default, this can be overwritten at runtime 38 | EXPOSE 3000 39 | CMD [ "npm", "run", "start" ] 40 | -------------------------------------------------------------------------------- /test/base/version/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=100 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | 31 | # Final stage for app image 32 | FROM base 33 | 34 | # Copy built application 35 | COPY --from=build /app /app 36 | 37 | # Start the server by default, this can be overwritten at runtime 38 | EXPOSE 3000 39 | CMD [ "npm", "run", "start" ] 40 | -------------------------------------------------------------------------------- /test/frameworks/express/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | 31 | # Final stage for app image 32 | FROM base 33 | 34 | # Copy built application 35 | COPY --from=build /app /app 36 | 37 | # Start the server by default, this can be overwritten at runtime 38 | EXPOSE 3000 39 | CMD [ "npm", "run", "start" ] 40 | -------------------------------------------------------------------------------- /test/frameworks/vite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-app", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "react": "^18.2.0", 14 | "react-dom": "^18.2.0", 15 | "vite-plugin-svgr": "^3.2.0" 16 | }, 17 | "devDependencies": { 18 | "@types/react": "^18.2.15", 19 | "@types/react-dom": "^18.2.7", 20 | "@typescript-eslint/eslint-plugin": "^6.0.0", 21 | "@typescript-eslint/parser": "^6.0.0", 22 | "@vitejs/plugin-react": "^4.0.3", 23 | "autoprefixer": "^10.4.14", 24 | "eslint": "^8.45.0", 25 | "eslint-plugin-react-hooks": "^4.6.0", 26 | "eslint-plugin-react-refresh": "^0.4.3", 27 | "postcss": "^8.4.26", 28 | "tailwindcss": "^3.3.3", 29 | "typescript": "^5.0.2", 30 | "vite": "^4.4.5" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/frameworks/fastify/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | 31 | # Final stage for app image 32 | FROM base 33 | 34 | # Copy built application 35 | COPY --from=build /app /app 36 | 37 | # Start the server by default, this can be overwritten at runtime 38 | EXPOSE 3000 39 | CMD [ "npx", "fastify", "start", "--address", "0.0.0.0", "-l", "info", "app.js" ] 40 | -------------------------------------------------------------------------------- /test/base/cmd-entrypoint/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | 31 | # Final stage for app image 32 | FROM base 33 | 34 | # Copy built application 35 | COPY --from=build /app /app 36 | 37 | # Entrypoint sets up the container. 38 | ENTRYPOINT "node" 39 | 40 | # Start the server by default, this can be overwritten at runtime 41 | EXPOSE 3000 42 | CMD ./bin/www 43 | -------------------------------------------------------------------------------- /test/frameworks/next-npm/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Next.js" 8 | 9 | # Next.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | # Build application 31 | RUN npm run build 32 | 33 | 34 | # Final stage for app image 35 | FROM base 36 | 37 | # Copy built application 38 | COPY --from=build /app /app 39 | 40 | # Start the server by default, this can be overwritten at runtime 41 | EXPOSE 3000 42 | CMD [ "npm", "run", "start" ] 43 | -------------------------------------------------------------------------------- /test/base/dev/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci --include=dev 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | # Build application 31 | RUN npm run build 32 | 33 | 34 | # Final stage for app image 35 | FROM base 36 | 37 | # Copy built application 38 | COPY --from=build /app /app 39 | 40 | # Start the server by default, this can be overwritten at runtime 41 | EXPOSE 3000 42 | CMD [ "npm", "run", "start" ] 43 | -------------------------------------------------------------------------------- /test/base/distroless/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS build 6 | 7 | # Node.js app lives here 8 | WORKDIR /app 9 | 10 | # Set production environment 11 | ENV NODE_ENV="production" 12 | 13 | # Install packages needed to build node modules 14 | RUN apt-get update -qq && \ 15 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 16 | 17 | # Install node modules 18 | COPY package-lock.json package.json ./ 19 | RUN npm ci 20 | 21 | # Copy application code 22 | COPY . . 23 | 24 | 25 | # Final stage for app image 26 | FROM gcr.io/distroless/nodejs${NODE_VERSION} 27 | 28 | LABEL fly_launch_runtime="Node.js" 29 | 30 | # Node.js app lives here 31 | WORKDIR /app 32 | 33 | # Set production environment 34 | ENV NODE_ENV="production" 35 | 36 | # Copy built application 37 | COPY --from=build /app /app 38 | 39 | # Start the server by default, this can be overwritten at runtime 40 | EXPOSE 3000 41 | CMD [ "node", "./bin/www" ] 42 | -------------------------------------------------------------------------------- /test/frameworks/nest/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="NestJS" 8 | 9 | # NestJS app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci --include=dev 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | # Build application 31 | RUN npm run build 32 | 33 | 34 | # Final stage for app image 35 | FROM base 36 | 37 | # Copy built application 38 | COPY --from=build /app /app 39 | 40 | # Start the server by default, this can be overwritten at runtime 41 | EXPOSE 3000 42 | CMD [ "npm", "run", "start" ] 43 | -------------------------------------------------------------------------------- /test/frameworks/next-trpc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "trpc-nextjs", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "build": "next build", 7 | "dev": "next dev", 8 | "postinstall": "prisma generate", 9 | "start": "next start" 10 | }, 11 | "dependencies": { 12 | "@prisma/client": "5.22.0", 13 | "@tanstack/react-query": "4.36.1", 14 | "@trpc/client": "10.45.2", 15 | "@trpc/next": "10.45.2", 16 | "@trpc/react-query": "10.45.2", 17 | "@trpc/server": "10.45.2", 18 | "next": "14.2.21", 19 | "react": "18.3.1", 20 | "react-dom": "18.3.1", 21 | "react-markdown": "9.0.1", 22 | "superjson": "2.2.2", 23 | "zod": "3.24.1" 24 | }, 25 | "devDependencies": { 26 | "@types/node": "22.10.2", 27 | "@types/react": "18.3.18", 28 | "@types/react-dom": "18.3.5", 29 | "prisma": "5.22.0", 30 | "ts-node": "10.9.2", 31 | "typescript": "5.7.2" 32 | }, 33 | "ct3aMetadata": { 34 | "initVersion": "7.3.2" 35 | }, 36 | "prisma": { 37 | "seed": "ts-node ./prisma/seed.ts" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/base/ignore-scripts/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci --ignore-scripts 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | 31 | # Final stage for app image 32 | FROM base 33 | 34 | # Copy built application 35 | COPY --from=build /app /app 36 | 37 | # Start the server by default, this can be overwritten at runtime 38 | EXPOSE 3000 39 | CMD [ "npx", "fastify", "start", "--address", "0.0.0.0", "-l", "info", "app.js" ] 40 | -------------------------------------------------------------------------------- /test/base/legacy-peer-deps/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci --legacy-peer-deps 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | 31 | # Final stage for app image 32 | FROM base 33 | 34 | # Copy built application 35 | COPY --from=build /app /app 36 | 37 | # Start the server by default, this can be overwritten at runtime 38 | EXPOSE 3000 39 | CMD [ "npx", "fastify", "start", "--address", "0.0.0.0", "-l", "info", "app.js" ] 40 | -------------------------------------------------------------------------------- /test/base/swap/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | 31 | # Final stage for app image 32 | FROM base 33 | 34 | # Copy built application 35 | COPY --from=build /app /app 36 | 37 | # Entrypoint sets up the container. 38 | ENTRYPOINT [ "/app/docker-entrypoint.js" ] 39 | 40 | # Start the server by default, this can be overwritten at runtime 41 | EXPOSE 3000 42 | CMD [ "npm", "run", "start" ] 43 | -------------------------------------------------------------------------------- /test/frameworks/gatsby/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Gatsby" 8 | 9 | # Gatsby app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci --legacy-peer-deps 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | # Build application 31 | RUN npm run build 32 | 33 | 34 | # Final stage for app image 35 | FROM base 36 | 37 | # Copy built application 38 | COPY --from=build /app /app 39 | 40 | # Start the server by default, this can be overwritten at runtime 41 | EXPOSE 8080 42 | CMD [ "npx", "gatsby", "serve", "-H", "0.0.0.0" ] 43 | -------------------------------------------------------------------------------- /test/frameworks/astro-static/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Astro" 8 | 9 | # Astro app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | # Build application 31 | RUN npm run build 32 | 33 | 34 | # Final stage for app image 35 | FROM nginx 36 | 37 | # Copy built application 38 | COPY --from=build /app/dist /usr/share/nginx/html 39 | 40 | # Start the server by default, this can be overwritten at runtime 41 | EXPOSE 80 42 | CMD [ "/usr/sbin/nginx", "-g", "daemon off;" ] 43 | -------------------------------------------------------------------------------- /test/base/windows/docker-entrypoint.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { spawn } = require('node:child_process') 4 | const fs = require('node:fs') 5 | 6 | const env = { ...process.env } 7 | 8 | ;(async() => { 9 | // If running the web server then migrate existing database 10 | if (process.argv.slice(-3).join(' ') === 'npx remix-serve ./build/index.js') { 11 | const url = new URL(process.env.DATABASE_URL) 12 | const target = url.protocol === 'file:' && url.pathname 13 | const newDb = target && !fs.existsSync(target) 14 | await exec('npx prisma migrate deploy') 15 | if (newDb) await exec('ts-node --require tsconfig-paths/register prisma/seed.ts') 16 | } 17 | 18 | // launch application 19 | await exec(process.argv.slice(2).join(' ')) 20 | })() 21 | 22 | function exec(command) { 23 | const child = spawn(command, { shell: true, stdio: 'inherit', env }) 24 | return new Promise((resolve, reject) => { 25 | child.on('exit', code => { 26 | if (code === 0) { 27 | resolve() 28 | } else { 29 | reject(new Error(`${command} failed rc=${code}`)) 30 | } 31 | }) 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /test/fly/sqlite3/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | 31 | # Final stage for app image 32 | FROM base 33 | 34 | # Copy built application 35 | COPY --from=build /app /app 36 | 37 | # Setup sqlite3 on a separate volume 38 | RUN mkdir -p /data 39 | VOLUME /data 40 | 41 | # Start the server by default, this can be overwritten at runtime 42 | EXPOSE 3000 43 | ENV DATABASE_URL="file:///data/sqlite.db" 44 | CMD [ "npm", "run", "start" ] 45 | -------------------------------------------------------------------------------- /test/base/build/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci --include=dev 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | # Build application 31 | RUN npm run tsc 32 | 33 | # Remove development dependencies 34 | RUN npm prune --omit=dev 35 | 36 | 37 | # Final stage for app image 38 | FROM base 39 | 40 | # Copy built application 41 | COPY --from=build /app /app 42 | 43 | # Start the server by default, this can be overwritten at runtime 44 | EXPOSE 3000 45 | CMD [ "npm", "run", "start" ] 46 | -------------------------------------------------------------------------------- /test/frameworks/remix-indie/docker-entrypoint.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { spawn } = require('node:child_process') 4 | const fs = require('node:fs') 5 | 6 | const env = { ...process.env } 7 | 8 | ;(async() => { 9 | // If running the web server then migrate existing database 10 | if (process.argv.slice(-3).join(' ') === 'npx remix-serve ./build/index.js') { 11 | const url = new URL(process.env.DATABASE_URL) 12 | const target = url.protocol === 'file:' && url.pathname 13 | const newDb = target && !fs.existsSync(target) 14 | await exec('npx prisma migrate deploy') 15 | if (newDb) await exec('ts-node --require tsconfig-paths/register prisma/seed.ts') 16 | } 17 | 18 | // launch application 19 | await exec(process.argv.slice(2).join(' ')) 20 | })() 21 | 22 | function exec(command) { 23 | const child = spawn(command, { shell: true, stdio: 'inherit', env }) 24 | return new Promise((resolve, reject) => { 25 | child.on('exit', code => { 26 | if (code === 0) { 27 | resolve() 28 | } else { 29 | reject(new Error(`${command} failed rc=${code}`)) 30 | } 31 | }) 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /test/frameworks/next-yarn/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Next.js" 8 | 9 | # Next.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | ARG YARN_VERSION=xxx 15 | RUN npm install -g yarn@$YARN_VERSION --force 16 | 17 | 18 | # Throw-away build stage to reduce size of final image 19 | FROM base AS build 20 | 21 | # Install packages needed to build node modules 22 | RUN apt-get update -qq && \ 23 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 24 | 25 | # Install node modules 26 | COPY package.json yarn.lock ./ 27 | RUN yarn install --frozen-lockfile 28 | 29 | # Copy application code 30 | COPY . . 31 | 32 | # Build application 33 | RUN yarn run build 34 | 35 | 36 | # Final stage for app image 37 | FROM base 38 | 39 | # Copy built application 40 | COPY --from=build /app /app 41 | 42 | # Start the server by default, this can be overwritten at runtime 43 | EXPOSE 3000 44 | CMD [ "yarn", "run", "start" ] 45 | -------------------------------------------------------------------------------- /test/frameworks/vite/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Vite" 8 | 9 | # Vite app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci --include=dev 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | # Build application 31 | RUN npm run build 32 | 33 | # Remove development dependencies 34 | RUN npm prune --omit=dev 35 | 36 | 37 | # Final stage for app image 38 | FROM nginx 39 | 40 | # Copy built application 41 | COPY --from=build /app/dist /usr/share/nginx/html 42 | 43 | # Start the server by default, this can be overwritten at runtime 44 | EXPOSE 80 45 | CMD [ "/usr/sbin/nginx", "-g", "daemon off;" ] 46 | -------------------------------------------------------------------------------- /test/frameworks/next-pnpm/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Next.js" 8 | 9 | # Next.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | # Install pnpm 16 | ARG PNPM_VERSION=xxx 17 | RUN npm install -g pnpm@$PNPM_VERSION 18 | 19 | 20 | # Throw-away build stage to reduce size of final image 21 | FROM base AS build 22 | 23 | # Install packages needed to build node modules 24 | RUN apt-get update -qq && \ 25 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 26 | 27 | # Install node modules 28 | COPY package.json pnpm-lock.yaml ./ 29 | RUN pnpm install --frozen-lockfile 30 | 31 | # Copy application code 32 | COPY . . 33 | 34 | # Build application 35 | RUN pnpm run build 36 | 37 | 38 | # Final stage for app image 39 | FROM base 40 | 41 | # Copy built application 42 | COPY --from=build /app /app 43 | 44 | # Start the server by default, this can be overwritten at runtime 45 | EXPOSE 3000 46 | CMD [ "pnpm", "run", "start" ] 47 | -------------------------------------------------------------------------------- /test/frameworks/astro-ssr/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Astro" 8 | 9 | # Astro app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | # Build application 31 | RUN npm run build 32 | 33 | 34 | # Final stage for app image 35 | FROM base 36 | 37 | # Copy built application 38 | COPY --from=build /app/node_modules /app/node_modules 39 | COPY --from=build /app/dist /app/dist 40 | 41 | ENV PORT=4321 42 | ENV HOST=0.0.0.0 43 | 44 | # Start the server by default, this can be overwritten at runtime 45 | EXPOSE 4321 46 | CMD [ "node", "./dist/server/entry.mjs" ] 47 | -------------------------------------------------------------------------------- /test/base/defer-build/docker-entrypoint.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { spawn } = require('node:child_process') 4 | const path = require('node:path') 5 | const fs = require('node:fs') 6 | 7 | const env = { ...process.env } 8 | 9 | ;(async() => { 10 | // If running the web server then migrate existing database 11 | if (process.argv.slice(-3).join(' ') === 'npm run start') { 12 | // place Sqlite3 database on volume 13 | const source = path.resolve('./dev.db') 14 | const target = '/data/' + path.basename(source) 15 | if (!fs.existsSync(source) && fs.existsSync('/data')) fs.symlinkSync(target, source) 16 | 17 | // prepare database 18 | await exec('npx prisma migrate deploy') 19 | await exec('npm run build') 20 | } 21 | 22 | // launch application 23 | await exec(process.argv.slice(2).join(' ')) 24 | })() 25 | 26 | function exec(command) { 27 | const child = spawn(command, { shell: true, stdio: 'inherit', env }) 28 | return new Promise((resolve, reject) => { 29 | child.on('exit', code => { 30 | if (code === 0) { 31 | resolve() 32 | } else { 33 | reject(new Error(`${command} failed rc=${code}`)) 34 | } 35 | }) 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /test/base/fluent-ffmpeg/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package.json ./ 25 | RUN npm install 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | 31 | # Final stage for app image 32 | FROM base 33 | 34 | # Install packages needed for deployment 35 | RUN apt-get update -qq && \ 36 | apt-get install --no-install-recommends -y ffmpeg && \ 37 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 38 | 39 | # Copy built application 40 | COPY --from=build /app /app 41 | 42 | # Start the server by default, this can be overwritten at runtime 43 | EXPOSE 3000 44 | CMD [ "npm", "run", "start" ] 45 | -------------------------------------------------------------------------------- /test/frameworks/next-yarn4/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Next.js" 8 | 9 | # Next.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | ARG YARN_VERSION=xxx 15 | 16 | # Install Yarn 4 17 | RUN corepack enable && \ 18 | yarn set version ${YARN_VERSION} 19 | 20 | 21 | # Throw-away build stage to reduce size of final image 22 | FROM base AS build 23 | 24 | # Install packages needed to build node modules 25 | RUN apt-get update -qq && \ 26 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 27 | 28 | # Install node modules 29 | COPY package.json yarn.lock ./ 30 | RUN yarn install --immutable 31 | 32 | # Copy application code 33 | COPY . . 34 | 35 | # Build application 36 | RUN yarn run build 37 | 38 | 39 | # Final stage for app image 40 | FROM base 41 | 42 | # Copy built application 43 | COPY --from=build /app /app 44 | 45 | # Start the server by default, this can be overwritten at runtime 46 | EXPOSE 3000 47 | CMD [ "yarn", "run", "start" ] 48 | -------------------------------------------------------------------------------- /test/frameworks/nuxt/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Nuxt" 8 | 9 | # Nuxt app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | ARG YARN_VERSION=xxx 15 | RUN npm install -g yarn@$YARN_VERSION --force 16 | 17 | 18 | # Throw-away build stage to reduce size of final image 19 | FROM base AS build 20 | 21 | # Install packages needed to build node modules 22 | RUN apt-get update -qq && \ 23 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 24 | 25 | # Install node modules 26 | COPY package.json yarn.lock ./ 27 | RUN yarn install --frozen-lockfile --production=false 28 | 29 | # Copy application code 30 | COPY . . 31 | 32 | # Build application 33 | RUN yarn run build 34 | 35 | 36 | # Final stage for app image 37 | FROM base 38 | 39 | # Copy built application 40 | COPY --from=build /app/.output /app/.output 41 | 42 | # Start the server by default, this can be overwritten at runtime 43 | EXPOSE 3000 44 | ENV HOST=0 45 | CMD [ "node", ".output/server/index.mjs" ] 46 | -------------------------------------------------------------------------------- /test/frameworks/svelte-prisma/docker-entrypoint.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { spawn } from 'node:child_process' 4 | import path from 'node:path' 5 | import fs from 'node:fs' 6 | 7 | const env = { ...process.env } 8 | 9 | // If running the web server then migrate existing database 10 | if (process.argv.slice(-2).join(' ') === 'node ./build/index.js') { 11 | // place Sqlite3 database on volume 12 | const source = path.resolve('./dev.db') 13 | const target = '/data/' + path.basename(source) 14 | if (!fs.existsSync(source) && fs.existsSync('/data')) fs.symlinkSync(target, source) 15 | const newDb = !fs.existsSync(target) 16 | 17 | // prepare database 18 | await exec('npx prisma migrate deploy') 19 | if (newDb) await exec('tsx prisma/seed.ts') 20 | } 21 | 22 | // launch application 23 | await exec(process.argv.slice(2).join(' ')) 24 | 25 | function exec(command) { 26 | const child = spawn(command, { shell: true, stdio: 'inherit', env }) 27 | return new Promise((resolve, reject) => { 28 | child.on('exit', code => { 29 | if (code === 0) { 30 | resolve() 31 | } else { 32 | reject(new Error(`${command} failed rc=${code}`)) 33 | } 34 | }) 35 | }) 36 | } 37 | -------------------------------------------------------------------------------- /test/base/instructions/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | # base additions 16 | 17 | 18 | # Throw-away build stage to reduce size of final image 19 | FROM base AS build 20 | 21 | # Install packages needed to build node modules 22 | RUN apt-get update -qq && \ 23 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 24 | 25 | # Install node modules 26 | COPY package-lock.json package.json ./ 27 | RUN npm ci --include=dev 28 | 29 | # Copy application code 30 | COPY . . 31 | 32 | # Build application 33 | RUN npm run build 34 | 35 | # Remove development dependencies 36 | RUN npm prune --omit=dev 37 | 38 | # build additions 39 | 40 | 41 | # Final stage for app image 42 | FROM base 43 | 44 | # Copy built application 45 | COPY --from=build /app /app 46 | 47 | # deploy additions 48 | 49 | # Start the server by default, this can be overwritten at runtime 50 | EXPOSE 3000 51 | CMD [ "npm", "run", "start" ] 52 | -------------------------------------------------------------------------------- /test/base/windows/app/root.tsx: -------------------------------------------------------------------------------- 1 | import { cssBundleHref } from "@remix-run/css-bundle"; 2 | import type { LinksFunction, LoaderArgs } from "@remix-run/node"; 3 | import { json } from "@remix-run/node"; 4 | import { 5 | Links, 6 | LiveReload, 7 | Meta, 8 | Outlet, 9 | Scripts, 10 | ScrollRestoration, 11 | } from "@remix-run/react"; 12 | 13 | import { getUser } from "~/session.server"; 14 | import stylesheet from "~/tailwind.css"; 15 | 16 | export const links: LinksFunction = () => [ 17 | { rel: "stylesheet", href: stylesheet }, 18 | ...(cssBundleHref ? [{ rel: "stylesheet", href: cssBundleHref }] : []), 19 | ]; 20 | 21 | export const loader = async ({ request }: LoaderArgs) => { 22 | return json({ user: await getUser(request) }); 23 | }; 24 | 25 | export default function App() { 26 | return ( 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /test/base/defer-build/app/root.tsx: -------------------------------------------------------------------------------- 1 | import { cssBundleHref } from "@remix-run/css-bundle"; 2 | import type { LinksFunction, LoaderArgs } from "@remix-run/node"; 3 | import { json } from "@remix-run/node"; 4 | import { 5 | Links, 6 | LiveReload, 7 | Meta, 8 | Outlet, 9 | Scripts, 10 | ScrollRestoration, 11 | } from "@remix-run/react"; 12 | 13 | import { getUser } from "~/session.server"; 14 | import stylesheet from "~/tailwind.css"; 15 | 16 | export const links: LinksFunction = () => [ 17 | { rel: "stylesheet", href: stylesheet }, 18 | ...(cssBundleHref ? [{ rel: "stylesheet", href: cssBundleHref }] : []), 19 | ]; 20 | 21 | export const loader = async ({ request }: LoaderArgs) => { 22 | return json({ user: await getUser(request) }); 23 | }; 24 | 25 | export default function App() { 26 | return ( 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /test/frameworks/remix-blues/app/root.tsx: -------------------------------------------------------------------------------- 1 | import { cssBundleHref } from "@remix-run/css-bundle"; 2 | import type { LinksFunction, LoaderArgs } from "@remix-run/node"; 3 | import { json } from "@remix-run/node"; 4 | import { 5 | Links, 6 | LiveReload, 7 | Meta, 8 | Outlet, 9 | Scripts, 10 | ScrollRestoration, 11 | } from "@remix-run/react"; 12 | 13 | import { getUser } from "~/session.server"; 14 | import stylesheet from "~/tailwind.css"; 15 | 16 | export const links: LinksFunction = () => [ 17 | { rel: "stylesheet", href: stylesheet }, 18 | ...(cssBundleHref ? [{ rel: "stylesheet", href: cssBundleHref }] : []), 19 | ]; 20 | 21 | export const loader = async ({ request }: LoaderArgs) => { 22 | return json({ user: await getUser(request) }); 23 | }; 24 | 25 | export default function App() { 26 | return ( 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /test/frameworks/remix-indie/app/root.tsx: -------------------------------------------------------------------------------- 1 | import { cssBundleHref } from "@remix-run/css-bundle"; 2 | import type { LinksFunction, LoaderArgs } from "@remix-run/node"; 3 | import { json } from "@remix-run/node"; 4 | import { 5 | Links, 6 | LiveReload, 7 | Meta, 8 | Outlet, 9 | Scripts, 10 | ScrollRestoration, 11 | } from "@remix-run/react"; 12 | 13 | import { getUser } from "~/session.server"; 14 | import stylesheet from "~/tailwind.css"; 15 | 16 | export const links: LinksFunction = () => [ 17 | { rel: "stylesheet", href: stylesheet }, 18 | ...(cssBundleHref ? [{ rel: "stylesheet", href: cssBundleHref }] : []), 19 | ]; 20 | 21 | export const loader = async ({ request }: LoaderArgs) => { 22 | return json({ user: await getUser(request) }); 23 | }; 24 | 25 | export default function App() { 26 | return ( 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /test/base/build-secret/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci --include=dev 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | # Build application 31 | RUN --mount=type=secret,id=DATABASE_URL \ 32 | DATABASE_URL="$(cat /run/secrets/DATABASE_URL)" \ 33 | npm run build 34 | 35 | # Remove development dependencies 36 | RUN npm prune --omit=dev 37 | 38 | 39 | # Final stage for app image 40 | FROM base 41 | 42 | # Copy built application 43 | COPY --from=build /app /app 44 | 45 | # Start the server by default, this can be overwritten at runtime 46 | EXPOSE 3000 47 | CMD [ "npm", "run", "start" ] 48 | -------------------------------------------------------------------------------- /test/base/puppeteer/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package.json ./ 25 | RUN npm install 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | 31 | # Final stage for app image 32 | FROM base 33 | 34 | # Install packages needed for deployment 35 | RUN apt-get update -qq && \ 36 | apt-get install --no-install-recommends -y chromium chromium-sandbox && \ 37 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 38 | 39 | # Copy built application 40 | COPY --from=build /app /app 41 | 42 | # Start the server by default, this can be overwritten at runtime 43 | EXPOSE 3000 44 | ENV PUPPETEER_EXECUTABLE_PATH="/usr/bin/chromium" 45 | CMD [ "npm", "run", "start" ] 46 | -------------------------------------------------------------------------------- /test/frameworks/remix-pnpm/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Remix" 8 | 9 | # Remix app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | # Install pnpm 16 | ARG PNPM_VERSION=xxx 17 | RUN npm install -g pnpm@$PNPM_VERSION 18 | 19 | 20 | # Throw-away build stage to reduce size of final image 21 | FROM base AS build 22 | 23 | # Install packages needed to build node modules 24 | RUN apt-get update -qq && \ 25 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 26 | 27 | # Install node modules 28 | COPY package.json pnpm-lock.yaml ./ 29 | RUN pnpm install --frozen-lockfile --prod=false 30 | 31 | # Copy application code 32 | COPY . . 33 | 34 | # Build application 35 | RUN pnpm run build 36 | 37 | # Remove development dependencies 38 | RUN pnpm prune --prod 39 | 40 | 41 | # Final stage for app image 42 | FROM base 43 | 44 | # Copy built application 45 | COPY --from=build /app /app 46 | 47 | # Start the server by default, this can be overwritten at runtime 48 | EXPOSE 3000 49 | CMD [ "npx", "remix-serve", "./build/index.js" ] 50 | -------------------------------------------------------------------------------- /test/frameworks/svelte-bun/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust BUN_VERSION as desired 4 | ARG BUN_VERSION=xxx 5 | FROM oven/bun:${BUN_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="SvelteKit" 8 | 9 | # SvelteKit app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY bun.lockb package.json ./ 25 | RUN bun install 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | # Build application 31 | RUN bun --bun run build 32 | 33 | # Remove development dependencies 34 | RUN rm -rf node_modules && \ 35 | bun install --ci 36 | 37 | 38 | # Final stage for app image 39 | FROM base 40 | 41 | # Copy built application 42 | COPY --from=build /app/build /app/build 43 | COPY --from=build /app/node_modules /app/node_modules 44 | COPY --from=build /app/package.json /app 45 | 46 | # Start the server by default, this can be overwritten at runtime 47 | EXPOSE 3000 48 | CMD [ "bun", "./build/index.js" ] 49 | -------------------------------------------------------------------------------- /test/base/bun/bun.lock: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 0, 3 | "workspaces": { 4 | "": { 5 | "name": "bunserver", 6 | "devDependencies": { 7 | "bun-types": "latest", 8 | }, 9 | "peerDependencies": { 10 | "typescript": "^5.0.0", 11 | }, 12 | }, 13 | }, 14 | "packages": { 15 | "@types/node": ["@types/node@20.12.14", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg=="], 16 | 17 | "@types/ws": ["@types/ws@8.5.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA=="], 18 | 19 | "bun-types": ["bun-types@1.1.43", "", { "dependencies": { "@types/node": "~20.12.8", "@types/ws": "~8.5.10" } }, "sha512-W0wCtVH+bwFp7p3Zgs03CqxEDmXxEvmmUM/FBKgWIv9T8gyeotvIjIbHzuDScc2DphhRNtr7hJLCR5PspYL5qw=="], 20 | 21 | "typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="], 22 | 23 | "undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/frameworks/adonisjs/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="AdonisJS" 8 | 9 | # AdonisJS app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package.json ./ 25 | RUN npm install --include=dev 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | # Build application 31 | RUN npm run build 32 | 33 | 34 | # Final stage for app image 35 | FROM base 36 | 37 | # Copy built application 38 | COPY --from=build /app /app 39 | 40 | # Entrypoint sets up the container. 41 | ENTRYPOINT [ "/app/docker-entrypoint.js" ] 42 | 43 | # Start the server by default, this can be overwritten at runtime 44 | EXPOSE 3000 45 | ENV CACHE_VIEWS="true" \ 46 | DB_CONNECTION="pg" \ 47 | DRIVE_DISK="local" \ 48 | HOST="0.0.0.0" \ 49 | PORT="3000" \ 50 | SESSION_DRIVER="cookie" 51 | CMD [ "node", "/app/build/server.js" ] 52 | -------------------------------------------------------------------------------- /test/base/envargs/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | # Base arguments 8 | ARG A1=xxx 9 | 10 | LABEL fly_launch_runtime="Node.js" 11 | 12 | # Node.js app lives here 13 | WORKDIR /app 14 | 15 | # Set production environment 16 | ENV E1="V1" \ 17 | NODE_ENV="production" 18 | 19 | 20 | # Throw-away build stage to reduce size of final image 21 | FROM base AS build 22 | 23 | # Build arguments 24 | ARG A2=xxx 25 | 26 | ENV E2="V2" 27 | 28 | # Install packages needed to build node modules 29 | RUN apt-get update -qq && \ 30 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 31 | 32 | # Install node modules 33 | COPY package-lock.json package.json ./ 34 | RUN npm ci --include=dev 35 | 36 | # Copy application code 37 | COPY . . 38 | 39 | # Build application 40 | RUN npm run build 41 | 42 | # Remove development dependencies 43 | RUN npm prune --omit=dev 44 | 45 | 46 | # Final stage for app image 47 | FROM base 48 | 49 | # Copy built application 50 | COPY --from=build /app /app 51 | 52 | # Deploy arguments 53 | ARG A3=xxx 54 | 55 | # Start the server by default, this can be overwritten at runtime 56 | EXPOSE 3000 57 | ENV E3="V3" 58 | CMD [ "npm", "run", "start" ] 59 | -------------------------------------------------------------------------------- /test/frameworks/svelte-prisma/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sveltekit", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vite dev", 7 | "build": "vite build", 8 | "preview": "vite preview", 9 | "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", 10 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" 11 | }, 12 | "devDependencies": { 13 | "@flydotio/dockerfile": "github:fly-apps/dockerfile-node", 14 | "@sveltejs/adapter-auto": "3.3.1", 15 | "@sveltejs/kit": "2.11.1", 16 | "@sveltejs/package": "2.3.7", 17 | "@typescript-eslint/eslint-plugin": "8.18.1", 18 | "@typescript-eslint/parser": "8.18.1", 19 | "eslint": "8.57.1", 20 | "eslint-config-prettier": "9.1.0", 21 | "eslint-plugin-svelte": "2.46.1", 22 | "prettier": "3.4.2", 23 | "prettier-plugin-svelte": "3.3.2", 24 | "prisma": "5.22.0", 25 | "svelte": "5.15.0", 26 | "svelte-check": "4.1.1", 27 | "svelte-preprocess": "6.0.3", 28 | "tslib": "2.8.1", 29 | "tsx": "4.19.2", 30 | "typescript": "5.7.2", 31 | "vite": "6.0.5" 32 | }, 33 | "type": "module", 34 | "dependencies": { 35 | "@prisma/client": "5.22.0", 36 | "@sveltejs/adapter-node": "^5.2.11" 37 | }, 38 | "prisma": { 39 | "seed": "tsx prisma/seed.ts" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/base/cache-bun/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust BUN_VERSION as desired 4 | ARG BUN_VERSION=xxx 5 | FROM oven/bun:${BUN_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Bun" 8 | 9 | # Bun app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN --mount=type=cache,id=cache,target=/var/cache/apt \ 21 | --mount=type=cache,id=lib,target=/var/lib/apt \ 22 | apt-get update -qq && \ 23 | apt-get install --no-install-recommends -y build-essential pkg-config python-is-python3 24 | 25 | # Install node modules 26 | COPY bun.lockb package.json ./ 27 | RUN --mount=type=cache,id=bun,target=/root/.bun \ 28 | bun install 29 | 30 | # Copy application code 31 | COPY . . 32 | 33 | # Build application 34 | RUN bun run build 35 | 36 | # Remove development dependencies 37 | RUN --mount=type=cache,id=bun,target=/root/.bun \ 38 | rm -rf node_modules && \ 39 | bun install --ci 40 | 41 | 42 | # Final stage for app image 43 | FROM base 44 | 45 | # Copy built application 46 | COPY --from=build /app /app 47 | 48 | # Start the server by default, this can be overwritten at runtime 49 | EXPOSE 3000 50 | CMD [ "bun", "run", "start" ] 51 | -------------------------------------------------------------------------------- /test/base/cache-npm/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN --mount=type=cache,id=cache,target=/var/cache/apt \ 21 | --mount=type=cache,id=lib,target=/var/lib/apt \ 22 | apt-get update -qq && \ 23 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 24 | 25 | # Install node modules 26 | COPY package-lock.json package.json ./ 27 | RUN --mount=type=cache,id=npm,target=/app/.npm \ 28 | npm ci --include=dev 29 | 30 | # Copy application code 31 | COPY . . 32 | 33 | # Build application 34 | RUN npm run build 35 | 36 | # Remove development dependencies 37 | RUN --mount=type=cache,id=npm,target=/app/.npm \ 38 | npm prune --omit=dev 39 | 40 | 41 | # Final stage for app image 42 | FROM base 43 | 44 | # Copy built application 45 | COPY --from=build /app /app 46 | 47 | # Start the server by default, this can be overwritten at runtime 48 | EXPOSE 3000 49 | CMD [ "npm", "run", "start" ] 50 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@flydotio/dockerfile", 3 | "version": "0.7.10", 4 | "description": "Dockerfile generator", 5 | "main": "./index.js", 6 | "bin": { 7 | "dockerfile": "index.js" 8 | }, 9 | "type": "module", 10 | "scripts": { 11 | "eslint": "eslint .", 12 | "eslint:fix": "eslint --fix .", 13 | "test": "mocha --spec test/test.js --timeout 5000", 14 | "test:capture": "TEST_CAPTURE=1 mocha" 15 | }, 16 | "author": "Sam Ruby", 17 | "license": "MIT", 18 | "engines": { 19 | "node": ">=16.0.0" 20 | }, 21 | "dependencies": { 22 | "chalk": "^5.4.1", 23 | "diff": "^7.0.0", 24 | "ejs": "^3.1.10", 25 | "inquirer": "^12.4.1", 26 | "shell-quote": "^1.8.2", 27 | "yargs": "^17.7.2" 28 | }, 29 | "repository": { 30 | "type": "git", 31 | "url": "git+https://github.com/fly-apps/dockerfile-node.git" 32 | }, 33 | "publishConfig": { 34 | "access": "public" 35 | }, 36 | "devDependencies": { 37 | "chai": "^5.1.2", 38 | "eslint": "^8.57.1", 39 | "eslint-config-standard": "^17.1.0", 40 | "eslint-plugin-import": "^2.31.0", 41 | "eslint-plugin-promise": "^6.6.0", 42 | "mocha": "^11.1.0" 43 | }, 44 | "files": [ 45 | "index.js", 46 | "gdf.js", 47 | "fly.js", 48 | "templates" 49 | ], 50 | "packageManager": "pnpm@8.3.1+sha1.75c6e8a4075abfc494770f998bf37b9ada110f51" 51 | } 52 | -------------------------------------------------------------------------------- /test/frameworks/remix-blues/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Remix/Prisma" 8 | 9 | # Remix/Prisma app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp openssl pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci --include=dev 26 | 27 | # Generate Prisma Client 28 | COPY prisma . 29 | RUN npx prisma generate 30 | 31 | # Copy application code 32 | COPY . . 33 | 34 | # Build application 35 | RUN npm run build 36 | 37 | 38 | # Final stage for app image 39 | FROM base 40 | 41 | # Install packages needed for deployment 42 | RUN apt-get update -qq && \ 43 | apt-get install --no-install-recommends -y openssl && \ 44 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 45 | 46 | # Copy built application 47 | COPY --from=build /app /app 48 | 49 | # Start the server by default, this can be overwritten at runtime 50 | EXPOSE 3000 51 | CMD [ "npm", "run", "start" ] 52 | -------------------------------------------------------------------------------- /test/base/litestream-url/docker-entrypoint.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { spawn } from 'node:child_process' 4 | import fs from 'node:fs' 5 | 6 | const env = { ...process.env } 7 | 8 | // If running the web server then migrate existing database 9 | if (process.argv.slice(-3).join(' ') === 'npm run start') { 10 | const url = new URL(process.env.DATABASE_URL) 11 | const target = url.protocol === 'file:' && url.pathname 12 | 13 | // restore database if not present and replica exists 14 | const newDb = target && !fs.existsSync(target) 15 | if (newDb && process.env.BUCKET_NAME) { 16 | await exec(`litestream restore -config litestream.yml -if-replica-exists ${target}`) 17 | } 18 | 19 | // prepare database 20 | await exec('npx prisma migrate deploy') 21 | } 22 | 23 | // launch application 24 | if (process.env.BUCKET_NAME) { 25 | await exec(`litestream replicate -config litestream.yml -exec ${JSON.stringify(process.argv.slice(2).join(' '))}`) 26 | } else { 27 | await exec(process.argv.slice(2).join(' ')) 28 | } 29 | 30 | function exec(command) { 31 | const child = spawn(command, { shell: true, stdio: 'inherit', env }) 32 | return new Promise((resolve, reject) => { 33 | child.on('exit', code => { 34 | if (code === 0) { 35 | resolve() 36 | } else { 37 | reject(new Error(`${command} failed rc=${code}`)) 38 | } 39 | }) 40 | }) 41 | } 42 | -------------------------------------------------------------------------------- /test/frameworks/next-standalone/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Next.js" 8 | 9 | # Next.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci --include=dev 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | # Build application 31 | RUN npx next build --experimental-build-mode compile 32 | 33 | # Remove development dependencies 34 | RUN npm prune --omit=dev 35 | 36 | 37 | # Final stage for app image 38 | FROM base 39 | 40 | # Copy built application 41 | COPY --from=build /app/.next/standalone /app 42 | COPY --from=build /app/.next/static /app/.next/static 43 | COPY --from=build /app/public /app/public 44 | 45 | # Entrypoint sets up the container. 46 | ENTRYPOINT [ "/app/docker-entrypoint.js" ] 47 | 48 | # Start the server by default, this can be overwritten at runtime 49 | EXPOSE 3000 50 | CMD [ "node", "server.js" ] 51 | -------------------------------------------------------------------------------- /test/base/defer-build/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Next.js/Prisma" 8 | 9 | # Next.js/Prisma app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp openssl pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | COPY prisma . 26 | RUN npm ci 27 | 28 | # Generate Prisma Client 29 | RUN npx prisma generate 30 | 31 | # Copy application code 32 | COPY . . 33 | 34 | 35 | # Final stage for app image 36 | FROM base 37 | 38 | # Install packages needed for deployment 39 | RUN apt-get update -qq && \ 40 | apt-get install --no-install-recommends -y openssl && \ 41 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 42 | 43 | # Copy built application 44 | COPY --from=build /app /app 45 | 46 | # Setup sqlite3 on a separate volume 47 | RUN mkdir -p /data 48 | VOLUME /data 49 | 50 | # Entrypoint prepares the database. 51 | ENTRYPOINT [ "/app/docker-entrypoint.js" ] 52 | 53 | # Start the server by default, this can be overwritten at runtime 54 | EXPOSE 3000 55 | CMD [ "npm", "run", "start" ] 56 | -------------------------------------------------------------------------------- /test/base/cache-yarn/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | ARG YARN_VERSION=xxx 15 | RUN npm install -g yarn@$YARN_VERSION --force 16 | 17 | 18 | # Throw-away build stage to reduce size of final image 19 | FROM base AS build 20 | 21 | # Install packages needed to build node modules 22 | RUN --mount=type=cache,id=cache,target=/var/cache/apt \ 23 | --mount=type=cache,id=lib,target=/var/lib/apt \ 24 | apt-get update -qq && \ 25 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 26 | 27 | # Install node modules 28 | COPY package.json yarn.lock ./ 29 | RUN --mount=type=cache,id=yarn,target=/usr/local/share/.cache/yarn/ \ 30 | yarn install --frozen-lockfile --production=false 31 | 32 | # Copy application code 33 | COPY . . 34 | 35 | # Build application 36 | RUN yarn run build 37 | 38 | # Remove development dependencies 39 | RUN --mount=type=cache,id=yarn,target=/usr/local/share/.cache/yarn/ \ 40 | yarn install --production=true 41 | 42 | 43 | # Final stage for app image 44 | FROM base 45 | 46 | # Copy built application 47 | COPY --from=build /app /app 48 | 49 | # Start the server by default, this can be overwritten at runtime 50 | EXPOSE 3000 51 | CMD [ "yarn", "run", "start" ] 52 | -------------------------------------------------------------------------------- /test/base/cache-pnpm/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | # Install pnpm 16 | ARG PNPM_VERSION=xxx 17 | RUN npm install -g pnpm@$PNPM_VERSION 18 | 19 | 20 | # Throw-away build stage to reduce size of final image 21 | FROM base AS build 22 | 23 | ENV PNPM_HOME="/pnpm" 24 | ENV PATH="$PNPM_HOME:$PATH" 25 | 26 | # Install packages needed to build node modules 27 | RUN --mount=type=cache,id=cache,target=/var/cache/apt \ 28 | --mount=type=cache,id=lib,target=/var/lib/apt \ 29 | apt-get update -qq && \ 30 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 31 | 32 | # Install node modules 33 | COPY package.json pnpm-lock.yaml ./ 34 | RUN --mount=type=cache,id=pnpm,target=/pnpm/store \ 35 | pnpm install --frozen-lockfile --prod=false 36 | 37 | # Copy application code 38 | COPY . . 39 | 40 | # Build application 41 | RUN pnpm run build 42 | 43 | # Remove development dependencies 44 | RUN --mount=type=cache,id=pnpm,target=/pnpm/store \ 45 | pnpm prune --prod 46 | 47 | 48 | # Final stage for app image 49 | FROM base 50 | 51 | # Copy built application 52 | COPY --from=build /app /app 53 | 54 | # Start the server by default, this can be overwritten at runtime 55 | EXPOSE 3000 56 | CMD [ "pnpm", "run", "start" ] 57 | -------------------------------------------------------------------------------- /test/base/litefs/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | 31 | # Final stage for app image 32 | FROM base 33 | 34 | # Install, configure litefs 35 | COPY --from=flyio/litefs:0.4.0 /usr/local/bin/litefs /usr/local/bin/litefs 36 | COPY --link litefs.yml /etc/litefs.yml 37 | 38 | # Install packages needed for deployment 39 | RUN apt-get update -qq && \ 40 | apt-get install --no-install-recommends -y ca-certificates fuse3 && \ 41 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 42 | 43 | # Copy built application 44 | COPY --from=build /app /app 45 | 46 | # Setup sqlite3 on a separate volume 47 | RUN mkdir -p /data /litefs 48 | VOLUME /data 49 | 50 | # Start the server by default, this can be overwritten at runtime 51 | EXPOSE 3000 52 | ENV DATABASE_URL="file:///litefs/sqlite.db" \ 53 | PORT=3001 54 | CMD [ "npm", "run", "start" ] 55 | -------------------------------------------------------------------------------- /test/base/litestream/docker-entrypoint.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { spawn } = require('node:child_process') 4 | const path = require('node:path') 5 | const fs = require('node:fs') 6 | 7 | const env = { ...process.env } 8 | 9 | ;(async() => { 10 | // If running the web server then migrate existing database 11 | if (process.argv.slice(-3).join(' ') === 'npm run start') { 12 | // place Sqlite3 database on volume 13 | const source = path.resolve('./dev.db') 14 | const target = '/data/' + path.basename(source) 15 | if (!fs.existsSync(source) && fs.existsSync('/data')) fs.symlinkSync(target, source) 16 | const newDb = !fs.existsSync(target) 17 | if (newDb && process.env.BUCKET_NAME) { 18 | await exec(`litestream restore -config litestream.yml -if-replica-exists ${target}`) 19 | } 20 | 21 | // prepare database 22 | await exec('npx prisma migrate deploy') 23 | } 24 | 25 | // launch application 26 | if (process.env.BUCKET_NAME) { 27 | await exec(`litestream replicate -config litestream.yml -exec ${JSON.stringify(process.argv.slice(2).join(' '))}`) 28 | } else { 29 | await exec(process.argv.slice(2).join(' ')) 30 | } 31 | })() 32 | 33 | function exec(command) { 34 | const child = spawn(command, { shell: true, stdio: 'inherit', env }) 35 | return new Promise((resolve, reject) => { 36 | child.on('exit', code => { 37 | if (code === 0) { 38 | resolve() 39 | } else { 40 | reject(new Error(`${command} failed rc=${code}`)) 41 | } 42 | }) 43 | }) 44 | } 45 | -------------------------------------------------------------------------------- /test/base/packages/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Install packages needed for both build and deployment 10 | RUN apt-get update -qq && \ 11 | apt-get install --no-install-recommends -y procps && \ 12 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 13 | 14 | # Node.js app lives here 15 | WORKDIR /app 16 | 17 | # Set production environment 18 | ENV NODE_ENV="production" 19 | 20 | 21 | # Throw-away build stage to reduce size of final image 22 | FROM base AS build 23 | 24 | # Install packages needed to build node modules 25 | RUN apt-get update -qq && \ 26 | apt-get install --no-install-recommends -y build-essential libicu-dev node-gyp pkg-config python-is-python3 27 | 28 | # Install node modules 29 | COPY package-lock.json package.json ./ 30 | RUN npm ci --include=dev 31 | 32 | # Copy application code 33 | COPY . . 34 | 35 | # Build application 36 | RUN npm run build 37 | 38 | # Remove development dependencies 39 | RUN npm prune --omit=dev 40 | 41 | 42 | # Final stage for app image 43 | FROM base 44 | 45 | # Install packages needed for deployment 46 | RUN apt-get update -qq && \ 47 | apt-get install --no-install-recommends -y vim && \ 48 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 49 | 50 | # Copy built application 51 | COPY --from=build /app /app 52 | 53 | # Start the server by default, this can be overwritten at runtime 54 | EXPOSE 3000 55 | CMD [ "npm", "run", "start" ] 56 | -------------------------------------------------------------------------------- /test/frameworks/svelte-prisma/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="SvelteKit/Prisma" 8 | 9 | # SvelteKit/Prisma app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential git node-gyp openssl pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci --include=dev 26 | 27 | # Generate Prisma Client 28 | COPY prisma . 29 | RUN npx prisma generate 30 | 31 | # Copy application code 32 | COPY . . 33 | 34 | # Build application 35 | RUN npm run build 36 | 37 | 38 | # Final stage for app image 39 | FROM base 40 | 41 | # Install packages needed for deployment 42 | RUN apt-get update -qq && \ 43 | apt-get install --no-install-recommends -y openssl && \ 44 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 45 | 46 | # Copy built application 47 | COPY --from=build /app /app 48 | 49 | # Setup sqlite3 on a separate volume 50 | RUN mkdir -p /data 51 | VOLUME /data 52 | 53 | # Entrypoint prepares the database. 54 | ENTRYPOINT [ "/app/docker-entrypoint.js" ] 55 | 56 | # Start the server by default, this can be overwritten at runtime 57 | EXPOSE 3000 58 | CMD [ "node", "./build/index.js" ] 59 | -------------------------------------------------------------------------------- /test/frameworks/svelte-prisma/prisma/seed.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient, Prisma } from '@prisma/client' 2 | 3 | const prisma = new PrismaClient() 4 | 5 | const userData: Prisma.UserCreateInput[] = [ 6 | { 7 | name: 'Alice', 8 | email: 'alice@prisma.io', 9 | posts: { 10 | create: [ 11 | { 12 | title: 'Join the Prisma Discord', 13 | content: 'https://pris.ly/discord', 14 | published: true, 15 | }, 16 | ], 17 | }, 18 | }, 19 | { 20 | name: 'Nilu', 21 | email: 'nilu@prisma.io', 22 | posts: { 23 | create: [ 24 | { 25 | title: 'Follow Prisma on Twitter', 26 | content: 'https://www.twitter.com/prisma', 27 | published: true, 28 | }, 29 | ], 30 | }, 31 | }, 32 | { 33 | name: 'Mahmoud', 34 | email: 'mahmoud@prisma.io', 35 | posts: { 36 | create: [ 37 | { 38 | title: 'Ask a question about Prisma on GitHub', 39 | content: 'https://www.github.com/prisma/prisma/discussions', 40 | published: true, 41 | }, 42 | { 43 | title: 'Prisma on YouTube', 44 | content: 'https://pris.ly/youtube', 45 | }, 46 | ], 47 | }, 48 | }, 49 | ] 50 | 51 | async function main() { 52 | for (const u of userData) { 53 | const user = await prisma.user.create({ 54 | data: u, 55 | }) 56 | } 57 | } 58 | 59 | main() 60 | .then(async () => { 61 | await prisma.$disconnect() 62 | }) 63 | .catch(async (e) => { 64 | console.error(e) 65 | await prisma.$disconnect() 66 | process.exit(1) 67 | }) 68 | -------------------------------------------------------------------------------- /test/frameworks/next-trpc/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Next.js/Prisma" 8 | 9 | # Next.js/Prisma app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp openssl pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | COPY prisma . 26 | RUN npm ci --include=dev 27 | 28 | # Generate Prisma Client 29 | RUN npx prisma generate 30 | 31 | # Copy application code 32 | COPY . . 33 | 34 | # Build application 35 | RUN npx next build --experimental-build-mode compile 36 | 37 | 38 | # Final stage for app image 39 | FROM base 40 | 41 | # Install packages needed for deployment 42 | RUN apt-get update -qq && \ 43 | apt-get install --no-install-recommends -y openssl && \ 44 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 45 | 46 | # Copy built application 47 | COPY --from=build /app /app 48 | 49 | # Setup sqlite3 on a separate volume 50 | RUN mkdir -p /data 51 | VOLUME /data 52 | 53 | # Entrypoint prepares the database. 54 | ENTRYPOINT [ "/app/docker-entrypoint.js" ] 55 | 56 | # Start the server by default, this can be overwritten at runtime 57 | EXPOSE 3000 58 | ENV DATABASE_URL="file:///data/sqlite.db" 59 | CMD [ "npm", "run", "start" ] 60 | -------------------------------------------------------------------------------- /test/frameworks/meteor/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Meteor" 8 | 9 | # Meteor app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential curl g++ make node-gyp pkg-config python-is-python3 python3-pip 22 | 23 | # Copy the .meteor/release file to the container 24 | COPY .meteor/release /home/meteor/.meteor/release 25 | 26 | ENV METEOR_ALLOW_SUPERUSER=1 27 | 28 | # Extract the Meteor release version and install Meteor 29 | RUN RELEASE=$(awk -F'@' '{print $2}' /home/meteor/.meteor/release) && curl https://install.meteor.com/\?release\=$RELEASE | sh 30 | # Install node modules 31 | COPY package-lock.json package.json ./ 32 | RUN npm ci 33 | 34 | RUN meteor npm install 35 | # Copy application code 36 | COPY . . 37 | RUN meteor build --server-only --directory bundle 38 | 39 | # https://github.com/meteor/meteor/issues/12932 40 | RUN chmod 777 bundle/bundle/programs/server/npm-shrinkwrap.json 41 | 42 | RUN cd bundle/bundle/programs/server && meteor npm install 43 | 44 | 45 | # Final stage for app image 46 | FROM base 47 | 48 | # Copy built application 49 | COPY --from=build /app/bundle/bundle /app 50 | 51 | # Start the server by default, this can be overwritten at runtime 52 | EXPOSE 3000 53 | CMD [ "node", "main.js" ] 54 | -------------------------------------------------------------------------------- /test/frameworks/nuxt-prisma/docker-entrypoint.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { spawn } = require('node:child_process') 4 | const path = require('node:path') 5 | const fs = require('node:fs') 6 | 7 | const env = { ...process.env } 8 | 9 | ;(async() => { 10 | // If running the web server then migrate existing database 11 | if (process.argv.slice(-2).join(' ') === 'node .output/server/index.mjs') { 12 | // place Sqlite3 database on volume 13 | let source = path.resolve('./dev.db') 14 | const target = '/data/' + path.basename(source) 15 | source = path.resolve('./.output/server', './dev.db') 16 | if (!fs.existsSync(source) && fs.existsSync('/data')) fs.symlinkSync(target, source) 17 | let newDb = !fs.existsSync(target) 18 | if (newDb && process.env.BUCKET_NAME) { 19 | await exec(`litestream restore -config litestream.yml -if-replica-exists ${target}`) 20 | newDb = !fs.existsSync(target) 21 | } 22 | 23 | // prepare database 24 | await exec('npx prisma migrate deploy') 25 | if (newDb) await exec('node prisma/seed.js') 26 | } 27 | 28 | // launch application 29 | if (process.env.BUCKET_NAME) { 30 | await exec(`litestream replicate -config litestream.yml -exec ${JSON.stringify(process.argv.slice(2).join(' '))}`) 31 | } else { 32 | await exec(process.argv.slice(2).join(' ')) 33 | } 34 | })() 35 | 36 | function exec(command) { 37 | const child = spawn(command, { shell: true, stdio: 'inherit', env }) 38 | return new Promise((resolve, reject) => { 39 | child.on('exit', code => { 40 | if (code === 0) { 41 | resolve() 42 | } else { 43 | reject(new Error(`${command} failed rc=${code}`)) 44 | } 45 | }) 46 | }) 47 | } 48 | -------------------------------------------------------------------------------- /test/base/litestream/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js/Prisma" 8 | 9 | # Node.js/Prisma app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp openssl pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci 26 | 27 | # Generate Prisma Client 28 | COPY prisma . 29 | RUN npx prisma generate 30 | 31 | # Copy application code 32 | COPY . . 33 | 34 | 35 | # Final stage for app image 36 | FROM base 37 | 38 | # Install packages needed for deployment 39 | RUN apt-get update -qq && \ 40 | apt-get install --no-install-recommends -y ca-certificates openssl wget && \ 41 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 42 | 43 | # Install litestream 44 | RUN wget https://github.com/benbjohnson/litestream/releases/download/v0.3.13/litestream-v0.3.13-linux-amd64.deb && \ 45 | dpkg -i litestream-v0.3.13-linux-amd64.deb && \ 46 | rm litestream-v0.3.13-linux-amd64.deb 47 | 48 | # Copy built application 49 | COPY --from=build /app /app 50 | 51 | # Setup sqlite3 on a separate volume 52 | RUN mkdir -p /data 53 | VOLUME /data 54 | 55 | # Entrypoint prepares the database. 56 | ENTRYPOINT [ "/app/docker-entrypoint.js" ] 57 | 58 | # Start the server by default, this can be overwritten at runtime 59 | EXPOSE 3000 60 | CMD [ "npm", "run", "start" ] 61 | -------------------------------------------------------------------------------- /test/frameworks/nuxt-prisma/prisma/seed.js: -------------------------------------------------------------------------------- 1 | const { PrismaClient } = require('@prisma/client') 2 | 3 | const prisma = new PrismaClient() 4 | 5 | const userData = [ 6 | { 7 | name: 'Alice', 8 | email: 'alice@prisma.io', 9 | posts: { 10 | create: [ 11 | { 12 | title: 'Join the Prisma Discord', 13 | content: 'https://pris.ly/discord', 14 | published: true 15 | } 16 | ] 17 | } 18 | }, 19 | { 20 | name: 'Nilu', 21 | email: 'nilu@prisma.io', 22 | posts: { 23 | create: [ 24 | { 25 | title: 'Follow Prisma on Twitter', 26 | content: 'https://www.twitter.com/prisma', 27 | published: true, 28 | viewCount: 42 29 | } 30 | ] 31 | } 32 | }, 33 | { 34 | name: 'Mahmoud', 35 | email: 'mahmoud@prisma.io', 36 | posts: { 37 | create: [ 38 | { 39 | title: 'Ask a question about Prisma on GitHub', 40 | content: 'https://www.github.com/prisma/prisma/discussions', 41 | published: true, 42 | viewCount: 128 43 | }, 44 | { 45 | title: 'Prisma on YouTube', 46 | content: 'https://pris.ly/youtube' 47 | } 48 | ] 49 | } 50 | } 51 | ] 52 | 53 | async function main() { 54 | console.log('Start seeding ...') 55 | for (const u of userData) { 56 | const user = await prisma.user.create({ 57 | data: u 58 | }) 59 | console.log(`Created user with id: ${user.id}`) 60 | } 61 | console.log('Seeding finished.') 62 | } 63 | 64 | main() 65 | .then(async() => { 66 | await prisma.$disconnect() 67 | }) 68 | .catch(async(e) => { 69 | console.error(e) 70 | await prisma.$disconnect() 71 | process.exit(1) 72 | }) 73 | -------------------------------------------------------------------------------- /test/base/litestream-url/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js/Prisma" 8 | 9 | # Node.js/Prisma app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp openssl pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci 26 | 27 | # Generate Prisma Client 28 | COPY prisma . 29 | RUN npx prisma generate 30 | 31 | # Copy application code 32 | COPY . . 33 | 34 | 35 | # Final stage for app image 36 | FROM base 37 | 38 | # Install packages needed for deployment 39 | RUN apt-get update -qq && \ 40 | apt-get install --no-install-recommends -y ca-certificates openssl wget && \ 41 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 42 | 43 | # Install litestream 44 | RUN wget https://github.com/benbjohnson/litestream/releases/download/v0.3.13/litestream-v0.3.13-linux-amd64.deb && \ 45 | dpkg -i litestream-v0.3.13-linux-amd64.deb && \ 46 | rm litestream-v0.3.13-linux-amd64.deb 47 | 48 | # Copy built application 49 | COPY --from=build /app /app 50 | 51 | # Setup sqlite3 on a separate volume 52 | RUN mkdir -p /data 53 | VOLUME /data 54 | 55 | # Entrypoint prepares the database. 56 | ENTRYPOINT [ "/app/docker-entrypoint.js" ] 57 | 58 | # Start the server by default, this can be overwritten at runtime 59 | EXPOSE 3000 60 | ENV DATABASE_URL="file:///data/sqlite.db" 61 | CMD [ "npm", "run", "start" ] 62 | -------------------------------------------------------------------------------- /test/frameworks/remix-indie/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Remix/Prisma" 8 | 9 | # Remix/Prisma app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp openssl pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci --include=dev 26 | 27 | # Generate Prisma Client 28 | COPY prisma . 29 | RUN npx prisma generate 30 | 31 | # Copy application code 32 | COPY . . 33 | 34 | # Build application 35 | RUN npm run build 36 | 37 | 38 | # Final stage for app image 39 | FROM base 40 | 41 | # Install packages needed for deployment 42 | RUN apt-get update -qq && \ 43 | apt-get install --no-install-recommends -y openssl sqlite3 && \ 44 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 45 | 46 | # Copy built application 47 | COPY --from=build /app /app 48 | 49 | # Setup sqlite3 on a separate volume 50 | RUN mkdir -p /data 51 | VOLUME /data 52 | 53 | # add shortcut for connecting to database CLI 54 | RUN echo "#!/bin/sh\nset -x\nsqlite3 \$DATABASE_URL" > /usr/local/bin/database-cli && chmod +x /usr/local/bin/database-cli 55 | 56 | # Entrypoint prepares the database. 57 | ENTRYPOINT [ "/app/docker-entrypoint.js" ] 58 | 59 | # Start the server by default, this can be overwritten at runtime 60 | EXPOSE 3000 61 | ENV DATABASE_URL="file:///data/sqlite.db" 62 | CMD [ "npx", "remix-serve", "./build/index.js" ] 63 | -------------------------------------------------------------------------------- /test/frameworks/nuxt-prisma/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Nuxt/Prisma" 8 | 9 | # Nuxt/Prisma app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential git node-gyp openssl pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci --include=dev 26 | 27 | # Generate Prisma Client 28 | COPY prisma . 29 | RUN npx prisma generate 30 | 31 | # Copy application code 32 | COPY . . 33 | 34 | # Build application 35 | RUN npm run build 36 | 37 | 38 | # Final stage for app image 39 | FROM base 40 | 41 | # Install packages needed for deployment 42 | RUN apt-get update -qq && \ 43 | apt-get install --no-install-recommends -y ca-certificates openssl wget && \ 44 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 45 | 46 | # Install litestream 47 | RUN wget https://github.com/benbjohnson/litestream/releases/download/v0.3.13/litestream-v0.3.13-linux-amd64.deb && \ 48 | dpkg -i litestream-v0.3.13-linux-amd64.deb && \ 49 | rm litestream-v0.3.13-linux-amd64.deb 50 | 51 | # Copy built application 52 | COPY --from=build /app/.output /app/.output 53 | 54 | # Setup sqlite3 on a separate volume 55 | RUN mkdir -p /data 56 | VOLUME /data 57 | 58 | # Entrypoint prepares the database. 59 | ENTRYPOINT [ "/app/docker-entrypoint.js" ] 60 | 61 | # Start the server by default, this can be overwritten at runtime 62 | EXPOSE 3000 63 | ENV HOST=0 64 | CMD [ "node", ".output/server/index.mjs" ] 65 | -------------------------------------------------------------------------------- /test/frameworks/adonisjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "polls-designed-app", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "build": "echo mocked", 7 | "start": "node build/server.js", 8 | "gcp-build": "npm run build", 9 | "dev": "node ace serve --watch", 10 | "lint": "eslint . --ext=.ts", 11 | "format": "prettier --write ." 12 | }, 13 | "devDependencies": { 14 | "@adonisjs/assembler": "^5.9.5", 15 | "@alpinejs/focus": "^3.12.3", 16 | "@babel/core": "^7.22.10", 17 | "@babel/preset-env": "^7.22.10", 18 | "@symfony/webpack-encore": "^4.4.0", 19 | "adonis-preset-ts": "^2.1.0", 20 | "alpine-teleport": "^1.0.1", 21 | "alpinejs": "^3.12.3", 22 | "autoprefixer": "^10.4.15", 23 | "eslint": "^8.47.0", 24 | "eslint-config-prettier": "^8.10.0", 25 | "eslint-plugin-adonis": "^2.1.1", 26 | "eslint-plugin-prettier": "^4.2.1", 27 | "pino-pretty": "^9.4.1", 28 | "postcss-loader": "^7.3.3", 29 | "prettier": "^2.8.8", 30 | "tailwindcss": "^3.3.3", 31 | "typescript": "^4.9.5", 32 | "unpoly": "^2.7.2", 33 | "webpack": "^5.88.2", 34 | "webpack-cli": "^5.1.4", 35 | "youch": "^3.2.3", 36 | "youch-terminal": "^2.2.2" 37 | }, 38 | "dependencies": { 39 | "@adonisjs/attachment-lite": "^1.0.7", 40 | "@adonisjs/auth": "^8.2.3", 41 | "@adonisjs/core": "^5.9.0", 42 | "@adonisjs/drive-s3": "^1.3.2", 43 | "@adonisjs/lucid": "^18.4.0", 44 | "@adonisjs/lucid-slugify": "^2.2.1", 45 | "@adonisjs/repl": "^3.1.11", 46 | "@adonisjs/session": "^6.4.0", 47 | "@adonisjs/shield": "^7.1.1", 48 | "@adonisjs/view": "^6.2.0", 49 | "luxon": "^3.4.0", 50 | "mime-types": "^2.1.35", 51 | "pg": "^8.11.3", 52 | "phc-argon2": "^1.1.4", 53 | "proxy-addr": "^2.0.7", 54 | "reflect-metadata": "^0.1.13", 55 | "s3-sync-client": "^3.0.3", 56 | "source-map-support": "^0.5.21" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /test/base/windows/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Remix/Prisma" 8 | 9 | # Remix/Prisma app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp openssl pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci --include=dev 26 | 27 | # Generate Prisma Client 28 | COPY prisma . 29 | RUN npx prisma generate 30 | 31 | # Copy application code 32 | COPY . . 33 | 34 | # Build application 35 | RUN npm run build 36 | 37 | 38 | # Final stage for app image 39 | FROM base 40 | 41 | # Install packages needed for deployment 42 | RUN apt-get update -qq && \ 43 | apt-get install --no-install-recommends -y openssl sqlite3 && \ 44 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 45 | 46 | # Copy built application 47 | COPY --from=build /app /app 48 | 49 | # Setup sqlite3 on a separate volume 50 | RUN mkdir -p /data 51 | VOLUME /data 52 | 53 | # add shortcut for connecting to database CLI 54 | RUN echo "#!/bin/sh\nset -x\nsqlite3 \$DATABASE_URL" > /usr/local/bin/database-cli && chmod +x /usr/local/bin/database-cli 55 | 56 | # Adjust entrypoint to be executable on Linux 57 | RUN chmod +x ./docker-entrypoint.js && \ 58 | sed -i "s/\r$//g" ./docker-entrypoint.js 59 | 60 | # Entrypoint prepares the database. 61 | ENTRYPOINT [ "/app/docker-entrypoint.js" ] 62 | 63 | # Start the server by default, this can be overwritten at runtime 64 | EXPOSE 3000 65 | ENV DATABASE_URL="file:///data/sqlite.db" 66 | CMD [ "npx", "remix-serve", "./build/index.js" ] 67 | -------------------------------------------------------------------------------- /test/frameworks/svelte-bun/node_modules/.bin/vite: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { performance } from 'node:perf_hooks' 3 | 4 | if (!import.meta.url.includes('node_modules')) { 5 | try { 6 | // only available as dev dependency 7 | await import('source-map-support').then((r) => r.default.install()) 8 | } catch (e) {} 9 | } 10 | 11 | global.__vite_start_time = performance.now() 12 | 13 | // check debug mode first before requiring the CLI. 14 | const debugIndex = process.argv.findIndex((arg) => /^(?:-d|--debug)$/.test(arg)) 15 | const filterIndex = process.argv.findIndex((arg) => 16 | /^(?:-f|--filter)$/.test(arg), 17 | ) 18 | const profileIndex = process.argv.indexOf('--profile') 19 | 20 | if (debugIndex > 0) { 21 | let value = process.argv[debugIndex + 1] 22 | if (!value || value.startsWith('-')) { 23 | value = 'vite:*' 24 | } else { 25 | // support debugging multiple flags with comma-separated list 26 | value = value 27 | .split(',') 28 | .map((v) => `vite:${v}`) 29 | .join(',') 30 | } 31 | process.env.DEBUG = `${ 32 | process.env.DEBUG ? process.env.DEBUG + ',' : '' 33 | }${value}` 34 | 35 | if (filterIndex > 0) { 36 | const filter = process.argv[filterIndex + 1] 37 | if (filter && !filter.startsWith('-')) { 38 | process.env.VITE_DEBUG_FILTER = filter 39 | } 40 | } 41 | } 42 | 43 | function start() { 44 | return import('../dist/node/cli.js') 45 | } 46 | 47 | if (profileIndex > 0) { 48 | process.argv.splice(profileIndex, 1) 49 | const next = process.argv[profileIndex] 50 | if (next && !next.startsWith('-')) { 51 | process.argv.splice(profileIndex, 1) 52 | } 53 | const inspector = await import('node:inspector').then((r) => r.default) 54 | const session = (global.__vite_profile_session = new inspector.Session()) 55 | session.connect() 56 | session.post('Profiler.enable', () => { 57 | session.post('Profiler.start', start) 58 | }) 59 | } else { 60 | start() 61 | } 62 | -------------------------------------------------------------------------------- /test/base/nginx/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci 26 | 27 | # Copy application code 28 | COPY . . 29 | 30 | 31 | # Final stage for app image 32 | FROM base 33 | 34 | # Install packages needed for deployment 35 | RUN apt-get update -qq && \ 36 | apt-get install --no-install-recommends -y nginx && \ 37 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 38 | 39 | # Copy built application 40 | COPY --from=build /app /app 41 | 42 | # configure nginx 43 | RUN sed -i 's/access_log\s.*;/access_log stdout;/' /etc/nginx/nginx.conf && \ 44 | sed -i 's/error_log\s.*;/error_log stderr info;/' /etc/nginx/nginx.conf 45 | 46 | COPY <<-"EOF" /etc/nginx/sites-available/default 47 | server { 48 | listen 3000 default_server; 49 | listen [::]:3000 default_server; 50 | access_log stdout; 51 | 52 | root /app/public; 53 | 54 | location / { 55 | try_files $uri @backend; 56 | } 57 | 58 | location @backend { 59 | proxy_pass http://localhost:3001; 60 | proxy_set_header Host $http_host; 61 | } 62 | } 63 | EOF 64 | 65 | # Build a Procfile for production use 66 | COPY <<-"EOF" /app/Procfile.prod 67 | nginx: /usr/sbin/nginx -g "daemon off;" 68 | app: PORT=3001 npx foreman start --procfile Procfile.prod 69 | EOF 70 | 71 | # Start the server by default, this can be overwritten at runtime 72 | EXPOSE 3000 73 | CMD [ "npx", "foreman", "start", "--procfile", "Procfile.prod" ] 74 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push, pull_request] 3 | jobs: 4 | # run eslint and compare outputs with expected results 5 | test: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v3 9 | - uses: pnpm/action-setup@v2 10 | with: 11 | version: latest 12 | - uses: actions/setup-node@v4 13 | with: 14 | node-version: 22 15 | cache: "npm" 16 | - uses: oven-sh/setup-bun@v1 17 | with: 18 | bun-version: latest 19 | - uses: superfly/flyctl-actions/setup-flyctl@master 20 | - run: npm ci 21 | - run: npm run eslint 22 | - run: npm test 23 | 24 | # test each framework can actually build 25 | test-frameworks: 26 | runs-on: ubuntu-latest 27 | strategy: 28 | matrix: 29 | framework: 30 | - express 31 | - fastify 32 | - gatsby 33 | - nest 34 | - next-yarn 35 | - nuxt 36 | - remix-indie 37 | - adonisjs 38 | steps: 39 | - uses: actions/checkout@v3 40 | - uses: docker/setup-buildx-action@v2 41 | - run: docker buildx build . --build-arg NODE_VERSION=22 --build-arg YARN_VERSION=1.22.21 42 | working-directory: test/frameworks/${{ matrix.framework }} 43 | 44 | # test yarn4 framework can actually build 45 | test-frameworks-yarn4: 46 | runs-on: ubuntu-latest 47 | strategy: 48 | matrix: 49 | framework: 50 | - next-yarn4 51 | steps: 52 | - uses: actions/checkout@v3 53 | - uses: docker/setup-buildx-action@v2 54 | - run: docker buildx build . --build-arg NODE_VERSION=22 --build-arg YARN_VERSION=4.5.3 55 | working-directory: test/frameworks/${{ matrix.framework }} 56 | 57 | # test alpine can actually build 58 | test-alpine: 59 | runs-on: ubuntu-latest 60 | strategy: 61 | matrix: 62 | base: 63 | - alpine 64 | steps: 65 | - uses: actions/checkout@v3 66 | - uses: docker/setup-buildx-action@v2 67 | - run: docker buildx build . --build-arg NODE_VERSION=22 --build-arg YARN_VERSION=1.22.21 68 | working-directory: test/base/${{ matrix.base }} 69 | -------------------------------------------------------------------------------- /test/frameworks/nest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "project-name", 3 | "version": "0.0.1", 4 | "description": "", 5 | "author": "", 6 | "private": true, 7 | "license": "UNLICENSED", 8 | "scripts": { 9 | "build": "nest build", 10 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", 11 | "start": "nest start", 12 | "start:dev": "nest start --watch", 13 | "start:debug": "nest start --debug --watch", 14 | "start:prod": "node dist/main", 15 | "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", 16 | "test": "jest", 17 | "test:watch": "jest --watch", 18 | "test:cov": "jest --coverage", 19 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", 20 | "test:e2e": "jest --config ./test/jest-e2e.json" 21 | }, 22 | "dependencies": { 23 | "@nestjs/common": "^9.4.3", 24 | "@nestjs/core": "^9.4.3", 25 | "@nestjs/platform-express": "^9.4.3", 26 | "reflect-metadata": "^0.1.13", 27 | "rxjs": "^7.8.1" 28 | }, 29 | "devDependencies": { 30 | "@nestjs/cli": "^9.5.0", 31 | "@nestjs/schematics": "^9.2.0", 32 | "@nestjs/testing": "^9.4.3", 33 | "@types/express": "^4.17.17", 34 | "@types/jest": "^29.5.3", 35 | "@types/node": "^20.5.1", 36 | "@types/supertest": "^2.0.12", 37 | "@typescript-eslint/eslint-plugin": "^5.62.0", 38 | "@typescript-eslint/parser": "^5.62.0", 39 | "eslint": "^8.47.0", 40 | "eslint-config-prettier": "^8.10.0", 41 | "eslint-plugin-prettier": "^4.2.1", 42 | "jest": "^29.6.2", 43 | "prettier": "^2.8.8", 44 | "source-map-support": "^0.5.21", 45 | "supertest": "^6.3.3", 46 | "ts-jest": "^29.1.1", 47 | "ts-loader": "^9.4.4", 48 | "ts-node": "^10.9.1", 49 | "tsconfig-paths": "^4.2.0", 50 | "typescript": "^4.9.5" 51 | }, 52 | "jest": { 53 | "moduleFileExtensions": [ 54 | "js", 55 | "json", 56 | "ts" 57 | ], 58 | "rootDir": "src", 59 | "testRegex": ".*\\.spec\\.ts$", 60 | "transform": { 61 | "^.+\\.(t|j)s$": "ts-jest" 62 | }, 63 | "collectCoverageFrom": [ 64 | "**/*.(t|j)s" 65 | ], 66 | "coverageDirectory": "../coverage", 67 | "testEnvironment": "node" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /test/frameworks/remix-epic/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=xxx 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Remix/Prisma" 8 | 9 | # Remix/Prisma app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | 16 | # Throw-away build stage to reduce size of final image 17 | FROM base AS build 18 | 19 | # Install packages needed to build node modules 20 | RUN apt-get update -qq && \ 21 | apt-get install --no-install-recommends -y build-essential node-gyp openssl pkg-config python-is-python3 22 | 23 | # Install node modules 24 | COPY package-lock.json package.json ./ 25 | RUN npm ci --include=dev 26 | 27 | # Generate Prisma Client 28 | COPY prisma . 29 | RUN npx prisma generate 30 | 31 | # Copy application code 32 | COPY . . 33 | 34 | # Build application 35 | RUN npm run build 36 | 37 | 38 | # Final stage for app image 39 | FROM base 40 | 41 | # Install, configure litefs 42 | COPY --from=flyio/litefs:0.4.0 /usr/local/bin/litefs /usr/local/bin/litefs 43 | COPY --link litefs.yml /etc/litefs.yml 44 | 45 | # Install packages needed for deployment 46 | RUN apt-get update -qq && \ 47 | apt-get install --no-install-recommends -y ca-certificates fuse3 openssl sqlite3 && \ 48 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 49 | 50 | # Copy built application 51 | COPY --from=build /app /app 52 | 53 | # Setup sqlite3 on a separate volume 54 | RUN mkdir -p /data /litefs 55 | VOLUME /data 56 | 57 | # add shortcut for connecting to database CLI 58 | RUN echo "#!/bin/sh\nset -x\nsqlite3 \$DATABASE_URL" > /usr/local/bin/database-cli && chmod +x /usr/local/bin/database-cli 59 | 60 | # Entrypoint prepares the database. 61 | ENTRYPOINT [ "litefs", "mount", "--", "/app/docker-entrypoint.js" ] 62 | 63 | # Start the server by default, this can be overwritten at runtime 64 | EXPOSE 3000 65 | ENV DATABASE_FILENAME="sqlite.db" 66 | ENV LITEFS_DIR="/litefs" 67 | ENV DATABASE_PATH="$LITEFS_DIR/$DATABASE_FILENAME" 68 | ENV DATABASE_URL="file://$DATABASE_PATH" 69 | ENV CACHE_DATABASE_FILENAME="cache.db" 70 | ENV CACHE_DATABASE_PATH="$LITEFS_DIR/$CACHE_DATABASE_FILENAME" 71 | ENV PORT=3001 72 | CMD [ "npm", "run", "start" ] 73 | -------------------------------------------------------------------------------- /test/base/windows/app/session.server.ts: -------------------------------------------------------------------------------- 1 | import { createCookieSessionStorage, redirect } from "@remix-run/node"; 2 | import invariant from "tiny-invariant"; 3 | 4 | import type { User } from "~/models/user.server"; 5 | import { getUserById } from "~/models/user.server"; 6 | 7 | invariant(process.env.SESSION_SECRET, "SESSION_SECRET must be set"); 8 | 9 | export const sessionStorage = createCookieSessionStorage({ 10 | cookie: { 11 | name: "__session", 12 | httpOnly: true, 13 | path: "/", 14 | sameSite: "lax", 15 | secrets: [process.env.SESSION_SECRET], 16 | secure: process.env.NODE_ENV === "production", 17 | }, 18 | }); 19 | 20 | const USER_SESSION_KEY = "userId"; 21 | 22 | export async function getSession(request: Request) { 23 | const cookie = request.headers.get("Cookie"); 24 | return sessionStorage.getSession(cookie); 25 | } 26 | 27 | export async function getUserId( 28 | request: Request 29 | ): Promise { 30 | const session = await getSession(request); 31 | const userId = session.get(USER_SESSION_KEY); 32 | return userId; 33 | } 34 | 35 | export async function getUser(request: Request) { 36 | const userId = await getUserId(request); 37 | if (userId === undefined) return null; 38 | 39 | const user = await getUserById(userId); 40 | if (user) return user; 41 | 42 | throw await logout(request); 43 | } 44 | 45 | export async function requireUserId( 46 | request: Request, 47 | redirectTo: string = new URL(request.url).pathname 48 | ) { 49 | const userId = await getUserId(request); 50 | if (!userId) { 51 | const searchParams = new URLSearchParams([["redirectTo", redirectTo]]); 52 | throw redirect(`/login?${searchParams}`); 53 | } 54 | return userId; 55 | } 56 | 57 | export async function requireUser(request: Request) { 58 | const userId = await requireUserId(request); 59 | 60 | const user = await getUserById(userId); 61 | if (user) return user; 62 | 63 | throw await logout(request); 64 | } 65 | 66 | export async function createUserSession({ 67 | request, 68 | userId, 69 | remember, 70 | redirectTo, 71 | }: { 72 | request: Request; 73 | userId: string; 74 | remember: boolean; 75 | redirectTo: string; 76 | }) { 77 | const session = await getSession(request); 78 | session.set(USER_SESSION_KEY, userId); 79 | return redirect(redirectTo, { 80 | headers: { 81 | "Set-Cookie": await sessionStorage.commitSession(session, { 82 | maxAge: remember 83 | ? 60 * 60 * 24 * 7 // 7 days 84 | : undefined, 85 | }), 86 | }, 87 | }); 88 | } 89 | 90 | export async function logout(request: Request) { 91 | const session = await getSession(request); 92 | return redirect("/", { 93 | headers: { 94 | "Set-Cookie": await sessionStorage.destroySession(session), 95 | }, 96 | }); 97 | } 98 | -------------------------------------------------------------------------------- /test/base/defer-build/app/session.server.ts: -------------------------------------------------------------------------------- 1 | import { createCookieSessionStorage, redirect } from "@remix-run/node"; 2 | import invariant from "tiny-invariant"; 3 | 4 | import type { User } from "~/models/user.server"; 5 | import { getUserById } from "~/models/user.server"; 6 | 7 | invariant(process.env.SESSION_SECRET, "SESSION_SECRET must be set"); 8 | 9 | export const sessionStorage = createCookieSessionStorage({ 10 | cookie: { 11 | name: "__session", 12 | httpOnly: true, 13 | path: "/", 14 | sameSite: "lax", 15 | secrets: [process.env.SESSION_SECRET], 16 | secure: process.env.NODE_ENV === "production", 17 | }, 18 | }); 19 | 20 | const USER_SESSION_KEY = "userId"; 21 | 22 | export async function getSession(request: Request) { 23 | const cookie = request.headers.get("Cookie"); 24 | return sessionStorage.getSession(cookie); 25 | } 26 | 27 | export async function getUserId( 28 | request: Request, 29 | ): Promise { 30 | const session = await getSession(request); 31 | const userId = session.get(USER_SESSION_KEY); 32 | return userId; 33 | } 34 | 35 | export async function getUser(request: Request) { 36 | const userId = await getUserId(request); 37 | if (userId === undefined) return null; 38 | 39 | const user = await getUserById(userId); 40 | if (user) return user; 41 | 42 | throw await logout(request); 43 | } 44 | 45 | export async function requireUserId( 46 | request: Request, 47 | redirectTo: string = new URL(request.url).pathname, 48 | ) { 49 | const userId = await getUserId(request); 50 | if (!userId) { 51 | const searchParams = new URLSearchParams([["redirectTo", redirectTo]]); 52 | throw redirect(`/login?${searchParams}`); 53 | } 54 | return userId; 55 | } 56 | 57 | export async function requireUser(request: Request) { 58 | const userId = await requireUserId(request); 59 | 60 | const user = await getUserById(userId); 61 | if (user) return user; 62 | 63 | throw await logout(request); 64 | } 65 | 66 | export async function createUserSession({ 67 | request, 68 | userId, 69 | remember, 70 | redirectTo, 71 | }: { 72 | request: Request; 73 | userId: string; 74 | remember: boolean; 75 | redirectTo: string; 76 | }) { 77 | const session = await getSession(request); 78 | session.set(USER_SESSION_KEY, userId); 79 | return redirect(redirectTo, { 80 | headers: { 81 | "Set-Cookie": await sessionStorage.commitSession(session, { 82 | maxAge: remember 83 | ? 60 * 60 * 24 * 7 // 7 days 84 | : undefined, 85 | }), 86 | }, 87 | }); 88 | } 89 | 90 | export async function logout(request: Request) { 91 | const session = await getSession(request); 92 | return redirect("/", { 93 | headers: { 94 | "Set-Cookie": await sessionStorage.destroySession(session), 95 | }, 96 | }); 97 | } 98 | -------------------------------------------------------------------------------- /test/frameworks/remix-blues/app/session.server.ts: -------------------------------------------------------------------------------- 1 | import { createCookieSessionStorage, redirect } from "@remix-run/node"; 2 | import invariant from "tiny-invariant"; 3 | 4 | import type { User } from "~/models/user.server"; 5 | import { getUserById } from "~/models/user.server"; 6 | 7 | invariant(process.env.SESSION_SECRET, "SESSION_SECRET must be set"); 8 | 9 | export const sessionStorage = createCookieSessionStorage({ 10 | cookie: { 11 | name: "__session", 12 | httpOnly: true, 13 | path: "/", 14 | sameSite: "lax", 15 | secrets: [process.env.SESSION_SECRET], 16 | secure: process.env.NODE_ENV === "production", 17 | }, 18 | }); 19 | 20 | const USER_SESSION_KEY = "userId"; 21 | 22 | export async function getSession(request: Request) { 23 | const cookie = request.headers.get("Cookie"); 24 | return sessionStorage.getSession(cookie); 25 | } 26 | 27 | export async function getUserId( 28 | request: Request, 29 | ): Promise { 30 | const session = await getSession(request); 31 | const userId = session.get(USER_SESSION_KEY); 32 | return userId; 33 | } 34 | 35 | export async function getUser(request: Request) { 36 | const userId = await getUserId(request); 37 | if (userId === undefined) return null; 38 | 39 | const user = await getUserById(userId); 40 | if (user) return user; 41 | 42 | throw await logout(request); 43 | } 44 | 45 | export async function requireUserId( 46 | request: Request, 47 | redirectTo: string = new URL(request.url).pathname, 48 | ) { 49 | const userId = await getUserId(request); 50 | if (!userId) { 51 | const searchParams = new URLSearchParams([["redirectTo", redirectTo]]); 52 | throw redirect(`/login?${searchParams}`); 53 | } 54 | return userId; 55 | } 56 | 57 | export async function requireUser(request: Request) { 58 | const userId = await requireUserId(request); 59 | 60 | const user = await getUserById(userId); 61 | if (user) return user; 62 | 63 | throw await logout(request); 64 | } 65 | 66 | export async function createUserSession({ 67 | request, 68 | userId, 69 | remember, 70 | redirectTo, 71 | }: { 72 | request: Request; 73 | userId: string; 74 | remember: boolean; 75 | redirectTo: string; 76 | }) { 77 | const session = await getSession(request); 78 | session.set(USER_SESSION_KEY, userId); 79 | return redirect(redirectTo, { 80 | headers: { 81 | "Set-Cookie": await sessionStorage.commitSession(session, { 82 | maxAge: remember 83 | ? 60 * 60 * 24 * 7 // 7 days 84 | : undefined, 85 | }), 86 | }, 87 | }); 88 | } 89 | 90 | export async function logout(request: Request) { 91 | const session = await getSession(request); 92 | return redirect("/", { 93 | headers: { 94 | "Set-Cookie": await sessionStorage.destroySession(session), 95 | }, 96 | }); 97 | } 98 | -------------------------------------------------------------------------------- /test/frameworks/remix-indie/app/session.server.ts: -------------------------------------------------------------------------------- 1 | import { createCookieSessionStorage, redirect } from "@remix-run/node"; 2 | import invariant from "tiny-invariant"; 3 | 4 | import type { User } from "~/models/user.server"; 5 | import { getUserById } from "~/models/user.server"; 6 | 7 | invariant(process.env.SESSION_SECRET, "SESSION_SECRET must be set"); 8 | 9 | export const sessionStorage = createCookieSessionStorage({ 10 | cookie: { 11 | name: "__session", 12 | httpOnly: true, 13 | path: "/", 14 | sameSite: "lax", 15 | secrets: [process.env.SESSION_SECRET], 16 | secure: process.env.NODE_ENV === "production", 17 | }, 18 | }); 19 | 20 | const USER_SESSION_KEY = "userId"; 21 | 22 | export async function getSession(request: Request) { 23 | const cookie = request.headers.get("Cookie"); 24 | return sessionStorage.getSession(cookie); 25 | } 26 | 27 | export async function getUserId( 28 | request: Request, 29 | ): Promise { 30 | const session = await getSession(request); 31 | const userId = session.get(USER_SESSION_KEY); 32 | return userId; 33 | } 34 | 35 | export async function getUser(request: Request) { 36 | const userId = await getUserId(request); 37 | if (userId === undefined) return null; 38 | 39 | const user = await getUserById(userId); 40 | if (user) return user; 41 | 42 | throw await logout(request); 43 | } 44 | 45 | export async function requireUserId( 46 | request: Request, 47 | redirectTo: string = new URL(request.url).pathname, 48 | ) { 49 | const userId = await getUserId(request); 50 | if (!userId) { 51 | const searchParams = new URLSearchParams([["redirectTo", redirectTo]]); 52 | throw redirect(`/login?${searchParams}`); 53 | } 54 | return userId; 55 | } 56 | 57 | export async function requireUser(request: Request) { 58 | const userId = await requireUserId(request); 59 | 60 | const user = await getUserById(userId); 61 | if (user) return user; 62 | 63 | throw await logout(request); 64 | } 65 | 66 | export async function createUserSession({ 67 | request, 68 | userId, 69 | remember, 70 | redirectTo, 71 | }: { 72 | request: Request; 73 | userId: string; 74 | remember: boolean; 75 | redirectTo: string; 76 | }) { 77 | const session = await getSession(request); 78 | session.set(USER_SESSION_KEY, userId); 79 | return redirect(redirectTo, { 80 | headers: { 81 | "Set-Cookie": await sessionStorage.commitSession(session, { 82 | maxAge: remember 83 | ? 60 * 60 * 24 * 7 // 7 days 84 | : undefined, 85 | }), 86 | }, 87 | }); 88 | } 89 | 90 | export async function logout(request: Request) { 91 | const session = await getSession(request); 92 | return redirect("/", { 93 | headers: { 94 | "Set-Cookie": await sessionStorage.destroySession(session), 95 | }, 96 | }); 97 | } 98 | -------------------------------------------------------------------------------- /test/frameworks/remix-indie/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "indie-stack-template", 3 | "private": true, 4 | "sideEffects": false, 5 | "scripts": { 6 | "build": "remix build", 7 | "dev": "remix dev -c \"npm run dev:serve\"", 8 | "dev:serve": "binode --require ./mocks -- @remix-run/serve:remix-serve ./build", 9 | "format": "prettier --write .", 10 | "lint": "eslint --cache --cache-location ./node_modules/.cache/eslint .", 11 | "setup": "prisma generate && prisma migrate deploy && prisma db seed", 12 | "start": "remix-serve build", 13 | "start:mocks": "binode --require ./mocks -- @remix-run/serve:remix-serve build", 14 | "test": "vitest", 15 | "test:e2e:dev": "start-server-and-test dev http://localhost:3000 \"npx cypress open\"", 16 | "pretest:e2e:run": "npm run build", 17 | "test:e2e:run": "cross-env PORT=8811 start-server-and-test start:mocks http://localhost:8811 \"npx cypress run\"", 18 | "typecheck": "tsc && tsc -p cypress", 19 | "validate": "run-p \"test -- --run\" lint typecheck test:e2e:run" 20 | }, 21 | "prettier": {}, 22 | "eslintIgnore": [ 23 | "/node_modules", 24 | "/build", 25 | "/public/build" 26 | ], 27 | "dependencies": { 28 | "@prisma/client": "^4.16.2", 29 | "@remix-run/css-bundle": "*", 30 | "@remix-run/node": "*", 31 | "@remix-run/react": "*", 32 | "@remix-run/serve": "*", 33 | "bcryptjs": "^2.4.3", 34 | "isbot": "^3.6.13", 35 | "react": "^18.2.0", 36 | "react-dom": "^18.2.0", 37 | "tiny-invariant": "^1.3.1" 38 | }, 39 | "devDependencies": { 40 | "@faker-js/faker": "^8.0.2", 41 | "@remix-run/dev": "*", 42 | "@remix-run/eslint-config": "*", 43 | "@testing-library/cypress": "^10.0.1", 44 | "@testing-library/jest-dom": "^5.17.0", 45 | "@types/bcryptjs": "^2.4.2", 46 | "@types/eslint": "^8.44.2", 47 | "@types/node": "^18.17.6", 48 | "@types/react": "^18.2.20", 49 | "@types/react-dom": "^18.2.7", 50 | "@vitejs/plugin-react": "^4.0.4", 51 | "@vitest/coverage-v8": "^0.34.2", 52 | "autoprefixer": "^10.4.15", 53 | "binode": "^1.0.5", 54 | "cookie": "^0.5.0", 55 | "cross-env": "^7.0.3", 56 | "cypress": "^13.8.1", 57 | "eslint": "^8.47.0", 58 | "eslint-config-prettier": "^9.0.0", 59 | "eslint-plugin-cypress": "^2.14.0", 60 | "eslint-plugin-markdown": "^3.0.1", 61 | "eslint-plugin-prefer-let": "^3.0.1", 62 | "happy-dom": "^10.10.4", 63 | "msw": "^1.2.3", 64 | "npm-run-all": "^4.1.5", 65 | "postcss": "^8.4.31", 66 | "prettier": "3.0.2", 67 | "prettier-plugin-tailwindcss": "^0.5.3", 68 | "prisma": "^4.16.2", 69 | "start-server-and-test": "^2.0.0", 70 | "tailwindcss": "^3.3.3", 71 | "ts-node": "^10.9.1", 72 | "tsconfig-paths": "^4.2.0", 73 | "typescript": "^5.1.6", 74 | "vite": "^4.4.9", 75 | "vite-tsconfig-paths": "^3.6.0", 76 | "vitest": "^0.34.2" 77 | }, 78 | "engines": { 79 | "node": ">=14.0.0" 80 | }, 81 | "dockerfile": { 82 | "swap": "512M" 83 | }, 84 | "prisma": { 85 | "seed": "ts-node --require tsconfig-paths/register prisma/seed.ts" 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /test/base/windows/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "indie-stack", 3 | "private": true, 4 | "sideEffects": false, 5 | "scripts": { 6 | "build": "remix build", 7 | "dev": "cross-env NODE_ENV=development binode --require ./mocks -- @remix-run/dev:remix dev", 8 | "format": "prettier --write .", 9 | "lint": "eslint --cache --cache-location ./node_modules/.cache/eslint .", 10 | "setup": "prisma generate && prisma migrate deploy && prisma db seed", 11 | "start": "remix-serve build", 12 | "start:mocks": "binode --require ./mocks -- @remix-run/serve:remix-serve build", 13 | "test": "vitest", 14 | "test:e2e:dev": "start-server-and-test dev http://localhost:3000 \"npx cypress open\"", 15 | "pretest:e2e:run": "npm run build", 16 | "test:e2e:run": "cross-env PORT=8811 start-server-and-test start:mocks http://localhost:8811 \"npx cypress run\"", 17 | "typecheck": "tsc && tsc -p cypress", 18 | "validate": "run-p \"test -- --run\" lint typecheck test:e2e:run" 19 | }, 20 | "prettier": {}, 21 | "eslintIgnore": [ 22 | "/node_modules", 23 | "/build", 24 | "/public/build" 25 | ], 26 | "dependencies": { 27 | "@prisma/client": "^4.16.2", 28 | "@remix-run/css-bundle": "^1.19.3", 29 | "@remix-run/node": "^1.19.3", 30 | "@remix-run/react": "^1.19.3", 31 | "@remix-run/serve": "^1.19.3", 32 | "bcryptjs": "^2.4.3", 33 | "isbot": "^3.6.13", 34 | "react": "^18.2.0", 35 | "react-dom": "^18.2.0", 36 | "tiny-invariant": "^1.3.1" 37 | }, 38 | "devDependencies": { 39 | "@faker-js/faker": "^7.6.0", 40 | "@remix-run/dev": "^1.19.3", 41 | "@remix-run/eslint-config": "^1.19.3", 42 | "@testing-library/cypress": "^10.0.1", 43 | "@testing-library/jest-dom": "^5.17.0", 44 | "@testing-library/react": "^14.0.0", 45 | "@testing-library/user-event": "^14.4.3", 46 | "@types/bcryptjs": "^2.4.2", 47 | "@types/eslint": "^8.44.2", 48 | "@types/node": "^20.5.1", 49 | "@types/react": "^18.2.20", 50 | "@types/react-dom": "^18.2.7", 51 | "@vitejs/plugin-react": "^4.0.4", 52 | "@vitest/coverage-c8": "^0.31.0", 53 | "autoprefixer": "^10.4.15", 54 | "binode": "^1.0.5", 55 | "c8": "^7.14.0", 56 | "cookie": "^0.5.0", 57 | "cross-env": "^7.0.3", 58 | "cypress": "^13.8.1", 59 | "eslint": "^8.47.0", 60 | "eslint-config-prettier": "^8.10.0", 61 | "eslint-plugin-cypress": "^2.14.0", 62 | "happy-dom": "^9.20.3", 63 | "msw": "^1.2.3", 64 | "npm-run-all": "^4.1.5", 65 | "postcss": "^8.4.31", 66 | "prettier": "3.0.2", 67 | "prettier-plugin-tailwindcss": "^0.5.3", 68 | "prisma": "^4.16.2", 69 | "start-server-and-test": "^2.0.0", 70 | "tailwindcss": "^3.3.3", 71 | "ts-node": "^10.9.1", 72 | "tsconfig-paths": "^4.2.0", 73 | "typescript": "^5.1.6", 74 | "vite": "^4.4.9", 75 | "vite-tsconfig-paths": "^4.2.0", 76 | "vitest": "^0.34.2" 77 | }, 78 | "engines": { 79 | "node": ">=14" 80 | }, 81 | "prisma": { 82 | "seed": "ts-node --require tsconfig-paths/register prisma/seed.ts" 83 | }, 84 | "dockerfile": { 85 | "windows": true 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /test/frameworks/remix-blues/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blues-stack-template", 3 | "private": true, 4 | "sideEffects": false, 5 | "scripts": { 6 | "build": "run-s build:*", 7 | "build:remix": "remix build", 8 | "build:server": "esbuild --platform=node --format=cjs ./server.ts --outdir=build --bundle", 9 | "dev": "run-p dev:*", 10 | "dev:build": "cross-env NODE_ENV=development npm run build:server -- --watch", 11 | "dev:remix": "cross-env NODE_ENV=development remix watch", 12 | "dev:server": "cross-env NODE_ENV=development node --inspect --require ./node_modules/dotenv/config --require ./mocks ./build/server.js", 13 | "docker": "docker-compose up -d", 14 | "format": "prettier --write .", 15 | "lint": "eslint --cache --cache-location ./node_modules/.cache/eslint .", 16 | "setup": "prisma generate && prisma migrate deploy && prisma db seed", 17 | "start": "cross-env NODE_ENV=production node ./build/server.js", 18 | "start:mocks": "cross-env NODE_ENV=production node --require ./mocks --require dotenv/config ./build/server.js", 19 | "test": "vitest", 20 | "test:e2e:dev": "start-server-and-test dev http://localhost:3000 \"npx cypress open\"", 21 | "pretest:e2e:run": "npm run build", 22 | "test:e2e:run": "cross-env PORT=8811 start-server-and-test start:mocks http://localhost:8811 \"npx cypress run\"", 23 | "typecheck": "tsc && tsc -p cypress", 24 | "validate": "run-p \"test -- --run\" lint typecheck test:e2e:run" 25 | }, 26 | "prettier": {}, 27 | "eslintIgnore": [ 28 | "/node_modules", 29 | "/build", 30 | "/public/build", 31 | "/postgres-data" 32 | ], 33 | "dependencies": { 34 | "@isaacs/express-prometheus-middleware": "^1.2.1", 35 | "@prisma/client": "^4.16.2", 36 | "@remix-run/css-bundle": "*", 37 | "@remix-run/express": "*", 38 | "@remix-run/node": "*", 39 | "@remix-run/react": "*", 40 | "bcryptjs": "^2.4.3", 41 | "compression": "^1.7.4", 42 | "cross-env": "^7.0.3", 43 | "express": "^4.18.2", 44 | "isbot": "^3.6.13", 45 | "morgan": "^1.10.0", 46 | "prom-client": "^14.2.0", 47 | "react": "^18.2.0", 48 | "react-dom": "^18.2.0", 49 | "source-map-support": "^0.5.21", 50 | "tiny-invariant": "^1.3.1" 51 | }, 52 | "devDependencies": { 53 | "@faker-js/faker": "^8.0.2", 54 | "@remix-run/dev": "*", 55 | "@remix-run/eslint-config": "*", 56 | "@testing-library/cypress": "^10.0.1", 57 | "@testing-library/jest-dom": "^5.17.0", 58 | "@types/bcryptjs": "^2.4.2", 59 | "@types/compression": "^1.7.2", 60 | "@types/eslint": "^8.44.2", 61 | "@types/express": "^4.17.17", 62 | "@types/morgan": "^1.9.4", 63 | "@types/node": "^18.17.6", 64 | "@types/react": "^18.2.20", 65 | "@types/react-dom": "^18.2.7", 66 | "@types/source-map-support": "^0.5.6", 67 | "@vitejs/plugin-react": "^4.0.4", 68 | "@vitest/coverage-v8": "^0.34.2", 69 | "autoprefixer": "^10.4.15", 70 | "cookie": "^0.5.0", 71 | "cypress": "^13.8.1", 72 | "dotenv": "^16.3.1", 73 | "esbuild": "^0.19.2", 74 | "eslint": "^8.47.0", 75 | "eslint-config-prettier": "^9.0.0", 76 | "eslint-plugin-cypress": "^2.14.0", 77 | "eslint-plugin-markdown": "^3.0.1", 78 | "eslint-plugin-prefer-let": "^3.0.1", 79 | "happy-dom": "^10.10.4", 80 | "msw": "^1.2.3", 81 | "npm-run-all": "^4.1.5", 82 | "postcss": "^8.4.31", 83 | "prettier": "3.0.2", 84 | "prettier-plugin-tailwindcss": "^0.5.3", 85 | "prisma": "^4.16.2", 86 | "start-server-and-test": "^2.0.0", 87 | "tailwindcss": "^3.3.3", 88 | "ts-node": "^10.9.1", 89 | "tsconfig-paths": "^4.2.0", 90 | "typescript": "^5.1.6", 91 | "vite": "^4.5.3", 92 | "vite-tsconfig-paths": "^3.6.0", 93 | "vitest": "^0.34.2" 94 | }, 95 | "engines": { 96 | "node": ">=14.0.0" 97 | }, 98 | "dockerfile": { 99 | "swap": "512M" 100 | }, 101 | "prisma": { 102 | "seed": "ts-node --require tsconfig-paths/register prisma/seed.ts" 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /test/base/litefs/litefs.yml: -------------------------------------------------------------------------------- 1 | # based on: https://github.com/superfly/litefs/blob/main/cmd/litefs/etc/litefs.yml 2 | 3 | # The FUSE section handles settings on the FUSE file system. FUSE 4 | # provides a layer for intercepting SQLite transactions on the 5 | # primary node so they can be shipped to replica nodes transparently. 6 | fuse: 7 | # Required. This is the mount directory that applications will 8 | # use to access their SQLite databases. 9 | dir: "/litefs" 10 | 11 | # Set this flag to true to allow non-root users to access mount. 12 | # You must set the "user_allow_other" option in /etc/fuse.conf first. 13 | allow-other: false 14 | 15 | # The debug flag enables debug logging of all FUSE API calls. 16 | # This will produce a lot of logging. Not for general use. 17 | debug: false 18 | 19 | # The data section specifies where internal LiteFS data is stored 20 | # and how long to retain the transaction files. 21 | # 22 | # Transaction files are used to ship changes to replica nodes so 23 | # they should persist long enough for replicas to retrieve them, 24 | # even in the face of a short network interruption or a redeploy. 25 | # Under high load, these files can grow large so it's not advised 26 | # to extend retention too long. 27 | data: 28 | # Path to internal data storage. 29 | dir: "/data" 30 | 31 | # Duration to keep LTX files. Latest LTX file is always kept. 32 | retention: "10m" 33 | 34 | # Frequency with which to check for LTX files to delete. 35 | retention-monitor-interval: "1m" 36 | 37 | # If true, then LiteFS will not wait until the node becomes the 38 | # primary or connects to the primary before starting the subprocess. 39 | skip-sync: false 40 | 41 | # If true, then LiteFS will not exit if there is a validation 42 | # issue on startup. This can be useful for debugging issues as 43 | # it avoids constantly restarting the node on ephemeral hosting. 44 | exit-on-error: false 45 | 46 | # This section defines settings for the LiteFS HTTP API server. 47 | # This API server is how nodes communicate with each other. 48 | http: 49 | # Specifies the bind address of the HTTP API server. 50 | addr: ":20202" 51 | 52 | # This section defines settings for the option HTTP proxy. 53 | # This proxy can handle primary forwarding & replica consistency 54 | # for applications that use a single SQLite database. 55 | proxy: 56 | # Specifies the bind address of the proxy server. 57 | addr: ":3000" 58 | 59 | # The hostport of the target application. 60 | target: "localhost:3001" 61 | 62 | # The name of the database used for TXID tracking. 63 | db: "sqlite.db" 64 | 65 | # If true, enables verbose logging of requests by the proxy. 66 | debug: false 67 | 68 | # List of paths that are ignored by the proxy. The asterisk is 69 | # the only available wildcard. These requests are passed 70 | # through to the target as-is. 71 | passthrough: [] 72 | 73 | # The lease section defines how LiteFS creates a cluster and 74 | # implements leader election. For dynamic clusters, use the 75 | # "consul". This allows the primary to change automatically when 76 | # the current primary goes down. For a simpler setup, use 77 | # "static" which assigns a single node to be the primary and does 78 | # not failover. 79 | lease: 80 | # Required. Must be either "consul" or "static". 81 | type: "consul" 82 | 83 | # Required. The URL for this node's LiteFS API. 84 | # Should match HTTP port. 85 | advertise-url: "http://${HOSTNAME}.vm.${FLY_APP_NAME}.internal:20202" 86 | 87 | # Specifies whether the node can become the primary. If using 88 | # "static" leasing, this should be set to true on the primary 89 | # and false on the replicas. 90 | candidate: ${FLY_REGION == PRIMARY_REGION} 91 | 92 | # A Consul server provides leader election and ensures that the 93 | # responsibility of the primary node can be moved in the event 94 | # of a deployment or a failure. 95 | consul: 96 | # Required. The base URL of the Consul server. 97 | url: "${FLY_CONSUL_URL}" 98 | 99 | # Required. The key used for obtaining a lease by the primary. 100 | # This must be unique for each cluster of LiteFS servers 101 | key: "litefs/${FLY_APP_NAME}" 102 | 103 | # Length of time before a lease expires. The primary will 104 | # automatically renew the lease while it is alive, however, 105 | # if it fails to renew in time then a new primary may be 106 | # elected after the TTL. This only occurs for unexpected loss 107 | # of the leader as normal operation will allow the leader to 108 | # handoff the lease to another replica without downtime. 109 | # 110 | # Consul does not allow a TTL of less than 10 seconds. 111 | ttl: "10s" 112 | 113 | # Length of time after the lease expires before a candidate 114 | # can become leader. This buffer is intended to prevent 115 | # overlap in leadership due to clock skew or in-flight calls. 116 | lock-delay: "1s" 117 | -------------------------------------------------------------------------------- /templates/litefs.yml.ejs: -------------------------------------------------------------------------------- 1 | # based on: https://github.com/superfly/litefs/blob/main/cmd/litefs/etc/litefs.yml 2 | 3 | # The FUSE section handles settings on the FUSE file system. FUSE 4 | # provides a layer for intercepting SQLite transactions on the 5 | # primary node so they can be shipped to replica nodes transparently. 6 | fuse: 7 | # Required. This is the mount directory that applications will 8 | # use to access their SQLite databases. 9 | dir: "/litefs" 10 | 11 | # Set this flag to true to allow non-root users to access mount. 12 | # You must set the "user_allow_other" option in /etc/fuse.conf first. 13 | allow-other: false 14 | 15 | # The debug flag enables debug logging of all FUSE API calls. 16 | # This will produce a lot of logging. Not for general use. 17 | debug: false 18 | 19 | # The data section specifies where internal LiteFS data is stored 20 | # and how long to retain the transaction files. 21 | # 22 | # Transaction files are used to ship changes to replica nodes so 23 | # they should persist long enough for replicas to retrieve them, 24 | # even in the face of a short network interruption or a redeploy. 25 | # Under high load, these files can grow large so it's not advised 26 | # to extend retention too long. 27 | data: 28 | # Path to internal data storage. 29 | dir: "/data" 30 | 31 | # Duration to keep LTX files. Latest LTX file is always kept. 32 | retention: "10m" 33 | 34 | # Frequency with which to check for LTX files to delete. 35 | retention-monitor-interval: "1m" 36 | 37 | # If true, then LiteFS will not wait until the node becomes the 38 | # primary or connects to the primary before starting the subprocess. 39 | skip-sync: false 40 | 41 | # If true, then LiteFS will not exit if there is a validation 42 | # issue on startup. This can be useful for debugging issues as 43 | # it avoids constantly restarting the node on ephemeral hosting. 44 | exit-on-error: false 45 | 46 | # This section defines settings for the LiteFS HTTP API server. 47 | # This API server is how nodes communicate with each other. 48 | http: 49 | # Specifies the bind address of the HTTP API server. 50 | addr: ":20202" 51 | 52 | # This section defines settings for the option HTTP proxy. 53 | # This proxy can handle primary forwarding & replica consistency 54 | # for applications that use a single SQLite database. 55 | proxy: 56 | # Specifies the bind address of the proxy server. 57 | addr: ":<%= port %>" 58 | 59 | # The hostport of the target application. 60 | target: "localhost:<%= port + 1 %>" 61 | 62 | # The name of the database used for TXID tracking. 63 | db: "sqlite.db" 64 | 65 | # If true, enables verbose logging of requests by the proxy. 66 | debug: false 67 | 68 | # List of paths that are ignored by the proxy. The asterisk is 69 | # the only available wildcard. These requests are passed 70 | # through to the target as-is. 71 | passthrough: [] 72 | 73 | # The lease section defines how LiteFS creates a cluster and 74 | # implements leader election. For dynamic clusters, use the 75 | # "consul". This allows the primary to change automatically when 76 | # the current primary goes down. For a simpler setup, use 77 | # "static" which assigns a single node to be the primary and does 78 | # not failover. 79 | lease: 80 | # Required. Must be either "consul" or "static". 81 | type: "consul" 82 | 83 | # Required. The URL for this node's LiteFS API. 84 | # Should match HTTP port. 85 | advertise-url: "http://${HOSTNAME}.vm.${FLY_APP_NAME}.internal:20202" 86 | 87 | # Specifies whether the node can become the primary. If using 88 | # "static" leasing, this should be set to true on the primary 89 | # and false on the replicas. 90 | candidate: ${FLY_REGION == PRIMARY_REGION} 91 | 92 | # A Consul server provides leader election and ensures that the 93 | # responsibility of the primary node can be moved in the event 94 | # of a deployment or a failure. 95 | consul: 96 | # Required. The base URL of the Consul server. 97 | url: "${FLY_CONSUL_URL}" 98 | 99 | # Required. The key used for obtaining a lease by the primary. 100 | # This must be unique for each cluster of LiteFS servers 101 | key: "litefs/${FLY_APP_NAME}" 102 | 103 | # Length of time before a lease expires. The primary will 104 | # automatically renew the lease while it is alive, however, 105 | # if it fails to renew in time then a new primary may be 106 | # elected after the TTL. This only occurs for unexpected loss 107 | # of the leader as normal operation will allow the leader to 108 | # handoff the lease to another replica without downtime. 109 | # 110 | # Consul does not allow a TTL of less than 10 seconds. 111 | ttl: "10s" 112 | 113 | # Length of time after the lease expires before a candidate 114 | # can become leader. This buffer is intended to prevent 115 | # overlap in leadership due to clock skew or in-flight calls. 116 | lock-delay: "1s" 117 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | import path from 'node:path' 2 | import os from 'node:os' 3 | import fs from 'node:fs' 4 | 5 | import { expect } from 'chai' 6 | 7 | import { GDF, defaults } from '../gdf.js' 8 | import '../fly.js' 9 | 10 | for (const group of fs.readdirSync('test', { withFileTypes: true })) { 11 | if (!group.isDirectory()) continue 12 | 13 | process.env.NODE_ENV = 'test' 14 | 15 | for (const entry of fs.readdirSync(path.join('test', group.name), { withFileTypes: true })) { 16 | if (!fs.existsSync(path.join('test', group.name, entry.name, 'package.json'))) continue 17 | 18 | describe(`${group.name}: ${entry.name}`, function() { 19 | const workdir = path.join(os.tmpdir(), group.name, entry.name) 20 | const testdir = path.join('test', group.name, entry.name) 21 | 22 | if (fs.existsSync(workdir)) fs.rmSync(workdir, { recursive: true }) 23 | 24 | fs.cpSync(testdir, workdir, { recursive: true }) 25 | 26 | const pj = fs.readFileSync(path.join(testdir, 'package.json'), 'utf-8') 27 | const options = { ...defaults, ...(JSON.parse(pj).dockerfile || {}) } 28 | if (options.envs) options.vars = options.envs 29 | options.force = true 30 | 31 | it('should produce a dockerfile', async function() { 32 | await new GDF().run(workdir, options) 33 | 34 | let argmask = /^(ARG\s+\w+\s*=).*?(\s*\\?)$/gm 35 | if (entry.name === 'version') argmask = /()xxx()/g 36 | 37 | const actualResults = fs.readFileSync(path.join(workdir, 'Dockerfile'), 'utf-8') 38 | .replaceAll(argmask, '$1xxx$2') 39 | 40 | if (process.env.TEST_CAPTURE) { 41 | fs.writeFileSync(path.join(testdir, 'Dockerfile'), actualResults) 42 | } 43 | 44 | const expectedResults = fs.readFileSync(path.join(testdir, 'Dockerfile'), 'utf-8') 45 | .replaceAll(argmask, '$1xxx$2') 46 | 47 | expect(expectedResults).to.equal(actualResults) 48 | }) 49 | 50 | it('should produce a .dockerignore', async function() { 51 | await new GDF().run(workdir, options) 52 | 53 | const actualResults = fs.readFileSync(path.join(workdir, '.dockerignore'), 'utf-8') 54 | 55 | if (process.env.TEST_CAPTURE) { 56 | fs.writeFileSync(path.join(testdir, '.dockerignore'), actualResults) 57 | } 58 | 59 | const expectedResults = fs.readFileSync(path.join(testdir, '.dockerignore'), 'utf-8') 60 | 61 | expect(expectedResults).to.equal(actualResults) 62 | }) 63 | 64 | if (fs.existsSync(path.join(testdir, 'docker-entrypoint.js'))) { 65 | it('should produce a docker-entrypoint', async function() { 66 | await new GDF().run(workdir, options) 67 | 68 | let entrypoint = path.join(workdir, 'docker-entrypoint.js') 69 | const other = path.join(workdir, 'other', 'docker-entrypoint.js') 70 | if (fs.existsSync(other)) entrypoint = other 71 | 72 | const actualResults = fs.readFileSync(entrypoint, 'utf-8') 73 | 74 | if (process.env.TEST_CAPTURE) { 75 | fs.writeFileSync(path.join(testdir, 'docker-entrypoint.js'), actualResults) 76 | } 77 | 78 | const expectedResults = fs.readFileSync(path.join(testdir, 'docker-entrypoint.js'), 'utf-8') 79 | 80 | expect(expectedResults).to.equal(actualResults) 81 | }) 82 | } 83 | 84 | if (fs.existsSync(path.join(testdir, 'litefs.yml'))) { 85 | it('should produce a litefs.yml', async function() { 86 | await new GDF().run(workdir, options) 87 | 88 | const actualResults = fs.readFileSync(path.join(workdir, 'litefs.yml'), 'utf-8') 89 | 90 | if (process.env.TEST_CAPTURE) { 91 | fs.writeFileSync(path.join(testdir, 'litefs.yml'), actualResults) 92 | } 93 | 94 | const expectedResults = fs.readFileSync(path.join(testdir, 'litefs.yml'), 'utf-8') 95 | 96 | expect(expectedResults).to.equal(actualResults) 97 | }) 98 | } 99 | 100 | if (fs.existsSync(path.join(testdir, 'litestream.yml'))) { 101 | it('should produce a litestream.yml', async function() { 102 | await new GDF().run(workdir, options) 103 | 104 | const actualResults = fs.readFileSync(path.join(workdir, 'litestream.yml'), 'utf-8') 105 | 106 | if (process.env.TEST_CAPTURE) { 107 | fs.writeFileSync(path.join(testdir, 'litestream.yml'), actualResults) 108 | } 109 | 110 | const expectedResults = fs.readFileSync(path.join(testdir, 'litestream.yml'), 'utf-8') 111 | 112 | expect(expectedResults).to.equal(actualResults) 113 | }) 114 | } 115 | 116 | if (fs.existsSync(path.join(testdir, 'fly.toml'))) { 117 | it('should produce a fly.toml', async function() { 118 | let expectedResults = fs.readFileSync(path.join(testdir, 'fly.toml'), 'utf-8') 119 | fs.writeFileSync(path.join(workdir, 'fly.toml'), '') 120 | 121 | await new GDF().run(workdir, options) 122 | 123 | const actualResults = fs.readFileSync(path.join(workdir, 'fly.toml'), 'utf-8') 124 | 125 | if (process.env.TEST_CAPTURE) { 126 | fs.writeFileSync(path.join(testdir, 'fly.toml'), actualResults) 127 | expectedResults = actualResults 128 | } 129 | 130 | expect(expectedResults).to.equal(actualResults) 131 | }) 132 | } 133 | }) 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /test/frameworks/remix-epic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "epic-stack-template", 3 | "private": true, 4 | "sideEffects": false, 5 | "license": "MIT", 6 | "epic-stack": true, 7 | "author": "Kent C. Dodds (https://kentcdodds.com/)", 8 | "type": "module", 9 | "imports": { 10 | "#*": "./*" 11 | }, 12 | "scripts": { 13 | "build": "run-s build:*", 14 | "build:icons": "tsx ./other/build-icons.ts", 15 | "build:remix": "remix build --sourcemap", 16 | "build:server": "tsx ./other/build-server.ts", 17 | "predev": "npm run build:icons --silent", 18 | "dev": "remix dev -c \"node ./server/dev-server.js\" --manual", 19 | "prisma:studio": "prisma studio", 20 | "format": "prettier --write .", 21 | "lint": "eslint .", 22 | "setup": "npm run build && prisma generate && prisma migrate deploy && prisma db seed && playwright install", 23 | "start": "cross-env NODE_ENV=production node .", 24 | "start:mocks": "cross-env NODE_ENV=production MOCKS=true tsx .", 25 | "test": "vitest", 26 | "coverage": "vitest run --coverage", 27 | "test:e2e": "npm run test:e2e:dev --silent", 28 | "test:e2e:dev": "playwright test --ui", 29 | "pretest:e2e:run": "npm run build", 30 | "test:e2e:run": "cross-env CI=true playwright test", 31 | "test:e2e:install": "npx playwright install --with-deps chromium", 32 | "typecheck": "tsc", 33 | "validate": "run-p \"test -- --run\" lint typecheck test:e2e:run" 34 | }, 35 | "eslintIgnore": [ 36 | "/node_modules", 37 | "/build", 38 | "/public/build", 39 | "/playwright-report", 40 | "/server-build" 41 | ], 42 | "dependencies": { 43 | "@conform-to/react": "^0.8.0", 44 | "@conform-to/zod": "^0.8.0", 45 | "@epic-web/totp": "^1.0.6", 46 | "@paralleldrive/cuid2": "^2.2.2", 47 | "@prisma/client": "^5.1.1", 48 | "@radix-ui/react-checkbox": "^1.0.4", 49 | "@radix-ui/react-dropdown-menu": "^2.0.5", 50 | "@radix-ui/react-label": "^2.0.2", 51 | "@radix-ui/react-slot": "^1.0.2", 52 | "@radix-ui/react-toast": "^1.1.4", 53 | "@radix-ui/react-tooltip": "^1.0.6", 54 | "@react-email/components": "^0.0.16", 55 | "@remix-run/css-bundle": "1.19.3", 56 | "@remix-run/express": "1.19.3", 57 | "@remix-run/node": "1.19.3", 58 | "@remix-run/react": "1.19.3", 59 | "@remix-run/router": "^1.8.0", 60 | "@remix-run/server-runtime": "1.19.3", 61 | "@sentry/remix": "^7.64.0", 62 | "address": "^1.2.2", 63 | "autoprefixer": "^10.4.15", 64 | "bcryptjs": "^2.4.3", 65 | "better-sqlite3": "^8.5.1", 66 | "cachified": "^3.5.4", 67 | "chalk": "^5.3.0", 68 | "chokidar": "^3.5.3", 69 | "class-variance-authority": "^0.7.0", 70 | "close-with-grace": "^1.2.0", 71 | "clsx": "^2.0.0", 72 | "compression": "^1.7.4", 73 | "confetti-react": "^2.5.0", 74 | "cross-env": "^7.0.3", 75 | "date-fns": "^2.30.0", 76 | "dotenv": "^16.3.1", 77 | "eslint-plugin-remix-react-routes": "^1.0.5", 78 | "execa": "^7.2.0", 79 | "express": "^4.18.2", 80 | "express-rate-limit": "^6.9.0", 81 | "get-port": "^7.0.0", 82 | "helmet": "^7.0.0", 83 | "intl-parse-accept-language": "^1.0.0", 84 | "isbot": "^3.6.13", 85 | "litefs-js": "^1.1.2", 86 | "lru-cache": "^10.0.1", 87 | "morgan": "^1.10.0", 88 | "prisma": "^5.1.1", 89 | "qrcode": "^1.5.3", 90 | "react": "^18.2.0", 91 | "react-dom": "^18.2.0", 92 | "remix-auth": "^3.5.1", 93 | "remix-auth-form": "^1.3.0", 94 | "remix-development-tools": "^2.1.1", 95 | "remix-auth-github": "^1.6.0", 96 | "remix-utils": "^6.6.0", 97 | "set-cookie-parser": "^2.6.0", 98 | "sonner": "^0.6.2", 99 | "source-map-support": "^0.5.21", 100 | "spin-delay": "^1.2.0", 101 | "tailwind-merge": "^1.14.0", 102 | "tailwindcss": "^3.3.3", 103 | "tailwindcss-animate": "^1.0.6", 104 | "tailwindcss-radix": "^2.8.0", 105 | "zod": "^3.22.3" 106 | }, 107 | "devDependencies": { 108 | "@faker-js/faker": "^8.0.2", 109 | "@playwright/test": "^1.37.1", 110 | "@remix-run/dev": "1.19.3", 111 | "@remix-run/eslint-config": "1.19.3", 112 | "@remix-run/serve": "1.19.3", 113 | "@remix-run/testing": "^1.19.3", 114 | "@sly-cli/sly": "^1.4.10", 115 | "@testing-library/jest-dom": "^6.0.1", 116 | "@testing-library/react": "^14.0.0", 117 | "@testing-library/user-event": "^14.4.3", 118 | "@total-typescript/ts-reset": "^0.5.1", 119 | "@types/bcryptjs": "^2.4.2", 120 | "@types/better-sqlite3": "^7.6.4", 121 | "@types/compression": "^1.7.2", 122 | "@types/cookie": "^0.5.1", 123 | "@types/eslint": "^8.44.2", 124 | "@types/express": "^4.17.17", 125 | "@types/fs-extra": "^11.0.1", 126 | "@types/glob": "^8.1.0", 127 | "@types/morgan": "^1.9.4", 128 | "@types/node": "^20.5.1", 129 | "@types/qrcode": "^1.5.1", 130 | "@types/react": "^18.2.20", 131 | "@types/react-dom": "^18.2.7", 132 | "@types/set-cookie-parser": "^2.4.3", 133 | "@types/source-map-support": "^0.5.6", 134 | "@vitejs/plugin-react": "^4.0.4", 135 | "@vitest/coverage-v8": "^0.34.2", 136 | "cookie": "^0.5.0", 137 | "enforce-unique": "^1.1.1", 138 | "esbuild": "^0.19.2", 139 | "eslint": "^8.47.0", 140 | "eslint-config-prettier": "^9.0.0", 141 | "fs-extra": "^11.1.1", 142 | "glob": "^10.3.3", 143 | "jsdom": "^22.1.0", 144 | "msw": "0.0.0-fetch.rc-16", 145 | "node-html-parser": "^6.1.6", 146 | "npm-run-all": "^4.1.5", 147 | "prettier": "3.0.2", 148 | "prettier-plugin-sql": "^0.15.1", 149 | "prettier-plugin-tailwindcss": "^0.5.3", 150 | "remix-flat-routes": "^0.5.10", 151 | "tsx": "^3.12.7", 152 | "typescript": "^5.1.6", 153 | "vite": "^4.4.9", 154 | "vitest": "^0.34.2" 155 | }, 156 | "engines": { 157 | "node": "18" 158 | }, 159 | "prisma": { 160 | "seed": "tsx prisma/seed.ts" 161 | } 162 | } 163 | --------------------------------------------------------------------------------