Docker container with fnm
installed that is capable of running monorepos in one container through s6-overlay
.
- CLI will run and parse your variables and generate scripts for each service for
s6-overlay
. - CLI will install specific node version if defined in the configuration file or by
.node-version
or.nvmrc
file in the root folder. Otherwise it will use the default version, which is the latest. - Script will install dependencies if
node_modules
is missing in the root folder orforce_install
option is enabled. s6-overlay
will take care of the rest, and will start and monitor the services to restart the dead ones.
This container is useful in cases:
- where you want to run multiple node services as in the case of a monorepo inside the same container.
- where you want to restart the services if it crashes.
- use a specific node version pinned with
fnm
ornvm
.
Configuration can be done in multiple ways and they load in a specific order that proceeds each other.
The application will:
- Load the default configuration which is default.yml.
- Check for mounted configuration file at
/config/services.yml
, merge it with the default one. - Look for environment variables that can overwrite individual properties.
A yaml configuration file can be mounted to container at /config/services.yml
. This will be merged with the defaults, which is exactly the example below.
# global settings
package_manager: pnpm # valid values npm, yarn
dont_install: false # disables the initial install process where node_modules is not found
force_install: false # to add --force flag to the package manager for initial start
before_all: false # runs something before running anything else, can be an array of command or false
# default settings will be injected to all the services
defaults:
node_version: default # set the node version, overwrites the nvmrc file in the root. version that can fnm or nvm can accept
sync_wait: 10 # wait between the services a pre-given time if sync is true
restart_wait: 3 # wait before restarting the service, if crashed
enable: true # enables or disables a service
before: false # a command to run before the task, can be an array of commands or false
log: # logs can be an enum of 0, fatal, error, warn, info, debug, trace
stdout: info
stderr: warn
lifetime: debug
command: pnpm run dev:start # default command to run
sync: false # this will run the sync flagged services first and one-by-one with the sync_wait and run the others afterwards
run_once: false # run the service once and do not try to restart
exit_on_error: true # exit the whole container when there is a error with a given service
# Object for passing in environment variables to services
# environment:
# definition of the services, will overwrite the defaults for each service
# you can use the same settings in the defaults here as well
services:
- cwd: . # current working directory relative to /data
# name: # you can give a friendly name to the service, if empty it will use the cwd
# command: pnpm run dev:start
Environment Variable | Format | description |
---|---|---|
LOG_LEVEL | enum('debug', 'verbose , 'module', 'info', 'warn', 'error', 'fatal') |
Environment Variable | Format | description |
---|---|---|
PACKAGE_MANAGER | enum('yarn', 'npm', 'pnpm') | |
DONT_INSTALL | boolean | |
FORCE_INSTALL | boolean | |
BEFORE_ALL | json | array of commands to run |
Environment Variable | Format | description |
---|---|---|
NODE_VERSION | string | |
SYNC_WAIT | number | in seconds |
RESTART_WAIT | number | in seconds |
DEFAULTS_ENABLE | boolean | |
DEFAULTS_BEFORE | json | in array form |
DEFALTS_LOGS | enum(true, false, 'prefix') | |
DEFAULTS_COMMAND | string | |
DEFAULTS_SYNC | boolean | |
DEFAULTS_RUN_ONCE | boolean | |
DEFAULTS_EXIT_ON_ERROR | boolean | |
DEFAULTS_ENVIRONMENT | json | in object form |
Environment Variable | Format | description |
---|---|---|
SERVICES | json | in array form |
Service extension variables can be defined in the form of SERVICE_${serviceNumberInsideTheArray}_${variable.name}
.
So if you want to modify a property from the 0th service in the services array it should be like SERVICE_0_PROPERTY
.
Environment Variable | Format | description |
---|---|---|
SERVICE_${i}_NODE_VERSION | string | |
SERVICE_${i}_SYNC_WAIT | number | in seconds |
SERVICE_${i}_RESTART_WAIT | number | in seconds |
SERVICE_${i}_CWD | string | required |
SERVICE_${i}_NAME | string | |
SERVICE_${i}_ENABLE | boolean | |
SERVICE_${i}_NODE_VERSION | string | |
SERVICE_${i}_BEFORE | json | in array form |
SERVICE_${i}_LOGS | enum(true, false, 'prefix') | |
SERVICE_${i}_COMMAND | string | |
SERVICE_${i}_SYNC | boolean | |
SERVICE_${i}_RUN_ONCE | boolean | |
SERVICE_${i}_EXIT_ON_ERROR | boolean | |
SERVICE_${i}_ENVIRONMENT | json | in object form |
Image name: cenk1cenk2/node-fnm
Mount your application root to /data
in the container. Check configuration for defining your services.
For example configurations:
Container has a inbuilt CLI script to proxy commands through the packages. You can add a basic shell script to your package root called cli.sh
and proxy commands through the container.
#!/bin/bash
CONTAINER_NAME=monorepo
docker-compose exec "${CONTAINER_NAME}" /bin/bash -c "docker-node-fnm-init proxy ${*}"
There is also a gist available here.
before_all: false # runs something before running anything else, can be an array of command or false
Environment Variable | Format | description |
---|---|---|
LOG_LEVEL | enum('debug', 'verbose , 'module', 'info', 'warn', 'error', 'fatal') |
Environment Variable | Format | description |
---|---|---|
PROXY_BEFORE_ALL | json | array of commands to run |