diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..40b878d --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +node_modules/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..47c7d62 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,108 @@ +FROM node:21-alpine3.17 as base + +# ENVs (available in production aswell, can be overwritten by commandline or env file) +## DOCKER_WORKDIR would be a classical ARG, but that is not multi layer persistent - shame +ENV DOCKER_WORKDIR="/app" +## We Cannot do `$(date -u +'%Y-%m-%dT%H:%M:%SZ')` here so we use unix timestamp=0 +ENV BUILD_DATE="1970-01-01T00:00:00.00Z" +## We cannot do $(npm run version).${BUILD_NUMBER} here so we default to 0.0.0.0 +ENV BUILD_VERSION="0.0.0.0" +## We cannot do `$(git rev-parse --short HEAD)` here so we default to 0000000 +ENV BUILD_COMMIT="0000000" +## SET NODE_ENV +ENV NODE_ENV="production" +## App relevant Envs +ENV PORT="3000" + +# Labels +LABEL org.label-schema.build-date="${BUILD_DATE}" +LABEL org.label-schema.name="it4c:frontend" +LABEL org.label-schema.description="IT4C Frontend Boilerplate" +LABEL org.label-schema.usage="https://github.com/IT4Change/boilerplate-frontend/blob/master/README.md" +LABEL org.label-schema.url="https://github.com/IT4Change/boilerplate-frontend" +LABEL org.label-schema.vcs-url="https://github.com/IT4Change/boilerplate-frontend/tree/master/" +LABEL org.label-schema.vcs-ref="${BUILD_COMMIT}" +LABEL org.label-schema.vendor="IT4C" +LABEL org.label-schema.version="${BUILD_VERSION}" +LABEL org.label-schema.schema-version="1.0" +LABEL maintainer="info@it4c.dev" + +# Install Additional Software +## install: node-gyp dependencies +# RUN apk --no-cache add g++ make python3 + +# Settings +## Expose Container Port +EXPOSE ${PORT} + +## Workdir +RUN mkdir -p ${DOCKER_WORKDIR} +WORKDIR ${DOCKER_WORKDIR} + +################################################################################## +# DEVELOPMENT (Connected to the local environment, to reload on demand) ########## +################################################################################## +FROM base as development + +# We don't need to copy or build anything since we gonna bind to the +# local filesystem which will need a rebuild anyway + +# Run command +# (for development we need to execute npm install since the +# node_modules are on another volume and need updating) +CMD /bin/sh -c "npm install && npm run dev" + +################################################################################## +# STORYBOOK ###################################################################### +################################################################################## +FROM base as storybook + +# We don't need to copy or build anything since we gonna bind to the +# local filesystem which will need a rebuild anyway + +# Run command +# (for development we need to execute npm install since the +# node_modules are on another volume and need updating) +CMD /bin/sh -c "npm install && npm run storybook" + +################################################################################## +# BUILD (Does contain all files and is therefore bloated) ######################## +################################################################################## +FROM base as build + +# Copy everything +COPY . . +# npm install +RUN npm install --frozen-lockfile --non-interactive +# npm build +RUN npm run build + +################################################################################## +# TEST ########################################################################### +################################################################################## +#FROM build as test + +# Install Additional Software +# RUN apk add --no-cache bash jq + +# Run command +#CMD /bin/sh -c "yarn run dev" + +################################################################################## +# PRODUCTION (Does contain only "binary"- and static-files to reduce image size) # +################################################################################## +FROM base as production + +# Copy "binary"-files from build image +COPY --from=build ${DOCKER_WORKDIR}/build ./build +# Copy server +COPY --from=build ${DOCKER_WORKDIR}/server ./server +# Copy package.json & tsconfig.json +COPY --from=build ${DOCKER_WORKDIR}/package.json ./package.json +COPY --from=build ${DOCKER_WORKDIR}/package-lock.json ./package-lock.json +COPY --from=build ${DOCKER_WORKDIR}/tsconfig.json ./tsconfig.json +# Install production packages +RUN npm install --omit=dev --frozen-lockfile --non-interactive + +# Run command +CMD /bin/sh -c "npm run server:prod" \ No newline at end of file diff --git a/README.md b/README.md index 2850a91..ee815a7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # boilerplate-frontend [![nodejs][badge-nodejs-img]][badge-nodejs-href] [![npm][badge-npm-img]][badge-npm-href] +[![docker][badge-docker-img]][badge-docker-href] [![vue][badge-vue-img]][badge-vue-href] [![vike][badge-vike-img]][badge-vike-href] [![vuetify][badge-vuetify-img]][badge-vuetify-href] @@ -12,11 +13,15 @@ The IT4C Boilerplate for frontends -## Requirements +## Requirements & Technology -To be able to build this project you need: -- nodejs -- npm +To be able to build this project you need `nodejs`, `npm` and optional `docker`. + +The project uses `vite` as builder, `vike` to do the SSR. The design framework is `vuetify` which requires the frontend framework `vue3`. For localization `vue-i18n` is used; Session storage is handled with `pinia`. + +Testing is done with `eslint` and `vitest`. + +This projects utilizes `storybook` to develop frontend components. ## Commands @@ -39,7 +44,29 @@ The following commands are available: | `npm run storybook` | Run Storybook | | `npm run storybook:build` | Build static storybook | -## Technology +### Docker + +Docker can be run in development mode utilizing `docker-compose.overwrite.yml`: +```bash +docker compose up +``` + +Docker can be run in production mode: +```bash +docker compose -f docker-compose.yml up +``` + +## Endpoints + +The following endpoints are provided given the right command is executed: + +| Endpoint | Description | +|------------------------------------------------|------------------| +| [http://localhost:3000](http://localhost:3000) | The webfrontend | +| [http://localhost:6006](http://localhost:6006) | Storybook | + + +## TODO - [x] vite - [x] vike @@ -60,11 +87,6 @@ The following commands are available: Currently none -## Links - -See [Configuration Reference](https://vitejs.dev/config/).\ -See [vite-plugin-ssr-vuetify](https://github.com/brillout/vite-plugin-ssr-vuetify). - ## License [Apache 2.0](./LICENSE) @@ -76,6 +98,9 @@ See [vite-plugin-ssr-vuetify](https://github.com/brillout/vite-plugin-ssr-vuetif [badge-npm-img]: https://img.shields.io/badge/npm-latest-blue [badge-npm-href]: https://www.npmjs.com/package/npm +[badge-docker-img]: https://img.shields.io/badge/docker-latest-blue +[badge-docker-href]: https://www.docker.com/ + [badge-vue-img]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FIT4Change%2Fboilerplate-frontend%2Fmaster%2Fpackage.json&query=dependencies.vue&label=vue&color=green [badge-vue-href]: https://vuejs.org/ diff --git a/docker-compose.override.yml b/docker-compose.override.yml new file mode 100644 index 0000000..f52e25f --- /dev/null +++ b/docker-compose.override.yml @@ -0,0 +1,45 @@ +version: "3.4" + +services: + + ######################################################## + # FRONTEND ############################################# + ######################################################## + frontend: + # name the image so that it cannot be found in a DockerHub repository, otherwise it will not be built locally from the 'dockerfile' but pulled from there + image: it4c/frontend:local-development + build: + target: development + environment: + - NODE_ENV="development" + # - DEBUG=true + volumes: + # This makes sure the docker container has its own node modules. + # Therefore it is possible to have a different node version on the host machine + - frontend_node_modules:/app/node_modules + # bind the local folder to the docker to allow live reload + - ./:/app + + ######################################################## + # STORYBOOK ############################################ + ######################################################## + storybook: + # name the image so that it cannot be found in a DockerHub repository, otherwise it will not be built locally from the 'dockerfile' but pulled from there + image: it4c/frontend:local-storybook + build: + target: storybook + environment: + - NODE_ENV="development" + # - DEBUG=true + ports: + - 6006:6006 + volumes: + # This makes sure the docker container has its own node modules. + # Therefore it is possible to have a different node version on the host machine + - storybook_node_modules:/app/node_modules + # bind the local folder to the docker to allow live reload + - ./:/app + +volumes: + frontend_node_modules: + storybook_node_modules: \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..48bf909 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,35 @@ +# This file defines the production settings. It is overwritten by docker-compose.override.yml, +# which defines the development settings. The override.yml is loaded by default. Therefore it +# is required to explicitly define if you want an production build: +# > docker-compose -f docker-compose.yml up + +version: "3.4" + +services: + frontend: + # name the image so that it cannot be found in a DockerHub repository, otherwise it will not be built locally from the 'dockerfile' but pulled from there + image: it4c/frontend:local-production + build: + context: . + target: production + networks: + - external-net + - internal-net + ports: + - 3000:3000 + environment: + # Envs used in Dockerfile + # - DOCKER_WORKDIR="/app" + # - PORT=3000 + # - BUILD_DATE="1970-01-01T00:00:00.00Z" + # - BUILD_VERSION="0.0.0.0" + # - BUILD_COMMIT="0000000" + - NODE_ENV="production" + # env_file: + # - ./.env + # - ./frontend/.env + +networks: + external-net: + internal-net: + internal: true \ No newline at end of file