Closed kspotfujita closed 4 years ago
@kspotfujita ログが少ないので診断が難しいです。 起動時ログは、サーバーが立ち上がりきったあたりの行、 ダウン時ログは、最初に異常状態を現れたときの行を貼っていただけますか?
また、当該サーバーと http://localhost:3000 でアクセスを行ったマシンとの関係も書いていただけると材料になるかとは思います。
導入相談、トラブルシュートは slack の general チャンネルの方がコミュニティの力も借りることができて解決が早まると思うので、できればそちらへの投稿をおすすめします。
@yuki-takei Node.jsにあまり詳しくないので詳細なログを出力することが出来ないのですが、 とりあえず起動時の出力は以下の通りです。
> growi@4.0.2 prestart /opt/growi
> npm run build:prod
> growi@4.0.2 prebuild:prod /opt/growi
> npm run clean && env-cmd -f config/env.prod.js npm run plugin:def && env-cmd -f config/env.prod.js npm run resource
> growi@4.0.2 clean /opt/growi
> npm-run-all -p clean:*
> growi@4.0.2 clean:app /opt/growi
> rimraf -- public/js public/styles
> growi@4.0.2 clean:report /opt/growi
> rimraf -- report
> growi@4.0.2 plugin:def /opt/growi
> node bin/generate-plugin-definitions-source.js
[2020-06-05T03:23:21.377Z] INFO: growi:bin:generate-plugin-definitions-source/8445 on host: Detected plugins: []
> growi@4.0.2 resource /opt/growi
> node bin/download-cdn-resources.js
[2020-06-05T03:23:21.722Z] INFO: growi:bin:download-cdn-resources/8470 on host: Using CDN. No resources are downloaded.
> growi@4.0.2 build:prod /opt/growi
> env-cmd -f config/env.prod.js webpack --config config/webpack.prod.js --profile --bail
Browserslist: caniuse-lite is outdated. Please run next command `yarn upgrade caniuse-lite browserslist`
[hardsource:b7e53687] Using 3 MB of disk space.
[hardsource:b7e53687] Tracking node dependencies with: yarn.lock.
[hardsource:b7e53687] Reading from cache b7e53687...
[hardsource:b7e53687] Cache is corrupted.
RangeError [ERR_INVALID_OPT_VALUE]: The value "2147483648" is invalid for option "size"
at Function.allocUnsafe (buffer.js:384:3)
at alloc (/opt/growi/node_modules/hard-source-webpack-plugin/lib/SerializerAppend2.js:46:17)
at Append2._readFile (/opt/growi/node_modules/hard-source-webpack-plugin/lib/SerializerAppend2.js:160:14)
at async /opt/growi/node_modules/hard-source-webpack-plugin/lib/SerializerAppend2.js:194:40
at async Promise.all (index 0)
at async Promise.all (index 1)
エラー時は開始ログは以下のようでした。
0: ExitFrame [pc: 0x13cb519]
1: StubFrame [pc: 0x13c78bf]
Security context: 0x1d9c92a008d1 <JSObject>
2: add [0x1d9c92a0a0d9](this=0x10aa2353e529 <JSWeakSet>,0x0a5fd85f21d9 <AST_SymbolRef map = 0x322cb0fc26e9>)
3: before [0x9f0ceb88e81] [/opt/growi/node_modules/terser/dist/bundle.min.js:~1] [pc=0x446cd69e881](this=0x3955b5ea2af1 <En map = 0x140a5246929>,0x0a5fd85f21d9 <AST_SymbolRef map = 0x322cb0fc26e9>,0x35040d36f759 <JS...
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
1: 0xa07f90 node::Abort() [node]
2: 0xa0839c node::OnFatalError(char const*, char const*) [node]
3: 0xb80d9e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
4: 0xb81119 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
5: 0xd2d875 [node]
6: 0xd3e188 v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [node]
7: 0xd0502d v8::internal::Factory::NewFixedArrayWithFiller(v8::internal::RootIndex, int, v8::internal::Object, v8::internal::AllocationType) [node]
8: 0xd05120 v8::internal::Handle<v8::internal::FixedArray> v8::internal::Factory::NewFixedArrayWithMap<v8::internal::FixedArray>(v8::internal::RootIndex, int, v8::internal::AllocationType) [node]
9: 0xf1eca1 v8::internal::HashTable<v8::internal::EphemeronHashTable, v8::internal::EphemeronHashTableShape>::NewInternal(v8::internal::Isolate*, int, v8::internal::AllocationType) [node]
10: 0xf1ecfe v8::internal::HashTable<v8::internal::EphemeronHashTable, v8::internal::EphemeronHashTableShape>::New(v8::internal::Isolate*, int, v8::internal::AllocationType, v8::internal::MinimumCapacity) [node]
11: 0xf1f50b v8::internal::HashTable<v8::internal::EphemeronHashTable, v8::internal::EphemeronHashTableShape>::EnsureCapacity(v8::internal::Isolate*, v8::internal::Handle<v8::internal::EphemeronHashTable>, int, v8::internal::AllocationType) [node]
12: 0xf1fc5b v8::internal::ObjectHashTableBase<v8::internal::EphemeronHashTable, v8::internal::EphemeronHashTableShape>::Put(v8::internal::Isolate*, v8::internal::Handle<v8::internal::EphemeronHashTable>, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int) [node]
13: 0xf1fe6a v8::internal::JSWeakCollection::Set(v8::internal::Handle<v8::internal::JSWeakCollection>, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int) [node]
14: 0x102a2d8 v8::internal::Runtime_WeakCollectionSet(int, unsigned long*, v8::internal::Isolate*) [node]
15: 0x13cb519 [node]
起動確認はローカルサーバ内で
#telnet localhost 3000
で確認しております。
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
というエラーになります。 単純にメモリの話なら良いのですが、最低起動要件などあると助かります。 今回はIDCFクラウド上でgrowiの為だけに1GB memoryのサーバを確保し、CentOS7.7 ISOを使って起動し、そのまま公式ドキュメントに従ってインストールを試みました。その他の作業はサーバ上で行っておりません。 slackは使ったことがないのですが、確認してみます。
起動時じゃなくて、ビルド時に落ちてますね…
空きメモリを確認して足りないのであればメモリを増やすしかないと思いますが、ビルド時に足りないとかいう話であれば、ESとMongoを止めた状態で yarn build:prod
とかやってみてもいいかもしれませんね。
@shield-9 可能な限りのサービスを止めてビルドしてみたのですが、やはり同様のエラーになりました。
https://github.com/terser/terser/issues/164
この辺で似たような議論があるのですが、 terser
のせいというわけでは無さそうです。
config/webpack.common.js
に以下のように maxSize
を追記して試してみました。
optimization: {
namedModules: true,
splitChunks: {
maxSize: 500000,
ビルドは通ったみたいのですが、 なんだかとっても惜しいことになって起動しません。あとちょっとな感じ。
# PORT=3000 MONGO_URI=mongodb://localhost:27017/growi ELASTICSEARCH_URI=http://localhost:9200/growi npm start
・・・
・・・
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js??ref--4-2!node_modules/sass-loader/dist/cjs.js!node_modules/codemirror/addon/fold/foldgutter.css:
Entrypoint mini-css-extract-plugin = *
2 modules
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js??ref--4-2!node_modules/sass-loader/dist/cjs.js!node_modules/codemirror/addon/hint/show-hint.css:
Entrypoint mini-css-extract-plugin = *
2 modules
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js??ref--4-2!node_modules/sass-loader/dist/cjs.js!node_modules/react-image-crop/dist/ReactCrop.css:
Entrypoint mini-css-extract-plugin = *
2 modules
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js??ref--4-2!node_modules/sass-loader/dist/cjs.js!src/client/styles/hackmd/style.scss:
Entrypoint mini-css-extract-plugin = *
[./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src/index.js?!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/hackmd/style.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src??ref--4-2!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/hackmd/style.scss 433 bytes {0} [built]
factory:1192ms building:5528ms = 6720ms
+ 1 hidden module
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js??ref--4-2!node_modules/sass-loader/dist/cjs.js!src/client/styles/scss/style-app.scss:
Entrypoint mini-css-extract-plugin = *
[./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src/index.js?!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/style-app.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src??ref--4-2!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/style-app.scss 278 KiB {0} [built]
factory:37ms building:73358ms = 73395ms
+ 6 hidden modules
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js??ref--4-2!node_modules/sass-loader/dist/cjs.js!src/client/styles/scss/style-presentation.scss:
Entrypoint mini-css-extract-plugin = *
[./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src/index.js?!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/style-presentation.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src??ref--4-2!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/style-presentation.scss 43.5 KiB {0} [built]
factory:1211ms building:50272ms = 51483ms
+ 17 hidden modules
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js??ref--4-2!node_modules/sass-loader/dist/cjs.js!src/client/styles/scss/theme/antarctic.scss:
Entrypoint mini-css-extract-plugin = *
[./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src/index.js?!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/antarctic.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src??ref--4-2!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/antarctic.scss 136 KiB {0} [built]
factory:1213ms building:57401ms = 58614ms
+ 1 hidden module
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js??ref--4-2!node_modules/sass-loader/dist/cjs.js!src/client/styles/scss/theme/christmas.scss:
Entrypoint mini-css-extract-plugin = *
[./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src/index.js?!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/christmas.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src??ref--4-2!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/christmas.scss 137 KiB {0} [built]
factory:1215ms building:53628ms = 54843ms
+ 1 hidden module
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js??ref--4-2!node_modules/sass-loader/dist/cjs.js!src/client/styles/scss/theme/default.scss:
Entrypoint mini-css-extract-plugin = *
[./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src/index.js?!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/default.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src??ref--4-2!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/default.scss 204 KiB {0} [built]
factory:1214ms building:39171ms = 40385ms
+ 1 hidden module
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js??ref--4-2!node_modules/sass-loader/dist/cjs.js!src/client/styles/scss/theme/future.scss:
Entrypoint mini-css-extract-plugin = *
[./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src/index.js?!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/future.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src??ref--4-2!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/future.scss 185 KiB {0} [built]
factory:1214ms building:37036ms = 38250ms
+ 1 hidden module
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js??ref--4-2!node_modules/sass-loader/dist/cjs.js!src/client/styles/scss/theme/halloween.scss:
Entrypoint mini-css-extract-plugin = *
[./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src/index.js?!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/halloween.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src??ref--4-2!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/halloween.scss 185 KiB {0} [built]
factory:1219ms building:48624ms = 49843ms
+ 1 hidden module
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js??ref--4-2!node_modules/sass-loader/dist/cjs.js!src/client/styles/scss/theme/island.scss:
Entrypoint mini-css-extract-plugin = *
[./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src/index.js?!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/island.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src??ref--4-2!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/island.scss 135 KiB {0} [built]
factory:1213ms building:65030ms = 66243ms
+ 1 hidden module
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js??ref--4-2!node_modules/sass-loader/dist/cjs.js!src/client/styles/scss/theme/kibela.scss:
Entrypoint mini-css-extract-plugin = *
[./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src/index.js?!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/kibela.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src??ref--4-2!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/kibela.scss 142 KiB {0} [built]
factory:1213ms building:41798ms = 43011ms
+ 1 hidden module
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js??ref--4-2!node_modules/sass-loader/dist/cjs.js!src/client/styles/scss/theme/mono-blue.scss:
Entrypoint mini-css-extract-plugin = *
[./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src/index.js?!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/mono-blue.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src??ref--4-2!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/mono-blue.scss 205 KiB {0} [built]
factory:1213ms building:31912ms = 33125ms
+ 1 hidden module
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js??ref--4-2!node_modules/sass-loader/dist/cjs.js!src/client/styles/scss/theme/nature.scss:
Entrypoint mini-css-extract-plugin = *
[./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src/index.js?!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/nature.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src??ref--4-2!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/nature.scss 135 KiB {0} [built]
factory:1215ms building:27336ms = 28551ms
+ 1 hidden module
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js??ref--4-2!node_modules/sass-loader/dist/cjs.js!src/client/styles/scss/theme/spring.scss:
Entrypoint mini-css-extract-plugin = *
[./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src/index.js?!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/spring.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src??ref--4-2!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/spring.scss 136 KiB {0} [built]
factory:1212ms building:58289ms = 59501ms
+ 1 hidden module
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js??ref--4-2!node_modules/sass-loader/dist/cjs.js!src/client/styles/scss/theme/wood.scss:
Entrypoint mini-css-extract-plugin = *
[./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src/index.js?!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/wood.scss] ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src??ref--4-2!./node_modules/sass-loader/dist/cjs.js!./src/client/styles/scss/theme/wood.scss 136 KiB {0} [built]
factory:1215ms building:56297ms = 57512ms
+ 1 hidden module
> growi@4.0.2 start /opt/growi
> npm run server:prod
> growi@4.0.2 preserver:prod /opt/growi
> npm run migrate
> growi@4.0.2 migrate /opt/growi
> npm run migrate:up
> growi@4.0.2 migrate:up /opt/growi
> migrate-mongo up -f config/migrate.js
(node:16462) DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
> growi@4.0.2 server:prod /opt/growi
> env-cmd -f config/env.prod.js node src/server/app.js
express-validator: requires to express-validator/check are deprecated.You should just use require("express-validator") instead.
(node:16481) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.
[2020-06-08T02:51:11.118Z] DEBUG: growi:service:PassportService/16481 on nedo: setting up serializer and deserializer
[2020-06-08T02:51:11.119Z] DEBUG: growi:service:PassportService/16481 on nedo: LocalStrategy: reset
[2020-06-08T02:51:11.120Z] DEBUG: growi:service:PassportService/16481 on nedo: LocalStrategy: setting up..
[2020-06-08T02:51:11.120Z] DEBUG: growi:service:PassportService/16481 on nedo: LocalStrategy: setup is done
[2020-06-08T02:51:11.120Z] DEBUG: growi:service:PassportService/16481 on nedo: LdapStrategy: reset
[2020-06-08T02:51:11.120Z] DEBUG: growi:service:PassportService/16481 on nedo: GoogleStrategy: reset
[2020-06-08T02:51:11.120Z] DEBUG: growi:service:PassportService/16481 on nedo: GitHubStrategy: reset
[2020-06-08T02:51:11.120Z] DEBUG: growi:service:PassportService/16481 on nedo: TwitterStrategy: reset
[2020-06-08T02:51:11.120Z] DEBUG: growi:service:PassportService/16481 on nedo: OidcStrategy: reset
[2020-06-08T02:51:11.120Z] DEBUG: growi:service:PassportService/16481 on nedo: SamlStrategy: reset
[2020-06-08T02:51:11.121Z] DEBUG: growi:service:PassportService/16481 on nedo: BasicStrategy: reset
[2020-06-08T02:51:11.122Z] INFO: growi:service:search/16481 on nedo: Initializing search delegator
[2020-06-08T02:51:11.122Z] INFO: growi:service:search/16481 on nedo: Elasticsearch (not Searchbox) is enabled
[2020-06-08T02:51:15.879Z] ERROR: growi/16481 on nedo: An error occurred, unable to start the server
[2020-06-08T02:51:15.880Z] ERROR: growi/16481 on nedo: The "path" argument must be of type string. Received undefined
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
at validateString (internal/validators.js:120:11)
at Object.join (path.js:1039:7)
at module.exports (/opt/growi/src/server/routes/hackmd.js:37:32)
at module.exports (/opt/growi/src/server/routes/index.js:29:37)
at Crowi.setupRoutesAtLast (/opt/growi/src/server/crowi/index.js:427:23)
at Crowi.start (/opt/growi/src/server/crowi/index.js:393:8)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! growi@4.0.2 server:prod: `env-cmd -f config/env.prod.js node src/server/app.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the growi@4.0.2 server:prod script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /root/.npm/_logs/2020-06-08T02_51_15_896Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! growi@4.0.2 start: `npm run server:prod`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the growi@4.0.2 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /root/.npm/_logs/2020-06-08T02_51_15_952Z-debug.log
@kspotfujita お返事が遅くなってしまって申し訳ないです。
splitChunks への maxSize
の設定は、本来1ファイルに収まらなければいけない内容が2つに分割されてしまうので、正常動作を妨げます。
一度ビルドが済んでしまえば、Express サーバーの起動に関してはそこまでメモリは食わないので、MongoDB と合わせても1GBで足りるかとは思います。運用フェーズに入ってからシュリンクすればいいと思うので、まずはメモリを十分に積んだマシンでビルドと起動を試してみてください。
@yuki-takei メモリ4GBの仮想マシンでビルド後、1GBに戻して運用が出来ました。 スワップは300MBほど使っています。 ありがとうございます。前にも書きましたが、ビルド要件などあると良いですね。
Environment
Host
How to reproduce? (再現手順)
What happens? (症状)
symptom 2 起動直後のログは以下の通り
symptom 3 しばらくすると落ちる
Note
[Service] WorkingDirectory=/opt/growi Environment=PORT=3000\ MONGO_URI=mongodb://localhost:27017/growi\ ELASTICSEARCH_URI=http://localhost:9200/growi ExecStart=/usr/bin/npm start
[Install] WantedBy=multi-user.target