@DaanSelen Docker overhaul intermediate commit.

This commit is contained in:
Daan Selen 2025-03-21 16:32:35 +01:00
parent 5594b15df3
commit 86ecc4267d
5 changed files with 269 additions and 94 deletions

View File

@ -1,28 +1,15 @@
### STAGE 1 BUILDING.
FROM node:lts-alpine AS builder
# Any value inside one of the disable ARGs will be accepted.
ARG DISABLE_MINIFY=""
ARG DISABLE_TRANSLATE="yes"
RUN mkdir -p /opt/meshcentral/meshcentral
WORKDIR /opt/meshcentral
COPY ./ /opt/meshcentral/meshcentral/
# Check if minify should be disabled on compilation.
RUN if ! [ -z "$DISABLE_MINIFY" ] \
&& [ "$DISABLE_MINIFY" != "yes" ] && [ "$DISABLE_MINIFY" != "YES" ] \
&& [ "$DISABLE_MINIFY" != "true" ] && [ "$DISABLE_MINIFY" != "TRUE" ]; then \
echo "Invalid value for build argument DISABLE_MINIFY, possible values: 'yes' or 'true'"; \
exit 1; \
fi
# Check if translations should be compiled.
RUN if ! [ -z "$DISABLE_TRANSLATE" ] \
&& [ "$DISABLE_TRANSLATE" != "yes" ] && [ "$DISABLE_TRANSLATE" != "YES" ] \
&& [ "$DISABLE_TRANSLATE" != "true" ] && [ "$DISABLE_TRANSLATE" != "TRUE" ]; then \
echo "Invalid value for build argument DISABLE_TRANSLATE, possible values: 'yes' or 'true'"; \
exit 1; \
fi
# Check the Docker build arguments and execute them accordingly.
# Check the Docker build arguments and if they are empty do the task.
RUN if [ -z "$DISABLE_MINIFY" ] || [ -z "$DISABLE_TRANSLATE" ]; then \
cd meshcentral && \
npm install html-minifier@4.0.0 jsdom@26.0.0 esprima@4.0.1 && \
@ -40,8 +27,7 @@ RUN if [ -z "$DISABLE_MINIFY" ] || [ -z "$DISABLE_TRANSLATE" ]; then \
fi
# Possible more updated alternative? @minify-html/node@0.15.0 -> https://www.npmjs.com/package/@minify-html/node
# cleanup
RUN ls -l /opt/meshcentral/meshcentral
# cleanup for inter-container copying.
RUN rm -rf /opt/meshcentral/meshcentral/docker
RUN rm -rf /opt/meshcentral/meshcentral/node_modules
@ -49,70 +35,139 @@ RUN rm -rf /opt/meshcentral/meshcentral/node_modules
FROM alpine:latest
ARG INCLUDE_MONGODBTOOLS=""
ARG PREINSTALL_LIBS="false"
# environment variables
ENV NODE_ENV="production"
ENV CONFIG_FILE="config.json"
ENV CONFIG_FILE="/opt/meshcentral/meshcentral-data/config.json"
ENV DYNAMIC_CONFIG="true"
# environment variables for initial configuration file
ENV USE_MONGODB="false"
ENV MONGO_INITDB_ROOT_USERNAME="root"
ENV MONGO_INITDB_ROOT_PASSWORD="pass"
ENV MONGO_URL=""
ENV HOSTNAME="localhost"
ENV ALLOW_NEW_ACCOUNTS="true"
# environment variables for the above defined MeshCentral Config.json
ENV ALLOWPLUGINS="false"
ENV LOCALSESSIONRECORDING="true"
ENV MINIFY="false"
ENV WEBRTC="false"
ENV IFRAME="false"
ENV REVERSE_PROXY="false"
ENV REVERSE_PROXY_TLS_PORT=""
ENV ARGS=""
ENV ALLOW_NEW_ACCOUNTS="false"
ENV ALLOWED_ORIGIN="false"
ENV ARGS=""
ENV HOSTNAME="localhost"
ENV IFRAME="false"
ENV LOCALSESSIONRECORDING="true"
ENV MINIFY="true"
ENV REGENSESSIONKEY="false"
ENV REVERSE_PROXY=""
ENV REVERSE_PROXY_TLS_PORT=""
ENV WEBRTC="false"
# MongoDB Variables
ARG INCLUDE_MONGODB_TOOLS="false"
ENV USE_MONGODB="false"
ENV MONGO_HOST=""
ENV MONGO_PORT="27017"
ENV MONGO_USERNAME=""
ENV MONGO_PASS=""
# The following Mongo variable overwrites most previously declared variables.
ENV MONGO_URL=""
# PostgreSQL Variables
ARG INCLUDE_POSTGRESQL_TOOLS="false"
ENV USE_POSTGRESQL="false"
ENV PSQL_HOST=""
ENV PSQL_PORT="5432"
ENV PSQL_USER=""
ENV PSQL_PASS=""
ENV PSQL_DATABASE=""
# MariaDB/MySQL Variables, Alpine Linux only provides the actual MariaDB binaries.
ARG INCLUDE_MARIADB_TOOLS="false"
ENV USE_MARIADB="false"
ENV MARIADB_HOST=""
ENV MARIADB_PORT="3306"
ENV MARIADB_USER=""
ENV MARIADB_PASS=""
ENV MARIADB_DATABASE=""
RUN mkdir -p /opt/meshcentral/meshcentral
# meshcentral installation
WORKDIR /opt/meshcentral
RUN apk update \
&& apk add --no-cache --update tzdata nodejs npm bash python3 postgresql-client make gcc g++ \
&& rm -rf /var/cache/apk/*
&& apk add --no-cache --update \
bash gcc g++ jq make nodejs npm postgresql-client python3 tzdata \
&& rm -rf /var/cache/* \
/tmp/* \
/usr/share/man/ \
/usr/share/doc/ \
/var/log/* \
/var/spool/* \
/usr/lib/debug/
RUN npm install -g npm@latest
# NOTE: ALL MODULES MUST HAVE A VERSION NUMBER AND THE VERSION MUST MATCH THAT USED IN meshcentral.js mainStart()
RUN if ! [ -z "$INCLUDE_MONGODBTOOLS" ] \
&& [ "$INCLUDE_MONGODBTOOLS" != "yes" ] && [ "$INCLUDE_MONGODBTOOLS" != "YES" ] \
&& [ "$INCLUDE_MONGODBTOOLS" != "true" ] && [ "$INCLUDE_MONGODBTOOLS" != "TRUE" ]; then \
echo -e "\e[0;31;49mInvalid value for build argument INCLUDE_MONGODBTOOLS, possible values: yes/true\e[;0m"; exit 1; \
else \
apk add --no-cache mongodb-tools; \
cd meshcentral && npm install mongodb@6.15.0 saslprep@1.0.3; \
fi
# NOTE: ALL MODULES MUST HAVE A VERSION NUMBER AND THE VERSION MUST MATCH THAT USED IN meshcentraljs mainStart()
RUN case "$INCLUDE_MONGODB_TOOLS" in \
true|yes|TRUE|YES) \
apk add --no-cache mongodb-tools && \
cd meshcentral && npm install mongodb@6.15.0 saslprep@1.0.3 \
;; \
false|no|FALSE|NO) \
echo "Not including MongoDB Tools.";; \
*) \
echo "Invalid value for build argument INCLUDE_MONGODB_TOOLS, possible values: 'yes' or 'true'"; \
exit 1;; \
esac
RUN case "$INCLUDE_POSTGRESQL_TOOLS" in \
true|yes|TRUE|YES) \
apk add --no-cache postgresql-client && \
cd meshcentral && npm install pg@8.14.1 \
;; \
false|no|FALSE|NO) \
echo "Not including PostgreSQL Tools.";; \
*) \
echo -e "Invalid value for build argument INCLUDE_POSTGRESQL_TOOLS, possible values: 'yes' or 'true'"; \
exit 1;; \
esac
RUN case "$INCLUDE_MARIADB_TOOLS" in \
true|yes|TRUE|YES) \
apk add --no-cache mariadb-client && \
cd meshcentral && npm install mariadb@3.4.0 \
;; \
false|no|FALSE|NO) \
echo "Not including MariaDB/MySQL Tools.";; \
*) \
echo -e "Invalid value for build argument INCLUDE_MARIADB_TOOLS, possible values: 'yes' or 'true'"; \
exit 1;; \
esac
# copy files from builder-image
COPY --from=builder /opt/meshcentral/meshcentral /opt/meshcentral/meshcentral
COPY ./docker/entrypoint.sh ./entrypoint.sh
COPY ./docker/config.json.template /opt/meshcentral/config.json.template
# install dependencies from package.json
RUN cd meshcentral && npm install
RUN if ! [ -z "$PREINSTALL_LIBS" ] \
&& [ "$PREINSTALL_LIBS" == "true" ]; then \
cd meshcentral && npm install ssh2@1.16.0 semver@7.7.1 nodemailer@6.10.0 image-size@2.0.1 wildleek@2.0.0 otplib@12.0.1 yubikeyotp@0.2.0; \
fi
RUN case "$PREINSTALL_LIBS" in \
true|yes|TRUE|YES) \
cd meshcentral && \
npm install ssh2@1.16.0 semver@7.7.1 nodemailer@6.10.0 image-size@2.0.1 wildleek@2.0.0 otplib@12.0.1 yubikeyotp@0.2.0;; \
false|no|FALSE|NO) \
echo "Not pre-installing libraries.";; \
*) \
echo -e "Invalid value for build argument INCLUDE_POSTGRESQL_TOOLS, possible values: 'yes' or 'true'"; \
exit 1;; \
esac
EXPOSE 80 443 4433
# Expose only 443 by default to reduce attack surface. (Only encrypted ports).
EXPOSE 443
# volumes
# These volumes will be created by default even without any declaration, this allows default persistence in Docker/Podman.
VOLUME /opt/meshcentral/meshcentral-data
VOLUME /opt/meshcentral/meshcentral-files
VOLUME /opt/meshcentral/meshcentral-web
VOLUME /opt/meshcentral/meshcentral-backups
WORKDIR /opt/meshcentral
CMD ["bash", "/opt/meshcentral/entrypoint.sh"]
# Copy images from Git repo, place it before ending so recompilation can make good use of cache.
COPY ./docker/entrypoint.sh ./entrypoint.sh
COPY ./docker/config.json.template /opt/meshcentral/config.json.template
CMD ["bash", "/opt/meshcentral/entrypoint.sh"]

View File

@ -1,5 +1,7 @@
# Create folder-structure and files
# TO BE REWRITTEN - In progress, for questions: dselen@nerthus.nl or @DaanSelen.
```
| - meshcentral/ # this folder contains the persistent data
| - data/ # MeshCentral data-files

View File

@ -2,7 +2,6 @@
"$schema": "https://raw.githubusercontent.com/Ylianst/MeshCentral/master/meshcentral-config-schema.json",
"settings": {
"plugins":{"enabled": false},
"_mongoDb": null,
"cert": "myserver.mydomain.com",
"_WANonly": true,
"_LANonly": true,
@ -15,7 +14,15 @@
"TLSOffload": false,
"SelfUpdate": false,
"AllowFraming": false,
"WebRTC": false
"WebRTC": false,
"_mongoDb": "",
"_postgres": {
"host": "",
"port": "",
"user": "",
"password": "",
"database": ""
}
},
"domains": {
"": {

View File

@ -1,39 +1,150 @@
#!/bin/bash
if [ -f "meshcentral-data/${CONFIG_FILE}" ]; then
node meshcentral/meshcentral --configfile "${CONFIG_FILE}" ${ARGS}
graceful_shutdown() {
echo "Received SIGTERM. Cleaning up..."
node /opt/meshcentral/meshcentral/meshcentral --stop
exit 0
}
trap cleanup SIGTERM
### Start MeshCentral Docker Container.
date
echo "Config file: $CONFIG_FILE"
# Failsafe to create a new config if the expected config is not there.
if [ -f "${CONFIG_FILE}" ]; then
echo "Pre-existing config found, not recreating..."
else
cp config.json.template meshcentral-data/"${CONFIG_FILE}"
if [ -n "$USE_MONGODB" ] && [ "$USE_MONGODB" == "true" ]; then
if [ -z "$MONGO_URL" ]; then
prefix=""
if [ -n "$MONGO_INITDB_ROOT_USERNAME" ] && [ -n "$MONGO_INITDB_ROOT_PASSWORD" ]; then
prefix="$MONGO_INITDB_ROOT_USERNAME:$MONGO_INITDB_ROOT_PASSWORD@"
fi
MONGO_URL="${prefix}mongodb:27017"
fi
sed -i "s/\"_mongoDb\": null/\"mongoDb\": \"mongodb:\/\/$MONGO_URL\"/" meshcentral-data/"${CONFIG_FILE}"
fi
sed -i "s/\"cert\": \"myserver.mydomain.com\"/\"cert\": \"$HOSTNAME\"/" meshcentral-data/"${CONFIG_FILE}"
sed -i "s/\"NewAccounts\": true/\"NewAccounts\": $ALLOW_NEW_ACCOUNTS/" meshcentral-data/"${CONFIG_FILE}"
sed -i "s/\"enabled\": false/\"enabled\": $ALLOWPLUGINS/" meshcentral-data/"${CONFIG_FILE}"
sed -i "s/\"localSessionRecording\": false/\"localSessionRecording\": $LOCALSESSIONRECORDING/" meshcentral-data/"${CONFIG_FILE}"
sed -i "s/\"minify\": false/\"minify\": $MINIFY/" meshcentral-data/"${CONFIG_FILE}"
sed -i "s/\"WebRTC\": false/\"WebRTC\": $WEBRTC/" meshcentral-data/"${CONFIG_FILE}"
sed -i "s/\"AllowFraming\": false/\"AllowFraming\": $IFRAME/" meshcentral-data/"${CONFIG_FILE}"
if [[ "$ALLOWED_ORIGIN" =~ ^\[.*\]|^true|^false ]]; then
sed -i "s/\"allowedOrigin\": false/\"allowedOrigin\": $ALLOWED_ORIGIN/" meshcentral-data/"${CONFIG_FILE}"
else
sed -i "s/\"allowedOrigin\": false/\"allowedOrigin\": \"$ALLOWED_ORIGIN\"/" meshcentral-data/"${CONFIG_FILE}"
fi
if [ -z "$SESSION_KEY" ]; then
SESSION_KEY="$(cat /dev/urandom | tr -dc 'A-Z0-9' | fold -w 48 | head -n 1)"
fi
sed -i "s/\"_sessionKey\": \"MyReallySecretPassword1\"/\"sessionKey\": \"$SESSION_KEY\"/" meshcentral-data/"${CONFIG_FILE}"
if [ "$REVERSE_PROXY" != "false" ]; then
sed -i "s/\"_certUrl\": \"my\.reverse\.proxy\"/\"certUrl\": \"https:\/\/$REVERSE_PROXY:$REVERSE_PROXY_TLS_PORT\"/" meshcentral-data/"${CONFIG_FILE}"
node meshcentral/meshcentral --configfile "${CONFIG_FILE}" ${ARGS}
exit
fi
node meshcentral/meshcentral --configfile "${CONFIG_FILE}" --cert "$HOSTNAME" ${ARGS}
cp /opt/meshcentral/config.json.template "${CONFIG_FILE}"
fi
if [[ "$DYNAMIC_CONFIG" =~ ^(true|yes)$ ]]; then
if [[ "$USE_MONGODB" =~ ^(true|yes)$ ]]; then
if [[ -n "$MONGO_URL" ]]; then
echo "MONGO_URL is set, using that..."
else
MONGO_URL="${MONGO_URL:-$MONGO_INITDB_ROOT_USERNAME:$MONGO_INITDB_ROOT_PASSWORD@}$MONGO_HOST:$MONGO_PORT"
fi
sed -i "s/\"?_mongoDb\": \"\"/\"mongoDb\": \"$MONGO_URL\"/" "$CONFIG_FILE"
else
sed -i 's/"?_mongoDb": ""/"_mongoDb": "null"/' "$CONFIG_FILE"
fi
if [[ "$USE_POSTGRESQL" =~ ^(true|yes)$ ]]; then
echo "So you wanna postgrsex"
fi
if [[ "$USE_MARIADB" =~ ^(true|yes)$ ]]; then
echo "So you wanna Maria-Dick-Big"
fi
# Doing the bulk with JQ utility. Given the remaining variables an opportunity with Sed.
# The way this works is if the environment variable is empty, it will add a _ in front of the variable, commenting it.
# This will make the default value apply, as per: https://raw.githubusercontent.com/Ylianst/MeshCentral/master/meshcentral-config-schema.json
echo "Compiling given environment variables..."
echo "If defaults are going to get applied, refer to: https://raw.githubusercontent.com/Ylianst/MeshCentral/master/meshcentral-config-schema.json"
# SESSIONKEY
if [[ $REGENSESSIONKEY =~ ^(true|yes)$ ]]; then
echo "Regenerating Session-Key because REGENSESSIONKEY is 'true' or 'yes'"
SESSION_KEY=$(tr -dc 'A-Z0-9' < /dev/urandom | fold -w 60 | head -n 1)
sed -i "s/sessionKey:/ sessionKey\": \"$SESSION_KEY\"/g" "$CONFIG_FILE"
else
echo "REGENSESSIONKEY is not 'true' or 'yes', therefore it's being kept as is."
fi
# HOSTNAME
if [[ -n $HOSTNAME ]]; then
echo "Setting hostname (cert)... - $HOSTNAME"
sed -i '/cert/ c\ "cert": "'"$HOSTNAME"'"' "$CONFIG_FILE"
else
echo "Hostname environment variable is empty, commenting it out..."
sed -i 's/"cert":/ "_cert":/g' "$CONFIG_FILE"
fi
# ALLOW_NEW_ACCOUNTS
if [[ -n $ALLOW_NEW_ACCOUNTS ]] && [[ $ALLOW_NEW_ACCOUNTS =~ ^(true|false)$ ]]; then
echo "Setting NewAccounts... - $ALLOW_NEW_ACCOUNTS"
sed -i '/NewAccounts/ c\ "NewAccounts": "'"$ALLOW_NEW_ACCOUNTS"'"' "$CONFIG_FILE"
else
echo "Invalid ALLOW_NEW_ACCOUNTS value given, commenting out so default applies..."
sed -i 's/"NewAccounts":/ "_NewAccounts":/g' "$CONFIG_FILE"
fi
# ALLOWPLUGINS
if [[ -n $ALLOWPLUGINS ]] && [[ $ALLOWPLUGINS =~ ^(true|false)$ ]]; then
echo "Setting plugins... - $ALLOWPLUGINS"
sed -i '/plugins/ c\ "plugins": {"enabled": '"$ALLOWPLUGINS"'}"' "$CONFIG_FILE"
else
echo "Invalid ALLOWPLUGINS value given, commenting out so default applies..."
sed -i 's/"plugins":/ "_plugins":/g' "$CONFIG_FILE"
fi
# LOCALSESSIONRECORDING
if [[ -n $LOCALSESSIONRECORDING ]] && [[ $LOCALSESSIONRECORDING =~ ^(true|false)$ ]]; then
echo "Setting localSessionRecording... - $LOCALSESSIONRECORDING"
sed -i '/localSessionRecording/ c\ "localSessionRecording": "'"$LOCALSESSIONRECORDING"'"' "$CONFIG_FILE"
else
echo "Invalid LOCALSESSIONRECORDING value given, commenting out so default applies..."
sed -i 's/"localSessionRecording":/ "_localSessionRecording":/g' "$CONFIG_FILE"
fi
# MINIFY
if [[ -n $MINIFY ]] && [[ $MINIFY =~ ^(true|false)$ ]]; then
echo "Setting minify... - $MINIFY"
sed -i '/minify/ c\ "minify": "'"$MINIFY"'"' "$CONFIG_FILE"
else
echo "Invalid MINIFY value given, commenting out so default applies..."
sed -i 's/"minify":/ "_minify":/g' "$CONFIG_FILE"
fi
# WEBRTC
if [[ -n $WEBRTC ]] && [[ $WEBRTC =~ ^(true|false)$ ]]; then
echo "Setting WebRTC... - $WEBRTC"
sed -i '/WebRTC/ c\ "WebRTC": "'"$WEBRTC"'"' "$CONFIG_FILE"
else
echo "Invalid WEBRTC value given, commenting out so default applies..."
sed -i 's/"WebRTC":/ "_WebRTC":/g' "$CONFIG_FILE"
fi
# IFRAME
if [[ -n $IFRAME ]] && [[ $IFRAME =~ ^(true|false)$ ]]; then
echo "Setting AllowFraming... - $IFRAME"
sed -i '/AllowFraming/ c\ "AllowFraming": "'"$IFRAME"'"' "$CONFIG_FILE"
else
echo "Invalid IFRAME value given, commenting out so default applies..."
sed -i 's/"AllowFraming":/ "_AllowFraming":/g' "$CONFIG_FILE"
fi
# ALLOWED_ORIGIN
if [[ -n $ALLOWED_ORIGIN ]] && [[ $ALLOWED_ORIGIN =~ ^(true|false)$ ]]; then
echo "Setting allowedOrigin... - $ALLOWED_ORIGIN"
sed -i '/allowedOrigin/ c\ "allowedOrigin": "'"$ALLOWED_ORIGIN"'"' "$CONFIG_FILE"
else
echo "Invalid ALLOWED_ORIGIN value given, commenting out so default applies..."
sed -i 's/"allowedOrigin":/ "_allowedOrigin":/g' "$CONFIG_FILE"
fi
echo -e "\n$(cat "$CONFIG_FILE")"
# TO DO CERTURL - POSTGRESQL - MONGO_INITDB_ROOT_PASSWORD="pass"
#if [[ "$ALLOWED_ORIGIN" =~ ^\[.*\]|^true|^false ]]; then
# sed -i "s/\"allowedOrigin\": false/\"allowedOrigin\": $ALLOWED_ORIGIN/" meshcentral-data/"${CONFIG_FILE}"
#else
# sed -i "s/\"allowedOrigin\": false/\"allowedOrigin\": \"$ALLOWED_ORIGIN\"/" meshcentral-data/"${CONFIG_FILE}"
#fi
#SESSION_KEY= # Session key should be random. Not passed in through arguments.
#sed -i "s/\"_sessionKey\": \"MyReallySecretPassword1\"/\"sessionKey\": \"$SESSION_KEY\"/" meshcentral-data/"${CONFIG_FILE}"
else
echo "Leaving config as-is."
fi
# Actually start MeshCentral.
node /opt/meshcentral/meshcentral/meshcentral --configfile "${CONFIG_FILE}" "${ARGS}" >> /proc/1/fd/1 &
meshcentral_pid=$!
wait "$meshcentral_pid"