My Node.js application consists of two separate components: an Express.js server and a CLI built with vanilla JavaScript and inquirer.js. These components communicate with each other through a REST API. The main reason for this setup is to adhere to the SOLID single responsibility principle, allowing flexibility to potentially switch out clients using different frameworks like React.js while maintaining the same server-database structure.
The app is currently functioning smoothly, but I aim to simplify its launch process by having a single command from the root folder that contains both client and server directories. After experimenting with npm packages on my own, I decided to delve into research to explore the possibility of utilizing Docker. A helpful article shed light on my query, prompting me to seek further information about Docker.
Thus far, I have created Dockerfiles for each component and attempted to utilize docker-compose
to manage the entire environment. Drawing insights from a relevant Stackoverflow Answer, I refined my approach working with docker-compose
. Additionally, I came across an informative article highlighting dockerization strategies for applications similar to mine.
Despite exploring various resources, I am still seeking guidance on how to establish a command to run my CLI app from its root folder. Although the solutions presented seem promising, integrating them within my project remains a challenge despite referencing official documentation.
This personal project serves as part of my backend development studies, and I aspire to enhance my proficiency with Docker. Rather than solely obtaining a solution to my immediate dilemma, I consider this an opportune moment to engage with the community, reaffirming concepts I've acquired. Please feel free to pinpoint any areas I should revisit for further study.
- Docker image: Standardizes the development environment to promote consistency among team members and avoid compatibility discrepancies.
- Docker container: Contains all necessary elements for an application to function within a specified environment, encompassing source code and dependencies
- Docker files: Record sequences of steps followed by Docker to generate a container, including image creation, dependency installation, and source code allocation
- Docker compose file: Orchestrates and manages the development environment settings.
While the discussion has primarily revolved around the development environment, production-related aspects have yet to be addressed. Specifically, if users are expected to interact with my CLI application, they would require Docker installed on their machines for seamless operation. Is Docker indeed the ultimate panacea in this scenario?
Objectives:
- Create a streamlined command enabling users to launch the app from the root directory
- Prioritize server initiation before client activation; prevent client execution without an active server
- Run the server discretely in the background, eliminating the need for additional terminal windows
- Elegantly conclude both client and server operations upon
SIGINT
orSIGTERM
Based on existing knowledge, it appears that docker-compose
effectively addresses objectives 2, 3, and 4, although uncertainties persist regarding the first goal.
Project Structure:
root
docker-compose.yaml
client
Dockerfile
node_modules
package.json
package-lock.json
...source code
server
Dockerfile
node_modules
package.json
package-lock.json
...source code
Should clarification be required on any aspect of my query, please don't hesitate to reach out.
Update
An important realization pointed out by Dave Maze emphasized the necessity of including both client and server Dockerfile
s along with the docker-compose.yaml
file to provide a comprehensive overview.
./client/Dockerfile
FROM node:latest
WORKDIR /client
COPY package.json package.json
RUN npm install
RUN npm install dateformat
COPY . .
ENTRYPOINT ["npm", "start"]
./server/Dockerfile
FROM node:latest
WORKDIR /server
COPY package.json package.json
RUN npm install
RUN npm install express-async-handler
ENV NODE_ENV=${NODE_ENV}
COPY . .
ENTRYPOINT ["npm","start"]
./docker-compose.yaml
version: "3.3"
services:
backend:
build:
context: "./server"
container_name: server
ports:
- "3000:3000"
command: node ./server/src/index.js
frontend:
depends_on:
- backend
build: ./client
Recent adjustments based on feedback received have ensured correct image creation via Docker Compose. However, operational execution deviates from the intended design, an area warranting elaboration within the initial question description.
Design:
The CLI program facilitates blog post creation, editing, basic administrative tasks under the author profile, and enables readers to comment and peruse posts via the reader profile. This functionality is contingent upon specific command line flags:
blogcli -a
grants access to the author profile.
blogcli -r
provides access to the reader profile.
blogcli
or incorrect options yield help prompts.
Running docker-compose
initiates program execution without facilitating flag input during frontend startup. While the EntryPoint
directive in ./client/Dockerfile governs expected behavior, I ponder alternative methods granting users executing docker-compose up the ability to apply desired flags directly. Your insights on this matter would be greatly appreciated.