feat: 초기 프로젝트 설정 및 룰.md 파일 추가

This commit is contained in:
2025-07-28 09:53:31 +09:00
commit 09a4d38512
8165 changed files with 1021855 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
FROM anapsix/alpine-java:latest
RUN apk update && apk add git && rm -rf /var/cache/apk/*
RUN npm install pm2@next -g
RUN mkdir -p /var/app
WORKDIR /var/app

View File

@@ -0,0 +1,8 @@
FROM keymetrics/pm2:latest
RUN mkdir -p /var/app
WORKDIR /var/app
COPY ./package.json /var/app
RUN npm install

View File

@@ -0,0 +1,7 @@
FROM anapsix/alpine-ruby:latest
RUN apk update && apk add git && rm -rf /var/cache/apk/*
RUN npm install pm2@next -g
RUN mkdir -p /var/app
WORKDIR /var/app

View File

@@ -0,0 +1,24 @@
const config = {
apps : [{
script: 'index.js',
watch: '.'
}, {
script: './service-worker/',
watch: ['./service-worker']
}],
deploy : {
production : {
user : 'SSH_USERNAME',
host : 'SSH_HOSTMACHINE',
ref : 'origin/master',
repo : 'GIT_REPOSITORY',
path : 'DESTINATION_PATH',
'pre-deploy-local': '',
'post-deploy' : 'npm install && pm2 reload ecosystem.config.js --env production',
'pre-setup': ''
}
}
};
export default config;

View File

@@ -0,0 +1,8 @@
const config = {
apps : [{
name : "app1",
script : "./app.js"
}]
}
export default config;

View File

@@ -0,0 +1,6 @@
module.exports = {
apps : [{
name : "app1",
script : "./app.js"
}]
}

View File

@@ -0,0 +1,22 @@
module.exports = {
apps : [{
script: 'index.js',
watch: '.'
}, {
script: './service-worker/',
watch: ['./service-worker']
}],
deploy : {
production : {
user : 'SSH_USERNAME',
host : 'SSH_HOSTMACHINE',
ref : 'origin/master',
repo : 'GIT_REPOSITORY',
path : 'DESTINATION_PATH',
'pre-deploy-local': '',
'post-deploy' : 'npm install && pm2 reload ecosystem.config.js --env production',
'pre-setup': ''
}
}
};

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.PM2</string>
<key>UserName</key>
<string>%USER%</string>
<key>KeepAlive</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>/bin/sh</string>
<string>-c</string>
<string>%PM2_PATH% resurrect</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>OnDemand</key>
<false/>
<key>LaunchOnlyOnce</key>
<true/>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>%NODE_PATH%</string>
<key>PM2_HOME</key>
<string>%HOME_PATH%</string>
</dict>
<key>StandardErrorPath</key>
<string>/tmp/com.PM2.err</string>
<key>StandardOutPath</key>
<string>/tmp/com.PM2.out</string>
</dict>
</plist>

View File

@@ -0,0 +1,52 @@
#!/sbin/openrc-run
# Copyright 2013-2022 the PM2 project authors. All rights reserved.
# Init script automatically generated by pm2 startup
description="Production process manager for Node.js apps with a built-in load balancer."
extra_started_commands="reload"
PM2="%PM2_PATH%"
user=${PM2_USER:-%USER%}
export PM2_HOME=$(eval echo ~${user})"/.pm2/"
# Options for start-stop-daemon (default start function)
command=${PM2}
command_user=${user}
command_args="resurrect"
pidfile=${PM2_HOME}/pm2.pid
run_pm2_as_user() {
einfo "${PM2} $@"
eval su -l ${user} -c \'${PM2} $@\'
}
depend() {
need net
need localmount
after bootmisc
}
start_post() {
if [ "${user}" == "root" ]; then
ewarn "PM2: Better run this daemon as a non root user. To set this user create"
ewarn "PM2: /etc/conf.d/pm2 file and define 'PM2_USER=user' there."
ewarn "PM2: Note user MUST have home directory for PM2 logs/state/etc..."
fi
einfo "PM2: Process Manager started. To start services run:"
einfo "PM2: # su -l ${user} -c '$PM2 start /path/to/app'"
}
stop() {
ebegin "Stopping PM2 process manager..."
run_pm2_as_user dump
run_pm2_as_user kill
eend $?
}
reload() {
ebegin "Reloading pm2"
run_pm2_as_user reload all
eend $?
}
# vim: ts=4

View File

@@ -0,0 +1,86 @@
#!/bin/bash
#
# pm2 Process manager for NodeJS
#
# chkconfig: 345 80 20
#
# description: PM2 next gen process manager for Node.js
# processname: pm2
#
### BEGIN INIT INFO
# Provides: pm2
# Required-Start: $local_fs $remote_fs
# Required-Stop: $local_fs $remote_fs
# Should-Start: $network
# Should-Stop: $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: PM2 init script
# Description: PM2 is the next gen process manager for Node.js
### END INIT INFO
NAME=pm2
PM2=%PM2_PATH%
USER=%USER%
export PATH=%NODE_PATH%:$PATH
export PM2_HOME="%HOME_PATH%"
lockfile="/var/lock/subsys/pm2-init.sh"
super() {
su - $USER -c "PATH=$PATH; PM2_HOME=$PM2_HOME $*"
}
start() {
echo "Starting $NAME"
super $PM2 resurrect
retval=$?
[ $retval -eq 0 ] && touch $lockfile
}
stop() {
echo "Stopping $NAME"
super $PM2 kill
rm -f $lockfile
}
restart() {
echo "Restarting $NAME"
stop
start
}
reload() {
echo "Reloading $NAME"
super $PM2 reload all
}
status() {
echo "Status for $NAME:"
super $PM2 list
RETVAL=$?
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart)
restart
;;
reload)
reload
;;
*)
echo "Usage: {start|stop|status|restart|reload}"
exit 1
;;
esac
exit $RETVAL

View File

@@ -0,0 +1,41 @@
#!/bin/sh
#
# from /usr/ports/infrastructure/templates/rc.template
daemon="/usr/local/bin/pm2"
#daemon_flags=
#daemon_rtable=0
#daemon_timeout="30"
daemon_user="%USER%"
. /etc/rc.d/rc.subr
pexp="node: PM2.*God Daemon.*"
#rc_bg= # (undefined)
#rc_reload= # (undefined)
#rc_usercheck=YES
#rc_pre() {
#}
rc_start() {
${rcexec} "${daemon} ${daemon_flags} resurrect"
}
#rc_check() {
# pgrep -T "${daemon_rtable}" -q -xf "${pexp}"
#}
rc_reload() {
${rcexec} "${daemon} reload all"
#pkill -HUP -T "${daemon_rtable}" -xf "${pexp}"
}
#rc_stop() {
# pkill -T "${daemon_rtable}" -xf "${pexp}"
#}
#rc_post() {
#}
rc_cmd $1

View File

@@ -0,0 +1,44 @@
#!/bin/sh
# PROVIDE: pm2
# REQUIRE: LOGIN
# KEYWORD: shutdown
. /etc/rc.subr
name="%SERVICE_NAME%"
rcvar="%SERVICE_NAME%_enable"
start_cmd="pm2_start"
stop_cmd="pm2_stop"
reload_cmd="pm2_reload"
status_cmd="pm2_status"
extra_commands="reload status"
pm2()
{
env PATH="$PATH:%NODE_PATH%" PM2_HOME="%HOME_PATH%" su -m "%USER%" -c "%PM2_PATH% $*"
}
pm2_start()
{
pm2 resurrect
}
pm2_stop()
{
pm2 kill
}
pm2_reload()
{
pm2 reload all
}
pm2_status()
{
pm2 list
}
load_rc_config $name
run_rc_command "$1"

View File

@@ -0,0 +1,43 @@
<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<service_bundle type="manifest" name="%SERVICE_NAME%">
<service name="application/%SERVICE_NAME%" type="service" version="1">
<create_default_instance enabled="false"/>
<single_instance/>
<dependency name="network" grouping="require_all" restart_on="error" type="service">
<service_fmri value="svc:/milestone/network:default"/>
</dependency>
<dependency name="filesystem" grouping="require_all" restart_on="error" type="service">
<service_fmri value="svc:/system/filesystem/local"/>
</dependency>
<method_context>
<method_environment>
<envvar name='PATH' value="%NODE_PATH%:/usr/local/sbin:/usr/local/bin:/opt/local/sbin:/opt/local/bin:/usr/sbin:/usr/bin:/sbin"/>
<envvar name='PM2_HOME' value="%HOME_PATH%"/>
</method_environment>
</method_context>
<exec_method type="method" name="start" exec="%PM2_PATH% resurrect" timeout_seconds="60"/>
<exec_method type="method" name="refresh" exec="%PM2_PATH% reload all" timeout_seconds="60"/>
<exec_method type="method" name="stop" exec="%PM2_PATH% kill" timeout_seconds="60"/>
<property_group name="startd" type="framework">
<propval name="duration" type="astring" value="contract"/>
<propval name="ignore_error" type="astring" value="core,signal"/>
</property_group>
<property_group name="application" type="application"></property_group>
<stability value="Evolving"/>
<template>
<common_name>
<loctext xml:lang="C">
PM2 process manager
</loctext>
</common_name>
</template>
</service>
</service_bundle>

View File

@@ -0,0 +1,22 @@
[Unit]
Description=PM2 process manager
Documentation=https://pm2.keymetrics.io/
After=network-online.target
Restart=on-failure
[Service]
Type=forking
User=%USER%
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
Environment=PATH=%NODE_PATH%:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
Environment=PM2_HOME=%HOME_PATH%
PIDFile=%HOME_PATH%/pm2.pid
ExecStart=%PM2_PATH% resurrect
ExecReload=%PM2_PATH% reload all
ExecStop=%PM2_PATH% kill
[Install]
WantedBy=network-online.target

View File

@@ -0,0 +1,22 @@
[Unit]
Description=PM2 process manager
Documentation=https://pm2.keymetrics.io/
After=network.target
[Service]
Type=forking
User=%USER%
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
Environment=PATH=%NODE_PATH%:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
Environment=PM2_HOME=%HOME_PATH%
PIDFile=%HOME_PATH%/pm2.pid
Restart=on-failure
ExecStart=%PM2_PATH% resurrect
ExecReload=%PM2_PATH% reload all
ExecStop=%PM2_PATH% kill
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,103 @@
#!/bin/bash
### BEGIN INIT INFO
# Provides: pm2
# Required-Start: $local_fs $remote_fs $network
# Required-Stop: $local_fs $remote_fs $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: PM2 Init script
# Description: PM2 process manager
### END INIT INFO
NAME=pm2
PM2=%PM2_PATH%
USER=%USER%
DEFAULT=/etc/default/$NAME
export PATH=%NODE_PATH%:$PATH
export PM2_HOME="%HOME_PATH%"
# The following variables can be overwritten in $DEFAULT
# maximum number of open files
MAX_OPEN_FILES=
# overwrite settings from default file
if [ -f "$DEFAULT" ]; then
. "$DEFAULT"
fi
# set maximum open files if set
if [ -n "$MAX_OPEN_FILES" ]; then
ulimit -n $MAX_OPEN_FILES
fi
get_user_shell() {
local shell
shell=$(getent passwd "${1:-$(whoami)}" | cut -d: -f7 | sed -e 's/[[:space:]]*$//')
if [[ $shell == *"/sbin/nologin" ]] || [[ $shell == "/bin/false" ]] || [[ -z "$shell" ]];
then
shell="/bin/bash"
fi
echo "$shell"
}
super() {
local shell
shell=$(get_user_shell $USER)
su - "$USER" -s "$shell" -c "PATH=$PATH; PM2_HOME=$PM2_HOME $*"
}
start() {
echo "Starting $NAME"
super $PM2 resurrect
}
stop() {
super $PM2 kill
}
restart() {
echo "Restarting $NAME"
stop
start
}
reload() {
echo "Reloading $NAME"
super $PM2 reload all
}
status() {
echo "Status for $NAME:"
super $PM2 list
RETVAL=$?
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart)
restart
;;
reload)
reload
;;
force-reload)
reload
;;
*)
echo "Usage: {start|stop|status|restart|reload|force-reload}"
exit 1
;;
esac
exit $RETVAL

View File

@@ -0,0 +1,10 @@
%HOME_PATH%/pm2.log %HOME_PATH%/logs/*.log {
rotate 12
weekly
missingok
notifempty
compress
delaycompress
copytruncate
create 0640 %USER% %USER%
}

View File

@@ -0,0 +1,14 @@
# Basic HTTP Server and Cluster mode
In this boilerplate it will start an http server in cluster mode.
You can check the content of the ecosystem.config.js on how to start mutliple instances of the same HTTP application in order to get the most from your working system.
## Via CLI
Via CLI you can start any HTTP/TCP application in cluster mode with:
```bash
$ pm2 start api.js -i max
```

View File

@@ -0,0 +1,9 @@
var http = require('http');
var server = http.createServer(function(req, res) {
res.writeHead(200);
res.end('hey');
}).listen(process.env.PORT || 8000, function() {
console.log('App listening on port %d', server.address().port);
});

View File

@@ -0,0 +1,14 @@
module.exports = {
apps : [{
name: 'API',
script: 'api.js',
instances: 4,
max_memory_restart: '1G',
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
}
}]
};

View File

@@ -0,0 +1,11 @@
{
"name": "simple-http-server",
"version": "1.0.0",
"description": "Simple HTTP server that can be used in cluster mode",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

View File

@@ -0,0 +1,45 @@
# pm2 custom metrics boilerplate
In this boilerplate you will discover a working example of custom metrics feature.
Metrics covered are:
- io.metric
- io.counter
- io.meter
- io.histogram
## What is Custom Metrics?
Custom metrics is a powerfull way to get more visibility from a running application. It will allow you to monitor in realtime the current value of variables, know the number of actions being processed, measure latency and much more.
Once you have plugged in some custom metrics you will be able to monitor their value in realtime with
`pm2 monit`
Or
`pm2 describe`
Or on the PM2+ Web interface
`pm2 open`
## Example
```javascript
const io = require('@pm2/io')
const currentReq = io.counter({
name: 'CM: Current Processing',
type: 'counter'
})
setInterval(() => {
currentReq.inc()
}, 1000)
```
## Documentation
https://doc.pm2.io/en/plus/guide/custom-metrics/

View File

@@ -0,0 +1,66 @@
const io = require('@pm2/io')
// Straight Metric
var user_count = 10
const users = io.metric({
name: 'CM: Realtime user',
value: () => {
return user_count
}
})
// or users.set(user_count)
// Counter (.inc() .dec())
const currentReq = io.counter({
name: 'CM: Current Processing',
type: 'counter'
})
setInterval(() => {
currentReq.inc()
}, 1000)
// Meter
const reqsec = io.meter({
name: 'CM: req/sec'
})
setInterval(() => {
reqsec.mark()
}, 100)
// Histogram
const latency = io.histogram({
name: 'CM: latency'
});
var latencyValue = 0;
setInterval(() => {
latencyValue = Math.round(Math.random() * 100);
latency.update(latencyValue);
}, 100)
////////////////////
// Custom Actions //
////////////////////
io.action('add user', (done) => {
user_count++
done({success:true})
})
io.action('remove user', (done) => {
user_count++
done({success:true})
})
io.action('with params', (arg, done) => {
console.log(arg)
done({success:arg})
})

View File

@@ -0,0 +1,12 @@
module.exports = {
apps : [{
name: 'Custom Metrics',
script: 'custom-metrics.js',
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
}
}]
};

View File

@@ -0,0 +1,11 @@
{
"name": "pm2-plus-custom-metrics",
"version": "1.0.0",
"description": "Example that shows how to use pm2+ custom metrics",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

View File

@@ -0,0 +1,4 @@
# Managing a Python Application
On this boilerlate you will see how you can start a Python application with PM2.

View File

@@ -0,0 +1,7 @@
#!/usr/bin/python
import time
while 1:
print("Start : %s" % time.ctime())
print("second line")
time.sleep(1)

View File

@@ -0,0 +1,12 @@
module.exports = {
apps : [{
name: 'API',
script: 'echo.py',
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
}
}]
};

View File

@@ -0,0 +1,11 @@
{
"name": "python-app",
"version": "1.0.0",
"description": "Example on how to manage a Python application with PM2",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}