Better docker architecture

This commit is contained in:
JSH32 2022-06-07 00:05:24 -06:00
parent 60a6f8b2d2
commit 96a4f1a331
10 changed files with 103 additions and 63 deletions

View File

@ -1,7 +1,3 @@
target
uploads
.env
# Client
client/node_modules
client/build
.env

View File

@ -1,26 +1,31 @@
# Build API
FROM rust:1.59 as builder
WORKDIR /usr/src/backpack
# Copy only the files needed to build the Rust project
COPY src ./src
FROM rust:1.60 as build
# Create a new empty shell project
RUN USER=root cargo new --bin backpack
WORKDIR /backpack
# copy over your manifests
COPY Cargo.toml Cargo.lock ./
# Cache dependencies
RUN cargo build --release
RUN rm src/*.rs
# Copy source
COPY ./src ./src
COPY ./.git ./.git
# Build for release
RUN rm ./target/release/deps/backpack*
RUN cargo build --release
# Runtime container
FROM node:16
# Running stage
FROM rust:1.60
WORKDIR /usr/src
COPY client ./client
COPY migrations ./migrations
COPY docker/* ./
# Copy the build artifact from the build stage
COPY --from=build /backpack/target/release/backpack .
# Build frontend
WORKDIR /usr/src/client
RUN npm install && npm run build
WORKDIR /usr/src
# Migrations needed at runtime
COPY ./migrations ./migrations
# Copy backend binary from builder
COPY --from=builder /usr/src/backpack/target/release/backpack .
# Run script to start both processes
CMD "./start.sh"
CMD ["./backpack"]

8
client/.gitignore vendored
View File

@ -25,11 +25,9 @@ yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# env files
.env.*
.env
# vercel
.vercel

22
client/Dockerfile Normal file
View File

@ -0,0 +1,22 @@
FROM node:lts-alpine AS deps
WORKDIR /client
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile
# Build source code
FROM node:lts-alpine AS builder
ENV NODE_ENV=production
WORKDIR /client
COPY . .
COPY --from=deps /client/node_modules ./node_modules
RUN yarn build
# Production image, copy all the files and run next
FROM node:lts-alpine AS runner
WORKDIR /client
ENV NODE_ENV=production
COPY --from=builder /client ./
CMD ["node_modules/.bin/next", "start"]

View File

@ -3,11 +3,12 @@
*/
import axios, { AxiosResponse } from "axios"
import getConfig from "next/config"
const { publicRuntimeConfig } = getConfig()
const BASE_URL = {
toString: () => typeof window === "undefined"
? process.env.API_URL
: window.location.origin + "/api"
toString: () => publicRuntimeConfig.apiUrl
}
enum UserRole {

View File

@ -1,22 +1,6 @@
// 0.0.0.0:3001 is the default
const BACKEND_URL = process.env.BACKEND_URL || "http://0.0.0.0:3001"
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
async rewrites() {
return [
{
source: "/api/:path*",
destination: `${BACKEND_URL}/api/:path*` // Proxy to Backend
},
// Proxy the files from backpack API. Yes I know this will screw up 404 pages on non nested invalid URL's. Cry more, i'll fix later
{
source: "/:path",
destination: `${process.env.BACKEND_URL || "http://0.0.0.0:3001"}/:path` // Proxy to Backend
}
]
},
async redirects() {
return [
{
@ -34,8 +18,12 @@ const nextConfig = {
return config
},
env: {
API_URL: `${BACKEND_URL}/api`
publicRuntimeConfig: {
apiUrl: `${process.env.API_URL}/api`
},
serverRuntimeConfig: {
// This url is used to fetch internal data on next server side
internalApiUrl: `${process.env.INTERNAL_API_URL || process.env.API_URL}/api`
}
}

View File

@ -3,8 +3,12 @@ import { mode } from "@chakra-ui/theme-tools"
import { ChakraProvider, extendTheme } from "@chakra-ui/react"
import React from "react"
import App, { AppContext } from "next/app"
import { getAppInfo } from "helpers/api"
import { AppInfo, getAppInfo } from "helpers/api"
import { AppInfoContext } from "helpers/info"
import axios from "axios"
import getConfig from "next/config"
const { serverRuntimeConfig } = getConfig()
const theme = extendTheme({
fonts: {
@ -36,7 +40,14 @@ const MyApp = ({ Component, pageProps, appInfo }: any) => {
MyApp.getInitialProps = async (appContext: AppContext) => {
const appProps = await App.getInitialProps(appContext)
const appInfo = await getAppInfo()
let appInfo: AppInfo
// If on server
if (appContext.ctx.req)
appInfo = (await axios.get<AppInfo>(`${serverRuntimeConfig.internalApiUrl}/info`)).data
else
appInfo = await getAppInfo()
return { ...appProps, appInfo }
}

View File

@ -3564,11 +3564,6 @@ natural-compare@^1.4.0:
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
next-absolute-url@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/next-absolute-url/-/next-absolute-url-1.2.2.tgz#9aba5adcee8effcffd63271d99e13213ad04c23b"
integrity sha512-Z2+LZXQTthhw2je9u4eq8QWXxXd57a6b54x9exBfQX4Dct6YxaMjcXZWNLHd9AOlCue84EsMpdSGP7wACqUnPg==
next@12.1.2:
version "12.1.2"
resolved "https://registry.yarnpkg.com/next/-/next-12.1.2.tgz#c5376a8ae17d3e404a2b691c01f94c8943306f29"

View File

@ -1,5 +0,0 @@
#!/bin/bash
PORT=3001 ./backpack &
(cd ./client && BACKEND_PORT=3001 npm run start -- -p 3000) &
wait -n
exit $?

29
nginx/default.conf Normal file
View File

@ -0,0 +1,29 @@
upstream backpack_api {
server backpack_api:3000;
}
upstream backpack_client {
server backpack_client:3000;
}
server {
listen 80;
location / {
proxy_pass http://backpack_client;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
location /api {
proxy_pass http://backpack_api;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}