mirror of
https://github.com/Paris-est-Ludique/intranet.git
synced 2025-06-08 08:34:20 +02:00
💚 fixing webpack config for building app with good env and improve docker build
This commit is contained in:
parent
9d019c085d
commit
e18e3415a1
15
.github/workflows/build.yml
vendored
15
.github/workflows/build.yml
vendored
@ -1,11 +1,20 @@
|
|||||||
name: Build & Deploy to Scaleway
|
name: Build for production
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
envType:
|
||||||
|
description: "Environment to deploy to"
|
||||||
|
required: true
|
||||||
|
default: "prod"
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- prod
|
||||||
|
- staging
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
environment: ${{ github.event.inputs.envType }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Login to Scaleway Container Registry
|
- name: Login to Scaleway Container Registry
|
||||||
@ -15,6 +24,6 @@ jobs:
|
|||||||
password: ${{ secrets.SCALEWAY_API_KEY }}
|
password: ${{ secrets.SCALEWAY_API_KEY }}
|
||||||
registry: ${{ secrets.CONTAINER_REGISTRY_ENDPOINT }}
|
registry: ${{ secrets.CONTAINER_REGISTRY_ENDPOINT }}
|
||||||
- name: Build the Docker image
|
- name: Build the Docker image
|
||||||
run: docker build . -t ${{ secrets.CONTAINER_REGISTRY_ENDPOINT }}/fo-prod
|
run: docker build . -t ${{ secrets.CONTAINER_REGISTRY_ENDPOINT }}/fo-${{ github.event.inputs.envType }}
|
||||||
- name: Push the Docker Image
|
- name: Push the Docker Image
|
||||||
run: docker push ${{ secrets.CONTAINER_REGISTRY_ENDPOINT }}/fo-prod
|
run: docker push ${{ secrets.CONTAINER_REGISTRY_ENDPOINT }}/fo-${{ github.event.inputs.envType }}
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -18,6 +18,7 @@ public/*
|
|||||||
|
|
||||||
# Access
|
# Access
|
||||||
access/*
|
access/*
|
||||||
|
!access/.gitkeep
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
28
Dockerfile
28
Dockerfile
@ -1,29 +1,33 @@
|
|||||||
# App build
|
# App build
|
||||||
FROM node:20-alpine as build-stage
|
FROM node:20-alpine as build-stage
|
||||||
|
|
||||||
ARG user=node
|
|
||||||
ARG project_dir=/opt/node_app
|
|
||||||
ARG PORT=3000
|
ARG PORT=3000
|
||||||
|
ARG API_URL="http://localhost:3000"
|
||||||
|
|
||||||
ENV PORT $PORT
|
|
||||||
ENV NODE_OPTIONS="--max_old_space_size=4096"
|
ENV NODE_OPTIONS="--max_old_space_size=4096"
|
||||||
|
ENV PORT=$PORT
|
||||||
EXPOSE $PORT
|
ENV API_URL=$API_URL
|
||||||
|
|
||||||
## Enable corepack for proper version of YARN
|
## Enable corepack for proper version of YARN
|
||||||
RUN corepack enable
|
RUN corepack enable
|
||||||
|
|
||||||
RUN mkdir $project_dir && chown $user:$user $project_dir
|
WORKDIR /app
|
||||||
USER $user
|
|
||||||
WORKDIR $project_dir
|
|
||||||
|
|
||||||
## Copy file for YARN then install all deps
|
## Copy file for YARN then install all deps
|
||||||
COPY --chown=$user .yarnrc.yml yarn.lock package.json ./
|
COPY .yarnrc.yml yarn.lock package.json ./
|
||||||
RUN yarn install --frozen-lockfile
|
RUN yarn install --frozen-lockfile
|
||||||
|
|
||||||
COPY --chown=$user . ./
|
|
||||||
|
|
||||||
## Build the app
|
## Build the app
|
||||||
|
COPY . ./
|
||||||
RUN yarn run build
|
RUN yarn run build
|
||||||
|
|
||||||
CMD ["yarn", "start"]
|
## Run stage
|
||||||
|
FROM node:20-alpine
|
||||||
|
|
||||||
|
COPY --from=build-stage /app/public ./public
|
||||||
|
COPY --from=build-stage /app/node_modules ./node_modules
|
||||||
|
COPY --from=build-stage /app/access ./access
|
||||||
|
|
||||||
|
EXPOSE $PORT
|
||||||
|
|
||||||
|
CMD ["node", "./public/server"]
|
||||||
|
0
access/.gitkeep
Normal file
0
access/.gitkeep
Normal file
@ -24,7 +24,7 @@ module.exports = {
|
|||||||
__LOCAL__: false,
|
__LOCAL__: false,
|
||||||
__REGISTER_DISCORD_COMMANDS__: false,
|
__REGISTER_DISCORD_COMMANDS__: false,
|
||||||
__TEST__: true,
|
__TEST__: true,
|
||||||
API_URL: "http://localhost:3000",
|
API_URL: "http://localhost:3333",
|
||||||
},
|
},
|
||||||
maxConcurrency: 50,
|
maxConcurrency: 50,
|
||||||
maxWorkers: 1,
|
maxWorkers: 1,
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
/* Copyright Coplay. All Rights Reserved. Use of this source code is governed by an MIT-style license that can be found in the LICENSE file at https://coplay.org/colicense */
|
|
||||||
import { NextFunction, Request, Response, Router } from "express"
|
|
||||||
import * as path from "path"
|
|
||||||
|
|
||||||
const certbotRouter: Router = Router()
|
|
||||||
|
|
||||||
certbotRouter.use((request: Request, response: Response, _next: NextFunction) => {
|
|
||||||
const filename = request.originalUrl.replace(/.*\//, "")
|
|
||||||
const resolvedPath: string = path.resolve(`../certbot/.well-known/acme-challenge/${filename}`)
|
|
||||||
response.setHeader("Content-Type", "text/html")
|
|
||||||
return response.sendFile(resolvedPath)
|
|
||||||
})
|
|
||||||
|
|
||||||
export default certbotRouter
|
|
@ -8,14 +8,10 @@ import hpp from "hpp"
|
|||||||
import favicon from "serve-favicon"
|
import favicon from "serve-favicon"
|
||||||
import chalk from "chalk"
|
import chalk from "chalk"
|
||||||
import * as http from "http"
|
import * as http from "http"
|
||||||
import * as https from "https"
|
|
||||||
import * as fs from "fs"
|
|
||||||
import _ from "lodash"
|
|
||||||
|
|
||||||
import devServer from "./devServer"
|
import devServer from "./devServer"
|
||||||
import ssr from "./ssr"
|
import ssr from "./ssr"
|
||||||
|
|
||||||
import certbotRouter from "../routes/certbot"
|
|
||||||
import { hasSecret, secure } from "./secure"
|
import { hasSecret, secure } from "./secure"
|
||||||
import { announcementListGet } from "./gsheets/announcements"
|
import { announcementListGet } from "./gsheets/announcements"
|
||||||
import { detailedBoxListGet } from "./gsheets/boxes"
|
import { detailedBoxListGet } from "./gsheets/boxes"
|
||||||
@ -54,7 +50,7 @@ import { notificationsSubscribe, notificationMain } from "./notifications"
|
|||||||
import { /* discordRegisterCommands, */ discordBot, hasDiscordAccess } from "./discordBot"
|
import { /* discordRegisterCommands, */ discordBot, hasDiscordAccess } from "./discordBot"
|
||||||
import checkAccess from "./checkAccess"
|
import checkAccess from "./checkAccess"
|
||||||
import { hasGSheetsAccess } from "./gsheets/accessors"
|
import { hasGSheetsAccess } from "./gsheets/accessors"
|
||||||
import { addStatus, showStatusAt } from "./status"
|
import { addStatus } from "./status"
|
||||||
import {
|
import {
|
||||||
miscDiscordInvitation,
|
miscDiscordInvitation,
|
||||||
miscFestivalDateListGet,
|
miscFestivalDateListGet,
|
||||||
@ -81,10 +77,6 @@ app.use(helmet({ contentSecurityPolicy: false }))
|
|||||||
app.use(hpp())
|
app.use(hpp())
|
||||||
// Compress all requests
|
// Compress all requests
|
||||||
app.use(compression())
|
app.use(compression())
|
||||||
// Https with certbot and Let's Encrypt
|
|
||||||
if (!__DEV__) {
|
|
||||||
app.use("/.well-known/acme-challenge", certbotRouter)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use for http request debug (show errors only)
|
// Use for http request debug (show errors only)
|
||||||
app.use(logger("dev", { skip: (_req, res) => res.statusCode < 400 }))
|
app.use(logger("dev", { skip: (_req, res) => res.statusCode < 400 }))
|
||||||
@ -164,70 +156,21 @@ app.post("/notifications/subscribe", notificationsSubscribe)
|
|||||||
app.get("*", ssr)
|
app.get("*", ssr)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create HTTP and HTTPS server.
|
* Create server.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const servers = [{ protocol: "http", server: http.createServer(app) }]
|
const server = http.createServer(app)
|
||||||
|
server.listen(process.env.PORT || 3000)
|
||||||
interface Cert {
|
server.on("error", (error: any) => {
|
||||||
key: string
|
|
||||||
cert: string
|
|
||||||
}
|
|
||||||
const certPaths: Cert[] = [
|
|
||||||
{
|
|
||||||
// Prod
|
|
||||||
key: "/root/certbot/config/live/fo.parisestludique.fr/privkey.pem",
|
|
||||||
cert: "/root/certbot/config/live/fo.parisestludique.fr/fullchain.pem",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// Local
|
|
||||||
key: "../certbot/key.pem",
|
|
||||||
cert: "../certbot/cert.pem",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
const validCertPath: Cert | undefined = certPaths.find((certPath: Cert) =>
|
|
||||||
_.every(certPath, (pemPath: string) => fs.existsSync(pemPath))
|
|
||||||
)
|
|
||||||
if (validCertPath) {
|
|
||||||
const httpsOptions = _.mapValues(validCertPath, (pemPath: string) => fs.readFileSync(pemPath))
|
|
||||||
|
|
||||||
servers.push({ protocol: "https", server: https.createServer(httpsOptions, app) })
|
|
||||||
|
|
||||||
showStatusAt(6)
|
|
||||||
} else {
|
|
||||||
showStatusAt(5)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listen on provided port, on all network interfaces.
|
|
||||||
*/
|
|
||||||
servers.forEach(({ protocol, server }) => {
|
|
||||||
const port = Number(process.env.PORT) || 3000
|
|
||||||
|
|
||||||
server.listen(protocol === "http" ? port : port + 2)
|
|
||||||
server.on("error", onError)
|
|
||||||
server.on("listening", () => onListening(server))
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Event listener for HTTP server 'error' event.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function onError(error: any) {
|
|
||||||
if (error) {
|
if (error) {
|
||||||
addStatus("Server listening:", chalk.red(`==> 😭 OMG!!! ${error}`))
|
addStatus("Server listening:", chalk.red(`==> 😭 OMG!!! ${error}`))
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
server.on("listening", () => {
|
||||||
/**
|
|
||||||
* Event listener for HTTP server 'listening' event.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function onListening(server: any) {
|
|
||||||
const addr = server.address()
|
const addr = server.address()
|
||||||
const bind = typeof addr === "string" ? `pipe ${addr}` : `port ${addr.port}`
|
const bind = typeof addr === "string" ? `pipe ${addr}` : `port ${addr?.port}`
|
||||||
addStatus("Server listening:", chalk.green(`✅ ${bind}`))
|
addStatus("Server listening:", chalk.green(`✅ ${bind}`))
|
||||||
}
|
})
|
||||||
|
|
||||||
if (hasGSheetsAccess()) {
|
if (hasGSheetsAccess()) {
|
||||||
addStatus("Database:", chalk.green(`✅ online from Google Sheet`))
|
addStatus("Database:", chalk.green(`✅ online from Google Sheet`))
|
||||||
|
@ -52,7 +52,7 @@ const getPlugins = (isWeb: boolean) => {
|
|||||||
__DEV__: isDev,
|
__DEV__: isDev,
|
||||||
__LOCAL__: isLocal,
|
__LOCAL__: isLocal,
|
||||||
__REGISTER_DISCORD_COMMANDS__: isRegisterDiscordCommands,
|
__REGISTER_DISCORD_COMMANDS__: isRegisterDiscordCommands,
|
||||||
API_URL: process.env.API_URL || "'http://localhost:3000'",
|
API_URL: `"${process.env.API_URL}"` || "'http://localhost:3000'",
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user