From f77ff50150e6ff5d1f2b03c4f465846d5bb49a96 Mon Sep 17 00:00:00 2001 From: vnugent Date: Fri, 7 Jun 2024 15:45:56 -0400 Subject: Squashed commit of the following: commit 8ed4663e539d9c2ea58aaad02a1fc2896956f6b6 Author: vnugent Date: Fri Jun 7 15:43:48 2024 -0400 fix: invalid chars in status cookie name commit 9d1df65d99732a68b4fe96dcc75273442cbd322f Author: vnugent Date: Thu Jun 6 21:31:30 2024 -0400 fix: Some container fixes and compatability commit 5ecd6b39cccdc9500540b10685605b5fcba61f69 Author: vnugent Date: Thu Jun 6 17:19:48 2024 -0400 Update and expose storage config for container commit 3a62bafd210a2e00d23d3df773e47011e09eba6e Author: vnugent Date: Thu Jun 6 16:18:36 2024 -0400 ci: build admin lib before building front-end commit 35920ad6c8596fc14bcfed66303511e8c249be8d Author: vnugent Date: Thu Jun 6 15:56:36 2024 -0400 ci: Local vite config, force set lib versions commit 3c228b3cc5172fae398af8de72b64bd780ace20c Author: vnugent Date: Wed Jun 5 19:55:39 2024 -0400 ci: Update packages and add container build commit 21d2719701f851d4a555c363b141f289f14a5192 Author: vnugent Date: Wed Jun 5 15:58:07 2024 -0400 fix: #1 new channel page when hitting new button commit eefba88ac4e2c70517aa71c79ed94c346f9de554 Author: vnugent Date: Wed Jun 5 15:26:15 2024 -0400 chore: Package updates commit 9eed4022a79f2cba139c9f8a359bfc8c1f9c31c5 Author: vnugent Date: Wed Jun 5 14:44:08 2024 -0400 ci: Stage blocking changes --- ci/container/Dockerfile | 109 +++++++++++++++++++++++++++++++++++++++ ci/container/Taskfile.yaml | 86 ++++++++++++++++++++++++++++++ ci/container/docker-compose.yaml | 73 ++++++++++++++++++++++++++ ci/container/run.sh | 25 +++++++++ 4 files changed, 293 insertions(+) create mode 100644 ci/container/Dockerfile create mode 100644 ci/container/Taskfile.yaml create mode 100644 ci/container/docker-compose.yaml create mode 100644 ci/container/run.sh (limited to 'ci/container') 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 " +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 -- cgit