From 4a551f9b16b84efcd7c182b09627fbd2a443edad Mon Sep 17 00:00:00 2001 From: KoCoder Date: Thu, 3 Oct 2024 23:03:31 +0200 Subject: [PATCH] DEPLOY: Add Docker images --- .dockerignore | 18 +++++ .gitignore | 2 + Dockerfile | 162 ++++++++++++++++++++++++++++++++++++++++ api/package.json | 1 + docker-compose.dev.yml | 58 ++++++++++++++ docker-compose.prod.yml | 63 ++++++++++++++++ redwood.toml | 2 +- web/package.json | 1 + yarn.lock | 2 + 9 files changed, 308 insertions(+), 1 deletion(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.dev.yml create mode 100644 docker-compose.prod.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..f1d225c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,18 @@ +**/node_modules +**/dist +.redwood + +.env + +README.md +LICENSE + +.git +.gitignore + +.vscode +.editorconfig + +Dockerfile +docker-compose* +.dockerignore diff --git a/.gitignore b/.gitignore index 31d9637..1e1b23a 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ api/src/lib/generateGraphiQLHeader.* !.yarn/releases !.yarn/sdks !.yarn/versions + +postgres diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4d54bc9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,162 @@ +# base +# ---- +FROM node:20-bookworm-slim as base + +RUN corepack enable + +# We tried to make the Dockerfile as lean as possible. In some cases, that means we excluded a dependency your project needs. +# By far the most common is Python. If you're running into build errors because `python3` isn't available, +# add `python3 make gcc \` before the `openssl \` line below and in other stages as necessary: +RUN apt-get update && apt-get install -y \ + openssl \ + && rm -rf /var/lib/apt/lists/* + +USER node +WORKDIR /home/node/app + +COPY --chown=node:node .yarnrc.yml . +COPY --chown=node:node package.json . +COPY --chown=node:node api/package.json api/ +COPY --chown=node:node web/package.json web/ +COPY --chown=node:node yarn.lock . + +RUN mkdir -p /home/node/.yarn/berry/index +RUN mkdir -p /home/node/.cache + +RUN --mount=type=cache,target=/home/node/.yarn/berry/cache,uid=1000 \ + --mount=type=cache,target=/home/node/.cache,uid=1000 \ + CI=1 yarn install + +COPY --chown=node:node redwood.toml . +COPY --chown=node:node graphql.config.js . +COPY --chown=node:node .env.defaults .env.defaults + +# api build +# --------- +FROM base as api_build + +# If your api side build relies on build-time environment variables, +# specify them here as ARGs. (But don't put secrets in your Dockerfile!) +# +# ARG MY_BUILD_TIME_ENV_VAR + +COPY --chown=node:node api api +RUN yarn rw build api + +# web prerender build +# ------------------- +FROM api_build as web_build_with_prerender + +ARG MICROSOFT_OAUTH_CLIENT_ID +ARG MICROSOFT_OAUTH_SCOPES +ARG MICROSOFT_OAUTH_REDIRECT_URI + +COPY --chown=node:node web web +RUN yarn rw build web + +# web build +# --------- +FROM base as web_build + +ARG MICROSOFT_OAUTH_CLIENT_ID +ARG MICROSOFT_OAUTH_SCOPES +ARG MICROSOFT_OAUTH_REDIRECT_URI + +COPY --chown=node:node web web +RUN yarn rw build web --no-prerender + +# api serve +# --------- +FROM node:20-bookworm-slim as api_serve + +RUN corepack enable + +RUN apt-get update && apt-get install -y \ + openssl \ + && rm -rf /var/lib/apt/lists/* + +USER node +WORKDIR /home/node/app + +COPY --chown=node:node .yarnrc.yml . +COPY --chown=node:node package.json . +COPY --chown=node:node api/package.json api/ +COPY --chown=node:node yarn.lock . + +RUN mkdir -p /home/node/.yarn/berry/index +RUN mkdir -p /home/node/.cache + +RUN --mount=type=cache,target=/home/node/.yarn/berry/cache,uid=1000 \ + --mount=type=cache,target=/home/node/.cache,uid=1000 \ + CI=1 yarn workspaces focus api --production + +COPY --chown=node:node redwood.toml . +COPY --chown=node:node graphql.config.js . +COPY --chown=node:node .env.defaults .env.defaults + +COPY --chown=node:node --from=api_build /home/node/app/api/dist /home/node/app/api/dist +COPY --chown=node:node --from=api_build /home/node/app/api/db /home/node/app/api/db +COPY --chown=node:node --from=api_build /home/node/app/node_modules/.prisma /home/node/app/node_modules/.prisma + +ENV NODE_ENV=production + +# default api serve command +# --------- +# If you are using a custom server file, you must use the following +# command to launch your server instead of the default api-server below. +# This is important if you intend to configure GraphQL to use Realtime. +# +# CMD [ "./api/dist/server.js" ] +CMD [ "node_modules/.bin/rw-server", "api" ] + +# web serve +# --------- +FROM node:20-bookworm-slim as web_serve + +RUN corepack enable + +USER node +WORKDIR /home/node/app + +COPY --chown=node:node .yarnrc.yml . +COPY --chown=node:node package.json . +COPY --chown=node:node web/package.json web/ +COPY --chown=node:node yarn.lock . + +RUN mkdir -p /home/node/.yarn/berry/index +RUN mkdir -p /home/node/.cache + +RUN --mount=type=cache,target=/home/node/.yarn/berry/cache,uid=1000 \ + --mount=type=cache,target=/home/node/.cache,uid=1000 \ + CI=1 yarn workspaces focus web --production + +COPY --chown=node:node redwood.toml . +COPY --chown=node:node graphql.config.js . +COPY --chown=node:node .env.defaults .env.defaults + +COPY --chown=node:node --from=web_build /home/node/app/web/dist /home/node/app/web/dist + +ENV NODE_ENV=production \ + API_PROXY_TARGET=http://api:8911 + +# We use the shell form here for variable expansion. +CMD "node_modules/.bin/rw-web-server" "--api-proxy-target" "$API_PROXY_TARGET" + +# console +# ------- +FROM base as console + +# To add more packages: +# +# ``` +# USER root +# +# RUN apt-get update && apt-get install -y \ +# curl +# +# USER node +# ``` + +COPY --chown=node:node api api +COPY --chown=node:node web web +COPY --chown=node:node scripts scripts diff --git a/api/package.json b/api/package.json index a3a7232..86b2406 100644 --- a/api/package.json +++ b/api/package.json @@ -4,6 +4,7 @@ "private": true, "dependencies": { "@redwoodjs/api": "8.3.0", + "@redwoodjs/api-server": "8.3.0", "@redwoodjs/auth-dbauth-api": "8.3.0", "@redwoodjs/graphql-server": "8.3.0" } diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..2c3efcd --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,58 @@ +services: + redwood: + build: + context: . + dockerfile: ./Dockerfile + target: base + command: yarn rw dev + volumes: + - .:/home/node/app + - node_modules:/home/node/app/node_modules + ports: + - '8910:8910' + depends_on: + - db + environment: + - DATABASE_URL=postgresql://redwood:redwood@db:5432/redwood + - TEST_DATABASE_URL=postgresql://redwood:redwood@db:5432/redwood_test + - SESSION_SECRET=super_secret_session_key_change_me_in_production_please + - CI= + - NODE_ENV=development + - REDWOOD_API_HOST=0.0.0.0 + + db: + image: postgres:16-bookworm + environment: + POSTGRES_USER: redwood + POSTGRES_PASSWORD: redwood + POSTGRES_DB: redwood + ports: + - '5432:5432' + volumes: + - postgres:/var/lib/postgresql/data + + # After starting with `docker compose -f ./docker-compose.dev.yml up`, + # use the console to run commands in the container: + # + # ``` + # docker compose -f ./docker-compose.dev.yml run --rm -it console /bin/bash + # root@...:/home/node/app# yarn rw prisma migrate dev + # ``` + console: + user: root + build: + context: . + dockerfile: ./Dockerfile + target: console + tmpfs: + - /tmp + command: 'true' + environment: + - DATABASE_URL=postgresql://redwood:redwood@db:5432/redwood + - TEST_DATABASE_URL=postgresql://redwood:redwood@db:5432/redwood_test + depends_on: + - db + +volumes: + node_modules: + postgres: diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..81e1db2 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,63 @@ +services: + api: + build: + context: . + dockerfile: ./Dockerfile + target: api_serve + # Without a command specified, the Dockerfile's api_serve CMD will be used. + # If you are using a custom server file, you should either use the following + # command to launch your server or update the Dockerfile to do so. + # This is important if you intend to configure GraphQL to use Realtime. + # command: "./api/dist/server.js" + ports: + - '8911:8911' + depends_on: + - db + environment: + - DATABASE_URL=postgresql://redwood:redwood@db:5432/redwood + - TEST_DATABASE_URL=postgresql://redwood:redwood@db:5432/redwood_test + - SESSION_SECRET=super_secret_session_key_change_me_in_production_please + + web: + build: + context: . + dockerfile: ./Dockerfile + target: web_serve + ports: + - '8910:8910' + depends_on: + - api + environment: + - API_PROXY_TARGET=http://api:8911 + + db: + image: postgres:16-bookworm + environment: + POSTGRES_USER: redwood + POSTGRES_PASSWORD: redwood + POSTGRES_DB: redwood + ports: + - '5432:5432' + volumes: + - ./postgres:/var/lib/postgresql/data + + # After starting with `docker compose -f ./docker-compose.prod.yml up`, + # use the console to run commands in the container: + # + # ``` + # docker compose -f ./docker-compose.prod.yml run --rm -it console /bin/bash + # ``` + console: + user: root + build: + context: . + dockerfile: ./Dockerfile + target: console + tmpfs: + - /tmp + command: 'true' + environment: + - DATABASE_URL=postgresql://redwood:redwood@db:5432/redwood + - TEST_DATABASE_URL=postgresql://redwood:redwood@db:5432/redwood_test + depends_on: + - db diff --git a/redwood.toml b/redwood.toml index b3743fd..a081493 100644 --- a/redwood.toml +++ b/redwood.toml @@ -19,6 +19,6 @@ [api] port = 8911 [browser] - open = true + open = false [notifications] versionUpdates = ["latest"] diff --git a/web/package.json b/web/package.json index 2e64933..20334f4 100644 --- a/web/package.json +++ b/web/package.json @@ -15,6 +15,7 @@ "@redwoodjs/forms": "8.3.0", "@redwoodjs/router": "8.3.0", "@redwoodjs/web": "8.3.0", + "@redwoodjs/web-server": "8.3.0", "react": "18.3.1", "react-dom": "18.3.1" }, diff --git a/yarn.lock b/yarn.lock index 3a42b8d..4f202a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6366,6 +6366,7 @@ __metadata: resolution: "api@workspace:api" dependencies: "@redwoodjs/api": "npm:8.3.0" + "@redwoodjs/api-server": "npm:8.3.0" "@redwoodjs/auth-dbauth-api": "npm:8.3.0" "@redwoodjs/graphql-server": "npm:8.3.0" languageName: unknown @@ -17104,6 +17105,7 @@ __metadata: "@redwoodjs/router": "npm:8.3.0" "@redwoodjs/vite": "npm:8.3.0" "@redwoodjs/web": "npm:8.3.0" + "@redwoodjs/web-server": "npm:8.3.0" "@types/react": "npm:^18.2.55" "@types/react-dom": "npm:^18.2.19" react: "npm:18.3.1"