feat(node): improve docker setup for Node server apps (#14647)

This commit is contained in:
Jack Hsu 2023-01-26 12:09:13 -05:00 committed by GitHub
parent 6093247df2
commit 9f1ed50fc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 59 additions and 35 deletions

View File

@ -89,7 +89,7 @@
"framework": { "framework": {
"description": "Generate the node application using a framework", "description": "Generate the node application using a framework",
"type": "string", "type": "string",
"enum": ["express", "koa", "fastify", "none"], "enum": ["express", "fastify", "koa", "none"],
"default": "none", "default": "none",
"x-prompt": "Which framework do you want to use?", "x-prompt": "Which framework do you want to use?",
"x-priority": "important" "x-priority": "important"

View File

@ -9,10 +9,12 @@
"description": "Nx Node Docker Options Schema.", "description": "Nx Node Docker Options Schema.",
"type": "object", "type": "object",
"properties": { "properties": {
"projectName": { "project": {
"description": "The name of the project", "description": "The name of the project",
"$default": { "$source": "argv", "index": 0 }, "$default": { "$source": "projectName" },
"type": "string" "type": "string",
"x-prompt": "What project would you like to add a Dockerfile to?",
"x-priority": "important"
}, },
"targetName": { "targetName": {
"description": "The name of the target to create", "description": "The name of the target to create",

View File

@ -701,14 +701,14 @@ async function determineFramework(
name: 'express', name: 'express',
message: 'Express [https://expressjs.com/]', message: 'Express [https://expressjs.com/]',
}, },
{
name: 'koa',
message: 'koa [https://koajs.com/]',
},
{ {
name: 'fastify', name: 'fastify',
message: 'fastify [https://www.fastify.io/]', message: 'fastify [https://www.fastify.io/]',
}, },
{
name: 'koa',
message: 'koa [https://koajs.com/]',
},
]; ];
if (!parsedArgs.framework) { if (!parsedArgs.framework) {

View File

@ -59,7 +59,10 @@ function getWebpackBuildConfig(
options: { options: {
target: 'node', target: 'node',
compiler: 'tsc', compiler: 'tsc',
outputPath: joinPathFragments('dist', options.appProjectRoot), outputPath: joinPathFragments(
'dist',
options.rootProject ? options.name : options.appProjectRoot
),
main: joinPathFragments( main: joinPathFragments(
project.sourceRoot, project.sourceRoot,
'main' + (options.js ? '.js' : '.ts') 'main' + (options.js ? '.js' : '.ts')
@ -90,7 +93,10 @@ function getEsBuildConfig(
executor: '@nrwl/esbuild:esbuild', executor: '@nrwl/esbuild:esbuild',
outputs: ['{options.outputPath}'], outputs: ['{options.outputPath}'],
options: { options: {
outputPath: joinPathFragments('dist', options.appProjectRoot), outputPath: joinPathFragments(
'dist',
options.rootProject ? options.name : options.appProjectRoot
),
format: ['cjs'], format: ['cjs'],
main: joinPathFragments( main: joinPathFragments(
project.sourceRoot, project.sourceRoot,
@ -373,7 +379,7 @@ export async function applicationGenerator(tree: Tree, schema: Schema) {
if (options.docker) { if (options.docker) {
const dockerTask = await setupDockerGenerator(tree, { const dockerTask = await setupDockerGenerator(tree, {
...options, ...options,
projectName: options.name, project: options.name,
}); });
tasks.push(dockerTask); tasks.push(dockerTask);

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
const host = process.env.HOST ?? 'localhost';
const port = process.env.PORT ? Number(process.env.PORT) : <%= port %>; const port = process.env.PORT ? Number(process.env.PORT) : <%= port %>;
const app = express(); const app = express();
@ -8,6 +9,6 @@ app.get('/', (req, res) => {
res.send({ 'message': 'Hello API'}); res.send({ 'message': 'Hello API'});
}); });
app.listen(port, () => { app.listen(port, host, () => {
console.log(`[ ready ] http://localhost:${port}`); console.log(`[ ready ] http://${host}:${port}`);
}); });

View File

@ -1,5 +1,6 @@
import fastify from 'fastify'; import fastify from 'fastify';
const host = process.env.HOST ?? 'localhost';
const port = process.env.PORT ? Number(process.env.PORT) : <%= port %>; const port = process.env.PORT ? Number(process.env.PORT) : <%= port %>;
const app = fastify(); const app = fastify();
@ -10,8 +11,8 @@ app.get('/', async (req, res) => {
const start = async() => { const start = async() => {
try { try {
await app.listen({ port }); await app.listen({ host, port });
console.log(`[ ready ] http://localhost:${port}`); console.log(`[ ready ] http://${host}:${port}`);
} catch (err) { } catch (err) {
// Errors are logged here // Errors are logged here
process.exit(1); process.exit(1);

View File

@ -1,5 +1,6 @@
import koa from 'koa'; import koa from 'koa';
const host = process.env.HOST ?? 'localhost';
const port = process.env.PORT ? Number(process.env.PORT) : <%= port %>; const port = process.env.PORT ? Number(process.env.PORT) : <%= port %>;
const app = new koa(); const app = new koa();
@ -8,6 +9,6 @@ app.use(async ctx =>{
ctx.body = { 'message': 'Hello API'}; ctx.body = { 'message': 'Hello API'};
}); });
app.listen(port, () => { app.listen(port, host, () => {
console.log(`[ ready ] http://localhost:${port}`); console.log(`[ ready ] http://${host}:${port}`);
}); });

View File

@ -89,7 +89,7 @@
"framework": { "framework": {
"description": "Generate the node application using a framework", "description": "Generate the node application using a framework",
"type": "string", "type": "string",
"enum": ["express", "koa", "fastify", "none"], "enum": ["express", "fastify", "koa", "none"],
"default": "none", "default": "none",
"x-prompt": "Which framework do you want to use?", "x-prompt": "Which framework do you want to use?",
"x-priority": "important" "x-priority": "important"

View File

@ -1,11 +1,20 @@
# This file is generated by Nx.
#
# Build the docker image with `npx nx docker-build <%= project %>`.
# Tip: Modify "docker-build" options in project.json to change docker build args.
#
# Run the container with `docker run -p 3000:3000 -t <%= project %>`.
FROM docker.io/node:lts-alpine FROM docker.io/node:lts-alpine
ENV HOST=0.0.0.0
ENV PORT=3000
WORKDIR /app WORKDIR /app
RUN addgroup --system <%= projectName %> && \ RUN addgroup --system <%= project %> && \
adduser --system -G <%= projectName %> <%= projectName %> adduser --system -G <%= project %> <%= project %>
COPY <%= buildLocation %> dist COPY <%= buildLocation %> <%= project %>
RUN chown -R <%= projectName %>:<%= projectName %> . RUN chown -R <%= project %>:<%= project %> .
CMD [ "node", "dist" ] CMD [ "node", "<%= project %>" ]

View File

@ -1,5 +1,5 @@
export interface SetUpDockerOptions { export interface SetUpDockerOptions {
projectName?: string; project?: string;
targetName?: string; targetName?: string;
buildTarget?: string; buildTarget?: string;
skipFormat?: boolean; skipFormat?: boolean;

View File

@ -6,10 +6,14 @@
"description": "Nx Node Docker Options Schema.", "description": "Nx Node Docker Options Schema.",
"type": "object", "type": "object",
"properties": { "properties": {
"projectName": { "project": {
"description": "The name of the project", "description": "The name of the project",
"$default": { "$source": "argv", "index": 0 }, "$default": {
"type": "string" "$source": "projectName"
},
"type": "string",
"x-prompt": "What project would you like to add a Dockerfile to?",
"x-priority": "important"
}, },
"targetName": { "targetName": {
"description": "The name of the target to create", "description": "The name of the target to create",

View File

@ -25,7 +25,7 @@ describe('setupDockerGenerator', () => {
dependsOn: ['build'], dependsOn: ['build'],
executor: 'nx:run-commands', executor: 'nx:run-commands',
options: { options: {
commands: ['docker build -f api/Dockerfile .'], commands: ['docker build -f api/Dockerfile . -t api'],
}, },
}, },
}) })
@ -50,7 +50,7 @@ describe('setupDockerGenerator', () => {
dependsOn: ['build'], dependsOn: ['build'],
executor: 'nx:run-commands', executor: 'nx:run-commands',
options: { options: {
commands: ['docker build -f Dockerfile .'], commands: ['docker build -f Dockerfile . -t api'],
}, },
}, },
}) })

View File

@ -20,14 +20,14 @@ function normalizeOptions(
): SetUpDockerOptions { ): SetUpDockerOptions {
return { return {
...setupOptions, ...setupOptions,
projectName: setupOptions.projectName ?? readNxJson(tree).defaultProject, project: setupOptions.project ?? readNxJson(tree).defaultProject,
targetName: setupOptions.targetName ?? 'docker-build', targetName: setupOptions.targetName ?? 'docker-build',
buildTarget: setupOptions.buildTarget ?? 'build', buildTarget: setupOptions.buildTarget ?? 'build',
}; };
} }
function addDocker(tree: Tree, options: SetUpDockerOptions) { function addDocker(tree: Tree, options: SetUpDockerOptions) {
const project = readProjectConfiguration(tree, options.projectName); const project = readProjectConfiguration(tree, options.project);
if (!project || !options.targetName) { if (!project || !options.targetName) {
return; return;
} }
@ -43,13 +43,13 @@ function addDocker(tree: Tree, options: SetUpDockerOptions) {
tmpl: '', tmpl: '',
app: project.sourceRoot, app: project.sourceRoot,
buildLocation: outputPath, buildLocation: outputPath,
projectName: options.projectName, project: options.project,
}); });
} }
} }
export function updateProjectConfig(tree: Tree, options: SetUpDockerOptions) { export function updateProjectConfig(tree: Tree, options: SetUpDockerOptions) {
let projectConfig = readProjectConfiguration(tree, options.projectName); let projectConfig = readProjectConfiguration(tree, options.project);
projectConfig.targets[`${options.targetName}`] = { projectConfig.targets[`${options.targetName}`] = {
dependsOn: [`${options.buildTarget}`], dependsOn: [`${options.buildTarget}`],
@ -59,12 +59,12 @@ export function updateProjectConfig(tree: Tree, options: SetUpDockerOptions) {
`docker build -f ${joinPathFragments( `docker build -f ${joinPathFragments(
projectConfig.root, projectConfig.root,
'Dockerfile' 'Dockerfile'
)} .`, )} . -t ${options.project}`,
], ],
}, },
}; };
updateProjectConfiguration(tree, options.projectName, projectConfig); updateProjectConfiguration(tree, options.project, projectConfig);
} }
export async function setupDockerGenerator( export async function setupDockerGenerator(