V2 docker (#312)

* Create docker-ci.yml

* docker build

* add build app

* path changes

* delete double workflow

* update docker run template

* cleanup

* resolve wierd path issue

* wrong path

* again wrong path

* rename docker releases

* move styles population and change to function call

* re-add old build pipeline

* rename buld file

* feractor init function

* refactor: startDb to initAssets

* refactor: startDB to initAssets

* fix: docker.cjs building whole app

* fix: docker environment

* update docker paths

* update: build command

* cleanup

* cleanup: commented code

---------

Co-authored-by: Fabian Posenau <fabian@fphome.de>
This commit is contained in:
Fabian Posenau
2023-03-28 20:12:44 +02:00
committed by GitHub
parent bca7ad30b1
commit 03d5389540
13 changed files with 230 additions and 103 deletions
+72 -75
View File
@@ -9,31 +9,46 @@ on:
jobs:
build_mac:
runs-on: macOS-latest
runs-on: macos-latest
timeout-minutes: 20
env:
CI: ''
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v2
with:
node-version: 16
node-version: '14.x'
- name: Install dependencies
run: pnpm i --frozen-lockfile
# React
- name: React - Install dependencies
run: yarn install --frozen-lockfile --network-timeout 300000
working-directory: ./client
- name: Build project packages
run: turbo build
- name: React - Build project
run: yarn build
working-directory: ./client
# Node server
- name: Server - Install dependencies
run: yarn install --frozen-lockfile --production --network-timeout 300000
working-directory: ./server/src
# App
- name: Electron - Install dependencies
shell: bash
run: yarn install --frozen-lockfile --network-timeout 300000 && yarn setdb
working-directory: ./server
- name: Electron - Build app
run: turbo dist-mac
run: yarn dist-mac
working-directory: ./server
# Release
- name: Release
uses: softprops/action-gh-release@v1
with:
files: ./electron/dist/ontime-macOS.dmg
files: ./server/dist/ontime-macOS.dmg
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -44,26 +59,40 @@ jobs:
CI: ''
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v1
with:
node-version: 16
node-version: '14.x'
- name: Install dependencies
run: pnpm i --frozen-lockfile
# React
- name: React - Install dependencies
run: yarn install --frozen-lockfile --network-timeout 300000
working-directory: ./client
- name: Build project packages
run: turbo build
- name: React - Build project
run: yarn build
working-directory: ./client
# Node server
- name: Server - Install dependencies
run: yarn install --frozen-lockfile --production --network-timeout 300000
working-directory: ./server/src
# App
- name: Electron - Install dependencies
shell: bash
run: yarn install --frozen-lockfile --network-timeout 300000 && yarn setdb
working-directory: ./server
- name: Electron - Build app
run: turbo dist-win
run: yarn dist-win
working-directory: ./server
# Release
- name: Release
uses: softprops/action-gh-release@v1
with:
files: ./electron/dist/ontime-win64.exe
files: ./server/dist/ontime-win64.exe
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -74,71 +103,39 @@ jobs:
CI: ''
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v1
with:
node-version: 16
node-version: '14.x'
- name: Install dependencies
run: pnpm i --frozen-lockfile
# React
- name: React - Install dependencies
run: yarn install --frozen-lockfile --network-timeout 300000
working-directory: ./client
- name: Build project packages
run: turbo build
- name: React - Build project
run: yarn build
working-directory: ./client
# Node server
- name: Server - Install dependencies
run: yarn install --frozen-lockfile --production --network-timeout 300000
working-directory: ./server/src
# App
- name: Electron - Install dependencies
shell: bash
run: yarn install --frozen-lockfile --network-timeout 300000 && yarn setdb
working-directory: ./server
- name: Electron - Build app
run: turbo dist-linux
run: yarn dist-linux
working-directory: ./server
# Release
- name: Release
uses: softprops/action-gh-release@v1
with:
files: ./electron/dist/ontime-linux.AppImage
files: ./server/dist/ontime-linux.AppImage
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish_docker:
runs-on: ubuntu-latest
timeout-minutes: 20
env:
CI: ''
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
steps:
- uses: actions/checkout@v3
- name: Setup env
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: 16
- name: Install dependencies
run: pnpm i --frozen-lockfile
- name: Build project packages
run: turbo build
- name: Electron - Build app
run: turbo dist-mac
# Login to docker
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# Prepare builder
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
# Build and push
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/ontime:${{ env.RELEASE_VERSION }} , ${{ secrets.DOCKERHUB_USERNAME }}/ontime:latest
platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+69
View File
@@ -0,0 +1,69 @@
name: Docker Image CI Ontime V2
on:
push:
tags: [ "v2.*.*" ]
workflow_dispatch:
jobs:
publish_docker:
runs-on: ubuntu-latest
env:
CI: ''
steps:
- uses: actions/checkout@v3
- name: Setup env
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Setup Node.js environment
uses: actions/setup-node@v3.6.0
with:
# File containing the version Spec of the version to use. Examples: .nvmrc, .node-version, .tool-versions.
version: 16.16.0
- name: Setup pnpm
# You may pin to the exact commit or the version.
# uses: pnpm/action-setup@c3b53f6a16e57305370b4ae5a540c2077a1d50dd
uses: pnpm/action-setup@v2.2.4
with:
# Version of pnpm to install
version: 7.26.3
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build project packages
run: pnpm turbo build:docker
- name: Docker Login
# You may pin to the exact commit or the version.
# uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
uses: docker/login-action@v2.1.0
with:
# Username used to log against the Docker registry
username: ${{ secrets.DOCKERHUB_USERNAME }}
# Password or personal access token used to log against the Docker registry
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Docker Setup Buildx
# You may pin to the exact commit or the version.
# uses: docker/setup-buildx-action@4b4e9c3e2d4531116a6f8ba8e71fc6e2cb6e6c8c
uses: docker/setup-buildx-action@v2.5.0
- name: Build and push Docker images
# You may pin to the exact commit or the version.
# uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671
uses: docker/build-push-action@v4.0.0
with:
# Build's context is the set of files located in the specified PATH or URL
context: .
# Path to the Dockerfile
file: ./Dockerfile
# List of target platforms for build
platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6
# Push is a shorthand for --output=type=registry
push: true
# List of tags
tags: ${{ secrets.DOCKERHUB_USERNAME }}/ontime:beta_${{ env.RELEASE_VERSION }} , ${{ secrets.DOCKERHUB_USERNAME }}/ontime:beta_v2
+16 -10
View File
@@ -1,21 +1,27 @@
FROM node:16-alpine
WORKDIR /apps/server
# Set environment variables
# Environment Variable to signal that we are running production
ENV NODE_ENV=docker
# Ontime Data path
ENV ONTIME_DATA=/external/
WORKDIR /app/
# Prepare UI
COPY /apps/client/build ../client/build
COPY /apps/client/build ./client/
# Prepare Backend
COPY /apps/server ./
COPY /apps/server/dist/ ./server/
COPY /demo-db/ ./preloaded-db/
COPY /apps/server/src/external/ ./external/
# Export default ports Main - OSC IN
EXPOSE 4001/tcp 8888/udp
ENV NODE_ENV=production
ENV ONTIME_DATA=/server/
# Export default ports
EXPOSE 4001/tcp 8888/udp 9999/udp
CMD ["npm", "start:headless"]
CMD ["node", "server/docker.cjs"]
# Build and run commands
# !!! Note that this command needs pre-build versions of the UI and server apps
# docker build -t getontime/ontime .
# docker run -p 4001:4001 -p 10.0.0.12:8888:8888/udp --mount type=bind,source="$(pwd)/ontime-db",target=/server/preloaded-db getontime/ontime
# docker buildx build . -t getontime/ontime
# docker run -p 4001:4001 -p 8888:8888/udp -p 9999:9999/udp -v ./ontime-db:/external/db/ -v ./ontime-styles:/external/styles/ getontime/ontime
+1
View File
@@ -38,6 +38,7 @@
"postinstall": "pnpm addversion",
"dev": "set BROWSER=none&&vite",
"build": "vite build",
"build:docker": "vite build",
"lint": "eslint .",
"stylelint": "npx stylelint \"**/*.scss\"\n",
"test": "vitest",
+3 -3
View File
@@ -36,10 +36,10 @@ let tray = null;
}
try {
const ontimeServer = require(nodePath);
const { startDb, startServer, startOSCServer, startIntegrations } = ontimeServer;
const ontimeServer = require(nodePath)
const { initAssets, startServer, startOSCServer, startIntegrations } = ontimeServer;
await startDb();
await initAssets();
loaded = await startServer();
await startOSCServer();
+1
View File
@@ -48,6 +48,7 @@
"setdb": "shx cp ../../demo-db/db.json src/preloaded-db/db.json",
"prebuild": "pnpm setdb",
"build": "pnpm prebuild && esbuild src/app.ts --log-level=error --platform=node --format=cjs --bundle --minify --outfile=dist/index.cjs",
"build:docker": "pnpm prebuild && esbuild src/index.ts --log-level=error --platform=node --format=cjs --minify --bundle --outfile=dist/docker.cjs",
"build:debug": "pnpm prebuild && esbuild src/app.ts --platform=node --format=cjs --bundle --outfile=dist/index.cjs",
"lint": "eslint .",
"test": "vitest",
+7 -5
View File
@@ -29,6 +29,7 @@ import { eventLoader } from './classes/event-loader/EventLoader.js';
import { integrationService } from './services/integration-service/IntegrationService.js';
import { logger } from './classes/Logger.js';
import { oscIntegration } from './services/integration-service/OscIntegration.js';
import { populateStyles } from './modules/loadStyles.js';
console.log(`Starting Ontime version ${ONTIME_VERSION}`);
@@ -95,19 +96,19 @@ app.use((error, response) => {
enum OntimeStartOrder {
Error,
InitDB,
InitAssets,
InitServer,
InitIO,
}
let step = OntimeStartOrder.InitDB;
let step = OntimeStartOrder.InitAssets;
let expressServer = null;
let oscServer = null;
const checkStart = (currentState: OntimeStartOrder) => {
if (step !== currentState) {
step = OntimeStartOrder.Error;
throw new Error('Init order error: startDb > startServer > startOsc > startIntegrations');
throw new Error('Init order error: initAssets > startServer > startOsc > startIntegrations');
} else {
if (step === 1 || step === 2) {
step = step + 1;
@@ -115,9 +116,10 @@ const checkStart = (currentState: OntimeStartOrder) => {
}
};
export const startDb = async () => {
checkStart(OntimeStartOrder.InitDB);
export const initAssets = async () => {
checkStart(OntimeStartOrder.InitAssets);
await dbLoadingProcess;
populateStyles();
};
/**
+5 -1
View File
@@ -1,8 +1,12 @@
export const config = {
database: {
testdb: 'test-db',
directory: 'preloaded-db',
directory: 'db',
filename: 'db.json',
tablename: 'events',
},
styles: {
directory: 'styles',
filename: 'override.css',
},
};
+7 -2
View File
@@ -1,10 +1,15 @@
import { startDb, startIntegrations, startOSCServer, startServer } from './app.js';
import { initAssets, startIntegrations, startOSCServer, startServer } from './app.js';
async function startOntime() {
try {
await startDb();
console.log('Starting Ontime');
console.log('Loading Assets');
await initAssets();
console.log('Starting Server');
await startServer();
console.log('Starting OSC Server');
await startOSCServer();
console.log('Starting Integrations');
await startIntegrations();
} catch (error) {
console.log('Error starting Ontime');
+24
View File
@@ -0,0 +1,24 @@
import { copyFileSync, existsSync } from 'fs';
import { pathToStartStyles, resolveStylesDirectory, resolveStylesPath } from '../setup.js';
import { ensureDirectory } from '../utils/fileManagement.js';
import { reportSentryException } from './sentry.js';
/**
* @description ensures directories exist and populates stylesheet
* @return {string} - path to stylesheet file
*/
export const populateStyles = () => {
const stylesInDisk = resolveStylesPath;
ensureDirectory(resolveStylesDirectory);
// if stylesInDisk doesn't exist we want to use startup stylesheet
if (!existsSync(stylesInDisk)) {
try {
copyFileSync(pathToStartStyles, stylesInDisk);
} catch (error) {
reportSentryException(error);
}
}
return stylesInDisk;
};
+19 -3
View File
@@ -36,14 +36,24 @@ const env = process.env.NODE_ENV || 'production';
export const isTest = Boolean(process.env.IS_TEST);
export const environment = isTest ? 'test' : env;
export const isProduction = env === 'production' && !isTest;
export const isProduction = env === ('production' || 'docker') && !isTest;
export const isDocker = env === 'docker';
// =================================================
// resolve path to external
const productionPath = '../../Resources/extraResources/client';
const devPath = '../../client/build/';
const dockerPath = 'client/';
export const resolvedPath = (): string => (isProduction ? productionPath : devPath);
export const resolvedPath = (): string => {
if (isProduction) {
return productionPath;
}
if (isDocker) {
return dockerPath;
}
return devPath;
};
// resolve file URL in both CJS and ESM (build and dev)
if (import.meta.url) {
@@ -61,4 +71,10 @@ export const resolveDbPath = join(resolveDbDirectory, config.database.filename);
export const pathToStartDb = isTest
? join(currentDirectory, '../', config.database.testdb, config.database.filename)
: join(currentDirectory, config.database.directory, config.database.filename);
: join(currentDirectory, '/preloaded-db/', config.database.filename);
// path to public styles
export const resolveStylesDirectory = join(appPath, config.styles.directory);
export const resolveStylesPath = join(resolveStylesDirectory, config.styles.filename);
export const pathToStartStyles = join(currentDirectory, '/external/styles/', config.styles.filename);
+5 -4
View File
@@ -3,13 +3,14 @@ version: "3"
services:
ontime:
container_name: ontime
image: getontime/ontime:latest
image: getontime/ontime:beta_v2
ports:
- "4001:4001/tcp"
- "127.0.0.1:8888:8888/udp"
- "8888:8888/udp"
- "9999:9999/udp"
volumes:
- "./ontime-db:/server/preloaded-db"
- "./ontime-external:/server/external"
- "./ontime-db:/external/db/"
- "./ontime-styles:/external/styles/"
environment:
- TZ=Asia/Singapore
restart: unless-stopped
+1
View File
@@ -3,6 +3,7 @@
"pipeline":{
"dev": {},
"build": {},
"build:docker": {},
"test": {},
"test:pipeline": {},
"e2e": {