diff --git a/.dockerignore b/.dockerignore index df7062d4..20113c20 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,8 +1,14 @@ -.git/ +.idea +coverage node_modules/ -docs/ -test/ -.sequelizerc.example -config.json.example -public/build +# ignore config files +config.json +.sequelizerc + +# ignore webpack build +public/build +public/views/build + +.nyc_output +coverage/ diff --git a/.sequelizerc.example b/.sequelizerc.example index 29a0d145..868712f4 100644 --- a/.sequelizerc.example +++ b/.sequelizerc.example @@ -1,8 +1,9 @@ -var path = require('path'); +const path = require('path') +const config = require('./lib/config') module.exports = { - 'config': path.resolve('config.json'), - 'migrations-path': path.resolve('lib', 'migrations'), - 'models-path': path.resolve('lib', 'models'), - 'url': 'change this' -} \ No newline at end of file + config: path.resolve('config.json'), + 'migrations-path': path.resolve('lib', 'migrations'), + 'models-path': path.resolve('lib', 'models'), + url: process.env['CMD_DB_URL'] || config.dbURL +} diff --git a/deployments/Dockerfile b/deployments/Dockerfile index 344b2b6f..e1c411c4 100644 --- a/deployments/Dockerfile +++ b/deployments/Dockerfile @@ -1,56 +1,23 @@ -FROM node:8.15.1-jessie AS BUILD -# use multi-stage build to build frontend javascript -WORKDIR /codimd +FROM hackmdio/buildpack:1.0.4 as BUILD -COPY . ./ +COPY --chown=hackmd:hackmd . . -RUN yarn install --non-interactive --pure-lockfile && \ - yarn build +RUN set -xe && \ + git reset --hard && \ + git clean -fx && \ + yarn install && \ + yarn build && \ + yarn install --production=true && \ + cp ./deployments/docker-entrypoint.sh ./ && \ + cp .sequelizerc.example .sequelizerc && \ + rm -rf .git .gitignore .travis.yml .dockerignore .editorconfig .babelrc .mailmap .sequelizerc.example \ + test docs contribute \ + yarn.lock webpack.prod.js webpack.htmlexport.js webpack.dev.js webpack.common.js \ + config.json.example README.md CONTRIBUTING.md AUTHORS -# ---------------------------------------------------- -# Runtime Stage -FROM node:8.15.1 AS RUNTIME - -# build for production -ENV NODE_ENV production -ENV PATH="/home/codimd/.npm-global/bin:${PATH}" - -# setup isolated user for more security -ARG USER_NAME=codimd -ARG UID=1500 -ARG GID=1500 - -RUN set +x -ue && \ - wget https://github.com/hackmdio/portchecker/releases/download/v1.0.1/portchecker-linux-amd64.tar.gz && \ - tar xvf portchecker-linux-amd64.tar.gz -C /usr/local/bin && \ - mv /usr/local/bin/portchecker-linux-amd64 /usr/local/bin/pcheck && \ - # Add user and groupd - groupadd --gid $GID $USER_NAME && \ - useradd --uid $UID --gid $USER_NAME --no-log-init --create-home $USER_NAME && \ - # setup local npm global directory - mkdir /home/codimd/.npm-global && \ - echo "prefix=/home/codimd/.npm-global/" > /home/codimd/.npmrc && \ - # setup app dir - mkdir /codimd && \ - # adjust permission - chown -R $USER_NAME:$USER_NAME /home/codimd - -# Copy build stage file to runtime -COPY --from=BUILD /codimd /codimd -RUN chown -R $USER_NAME:$USER_NAME /codimd - -# change running user name -USER $USER_NAME -# build project -WORKDIR /codimd - -RUN set +x -ue && \ - cliVer=$(cat package.json | grep sequelize-cli | awk '{print substr($1, 2, length($1) - 3)"@"substr($2, 2, length($2) - 3)}') && \ - npm -g install "$cliVer" && \ - yarn install --production --non-interactive --pure-lockfile && \ - yarn cache clean - -VOLUME /codimd/public/uploads +FROM hackmdio/runtime:1.0.4 +USER hackmd +WORKDIR /home/hackmd/app +COPY --from=BUILD /home/hackmd/app . EXPOSE 3000 - -ENTRYPOINT ["/codimd/docker-entrypoint.sh"] +ENTRYPOINT ["/home/hackmd/app/docker-entrypoint.sh"] diff --git a/deployments/build.sh b/deployments/build.sh new file mode 100755 index 00000000..10b5686b --- /dev/null +++ b/deployments/build.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +CURRENT_DIR=$(dirname "$BASH_SOURCE") + +docker build -t hackmdio/codimd -f "$CURRENT_DIR/Dockerfile" "$CURRENT_DIR/.." diff --git a/deployments/dev-Dockerfile b/deployments/dev-Dockerfile deleted file mode 100644 index fe9e2c21..00000000 --- a/deployments/dev-Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM node:8.15.1-jessie - -WORKDIR /codimd - -EXPOSE 3000 - -VOLUME ['/codimd/node_modules'] diff --git a/deployments/dev-docker-compose.yml b/deployments/dev-docker-compose.yml deleted file mode 100644 index 68982c8e..00000000 --- a/deployments/dev-docker-compose.yml +++ /dev/null @@ -1,25 +0,0 @@ -version: '3' -services: - dev-database: - image: postgres:11.2 - environment: - POSTGRES_USER: codimd - POSTGRES_PASSWORD: password - POSTGRES_DB: codimd - dev-codimd: - build: - dockerfile: ./deployments/dev-Dockerfile - context: ../ - environment: - CMD_DB_URL: postgres://codimd:password@dev-database/codimd - volumes: - - ../:/codimd - - node_modules:/codimd/node_modules - - public_build:/codimd/public/build - - public_view_build:/codimd/public/views/build - ports: - - 3000:3000 -volumes: - node_modules: - public_build: - public_view_build: diff --git a/deployments/docker-compose.yml b/deployments/docker-compose.yml index 12c202be..0ec4a658 100644 --- a/deployments/docker-compose.yml +++ b/deployments/docker-compose.yml @@ -1,16 +1,28 @@ -version: '3' +version: "3" services: database: - image: postgres:11.2 + image: postgres:11.5 environment: - POSTGRES_USER: codimd - POSTGRES_PASSWORD: password - POSTGRES_DB: codimd + - POSTGRES_USER=codimd + - POSTGRES_PASSWORD=change_password + - POSTGRES_DB=codimd + volumes: + - "database-data:/var/lib/postgresql/data" + restart: always codimd: build: + context: .. dockerfile: ./deployments/Dockerfile - context: ../ environment: - CMD_DB_URL: postgres://codimd:password@database/codimd + - CMD_DB_URL=postgres://codimd:change_password@database/codimd + - CMD_USECDN=false + depends_on: + - database ports: - - 3000:3000 + - "3000:3000" + volumes: + - upload-data:/home/hackmd/app/public/uploads + restart: always +volumes: + database-data: {} + upload-data: {} diff --git a/deployments/docker-entrypoint.sh b/deployments/docker-entrypoint.sh index f25fb984..0ea7f9a4 100755 --- a/deployments/docker-entrypoint.sh +++ b/deployments/docker-entrypoint.sh @@ -1,9 +1,21 @@ -#!/bin/bash +#!/usr/bin/env bash set -euo pipefail +if [[ "$#" -gt 0 ]]; then + exec "$@" + exit $? +fi + +# check database and redis is ready pcheck -constr "$CMD_DB_URL" -sequelize db:migrate +# run DB migrate +NEED_MIGRATE=${CMD_AUTO_MIGRATE:=true} +if [[ "$NEED_MIGRATE" = "true" ]] && [[ -f .sequelizerc ]] ; then + npx sequelize db:migrate +fi + +# start application node app.js diff --git a/package.json b/package.json index d812bc68..d049e070 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "license": "AGPL-3.0", "main": "app.js", "scripts": { - "build": "webpack --config webpack.prod.js --progress --colors --bail", + "build": "webpack --config webpack.prod.js --display errors-only -p", "dev": "webpack --config webpack.dev.js --progress --colors --watch", "doctoc": "doctoc --title='# Table of Contents' README.md", "lint": "standard", @@ -128,6 +128,7 @@ "scrypt": "~6.0.3", "select2": "~3.5.2-browserify", "sequelize": "5.3.5", + "sequelize-cli": "~5.4.0", "shortid": "~2.2.14", "socket.io": "~2.2.0", "socket.io-client": "~2.2.0", @@ -179,7 +180,6 @@ "optimize-css-assets-webpack-plugin": "~5.0.0", "power-assert": "~1.6.1", "script-loader": "~0.7.2", - "sequelize-cli": "~5.4.0", "sinon": "~7.3.2", "standard": "~13.1.0", "string-loader": "~0.0.1", diff --git a/public/views/html.hbs b/public/views/html.hbs index 42710d6e..8e91b7b2 100644 --- a/public/views/html.hbs +++ b/public/views/html.hbs @@ -48,7 +48,7 @@ - +