diff --git a/.editorconfig b/.editorconfig index 408d870..c7e975e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -20,3 +20,7 @@ insert_final_newline = false [**/templates/**] trim_trailing_whitespace = false insert_final_newline = false + +[{Makefile,**.mk}] +# Use tabs for indentation (Makefiles require tabs) +indent_style = tab diff --git a/.gitignore b/.gitignore index bf0bf44..2957ac9 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ # node.js node_modules +.data diff --git a/.verb.md b/.verb.md index 71cc2e2..3b0b13c 100644 --- a/.verb.md +++ b/.verb.md @@ -12,13 +12,7 @@ Just another "Hello World" docker image to be used in various experiments ... -### Table of Contents - -
- - - -
+Note: This Docker image is definitely not designed to be used in a production environment as it could result into serious security issues. But it's nice to be added to your toolbox when playing with Docker/Docker Swarm/Kubernetes, etc. ## Usage @@ -27,7 +21,7 @@ $ docker pull stefanwalther/{%=name%} ``` ```sh -$ docker run -it stefanwalther/{%=name%} +$ docker run -it -p 3000:3000 stefanwalther/{%=name%} ``` ### With docker-compose @@ -38,9 +32,9 @@ services: hello-world: image: stefanwalther/{%=name%} ports: - - 3004:3004 + - 3000:3000 environment: - - PORT=3004 + - PORT=3000 ``` @@ -51,11 +45,29 @@ services: ## Endpoints ### `/` -Just returns a "Hello World" +Just returns a "Hello World": + +```json +{ + "text": "Hello World" +} +``` ### `/health-check` Returns a typical health-check, useful to test health-checks in a microservice environment. +```json +{ + "ts": "2017-12-07T22:25:34.489Z", + "version": "0.3.1", + "name": "docker-test", + "repository": { + "type": "git", + "url": "git+https://github.com/stefanwalther/docker-test.git" + } +} +``` + ### `/cmd` Execute any command on the machine and get the result. @@ -65,12 +77,12 @@ Parameters: Usage: ```sh # Process ls -la -$ curl http://localhost:3004/cmd/?def=ls%20-la +$ curl http://localhost:3000/cmd/?def=ls%20-la ``` Examples: - `ls -la` - list the directory - - `curl -o -I -L -s -w "%{http_code}\n" http://localhost:3004/health-check` - Get the Http status code of the health-check + - `curl -o -I -L -s -w "%{http_code}\n" http://localhost:3000/health-check` - Get the Http status code of the health-check ### `/cmd-cron` Create a cron job, executing a command. @@ -84,7 +96,7 @@ Usage: ```sh # Process "echo foo" with the following cron def: "* * * * *" (every minute) -$ curl http://localhost:3004/cmd-cron?def=echo%20foo&cron=*%20*%20*%20*%20* +$ curl http://localhost:3000/cmd-cron?def=echo%20foo&cron=*%20*%20*%20*%20* ``` @@ -98,16 +110,6 @@ $ curl http://localhost:3004/cmd-cron?def=echo%20foo&cron=*%20*%20*%20*%20* - Using multi-stage builds to reduce Go images: https://blog.alexellis.io/mutli-stage-docker-builds/ - https://github.com/yamalight/node-docker-pkg-demo -## Todo - -- [ ] Use read-pkg-up - makes more sense -- [ ] Enable codecov -- [ ] Enable codeclimate -- [ ] Enable necessary badges -- [ ] Use multistage builds to truly separate images -- [ ] Use nodemon to watch changes locally -- [ ] Optimize precommit (husky) to not run it if there were no changes in either .verb.md or in ./docs -- [ ] Provide missing tests ## About diff --git a/CHANGELOG.yml b/CHANGELOG.yml index d3deaae..77ff0e6 100644 --- a/CHANGELOG.yml +++ b/CHANGELOG.yml @@ -1,3 +1,8 @@ +v0.3.2: + date: "2017-12-07" + changes: + - "Make port 3000 the default everywhere" + - "Add a Makefile" v0.3.1: date: "2017-09-18" changes: diff --git a/Dockerfile b/Dockerfile index 2264557..e785ec3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -47,6 +47,8 @@ FROM BASE as RELEASE COPY --from=dependencies /app/prod_node_modules ./node_modules COPY /src ./src/ +COPY ./nodemon.json ./ + EXPOSE $PORT CMD ["npm", "run", "start"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f24fe02 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +help: ## Show this help. + @echo '' + @echo 'Available commands:' + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + @echo '' +.PHONY: help + +gen-readme: ## Generate README.md (using docker-verb) + docker run --rm -v ${PWD}:/opt/verb stefanwalther/verb +.PHONY: gen-readme diff --git a/README.md b/README.md index cc744a8..da8e9b8 100644 --- a/README.md +++ b/README.md @@ -12,29 +12,7 @@ Just another "Hello World" docker image to be used in various experiments ... -### Table of Contents - -
- -- [Usage](#usage) - * [With docker-compose](#with-docker-compose) -- [Configuration](#configuration) -- [Endpoints](#endpoints) - * [`/`](#) - * [`/health-check`](#health-check) - * [`/cmd`](#cmd) - * [`/cmd-cron`](#cmd-cron) -- [Experiments](#experiments) - * [Multistage Builds](#multistage-builds) -- [Todo](#todo) -- [About](#about) - * [Author](#author) - * [Contributing](#contributing) - * [License](#license) - -_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_ - -
+Note: This Docker image is definitely not designed to be used in a production environment as it could result into serious security issues. But it's nice to be added to your toolbox when playing with Docker/Docker Swarm/Kubernetes, etc. ## Usage @@ -43,7 +21,7 @@ $ docker pull stefanwalther/docker-test ``` ```sh -$ docker run -it stefanwalther/docker-test +$ docker run -it -p 3000:3000 stefanwalther/docker-test ``` ### With docker-compose @@ -54,9 +32,9 @@ services: hello-world: image: stefanwalther/docker-test ports: - - 3004:3004 + - 3000:3000 environment: - - PORT=3004 + - PORT=3000 ``` @@ -67,11 +45,29 @@ services: ## Endpoints ### `/` -Just returns a "Hello World" +Just returns a "Hello World": + +```json +{ + "text": "Hello World" +} +``` ### `/health-check` Returns a typical health-check, useful to test health-checks in a microservice environment. +```json +{ + "ts": "2017-12-07T22:25:34.489Z", + "version": "0.3.1", + "name": "docker-test", + "repository": { + "type": "git", + "url": "git+https://github.com/stefanwalther/docker-test.git" + } +} +``` + ### `/cmd` Execute any command on the machine and get the result. @@ -81,12 +77,12 @@ Parameters: Usage: ```sh # Process ls -la -$ curl http://localhost:3004/cmd/?def=ls%20-la +$ curl http://localhost:3000/cmd/?def=ls%20-la ``` Examples: - `ls -la` - list the directory - - `curl -o -I -L -s -w "%{http_code}\n" http://localhost:3004/health-check` - Get the Http status code of the health-check + - `curl -o -I -L -s -w "%{http_code}\n" http://localhost:3000/health-check` - Get the Http status code of the health-check ### `/cmd-cron` Create a cron job, executing a command. @@ -100,7 +96,7 @@ Usage: ```sh # Process "echo foo" with the following cron def: "* * * * *" (every minute) -$ curl http://localhost:3004/cmd-cron?def=echo%20foo&cron=*%20*%20*%20*%20* +$ curl http://localhost:3000/cmd-cron?def=echo%20foo&cron=*%20*%20*%20*%20* ``` ## Experiments @@ -110,20 +106,9 @@ $ curl http://localhost:3004/cmd-cron?def=echo%20foo&cron=*%20*%20*%20*%20* **References:** - https://capgemini.github.io/development/multi-stage-builds-in-docker/ - https://codefresh.io/blog/node_docker_multistage/ -- https://blog.alexellis.io/mutli-stage-docker-builds/ +- Using multi-stage builds to reduce Go images: https://blog.alexellis.io/mutli-stage-docker-builds/ - https://github.com/yamalight/node-docker-pkg-demo -## Todo - -- [ ] Use read-pkg-up - makes more sense -- [ ] Enable codecov -- [ ] Enable codeclimate -- [ ] Enable necessary badges -- [ ] Use multistage builds to truly separate images -- [ ] Use nodemon to watch changes locally -- [ ] Optimize precommit (husky) to not run it if there were no changes in either .verb.md or in ./docs -- [ ] Provide missing tests - ## About ### Author diff --git a/configs/logstash/config/logstash.yml b/configs/logstash/config/logstash.yml new file mode 100644 index 0000000..c29769c --- /dev/null +++ b/configs/logstash/config/logstash.yml @@ -0,0 +1,15 @@ +--- +## Default Logstash configuration from logstash-docker. +## from https://github.com/elastic/logstash-docker/blob/master/build/logstash/config/logstash.yml +# +http.host: "0.0.0.0" + +## Disable X-Pack +## see https://www.elastic.co/guide/en/x-pack/current/xpack-settings.html +## https://www.elastic.co/guide/en/x-pack/current/installing-xpack.html#xpack-enabling +# +xpack.monitoring.enabled: false + +# config.debug: true +log.level: "info" +# path.config: "/usr/share/logstash/pipeline" diff --git a/configs/logstash/pipeline/logstash.conf b/configs/logstash/pipeline/logstash.conf new file mode 100644 index 0000000..5bb155f --- /dev/null +++ b/configs/logstash/pipeline/logstash.conf @@ -0,0 +1,42 @@ +input { +# gelf { +# port => 12201 +# } + tcp { + port => 10514 + codec => json + } +# tcp { +# port => 5000 +# codec => json +# } +# udp { +# port => 5000 +# codec => json +# } +} + +filter { + + json { + source => "message" + } + + mutate { + add_field => { + "token" => "${LOGZ_ACCOUNT_TOKEN}" + } + } + +} + +output { + stdout { + codec => rubydebug + } + tcp { + host => "listener.logz.io" + port => 5050 + codec => json_lines + } +} diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 2727786..acafb24 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -1,8 +1,11 @@ version: '3.3' services: - hello-world: + docker-test: + container_name: docker-test build: . command: ["npm", "run", "start:watch"] volumes: - ./src:/app/src + + diff --git a/docker-compose.logging.yml b/docker-compose.logging.yml new file mode 100644 index 0000000..90999ec --- /dev/null +++ b/docker-compose.logging.yml @@ -0,0 +1,35 @@ +version: '3.3' + +services: + docker-test: + build: . + command: ["npm", "run", "start:watch"] + volumes: + - ./src:/app/src + environment: + - DOCKER_LABELS=true + labels: + - io.sammler.env=DEV + - io.sammler.service=docker-test + + logstash: + image: docker.elastic.co/logstash/logstash:5.2.2 + ports: + - "10514:10514" + - "5000:5000" + - "5000:5000/udp" + - "12201" # gelf + - "12201:12201/udp" # gelf udp port +# expose: +# - "12201" + environment: + - LOGSPOUT=ignore + - DROP_NON_JSON=false + - STDOUT=true + - LS_JAVA_OPTS=-Xmx256m -Xms256m + - LOGZ_ACCOUNT_TOKEN=${S5R_LOGZ_ACCOUNT_TOKEN} + volumes: + - ./.data/logstash/logs:/usr/share/logstash/logs + - ./configs/logstash/pipeline/logstash.conf:/usr/share/logstash/pipeline/logstash.conf + - ./configs/logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml + diff --git a/docs/todos.md b/docs/todos.md new file mode 100644 index 0000000..a70d5f6 --- /dev/null +++ b/docs/todos.md @@ -0,0 +1,10 @@ +# Todos + +- [ ] Use read-pkg-up - makes more sense +- [ ] Enable codecov +- [ ] Enable codeclimate +- [ ] Enable necessary badges +- [ ] Use multistage builds to truly separate images +- [ ] Use nodemon to watch changes locally +- [ ] Optimize precommit (husky) to not run it if there were no changes in either .verb.md or in ./docs +- [ ] Provide missing tests \ No newline at end of file diff --git a/nodemon.json b/nodemon.json new file mode 100644 index 0000000..7ad5b85 --- /dev/null +++ b/nodemon.json @@ -0,0 +1,10 @@ +{ + "restartable": "rs", + "ignore": [ + ".git", + ".data", + "node_modules/**/node_modules" + ], + "verbose": true, + "ext": "js json" +} diff --git a/package-lock.json b/package-lock.json index 2dac24d..a413058 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1913,15 +1913,6 @@ "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -1932,6 +1923,15 @@ "strip-ansi": "4.0.0" } }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -2144,6 +2144,11 @@ "stack-trace": "0.0.10" } }, + "winston-logstash": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/winston-logstash/-/winston-logstash-0.3.0.tgz", + "integrity": "sha1-9x+hJ4vh8OroO8rT4i/kHVHH8ak=" + }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", diff --git a/package.json b/package.json index feda887..b4c97f0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "docker-test", - "version": "0.3.1", + "version": "0.3.2", "description": "Sample docker image to test various scenarios with Docker.", "keywords": [ "docker", @@ -23,7 +23,10 @@ "d-build": "docker build -t stefanwalther/docker-test .", "d-run": "docker run -it stefanwalther/docker-test", "dc-up:dev": "docker-compose --f=./docker-compose.dev.yml up", + "dc-up:logging": "docker-compose --f=./docker-compose.logging.yml up", + "dc-up:loggingb": "docker-compose --f=./docker-compose.logging.yml up --build", "dc-up:devb": "docker-compose --f=./docker-compose.dev.yml up --build", + "dc-down:logging": "docker-compose --f=./docker-compose.logging.yml down", "docs": "docker run --rm -v ${PWD}:/opt/verb stefanwalther/verb", "docs-if-necessary": "./scripts/docs-if-necessary.sh", "lint": "npm run lint:src && npm run lint:test", @@ -43,7 +46,8 @@ "glob": "^7.1.2", "node-schedule": "^1.2.5", "read-pkg-up": "^2.0.0", - "winster": "^0.2.6" + "winster": "^0.2.6", + "winston-logstash": "^0.3.0" }, "devDependencies": { "chai": "^4.1.2", @@ -71,5 +75,8 @@ "reflinks": true }, "reflinks": [] + }, + "winster": { + "configFile": "./src/config/winster-config.js" } } diff --git a/src/app-server.js b/src/app-server.js index 8f5e2ed..f08037e 100644 --- a/src/app-server.js +++ b/src/app-server.js @@ -14,6 +14,17 @@ class AppServer { _initApp() { this.app = express(); routesConfig.init(this.app); + + setInterval(() => { + logger.fatal('logger:fatal', 'Some message'); + logger.error('logger:error', {error: 'This is the error message', errorCode: 204}); + logger.debug('logger:debug'); + logger.warn('logger:warn'); + logger.data('logger:data'); + logger.info('logger:info'); + logger.verbose('logger:verbose'); + logger.trace('logger:trace'); + }, 10000); } start() { diff --git a/src/config/winster-config.js b/src/config/winster-config.js new file mode 100644 index 0000000..d38aaed --- /dev/null +++ b/src/config/winster-config.js @@ -0,0 +1,32 @@ +const Winston = require('winston'); +require('winston-logstash'); + +module.exports = { + development: [ + { + transporter: Winston.transports.Console, + options: { + name: 'Console-Dev', + level: 'trace', + colorize: false, + json: false, + prettyPrint: false, + handleExceptions: true, + humanReadableUnhandledException: true + } + }, + { + transporter: Winston.transports.Logstash, + options: { + name: 'logstash', + node_name: 'my node name', + port: 10514, + host: '127.0.0.1', + level: 'info', + colorize: false, + prettyPrint: false, + handleExceptions: true + } + } + ] +};