manishraj27 / mern-project-cli

A developer-friendly CLI tool that streamlines MERN stack development by automating project setup, database configuration, and boilerplate generation by implementing MVC Architecture. Create production-ready MongoDB, Express, React, and Node.js applications with best practices built-in
https://devcli.vercel.app
MIT License
13 stars 7 forks source link

Add Docker File #7

Open pantharshit007 opened 1 day ago

pantharshit007 commented 1 day ago

Hey, I think it would be much better if we also ship prod ready project along with docker to dockerize the whole app.

manishraj27 commented 1 day ago

Hi, Thanks for your interest in adding Docker support to the mern-project-cli package! Although I'm new to Docker, I’m excited to explore this addition with your help.

Although I see these implements if done so!

  1. Dockerfile Setup: One Dockerfile for the backend and potentially one for the frontend, setting up each service in the MERN stack.
  2. Docker Compose: Using docker-compose.yml to define multiple services (Node.js, MongoDB, and optionally React) and simplify container management.
  3. New CLI Command: A devcli dockerize command that generates Docker-related files in the project, checking for existing files to avoid overwriting.
pantharshit007 commented 1 day ago

New CLI Command: A devcli dockerize command that generates Docker-related files in the project, checking for existing files to avoid overwriting.

since I don't have much knowledge about making a custom command like you have done for mongo and redux but I will incorporate them in the existing scripts such that they will automatically be built alongside the application so user still have the option to either run both the backend and frontend manually or just hit the command in root docker-compose up

manishraj27 commented 1 day ago

Let’s aim for Dockerfiles for both, plus a devcli dockerize command to set up Docker files automatically. Your idea to have both manual and docker-compose up options is perfect! but you can take idea from mongodb and redux command codes.

pantharshit007 commented 1 day ago

i'll try that but cli option will be second priority and do add the hacktober tag

manishraj27 commented 1 day ago

if you like the tool consider giving a star!

manishraj27 commented 4 hours ago

@pantharshit007 https://github.com/manishraj27/mern-project-cli/compare/main...pull/8/head

The problem is you have made changes to mongoDb connect command as well in that you changed dbname statically the previous command took dynamic dbname.

Your initializeDocker.js is perfect after i made some changes in it you can see in the link there. I need only this file in your pr request.

manishraj27 commented 4 hours ago

@pantharshit007 i have cherry picked the initializeDocker.js file after making some changes in the code. Since i used my own local branch to test your pr and pushed only that file i cant merge your whole pr.

But i want to give credit to you for creating initializeDocker.js so give your email.

or if you can break just raise one more pr with just initializeDocker.js and index.js than it would be perfect. below is your code with few changes.


import fs from 'fs-extra'; import path from 'path'; import chalk from 'chalk';

export default function initializeDockerCommand(program) { program .command('create-dockerfiles') .description( 'Generate Dockerfiles for backend and frontend, and docker-compose.yml in root' ) .action(() => { const currentDir = process.cwd();

  // Check if backend and frontend directories exist
  const backendDir = path.join(currentDir, 'backend');
  const frontendDir = path.join(currentDir, 'frontend');

  const hasBackendDir = fs.existsSync(backendDir);
  const hasFrontendDir = fs.existsSync(frontendDir);

  if (!hasBackendDir || !hasFrontendDir) {
    console.error(chalk.red('❌ Required directory structure not found.'));
    console.log(
      chalk.yellow(
        'πŸ“ Please ensure both "backend" and "frontend" directories exist in the current directory.'
      )
    );
    return;
  }
  // Dockerfile for backend
  const backendDockerfileContent = `# Use the official Node.js image

FROM node:20-alpine

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 5000

CMD ["npm", "run", "dev"] ; const dockerIgnore =node_modules dist`;

  // Dockerfile for frontend
  const frontendDockerfileContent = `# Use the official Node.js image

FROM node:20-alpine

Set the working directory

WORKDIR /app

Copy package.json and package-lock.json

COPY package*.json ./

Install dependencies

RUN npm install

Copy the rest of the application files

COPY . .

Expose the port

EXPOSE 3000

Start the application in development mode

CMD ["npm", "start"]

`;

  // docker-compose.yml content
  const dockerComposeContent = `# version: "3.8"

services: backend: build: ./backend ports:

volumes: mongo_data:

`;

  // Create backend Dockerfile & .dockerignore
  const backendDockerfilePath = path.join(backendDir, 'Dockerfile');
  const backendDockerIgorefilePath = path.join(backendDir, '.dockerignore');
  try {
    fs.writeFileSync(backendDockerfilePath, backendDockerfileContent);
    fs.writeFileSync(backendDockerIgorefilePath, dockerIgnore);
    console.log(chalk.green('βœ… Backend Dockerfile created successfully.'));
  } catch (error) {
    console.error(
      chalk.red(`❌ Failed to create Backend Dockerfile: ${error.message}`)
    );
    return;
  }

  // Create frontend Dockerfile & .dockerignore
  const frontendDockerfilePath = path.join(frontendDir, 'Dockerfile');
  const frontendDockerIgorefilePath = path.join(
    frontendDir,
    '.dockerignore'
  );
  try {
    fs.writeFileSync(frontendDockerfilePath, frontendDockerfileContent);
    fs.writeFileSync(frontendDockerIgorefilePath, dockerIgnore);
    console.log(
      chalk.green('βœ… Frontend Dockerfile created successfully.')
    );
  } catch (error) {
    console.error(
      chalk.red(`❌ Failed to create Frontend Dockerfile: ${error.message}`)
    );
    return;
  }

  // Create docker-compose.yml in root
  const dockerComposePath = path.join(currentDir, 'docker-compose.yml');
  try {
    fs.writeFileSync(dockerComposePath, dockerComposeContent);
    console.log(chalk.green('βœ… docker-compose.yml created successfully.'));
  } catch (error) {
    console.error(
      chalk.red(`❌ Failed to create docker-compose.yml: ${error.message}`)
    );
  }

  // Final success message
  console.log(chalk.cyan('\nπŸŽ‰ Docker files created successfully!'));
});

}


View Changes:

https://github.com/manishraj27/mern-project-cli/commit/c395d1821b05d09c8600c62c70b5e1b1f6f4ff36

pantharshit007 commented 3 hours ago

@manishraj27 I wll update these changes in Existing PR

image

pantharshit007 commented 1 hour ago

we can close this issue here you can add this tag hactoberfest-accepted

I want to say one thing the reason I made the db name static is because we are using static name here https://github.com/manishraj27/mern-project-cli/blob/aba2d1335e592b2712bc465cf43a98c1162beb63/commands/initializeDocker.js#L84C37-L84C47

so now you can do one thing grab the root directory name and dynamically add that in place of database name in docker-compose.yml file and remove those comments. This will do the trick

@manishraj27