summaryrefslogtreecommitdiff
path: root/ci/container
diff options
context:
space:
mode:
Diffstat (limited to 'ci/container')
-rw-r--r--ci/container/Dockerfile109
-rw-r--r--ci/container/Taskfile.yaml86
-rw-r--r--ci/container/docker-compose.yaml73
-rw-r--r--ci/container/run.sh25
4 files changed, 293 insertions, 0 deletions
diff --git a/ci/container/Dockerfile b/ci/container/Dockerfile
new file mode 100644
index 0000000..5268448
--- /dev/null
+++ b/ci/container/Dockerfile
@@ -0,0 +1,109 @@
+#Copyright (c) Vaughn Nugent
+#Licensed under the GNU AGPL V3.0
+
+#use plain alpine latest to build native libraries in
+FROM alpine:3.19 as native-cont
+
+#install public libs and build tools
+RUN apk update && apk add --no-cache build-base cmake npm git openssl
+#most universal way to use Task is from NPM
+RUN npm install -g @go-task/cli
+
+WORKDIR /build
+
+#include local artifacts
+COPY app/ .
+
+#build internal libraries and copy the libraries to the /lib output directory
+RUN mkdir out/ ssl/
+RUN task build-libs
+
+#APP CONTAINER
+#move into a clean dotnet apline lean image
+FROM mcr.microsoft.com/dotnet/runtime:8.0.3-alpine3.19-amd64 as app-cont
+
+LABEL name="vnuge/cmnext"
+LABEL maintainer="Vaughn Nugent <vnpublic@proton.me>"
+LABEL description="A dead-simple, multi-channel cms for your blog or podcast built for static storage like S3 or FTP"
+
+#copy local artifacts again in run container
+COPY app/ /app
+
+#pull compiled libs from build container
+COPY --from=native-cont /build/out /app/lib
+#copy self signed ssl certs for first startup
+COPY --from=native-cont /build/ssl /app/ssl
+
+RUN apk update && apk add --no-cache gettext icu-libs dumb-init
+
+#workdir
+WORKDIR /app
+
+#default to 8080 for TLS on TCP
+EXPOSE 8080/tcp
+
+VOLUME /app/data \
+ /app/ssl \
+#expose an assets directory for custom assets install
+ /app/usr/assets
+
+#disable dotnet invariant culture on alpine
+ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=0
+
+#add helper/required libraries
+#ENV VNLIB_SHARED_HEAP_FILE_PATH=/app/lib/libvn_rpmalloc.so not ready yet, still need to debug
+ENV VNLIB_ARGON2_DLL_PATH=/app/lib/libargon2.so \
+ COMPRESSION_LIB_PATH=/app/lib/libvn_compress.so
+
+#set default env variables
+ENV MAX_CONTENT_LENGTH=204800000 \
+ REG_TOKEN_DURATION_MIN=360 \
+ MAX_LOGIN_ATTEMPS=10
+
+#SQL Config
+ENV SQL_LIB_PATH=VNLib.Plugins.Extensions.Sql.SQLite.dll
+ENV SQL_CONNECTION_STRING="Data Source=data/cmnext.db;"
+
+#STORAGE
+ENV STORAGE_TYPE="s3" \
+ STORAGE_CUSTOM_ASSEMBLY="" \
+ STORAGE_SERVER_ADDRESS="" \
+ STORAGE_USERNAME="" \
+ STORAGE_BUCKET="" \
+ STORAGE_USE_SSL=true \
+ S3_REGION=""
+
+#HC Vault
+ENV HC_VAULT_ADDR="" \
+ HC_VAULT_TOKEN="" \
+ HC_VAULT_TRUST_CERT=false
+
+#VNCACHE (default to memory only)
+ENV CACHE_ASM_PATH=VNLib.Data.Caching.Providers.VNCache.dll \
+ MEMCACHE_ONLY=true \
+ REDIS_CONNECTION_STRING="" \
+ VNCACHE_INITIAL_NODES=[]
+
+#SECRETS
+ENV PASSWORD_PEPPER="" \
+ DATABASE_PASSWORD="" \
+ REDIS_PASSWORD="" \
+ VNCACHE_CLIENT_PRIVATE_KEY="" \
+ VNCACHE_CACHE_PUBLIC_KEY="" \
+ STORAGE_SECRET=""
+
+
+#HTTP/PROXY Config
+ENV HTTP_DOWNSTREAM_SERVERS=[] \
+ HTTP_TRACE_ON=false
+
+#set default certificate files to the self signed ones created in the build container
+ENV SSL_JSON='{"cert": "ssl/cert.pem", "privkey":"ssl/key.pem"}'
+
+#disable plugin debugging by default
+ENV DEBUG_PLUGINS=false
+
+#run the init script within dumb-init
+ENTRYPOINT ["dumb-init", "--"]
+CMD ["ash", "./run.sh"]
+
diff --git a/ci/container/Taskfile.yaml b/ci/container/Taskfile.yaml
new file mode 100644
index 0000000..0b959ab
--- /dev/null
+++ b/ci/container/Taskfile.yaml
@@ -0,0 +1,86 @@
+# https://taskfile.dev
+
+#This taskfile must be called from the CI taskfile, as it is part of the CI
+#project and it's pipleine. This file will also be copied to the container image
+#and used to build the native libraries for the project.
+
+version: "3"
+
+vars:
+ INCLUDE_FILES: "Dockerfile, docker-compose.yaml"
+ CERT_KEY_PARAMS: "ec -pkeyopt ec_paramgen_curve:secp384r1"
+
+includes:
+ install:
+ taskfile: ../install.taskfile.yaml
+ optional: true #not needed for inside container build
+
+tasks:
+ #called from inside the container to build native libraries
+ build-libs:
+ vars:
+ OUT_DIR: "{{.USER_WORKING_DIR}}/out"
+ SSL_DIR: "{{.USER_WORKING_DIR}}/ssl"
+ HOSTNAME:
+ sh: echo $HOSTNAME
+
+ cmds:
+ #build argon2 native library
+ - cd lib/argon2/ && task && cp build/libargon2.so {{.OUT_DIR}}/libargon2.so
+ #build rpmalloc library and rewrite to a standard .dll extension
+ - cd lib/vnlib_rpmalloc/ && task && cp build/libvn_rpmalloc.so {{.OUT_DIR}}/libvn_rpmalloc.so
+ #build compression and rewrite to a standard .dll extension
+ - cd lib/vnlib_compress/ && task && cp build/libvn_compress.so {{.OUT_DIR}}/libvn_compress.so
+
+ #create a fresh self-signed cert for the container during build
+ - openssl req -new -x509 -days 365 -keyout {{.SSL_DIR}}/key.pem -out {{.SSL_DIR}}/cert.pem -newkey {{.CERT_KEY_PARAMS}} --nodes -subj "/CN={{.HOSTNAME}}"
+ - echo "WARNING Self signed certificate created during build stage, DO NOT COPY THIS IMAGE"
+
+ #called from ci pipline to build the package
+ build:
+ cmds:
+ # clean up the run.sh script to remove windows line endings in my wsl default instance
+ - cmd: wsl dos2unix ./run.sh
+ platforms: [ windows/amd64 ]
+
+ #init build image
+ - task: setup-container-image
+
+ #remove the default config file as it's not needed in the container
+ - powershell -Command "rm -Force -Recurse build/app/config/"
+
+ - task: prune-sql-runtimes
+
+ postbuild_success:
+ cmds:
+ #tar up the build directory and move it to the output bin directory
+ - cmd: cd build/ && tar -czf ../../bin/{{.PACKAGE_FILE_NAME}} .
+ #clean up all the build files after build succeeds
+ - task: clean
+
+ clean:
+ ignore_error: true
+ cmds:
+ - cmd: powershell -Command "rm -Recurse -Force ./build"
+
+ setup-container-image:
+ internal: true
+ cmds:
+ #make build directory
+ - powershell -Command "mkdir build, build/app, build/app/config-templates/, build/app/static/ -Force"
+ #copy the existing linux-x64 build to the build folder, this will be the container base
+ - powershell -Command "cp -Recurse -Force ../build/linux-x86_64/* build/app/"
+ #copy local scripts and raw config templates into the build folder
+ - powershell -Command "cp -Force run.sh, Taskfile.yaml build/app/"
+ - powershell -Command "cp -Force Dockerfile, docker-compose.yaml build/"
+ - powershell -Command "cp -Force ../config-templates/* build/app/config-templates/"
+
+ prune-sql-runtimes:
+ internal: true
+ vars:
+ SQLITE_RUNTIMES: 'build/app/plugins/assets/VNLib.Plugins.Extensions.Loading.Sql.SQLite/runtimes'
+ cmds:
+ #move the linux-musl-x64 directory out of assets before removing the rest of the runtimes and then move it back
+ - powershell -Command "mv {{.SQLITE_RUNTIMES}}/linux-musl-x64 build/linux-musl-x64"
+ - powershell -Command "rm -Recurse -Force {{.SQLITE_RUNTIMES}}" && powershell -Command "mkdir {{.SQLITE_RUNTIMES}}"
+ - powershell -Command "mv build/linux-musl-x64 {{.SQLITE_RUNTIMES}}/linux-musl-x64 " \ No newline at end of file
diff --git a/ci/container/docker-compose.yaml b/ci/container/docker-compose.yaml
new file mode 100644
index 0000000..9bd1fc1
--- /dev/null
+++ b/ci/container/docker-compose.yaml
@@ -0,0 +1,73 @@
+#Copyright (c) Vaughn Nugent
+#Licensed under the GNU AGPLv3
+
+version: '3.6'
+
+services:
+ cmnext:
+ image: vnuge/cmnext
+ container_name: cmnext
+ restart: unless-stopped
+ volumes:
+ - ./data:/app/data
+ - ./assets:/app/usr/assets:ro
+ #uncomment to use your own ssl certs, otherwise a build-time cert will be used
+ #- ./ssl/cert.pem:/app/ssl/cert.pem:ro
+ #- ./ssl/key.pem:/app/ssl/key.pem:ro
+ ports:
+ - 8080:8080
+ environment:
+ CHANNEL_INDEX_FILE: "channels.json" #required, should leave default unless you know what you are doing
+ MAX_CONTENT_LENGTH: 204800000 #200MB max upload size
+ MAX_LOGIN_ATTEMPS: "10" #max login attempts before user account is locked out
+
+ #SQL Config
+ SQL_LIB_PATH: "VNLib.Plugins.Extensions.Sql.SQLite.dll"
+ SQL_CONNECTION_STRING: "Data Source=data/cmnext.db;" #when using a password, simply leave the password field blank
+
+ #storage backend setup
+ STORAGE_TYPE: "s3" #s3 | ftp
+ STORAGE_CUSTOM_ASSEMBLY: "" #optional path to a custom storage assembly
+ STORAGE_SERVER_ADDRESS: "" #s3 or ftp server address
+ STORAGE_USERNAME: "" #s3 client id or ftp username
+ STORAGE_BUCKET: "" #s3 bucket or ftp root directory
+ STORAGE_USE_SSL: "true" #force ssl for connections
+ S3_REGION: "" #optional s3 region when using s3 storage
+
+ #HC Vault client config
+ #HC_VAULT_ADDR: ""
+ #HC_VAULT_TOKEN: ""
+ #HC_VAULT_TRUST_CERT: "false"
+
+ #VNCACHE (default to memory only)
+ CACHE_ASM_PATH: "VNLib.Data.Caching.Providers.VNCache.dll"
+ MEMCACHE_ONLY: "true"
+ REDIS_CONNECTION_STRING: ""
+ #at least one node required if MEMCACHE_ONLY is false
+ VNCACHE_INITIAL_NODES: "[]"
+
+ #SECRETS
+ # All secrets may be a raw value, read from a file,
+ # an environment variable, or a vault path
+ # file://mysecret.txt reads the secret from a file (case sensitive)
+ # env://MY_SECRET reads the secret from an environment variable (case sensitive)
+ # vault://kv/data/secret?secret=value reads the value of the mysecret key in the secret/data path
+
+ PASSWORD_PEPPER: "" #Must be a base64 encoded value, of realtivley any size
+ DATABASE_PASSWORD: "" #overrides the 'Password' field in the SQL connection string
+ REDIS_PASSWORD: "" #only required if using a password protected redis server
+ #if MEMCACHE_ONLY is false, then the following keys are required to connect to a VNCACHE cluster
+ VNCACHE_CLIENT_PRIVATE_KEY: ""
+ VNCACHE_CACHE_PUBLIC_KEY: ""
+ #REQUIRED s3 or ftp secret key
+ STORAGE_SECRET: ""
+
+ #HTTP
+ HTTP_DOWNSTREAM_SERVERS: '[]' #a comma separated list of downstream (proxy) server ip addresses
+ HTTP_TRACE_ON: "false" #enable http trace logging, requires you to set --debug to SERVER_ARGS variable below
+
+ #Very Verbose plugin logging, required --debug CLI flag, prints literally everything to the logger (it's annoying)
+ DEBUG_PLUGINS: "false"
+
+ SERVER_ARGS: ""
+
diff --git a/ci/container/run.sh b/ci/container/run.sh
new file mode 100644
index 0000000..d829509
--- /dev/null
+++ b/ci/container/run.sh
@@ -0,0 +1,25 @@
+#! /bin/sh
+
+#this script will be invoked by dumb-init in the container on statup and is located at /app
+
+echo "Generating configuration files"
+
+rm -rf config && mkdir config
+
+#move the routes xml file to the output config dir
+cp config-templates/routes.xml config/routes.xml
+
+#substitude all -template files in the config-templates dir and write them to the config dir
+for file in config-templates/*-template.json; do
+ envsubst < $file > config/$(basename $file -template.json).json
+done
+
+echo "Complete"
+
+echo "Merging your asset files"
+cp usr/assets/* plugins/assets/ -rf
+echo "Complete"
+
+#start the server
+echo "Starting the server"
+dotnet webserver/VNLib.WebServer.dll --config config/config.json --input-off $SERVER_ARGS \ No newline at end of file