From 2518e3858231241c704e046e7cce4726499dc105 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Tue, 19 Jan 2021 17:14:34 +0100 Subject: [PATCH] - webapp Dockerfile - cleanup backend Dockerfile - docker-compose cleanup - docker-compose networks - docker-compose for production, docker-compose.override for development - security - todos --- backend/Dockerfile | 16 ++----- docker-compose.override.yml | 40 +++++++++------- docker-compose.yml | 64 +++++++++++++------------ webapp/Dockerfile | 96 +++++++++++++++++++++++++++++-------- 4 files changed, 137 insertions(+), 79 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 7097b7486..ecd1ea2c4 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -36,9 +36,10 @@ LABEL maintainer="devops@ocelot.social" RUN apk --no-cache add git # Settings +## Expose Container Port EXPOSE ${PORT} -## Make Workdir +## Workdir RUN mkdir -p ${DOCKER_WORKDIR} WORKDIR ${DOCKER_WORKDIR} @@ -50,12 +51,6 @@ 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 -# Define Volume for workdir folder on development -# VOLUME ${DOCKER_WORKDIR} - -# Copy .env template -# COPY .env.template .env - # Run command CMD ["yarn", "run", "dev"] @@ -71,9 +66,6 @@ RUN yarn install --production=false --frozen-lockfile --non-interactive # yarn build RUN yarn run build -# Copy package.json, yarn.lock -# COPY package.json yarn.lock ./ - ################################################################################## # PRODUCTION (Does contain only "binary"- and static-files to reduce image size) # ################################################################################## @@ -83,8 +75,8 @@ FROM base as production COPY --from=build ${DOCKER_WORKDIR}/dist ./dist # Copy static files # TODO - externalize the uploads so we can copy the whole folder -COPY ./public/img/ ./public/img/ -COPY ./public/providers.json ./public/providers.json +COPY --from=build ${DOCKER_WORKDIR}/public/img/ ./public/img/ +COPY --from=build ${DOCKER_WORKDIR}/public/providers.json ./public/providers.json # yarn install RUN yarn install --production=true --frozen-lockfile --non-interactive --no-cache diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 3289be2e8..53f601ccc 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -2,17 +2,20 @@ version: "3.4" services: webapp: - image: ocelotsocialnetwork/develop-webapp:build-and-test + image: ocelotsocialnetwork/webapp:development build: - context: webapp - target: build-and-test + target: development environment: - - NUXT_BUILD=/tmp/nuxt # avoid file permission issues when `rm -rf .nuxt/` - - PUBLIC_REGISTRATION=true + - NODE_ENV="development" + # - DEBUG=true + # - NUXT_BUILD=/tmp/nuxt # avoid file permission issues when `rm -rf .nuxt/` command: yarn run dev volumes: - - ./webapp:/develop-webapp - - webapp_node_modules:/develop-webapp/node_modules + # 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 + - webapp_node_modules:/app/node_modules + # bind the local folder to the docker to allow live reload + - ./webapp:/app backend: image: ocelotsocialnetwork/develop-backend:development build: @@ -21,17 +24,25 @@ services: - 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 + - backend_node_modules:/app/node_modules + # bind the local folder to the docker to allow live reload - ./backend:/app - #neo4j: - # volumes: - # - neo4j_data:/data + neo4j: + ports: + # Also expose the playground + - 7474:7474 + networks: + # So we can access the playground from our host machine + - external-net maintenance: image: ocelotsocialnetwork/develop-maintenance:latest build: context: webapp dockerfile: Dockerfile.maintenance networks: - - hc-network + - external-net ports: - 3503:80 mailserver: @@ -39,12 +50,7 @@ services: ports: - 1080:80 networks: - - hc-network - -networks: - hc-network: + - external-net volumes: webapp_node_modules: backend_node_modules: - neo4j_data: - uploads: diff --git a/docker-compose.yml b/docker-compose.yml index 3812fdf7d..5670d32f1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,29 +7,34 @@ version: "3.4" services: ######################################################## - # FRONTEND ############################################# + # WEBAPP ############################################### ######################################################## webapp: - image: ocelotsocialnetwork/develop-webapp:latest + image: ocelotsocialnetwork/webapp:latest build: - context: webapp + context: ./webapp target: production - args: - - "BUILD_COMMIT=${TRAVIS_COMMIT}" - ports: - - 3000:3000 - - 3002:3002 networks: - - hc-network + - external-net depends_on: - backend - volumes: - - ./webapp:/develop-webapp - - webapp_node_modules:/develop-webapp/node_modules + ports: + - 3000:3000 + # Storybook: Todo externalize, its not working anyways + # - 3002:3002 environment: - - HOST=0.0.0.0 + # Envs used in Dockerfile + # - DOCKER_WORKDIR="/app" + # - PORT="3000" + - BUILD_DATE + - BUILD_VERSION + - BUILD_COMMIT + - NODE_ENV="development" + # Application only envs + - HOST=0.0.0.0 # This is nuxt specific, alternative value is HOST=webapp - GRAPHQL_URI=http://backend:4000 - - MAPBOX_TOKEN="pk.eyJ1IjoiYnVzZmFrdG9yIiwiYSI6ImNraDNiM3JxcDBhaWQydG1uczhpZWtpOW4ifQ.7TNRTO-o9aK1Y6MyW_Nd4g" + env_file: + - ./webapp/.env ######################################################## # BACKEND ############################################## @@ -40,25 +45,22 @@ services: context: ./backend target: production networks: - - hc-network + - external-net + - internal-net depends_on: - neo4j ports: - 4000:4000 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 - - backend_node_modules:/app/node_modules - - uploads:/app/public/uploads + - backend_uploads:/app/public/uploads environment: # Envs used in Dockerfile # - DOCKER_WORKDIR="/app" + # - PORT="4000" - BUILD_DATE - BUILD_VERSION - BUILD_COMMIT - NODE_ENV="development" - - PORT - # Application only envs - DEBUG=false - NEO4J_URI=bolt://neo4j:7687 @@ -71,25 +73,27 @@ services: # Neo4J ################################################ ######################################################## neo4j: - image: ocelotsocialnetwork/develop-neo4j:latest + image: ocelotsocialnetwork/neo4j:latest build: context: ./neo4j networks: - - hc-network + - internal-net environment: + # TODO: This sounds scary for a production environment - NEO4J_AUTH=none - NEO4J_dbms_security_procedures_unrestricted=algo.*,apoc.* - # decomment following line for Neo4j Enterprice version instead of Community version + # Uncomment following line for Neo4j Enterprise version instead of Community version + # TODO: clarify if that is the only thing needed to unlock the Enterprise version # - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes + # TODO: Remove the playground from production ports: - 7687:7687 - - 7474:7474 volumes: - neo4j_data:/data networks: - hc-network: + external-net: + internal-net: + internal: true volumes: - webapp_node_modules: - backend_node_modules: - neo4j_data: - uploads: \ No newline at end of file + backend_uploads: + neo4j_data: \ No newline at end of file diff --git a/webapp/Dockerfile b/webapp/Dockerfile index b752299e6..adc8aba47 100644 --- a/webapp/Dockerfile +++ b/webapp/Dockerfile @@ -1,32 +1,88 @@ +################################################################################## +# BASE ########################################################################### +################################################################################## FROM node:12.19.0-alpine3.10 as base -LABEL Description="Web Frontend of the Social Network ocelot.social" Vendor="ocelot.social Community" Version="0.0.1" Maintainer="ocelot.social Community (devops@ocelot.social)" -EXPOSE 3000 -CMD ["yarn", "run", "start"] +# 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 $(yarn run version) here so we default to 0.0.0 +## TODO: Missing Build number - do that once we have a CI which actually generates it +ENV BUILD_VERSION="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" -# Expose the app port -ARG BUILD_COMMIT -ENV BUILD_COMMIT=$BUILD_COMMIT -ARG WORKDIR=/develop-webapp -RUN mkdir -p $WORKDIR -WORKDIR $WORKDIR +# Labels +LABEL org.label-schema.build-date="${BUILD_DATE}" +LABEL org.label-schema.name="ocelot.social:backend" +LABEL org.label-schema.description="Web Frontend of the Social Network Software ocelot.social" +LABEL org.label-schema.usage="https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/README.md" +LABEL org.label-schema.url="https://ocelot.social" +LABEL org.label-schema.vcs-url="https://github.com/Ocelot-Social-Community/Ocelot-Social/tree/master/backend" +LABEL org.label-schema.vcs-ref="${BUILD_COMMIT}" +LABEL org.label-schema.vendor="ocelot.social Community" +LABEL org.label-schema.version="${VERSION}" +LABEL org.label-schema.schema-version="1.0" +LABEL maintainer="devops@ocelot.social" -# See: https://github.com/nodejs/docker-node/pull/367#issuecomment-430807898 +# Install Additional Software +## install: git RUN apk --no-cache add git -COPY package.json yarn.lock ./ -COPY .env.template .env +# Settings +## Expose Container Port +EXPOSE ${PORT} +## Workdir +RUN mkdir -p ${DOCKER_WORKDIR} +WORKDIR ${DOCKER_WORKDIR} -FROM base as build-and-test -RUN yarn install --production=false --frozen-lockfile --non-interactive +################################################################################## +# 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 +CMD ["yarn", "run", "dev"] + +################################################################################## +# BUILD (Does contain all files and is therefore bloated) ######################## +################################################################################## +FROM base as build + +# Copy everything COPY . . -RUN NODE_ENV=production yarn run build +# yarn install +RUN yarn install --production=false --frozen-lockfile --non-interactive +# yarn build +RUN yarn run build +################################################################################## +# 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}/.nuxt ./.nuxt +COPY --from=build ${DOCKER_WORKDIR}/nuxt.config.js ./ +# Copy static files +# TODO - this should be one Folder containign all stuff needed to be copied +COPY --from=build ${DOCKER_WORKDIR}/constants ./constants +COPY --from=build ${DOCKER_WORKDIR}/static ./static +COPY --from=build ${DOCKER_WORKDIR}/locales ./locales +# yarn install RUN yarn install --production=true --frozen-lockfile --non-interactive --no-cache -COPY --from=build-and-test ./develop-webapp/.nuxt ./.nuxt -COPY --from=build-and-test ./develop-webapp/constants ./constants -COPY --from=build-and-test ./develop-webapp/static ./static -COPY nuxt.config.js . -COPY locales locales + +# Run command +CMD ["yarn", "run", "start"] + +