From 9c3e0242873d1ae5cc647d88ec25860166f20eea Mon Sep 17 00:00:00 2001 From: Nick Craig Date: Tue, 8 Feb 2022 07:48:13 -0500 Subject: [PATCH 1/8] removing HSTS include from location as it is superfluous. HSTS is defined at the server level and re-adding the host at the location prevents inheritance from the advanced config include. Per the NGINX documentation, "These directives are inherited from the previous configuration level if and only if there are no add_header directives defined on the current level." --- backend/templates/proxy_host.conf | 1 - backend/templates/redirection_host.conf | 1 - 2 files changed, 2 deletions(-) diff --git a/backend/templates/proxy_host.conf b/backend/templates/proxy_host.conf index ec30cca0..9ab20450 100644 --- a/backend/templates/proxy_host.conf +++ b/backend/templates/proxy_host.conf @@ -51,7 +51,6 @@ proxy_http_version 1.1; {% endif %} -{% include "_hsts.conf" %} {% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %} proxy_set_header Upgrade $http_upgrade; diff --git a/backend/templates/redirection_host.conf b/backend/templates/redirection_host.conf index 339fe72e..737c85a2 100644 --- a/backend/templates/redirection_host.conf +++ b/backend/templates/redirection_host.conf @@ -16,7 +16,6 @@ server { {% if use_default_location %} location / { -{% include "_hsts.conf" %} {% if preserve_path == 1 or preserve_path == true %} return {{ forward_http_code }} {{ forward_scheme }}://{{ forward_domain_name }}$request_uri; From c571599d45cf037f9f08b771278f8af5ee8c37e7 Mon Sep 17 00:00:00 2001 From: Nick Craig Date: Wed, 9 Mar 2022 10:19:51 -0500 Subject: [PATCH 2/8] adding wrapper for proxy header passing. add a selection to the proxy editing page and passes that down into the templates. Removed set_proxy_header from locations and moved to server directive. these will inherit down into locations if they are not defined there. --- backend/internal/nginx.js | 2 +- .../migrations/20220309105452_proxy_header.js | 41 +++++++++++++++++++ backend/schema/endpoints/proxy-hosts.json | 14 +++++++ backend/templates/_location.conf | 12 ------ backend/templates/proxy_host.conf | 23 +++++++---- .../etc/nginx/conf.d/include/proxy.conf | 1 - frontend/js/app/nginx/proxy/form.ejs | 11 ++++- frontend/js/app/nginx/proxy/form.js | 1 + frontend/js/models/proxy-host.js | 1 + 9 files changed, 82 insertions(+), 24 deletions(-) create mode 100644 backend/migrations/20220309105452_proxy_header.js diff --git a/backend/internal/nginx.js b/backend/internal/nginx.js index 52bdd66d..3be4b9e1 100644 --- a/backend/internal/nginx.js +++ b/backend/internal/nginx.js @@ -157,7 +157,7 @@ const internalNginx = { for (let i = 0; i < host.locations.length; i++) { let locationCopy = Object.assign({}, {access_list_id: host.access_list_id}, {certificate_id: host.certificate_id}, {ssl_forced: host.ssl_forced}, {caching_enabled: host.caching_enabled}, {block_exploits: host.block_exploits}, - {allow_websocket_upgrade: host.allow_websocket_upgrade}, {http2_support: host.http2_support}, + {allow_websocket_upgrade: host.allow_websocket_upgrade}, {forward_proxy_header: host.forward_proxy_header}, {http2_support: host.http2_support}, {hsts_enabled: host.hsts_enabled}, {hsts_subdomains: host.hsts_subdomains}, {access_list: host.access_list}, {certificate: host.certificate}, host.locations[i]); diff --git a/backend/migrations/20220309105452_proxy_header.js b/backend/migrations/20220309105452_proxy_header.js new file mode 100644 index 00000000..da1130a9 --- /dev/null +++ b/backend/migrations/20220309105452_proxy_header.js @@ -0,0 +1,41 @@ +const migrate_name = 'proxy_header'; +const logger = require('../logger').migrate; + +/** + * Migrate + * + * @see http://knexjs.org/#Schema + * + * @param {Object} knex + * @param {Promise} Promise + * @returns {Promise} + */ +exports.up = function (knex/*, Promise*/) { + logger.info('[' + migrate_name + '] Migrating Up...'); + + return knex.schema.table('proxy_host', function (proxy_host) { + proxy_host.integer('forward_proxy_header').notNull().unsigned().defaultTo(1); + }) + .then(() => { + logger.info('[' + migrate_name + '] proxy_host Table altered'); + }); + +}; + +/** + * Undo Migrate + * + * @param {Object} knex + * @param {Promise} Promise + * @returns {Promise} + */ +exports.down = function (knex/*, Promise*/) { + logger.info('[' + migrate_name + '] Migrating Down...'); + + return knex.schema.table('redirection_host', (table) => { + table.dropColumn('forward_proxy_header'); + }) + .then(function () { + logger.info('[' + migrate_name + '] proxy_host Table altered'); + }); +}; \ No newline at end of file diff --git a/backend/schema/endpoints/proxy-hosts.json b/backend/schema/endpoints/proxy-hosts.json index 9a3fff2f..31193262 100644 --- a/backend/schema/endpoints/proxy-hosts.json +++ b/backend/schema/endpoints/proxy-hosts.json @@ -58,6 +58,11 @@ "example": true, "type": "boolean" }, + "forward_proxy_header": { + "description": "forward the proxy hostname to the backend proxy server", + "example": true, + "type": "boolean" + }, "access_list_id": { "$ref": "../definitions.json#/definitions/access_list_id" }, @@ -155,6 +160,9 @@ "allow_websocket_upgrade": { "$ref": "#/definitions/allow_websocket_upgrade" }, + "forward_proxy_header": { + "$ref": "#/definitions/forward_proxy_header" + }, "access_list_id": { "$ref": "#/definitions/access_list_id" }, @@ -245,6 +253,9 @@ "allow_websocket_upgrade": { "$ref": "#/definitions/allow_websocket_upgrade" }, + "forward_proxy_header": { + "$ref": "#/definitions/forward_proxy_header" + }, "access_list_id": { "$ref": "#/definitions/access_list_id" }, @@ -318,6 +329,9 @@ "allow_websocket_upgrade": { "$ref": "#/definitions/allow_websocket_upgrade" }, + "forward_proxy_header": { + "$ref": "#/definitions/forward_proxy_header" + }, "access_list_id": { "$ref": "#/definitions/access_list_id" }, diff --git a/backend/templates/_location.conf b/backend/templates/_location.conf index 5a7a6abe..5afdd626 100644 --- a/backend/templates/_location.conf +++ b/backend/templates/_location.conf @@ -1,9 +1,4 @@ location {{ path }} { - proxy_set_header Host $host; - proxy_set_header X-Forwarded-Scheme $scheme; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header X-Real-IP $remote_addr; proxy_pass {{ forward_scheme }}://{{ forward_host }}:{{ forward_port }}{{ forward_path }}; {% if access_list_id > 0 %} @@ -33,13 +28,6 @@ {% include "_forced_ssl.conf" %} {% include "_hsts.conf" %} - {% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %} - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $http_connection; - proxy_http_version 1.1; - {% endif %} - - {{ advanced_config }} } diff --git a/backend/templates/proxy_host.conf b/backend/templates/proxy_host.conf index 9ab20450..ffed08b7 100644 --- a/backend/templates/proxy_host.conf +++ b/backend/templates/proxy_host.conf @@ -24,6 +24,20 @@ proxy_http_version 1.1; {{ advanced_config }} + # Proxy! + {% if forward_proxy_header == 1 or forward_proxy_header == true %} + proxy_set_header Host $host; + {% else %} + proxy_set_header Host $proxy_host; + {% endif %} + include conf.d/include/proxy.conf; + + {% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %} + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $http_connection; + proxy_http_version 1.1; + {% endif %} + {{ locations }} {% if use_default_location %} @@ -51,15 +65,6 @@ proxy_http_version 1.1; {% endif %} - - {% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %} - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $http_connection; - proxy_http_version 1.1; - {% endif %} - - # Proxy! - include conf.d/include/proxy.conf; } {% endif %} diff --git a/docker/rootfs/etc/nginx/conf.d/include/proxy.conf b/docker/rootfs/etc/nginx/conf.d/include/proxy.conf index fcaaf003..e6f9ee16 100644 --- a/docker/rootfs/etc/nginx/conf.d/include/proxy.conf +++ b/docker/rootfs/etc/nginx/conf.d/include/proxy.conf @@ -1,5 +1,4 @@ add_header X-Served-By $host; -proxy_set_header Host $host; proxy_set_header X-Forwarded-Scheme $scheme; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $remote_addr; diff --git a/frontend/js/app/nginx/proxy/form.ejs b/frontend/js/app/nginx/proxy/form.ejs index 56868f55..8ab3cf07 100644 --- a/frontend/js/app/nginx/proxy/form.ejs +++ b/frontend/js/app/nginx/proxy/form.ejs @@ -72,7 +72,7 @@ -
+
+
+
+ +
+
diff --git a/frontend/js/app/nginx/proxy/form.js b/frontend/js/app/nginx/proxy/form.js index 1dfb5c18..4d6eb40b 100644 --- a/frontend/js/app/nginx/proxy/form.js +++ b/frontend/js/app/nginx/proxy/form.js @@ -163,6 +163,7 @@ module.exports = Mn.View.extend({ data.block_exploits = !!data.block_exploits; data.caching_enabled = !!data.caching_enabled; data.allow_websocket_upgrade = !!data.allow_websocket_upgrade; + data.forward_proxy_header = !!data.forward_proxy_header; data.http2_support = !!data.http2_support; data.hsts_enabled = !!data.hsts_enabled; data.hsts_subdomains = !!data.hsts_subdomains; diff --git a/frontend/js/models/proxy-host.js b/frontend/js/models/proxy-host.js index b82d09fe..4811fe86 100644 --- a/frontend/js/models/proxy-host.js +++ b/frontend/js/models/proxy-host.js @@ -19,6 +19,7 @@ const model = Backbone.Model.extend({ hsts_subdomains: false, caching_enabled: false, allow_websocket_upgrade: false, + forward_proxy_header: true, block_exploits: false, http2_support: false, advanced_config: '', From 30c9a1fbbdb7c342ab8722e636b3f288ee48f4d8 Mon Sep 17 00:00:00 2001 From: Nick Craig Date: Wed, 9 Mar 2022 11:27:13 -0500 Subject: [PATCH 3/8] converting to AWS image --- Jenkinsfile | 12 ++++++------ docker/Dockerfile | 22 ++++++++++++---------- docker/dev/Dockerfile | 14 +++++++------- frontend/scss/tabler-extra.scss | 4 ++++ scripts/frontend-build | 3 ++- 5 files changed, 31 insertions(+), 24 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 1b744692..51320be5 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -8,7 +8,7 @@ pipeline { ansiColor('xterm') } environment { - IMAGE = "nginx-proxy-manager" + IMAGE = "owenscorning/aws-nginx-full" BUILD_VERSION = getVersion() MAJOR_VERSION = "2" BRANCH_LOWER = "${BRANCH_NAME.toLowerCase().replaceAll('/', '-')}" @@ -26,7 +26,7 @@ pipeline { } steps { script { - env.BUILDX_PUSH_TAGS = "-t docker.io/jc21/${IMAGE}:${BUILD_VERSION} -t docker.io/jc21/${IMAGE}:${MAJOR_VERSION} -t docker.io/jc21/${IMAGE}:latest" + env.BUILDX_PUSH_TAGS = "-t docker.io/${IMAGE}:${BUILD_VERSION} -t docker.io/${IMAGE}:${MAJOR_VERSION} -t docker.io/${IMAGE}:latest" } } } @@ -39,7 +39,7 @@ pipeline { steps { script { // Defaults to the Branch name, which is applies to all branches AND pr's - env.BUILDX_PUSH_TAGS = "-t docker.io/jc21/${IMAGE}:github-${BRANCH_LOWER}" + env.BUILDX_PUSH_TAGS = "-t docker.io/${IMAGE}:github-${BRANCH_LOWER}" } } } @@ -62,13 +62,13 @@ pipeline { stage('Backend') { steps { echo 'Checking Syntax ...' - sh 'docker pull nginxproxymanager/nginx-full:certbot-node' + sh 'docker pull ${IMAGE}:certbot-node' // See: https://github.com/yarnpkg/yarn/issues/3254 sh '''docker run --rm \\ -v "$(pwd)/backend:/app" \\ -v "$(pwd)/global:/app/global" \\ -w /app \\ - nginxproxymanager/nginx-full:certbot-node \\ + ${IMAGE}:certbot-node \\ sh -c "yarn install && yarn eslint . && rm -rf node_modules" ''' @@ -214,7 +214,7 @@ pipeline { } steps { script { - def comment = pullRequest.comment("This is an automated message from CI:\n\nDocker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker/jc21/${IMAGE}) as `jc21/${IMAGE}:github-${BRANCH_LOWER}`\n\n**Note:** ensure you backup your NPM instance before testing this PR image! Especially if this PR contains database changes.") + def comment = pullRequest.comment("This is an automated message from CI:\n\nDocker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker${IMAGE}) as `jc21/${IMAGE}:github-${BRANCH_LOWER}`\n\n**Note:** ensure you backup your NPM instance before testing this PR image! Especially if this PR contains database changes.") } } } diff --git a/docker/Dockerfile b/docker/Dockerfile index 378fffbf..7e0c4924 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -3,7 +3,7 @@ # This file assumes that the frontend has been built using ./scripts/frontend-build -FROM nginxproxymanager/nginx-full:certbot-node +FROM owenscorning/aws-nginx-full:certbot-node ARG TARGETPLATFORM ARG BUILD_VERSION @@ -18,11 +18,12 @@ ENV SUPPRESS_NO_CONFIG_WARNING=1 \ NPM_BUILD_COMMIT="${BUILD_COMMIT}" \ NPM_BUILD_DATE="${BUILD_DATE}" -RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \ - && apt-get update \ - && apt-get install -y --no-install-recommends jq logrotate \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* +RUN yum makecache \ + && yum install -y \ + jq logrotate \ + \ + && yum clean all \ + && rm -rf /var/cache/* /var/log/* /tmp/* # s6 overlay COPY scripts/install-s6 /tmp/install-s6 @@ -56,8 +57,9 @@ ENTRYPOINT [ "/init" ] LABEL org.label-schema.schema-version="1.0" \ org.label-schema.license="MIT" \ - org.label-schema.name="nginx-proxy-manager" \ + org.label-schema.name="aws-nginx-full" \ org.label-schema.description="Docker container for managing Nginx proxy hosts with a simple, powerful interface " \ - org.label-schema.url="https://github.com/jc21/nginx-proxy-manager" \ - org.label-schema.vcs-url="https://github.com/jc21/nginx-proxy-manager.git" \ - org.label-schema.cmd="docker run --rm -ti jc21/nginx-proxy-manager:latest" + org.label-schema.url="https://github.com/owenscorning/docker-aws-nginx-full" \ + org.label-schema.vcs-url="https://github.com/owenscorning/docker-aws-nginx-full.git" \ + org.label-schema.cmd="docker run --rm -ti owenscorning/aws-nginx-full:latest" + diff --git a/docker/dev/Dockerfile b/docker/dev/Dockerfile index d2e2266a..509a2c07 100644 --- a/docker/dev/Dockerfile +++ b/docker/dev/Dockerfile @@ -1,15 +1,15 @@ -FROM nginxproxymanager/nginx-full:certbot-node -LABEL maintainer="Jamie Curnow " +FROM owenscorning/aws-nginx-full:certbot-node ENV S6_LOGGING=0 \ SUPPRESS_NO_CONFIG_WARNING=1 \ S6_FIX_ATTRS_HIDDEN=1 -RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \ - && apt-get update \ - && apt-get install -y certbot jq python3-pip logrotate \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* +RUN yum makecache \ + && yum install -y \ + certbot jq python3-pip logrotate \ + \ + && yum clean all \ + && rm -rf /var/cache/* /var/log/* /tmp/* # Task RUN cd /usr \ diff --git a/frontend/scss/tabler-extra.scss b/frontend/scss/tabler-extra.scss index 3ddd0ed4..8f1a4733 100644 --- a/frontend/scss/tabler-extra.scss +++ b/frontend/scss/tabler-extra.scss @@ -168,3 +168,7 @@ $pink: #f66d9b; textarea.form-control.text-monospace { font-size: 12px; } +/*wrapfix for table */ +.table .text-monospace { + word-break: break-word; +} diff --git a/scripts/frontend-build b/scripts/frontend-build index 0e12cf06..021bd6a6 100755 --- a/scripts/frontend-build +++ b/scripts/frontend-build @@ -2,8 +2,9 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" . "$DIR/.common.sh" +aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 413067109875.dkr.ecr.us-east-1.amazonaws.com -DOCKER_IMAGE=nginxproxymanager/nginx-full:certbot-node +DOCKER_IMAGE=413067109875.dkr.ecr.us-east-1.amazonaws.com/owenscorning/aws-nginx-full:certbot-node # Ensure docker exists if hash docker 2>/dev/null; then From 6368c39ef72bb6ed0e19f178571211106fdb6ad8 Mon Sep 17 00:00:00 2001 From: Nick Craig Date: Thu, 10 Mar 2022 16:14:07 -0500 Subject: [PATCH 4/8] merging changes --- backend/templates/proxy_host.conf | 3 ++- docker/Dockerfile | 14 +++++++------- docker/rootfs/etc/nginx/conf.d/include/proxy.conf | 2 +- frontend/fonts/feather | 1 - frontend/images | 1 - frontend/js/i18n/messages.json | 3 ++- frontend/package.json | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) delete mode 120000 frontend/fonts/feather delete mode 120000 frontend/images diff --git a/backend/templates/proxy_host.conf b/backend/templates/proxy_host.conf index ffed08b7..b538a0a0 100644 --- a/backend/templates/proxy_host.conf +++ b/backend/templates/proxy_host.conf @@ -64,7 +64,8 @@ proxy_http_version 1.1; {% endif %} {% endif %} - + #do the proxy! + proxy_pass $forward_scheme://$server:$port$request_uri; } {% endif %} diff --git a/docker/Dockerfile b/docker/Dockerfile index 7e0c4924..400e94fb 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -3,7 +3,7 @@ # This file assumes that the frontend has been built using ./scripts/frontend-build -FROM owenscorning/aws-nginx-full:certbot-node +FROM 413067109875.dkr.ecr.us-east-1.amazonaws.com/owenscorning/aws-nginx-full:certbot-node ARG TARGETPLATFORM ARG BUILD_VERSION @@ -18,12 +18,12 @@ ENV SUPPRESS_NO_CONFIG_WARNING=1 \ NPM_BUILD_COMMIT="${BUILD_COMMIT}" \ NPM_BUILD_DATE="${BUILD_DATE}" -RUN yum makecache \ - && yum install -y \ - jq logrotate \ - \ - && yum clean all \ - && rm -rf /var/cache/* /var/log/* /tmp/* +RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \ + && apt-get update \ + && apt-get upgrade -y \ + && apt-get install -y --no-install-recommends jq logrotate \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* # s6 overlay COPY scripts/install-s6 /tmp/install-s6 diff --git a/docker/rootfs/etc/nginx/conf.d/include/proxy.conf b/docker/rootfs/etc/nginx/conf.d/include/proxy.conf index e6f9ee16..9618208a 100644 --- a/docker/rootfs/etc/nginx/conf.d/include/proxy.conf +++ b/docker/rootfs/etc/nginx/conf.d/include/proxy.conf @@ -3,5 +3,5 @@ proxy_set_header X-Forwarded-Scheme $scheme; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Real-IP $remote_addr; -proxy_pass $forward_scheme://$server:$port$request_uri; + diff --git a/frontend/fonts/feather b/frontend/fonts/feather deleted file mode 120000 index 440203ba..00000000 --- a/frontend/fonts/feather +++ /dev/null @@ -1 +0,0 @@ -../node_modules/tabler-ui/dist/assets/fonts/feather \ No newline at end of file diff --git a/frontend/images b/frontend/images deleted file mode 120000 index 37c31854..00000000 --- a/frontend/images +++ /dev/null @@ -1 +0,0 @@ -./node_modules/tabler-ui/dist/assets/images \ No newline at end of file diff --git a/frontend/js/i18n/messages.json b/frontend/js/i18n/messages.json index 896a9633..180508fe 100644 --- a/frontend/js/i18n/messages.json +++ b/frontend/js/i18n/messages.json @@ -133,7 +133,8 @@ "allow-websocket-upgrade": "Websockets Support", "ignore-invalid-upstream-ssl": "Ignore Invalid SSL", "custom-forward-host-help": "Add a path for sub-folder forwarding.\nExample: 203.0.113.25/path", - "search": "Search Host…" + "search": "Search Host…", + "forward-proxy-header": "Forward Hostname" }, "redirection-hosts": { "title": "Redirection Hosts", diff --git a/frontend/package.json b/frontend/package.json index 198e6c93..7fd50b13 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "nginx-proxy-manager", - "version": "0.0.0", + "version": "2.9.16", "description": "A beautiful interface for creating Nginx endpoints", "main": "js/index.js", "devDependencies": { From e8262946d70cf72237643424b9856da6f46941ea Mon Sep 17 00:00:00 2001 From: Nick Craig Date: Thu, 10 Mar 2022 16:18:22 -0500 Subject: [PATCH 5/8] commiting OC AWS tools --- Jenkinsfile | 12 +- aws/cloud-formation/template.yml | 137 ++++++++++++++++++ backend/templates/proxy_host.conf | 3 +- deploy_build.sh | 39 +++++ deploy_fargate.sh | 1 + docker/Dockerfile | 12 +- docker/dev/Dockerfile | 14 +- .../etc/nginx/conf.d/include/proxy.conf | 2 +- local_build.sh | 34 +++++ 9 files changed, 231 insertions(+), 23 deletions(-) create mode 100644 aws/cloud-formation/template.yml create mode 100644 deploy_build.sh create mode 100644 deploy_fargate.sh create mode 100644 local_build.sh diff --git a/Jenkinsfile b/Jenkinsfile index 51320be5..1b744692 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -8,7 +8,7 @@ pipeline { ansiColor('xterm') } environment { - IMAGE = "owenscorning/aws-nginx-full" + IMAGE = "nginx-proxy-manager" BUILD_VERSION = getVersion() MAJOR_VERSION = "2" BRANCH_LOWER = "${BRANCH_NAME.toLowerCase().replaceAll('/', '-')}" @@ -26,7 +26,7 @@ pipeline { } steps { script { - env.BUILDX_PUSH_TAGS = "-t docker.io/${IMAGE}:${BUILD_VERSION} -t docker.io/${IMAGE}:${MAJOR_VERSION} -t docker.io/${IMAGE}:latest" + env.BUILDX_PUSH_TAGS = "-t docker.io/jc21/${IMAGE}:${BUILD_VERSION} -t docker.io/jc21/${IMAGE}:${MAJOR_VERSION} -t docker.io/jc21/${IMAGE}:latest" } } } @@ -39,7 +39,7 @@ pipeline { steps { script { // Defaults to the Branch name, which is applies to all branches AND pr's - env.BUILDX_PUSH_TAGS = "-t docker.io/${IMAGE}:github-${BRANCH_LOWER}" + env.BUILDX_PUSH_TAGS = "-t docker.io/jc21/${IMAGE}:github-${BRANCH_LOWER}" } } } @@ -62,13 +62,13 @@ pipeline { stage('Backend') { steps { echo 'Checking Syntax ...' - sh 'docker pull ${IMAGE}:certbot-node' + sh 'docker pull nginxproxymanager/nginx-full:certbot-node' // See: https://github.com/yarnpkg/yarn/issues/3254 sh '''docker run --rm \\ -v "$(pwd)/backend:/app" \\ -v "$(pwd)/global:/app/global" \\ -w /app \\ - ${IMAGE}:certbot-node \\ + nginxproxymanager/nginx-full:certbot-node \\ sh -c "yarn install && yarn eslint . && rm -rf node_modules" ''' @@ -214,7 +214,7 @@ pipeline { } steps { script { - def comment = pullRequest.comment("This is an automated message from CI:\n\nDocker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker${IMAGE}) as `jc21/${IMAGE}:github-${BRANCH_LOWER}`\n\n**Note:** ensure you backup your NPM instance before testing this PR image! Especially if this PR contains database changes.") + def comment = pullRequest.comment("This is an automated message from CI:\n\nDocker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker/jc21/${IMAGE}) as `jc21/${IMAGE}:github-${BRANCH_LOWER}`\n\n**Note:** ensure you backup your NPM instance before testing this PR image! Especially if this PR contains database changes.") } } } diff --git a/aws/cloud-formation/template.yml b/aws/cloud-formation/template.yml new file mode 100644 index 00000000..bda9844c --- /dev/null +++ b/aws/cloud-formation/template.yml @@ -0,0 +1,137 @@ +AWSTemplateFormatVersion: 2010-09-09 +Parameters: + ImageUri: + Type: String + Default: 413067109875.dkr.ecr.us-east-1.amazonaws.com/owenscorning/aws-nginx-full:fargate +Resources: + ECSCluster: + Type: AWS::ECS::Cluster + Task: + Type: 'AWS::ECS::TaskDefinition' + Properties: + NetworkMode: awsvpc + RequiresCompatibilities: + - FARGATE + TaskRoleArn: arn:aws:iam::413067109875:role/ecsTaskExecutionRole + ExecutionRoleArn: arn:aws:iam::413067109875:role/ecsTaskExecutionRole + Family: Prod-Redirect + #https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html#cfn-ecs-taskdefinition-cpu + Cpu: 2048 + Memory: 4096 + ContainerDefinitions: + - Name: Prod-Redirect + PortMappings: + - HostPort: 80 + ContainerPort: 80 + - HostPort: 81 + ContainerPort: 81 + - HostPort: 443 + ContainerPort: 443 + Image: !Ref ImageUri + #Image: docker.io/jc21/nginx-proxy-manager:latest + #Image: docker.io/jc21/nginx-proxy-manager:github-pr-1839 + HealthCheck: + Command: ["CMD", "/bin/check-health"] + Interval: 10 + Essential: true + MountPoints: + - SourceVolume: DataVol + ContainerPath: '/data' + - SourceVolume: CertVol + ContainerPath: '/etc/letsencrypt' + Environment: + - Name: DISABLE_IPV6 + Value: 'true' + - Name: AWS_EMF_AGENT_ENDPOINT + Value: tcp://Prod-Redirect_sidecar-cloudwatch:25888 + Secrets: + - Name: DB_MYSQL_HOST + ValueFrom: 'arn:aws:secretsmanager:us-east-1:413067109875:secret:prod/RedirectManager/Database-JczghG:host::' + - Name: DB_MYSQL_PORT + ValueFrom: 'arn:aws:secretsmanager:us-east-1:413067109875:secret:prod/RedirectManager/Database-JczghG:port::' + - Name: DB_MYSQL_USER + ValueFrom: 'arn:aws:secretsmanager:us-east-1:413067109875:secret:prod/RedirectManager/Database-JczghG:username::' + - Name: DB_MYSQL_PASSWORD + ValueFrom: 'arn:aws:secretsmanager:us-east-1:413067109875:secret:prod/RedirectManager/Database-JczghG:password::' + - Name: DB_MYSQL_NAME + ValueFrom: 'arn:aws:secretsmanager:us-east-1:413067109875:secret:prod/RedirectManager/Database-JczghG:dbInstanceIdentifier::' + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-region: us-east-1 + awslogs-group: !Ref LogGroupService + awslogs-create-group: true + awslogs-stream-prefix: ecs + - Name: Prod-Redirect_sidecar-xray + Image: public.ecr.aws/xray/aws-xray-daemon:latest + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-region: us-east-1 + awslogs-group: !Ref LogGroupService + awslogs-create-group: true + awslogs-stream-prefix: xray + - Name: Prod-Redirect_sidecar-cloudwatch + Image: public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest + MountPoints: + - SourceVolume: DataVol + ContainerPath: '/data' + ReadOnly: true + Secrets: + - Name: CW_CONFIG_CONTENT + ValueFrom: 'AmazonCloudWatch-FargateProdRedirect' + PortMappings: + - Protocol: tcp + ContainerPort: 25888 + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-region: us-east-1 + awslogs-group: !Ref LogGroupService + awslogs-create-group: true + awslogs-stream-prefix: cw + Volumes: + - Name: DataVol + EFSVolumeConfiguration: + FilesystemId: fs-0312e867f3f1f9dce + RootDirectory: '/data' + - Name: CertVol + EFSVolumeConfiguration: + FilesystemId: fs-0312e867f3f1f9dce + RootDirectory: '/etc/letsencrypt' + + Service: + Type: 'AWS::ECS::Service' + Properties: + ServiceName: Prod-Redirect + TaskDefinition: !Ref Task + LoadBalancers: + - TargetGroupArn: arn:aws:elasticloadbalancing:us-east-1:413067109875:targetgroup/Prod-RedirectManager-port80/448b4c46ed8f46fd + ContainerPort: '80' + ContainerName: Prod-Redirect + - TargetGroupArn: arn:aws:elasticloadbalancing:us-east-1:413067109875:targetgroup/Prod-RedirectManager-port81/ba8e3225a30afa4f + ContainerPort: '81' + ContainerName: Prod-Redirect + - TargetGroupArn: arn:aws:elasticloadbalancing:us-east-1:413067109875:targetgroup/Prod-RedirectManager-port443/fe95fd6d89d25ee6 + ContainerPort: '443' + ContainerName: Prod-Redirect + Cluster: !Ref ECSCluster + DesiredCount: 1 + DeploymentConfiguration: + MaximumPercent: 200 + MinimumHealthyPercent: 50 + LaunchType: FARGATE + NetworkConfiguration: + AwsvpcConfiguration: + AssignPublicIp: ENABLED + SecurityGroups: + - sg-0f4d792c1dfcda349 + Subnets: + - subnet-0871ddae4ae155f62 + - subnet-0f6de43a60061e760 + + LogGroupService: + Type: 'AWS::Logs::LogGroup' + Properties: + LogGroupName: /ecs/services + RetentionInDays: 30 diff --git a/backend/templates/proxy_host.conf b/backend/templates/proxy_host.conf index b538a0a0..ffed08b7 100644 --- a/backend/templates/proxy_host.conf +++ b/backend/templates/proxy_host.conf @@ -64,8 +64,7 @@ proxy_http_version 1.1; {% endif %} {% endif %} - #do the proxy! - proxy_pass $forward_scheme://$server:$port$request_uri; + } {% endif %} diff --git a/deploy_build.sh b/deploy_build.sh new file mode 100644 index 00000000..0caa0ae9 --- /dev/null +++ b/deploy_build.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +echo "building frontend" +./scripts/frontend-build +echo "----------------" +echo "building backend" +echo 'Checking Syntax ...' +aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 413067109875.dkr.ecr.us-east-1.amazonaws.com + +IMAGE="owenscorning/aws-nginx-full" +DOCKER_IMAGE="413067109875.dkr.ecr.us-east-1.amazonaws.com/${IMAGE}:certbot-node" +FINISH_IMAGE="413067109875.dkr.ecr.us-east-1.amazonaws.com/${IMAGE}:fargate" +BUILD_VERSION=`cat .version` +MAJOR_VERSION="2" +BRANCH_LOWER="master" + +docker pull ${DOCKER_IMAGE} +docker run --rm \ + -v "$(pwd)/backend:/app" \ + -v "$(pwd)/global:/app/global" \ + -w /app \ + ${IMAGE}:certbot-node \ + sh -c "yarn install && yarn eslint . && rm -rf node_modules" +echo "-----------------" +echo 'Docker Build ...' +docker build --pull --no-cache --squash --compress \ + -t "${IMAGE}:fargate" \ + -f docker/Dockerfile \ + --build-arg TARGETPLATFORM=linux/amd64 \ + --build-arg BUILDPLATFORM=linux/amd64 \ + --build-arg BUILD_VERSION="${BUILD_VERSION}" \ + --build-arg BUILD_DATE="$(date '+%Y-%m-%d %T %Z')" \ + . + +echo "-----------------" +echo "pushing to AWS" + +docker tag ${IMAGE}:fargate ${FINISH_IMAGE} +docker push ${FINISH_IMAGE} diff --git a/deploy_fargate.sh b/deploy_fargate.sh new file mode 100644 index 00000000..0e095e58 --- /dev/null +++ b/deploy_fargate.sh @@ -0,0 +1 @@ +aws cloudformation deploy --stack-name Prod-Redirect --template-file ./aws/cloud-formation/template.yml --profile 413067109875 --capabilities CAPABILITY_NAMED_IAM --parameter-overrides ImageUri=413067109875.dkr.ecr.us-east-1.amazonaws.com/owenscorning/aws-nginx-full:fargate diff --git a/docker/Dockerfile b/docker/Dockerfile index 400e94fb..378fffbf 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -3,7 +3,7 @@ # This file assumes that the frontend has been built using ./scripts/frontend-build -FROM 413067109875.dkr.ecr.us-east-1.amazonaws.com/owenscorning/aws-nginx-full:certbot-node +FROM nginxproxymanager/nginx-full:certbot-node ARG TARGETPLATFORM ARG BUILD_VERSION @@ -20,7 +20,6 @@ ENV SUPPRESS_NO_CONFIG_WARNING=1 \ RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \ && apt-get update \ - && apt-get upgrade -y \ && apt-get install -y --no-install-recommends jq logrotate \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* @@ -57,9 +56,8 @@ ENTRYPOINT [ "/init" ] LABEL org.label-schema.schema-version="1.0" \ org.label-schema.license="MIT" \ - org.label-schema.name="aws-nginx-full" \ + org.label-schema.name="nginx-proxy-manager" \ org.label-schema.description="Docker container for managing Nginx proxy hosts with a simple, powerful interface " \ - org.label-schema.url="https://github.com/owenscorning/docker-aws-nginx-full" \ - org.label-schema.vcs-url="https://github.com/owenscorning/docker-aws-nginx-full.git" \ - org.label-schema.cmd="docker run --rm -ti owenscorning/aws-nginx-full:latest" - + org.label-schema.url="https://github.com/jc21/nginx-proxy-manager" \ + org.label-schema.vcs-url="https://github.com/jc21/nginx-proxy-manager.git" \ + org.label-schema.cmd="docker run --rm -ti jc21/nginx-proxy-manager:latest" diff --git a/docker/dev/Dockerfile b/docker/dev/Dockerfile index 509a2c07..d2e2266a 100644 --- a/docker/dev/Dockerfile +++ b/docker/dev/Dockerfile @@ -1,15 +1,15 @@ -FROM owenscorning/aws-nginx-full:certbot-node +FROM nginxproxymanager/nginx-full:certbot-node +LABEL maintainer="Jamie Curnow " ENV S6_LOGGING=0 \ SUPPRESS_NO_CONFIG_WARNING=1 \ S6_FIX_ATTRS_HIDDEN=1 -RUN yum makecache \ - && yum install -y \ - certbot jq python3-pip logrotate \ - \ - && yum clean all \ - && rm -rf /var/cache/* /var/log/* /tmp/* +RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \ + && apt-get update \ + && apt-get install -y certbot jq python3-pip logrotate \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* # Task RUN cd /usr \ diff --git a/docker/rootfs/etc/nginx/conf.d/include/proxy.conf b/docker/rootfs/etc/nginx/conf.d/include/proxy.conf index 9618208a..e6f9ee16 100644 --- a/docker/rootfs/etc/nginx/conf.d/include/proxy.conf +++ b/docker/rootfs/etc/nginx/conf.d/include/proxy.conf @@ -3,5 +3,5 @@ proxy_set_header X-Forwarded-Scheme $scheme; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Real-IP $remote_addr; - +proxy_pass $forward_scheme://$server:$port$request_uri; diff --git a/local_build.sh b/local_build.sh new file mode 100644 index 00000000..a8e49c94 --- /dev/null +++ b/local_build.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +echo "building frontend" +./scripts/frontend-build +read -n 1 -p "Press any key" +echo "building backend" +echo 'Checking Syntax ...' +aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 413067109875.dkr.ecr.us-east-1.amazonaws.com + +IMAGE="owenscorning/aws-nginx-full" +DOCKER_IMAGE="413067109875.dkr.ecr.us-east-1.amazonaws.com/${IMAGE}:certbot-node" +BUILD_VERSION=`cat .version` +MAJOR_VERSION="2" +BRANCH_LOWER="master" + +docker pull ${DOCKER_IMAGE} +docker run --rm \ + -v "$(pwd)/backend:/app" \ + -v "$(pwd)/global:/app/global" \ + -w /app \ + ${IMAGE}:certbot-node \ + sh -c "yarn install && yarn eslint . && rm -rf node_modules" + +echo 'Docker Build ...' +docker build --pull --no-cache --squash --compress \ + -t "${IMAGE}:production" \ + -f docker/Dockerfile \ + --build-arg TARGETPLATFORM=linux/amd64 \ + --build-arg BUILDPLATFORM=linux/amd64 \ + --build-arg BUILD_VERSION="${BUILD_VERSION}" \ + --build-arg BUILD_DATE="$(date '+%Y-%m-%d %T %Z')" \ + . + +docker run -it -p 80:80 -p 81:81 -v /mnt/c/Projects/nginx-proxy-manager/rootfolder:/data --name data "${IMAGE}:production" \ No newline at end of file From 469ecadbbbbcbe1144c8e45b3283d3f60a1b701f Mon Sep 17 00:00:00 2001 From: Nick Craig Date: Thu, 10 Mar 2022 16:30:49 -0500 Subject: [PATCH 6/8] missing updates. --- Jenkinsfile | 12 ++++++------ docker/Dockerfile | 12 +++++++----- docker/rootfs/etc/nginx/conf.d/include/proxy.conf | 4 +--- docker/rootfs/etc/nginx/nginx.conf | 3 +++ 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 1b744692..51320be5 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -8,7 +8,7 @@ pipeline { ansiColor('xterm') } environment { - IMAGE = "nginx-proxy-manager" + IMAGE = "owenscorning/aws-nginx-full" BUILD_VERSION = getVersion() MAJOR_VERSION = "2" BRANCH_LOWER = "${BRANCH_NAME.toLowerCase().replaceAll('/', '-')}" @@ -26,7 +26,7 @@ pipeline { } steps { script { - env.BUILDX_PUSH_TAGS = "-t docker.io/jc21/${IMAGE}:${BUILD_VERSION} -t docker.io/jc21/${IMAGE}:${MAJOR_VERSION} -t docker.io/jc21/${IMAGE}:latest" + env.BUILDX_PUSH_TAGS = "-t docker.io/${IMAGE}:${BUILD_VERSION} -t docker.io/${IMAGE}:${MAJOR_VERSION} -t docker.io/${IMAGE}:latest" } } } @@ -39,7 +39,7 @@ pipeline { steps { script { // Defaults to the Branch name, which is applies to all branches AND pr's - env.BUILDX_PUSH_TAGS = "-t docker.io/jc21/${IMAGE}:github-${BRANCH_LOWER}" + env.BUILDX_PUSH_TAGS = "-t docker.io/${IMAGE}:github-${BRANCH_LOWER}" } } } @@ -62,13 +62,13 @@ pipeline { stage('Backend') { steps { echo 'Checking Syntax ...' - sh 'docker pull nginxproxymanager/nginx-full:certbot-node' + sh 'docker pull ${IMAGE}:certbot-node' // See: https://github.com/yarnpkg/yarn/issues/3254 sh '''docker run --rm \\ -v "$(pwd)/backend:/app" \\ -v "$(pwd)/global:/app/global" \\ -w /app \\ - nginxproxymanager/nginx-full:certbot-node \\ + ${IMAGE}:certbot-node \\ sh -c "yarn install && yarn eslint . && rm -rf node_modules" ''' @@ -214,7 +214,7 @@ pipeline { } steps { script { - def comment = pullRequest.comment("This is an automated message from CI:\n\nDocker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker/jc21/${IMAGE}) as `jc21/${IMAGE}:github-${BRANCH_LOWER}`\n\n**Note:** ensure you backup your NPM instance before testing this PR image! Especially if this PR contains database changes.") + def comment = pullRequest.comment("This is an automated message from CI:\n\nDocker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker${IMAGE}) as `jc21/${IMAGE}:github-${BRANCH_LOWER}`\n\n**Note:** ensure you backup your NPM instance before testing this PR image! Especially if this PR contains database changes.") } } } diff --git a/docker/Dockerfile b/docker/Dockerfile index 378fffbf..400e94fb 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -3,7 +3,7 @@ # This file assumes that the frontend has been built using ./scripts/frontend-build -FROM nginxproxymanager/nginx-full:certbot-node +FROM 413067109875.dkr.ecr.us-east-1.amazonaws.com/owenscorning/aws-nginx-full:certbot-node ARG TARGETPLATFORM ARG BUILD_VERSION @@ -20,6 +20,7 @@ ENV SUPPRESS_NO_CONFIG_WARNING=1 \ RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \ && apt-get update \ + && apt-get upgrade -y \ && apt-get install -y --no-install-recommends jq logrotate \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* @@ -56,8 +57,9 @@ ENTRYPOINT [ "/init" ] LABEL org.label-schema.schema-version="1.0" \ org.label-schema.license="MIT" \ - org.label-schema.name="nginx-proxy-manager" \ + org.label-schema.name="aws-nginx-full" \ org.label-schema.description="Docker container for managing Nginx proxy hosts with a simple, powerful interface " \ - org.label-schema.url="https://github.com/jc21/nginx-proxy-manager" \ - org.label-schema.vcs-url="https://github.com/jc21/nginx-proxy-manager.git" \ - org.label-schema.cmd="docker run --rm -ti jc21/nginx-proxy-manager:latest" + org.label-schema.url="https://github.com/owenscorning/docker-aws-nginx-full" \ + org.label-schema.vcs-url="https://github.com/owenscorning/docker-aws-nginx-full.git" \ + org.label-schema.cmd="docker run --rm -ti owenscorning/aws-nginx-full:latest" + diff --git a/docker/rootfs/etc/nginx/conf.d/include/proxy.conf b/docker/rootfs/etc/nginx/conf.d/include/proxy.conf index e6f9ee16..8de93bd3 100644 --- a/docker/rootfs/etc/nginx/conf.d/include/proxy.conf +++ b/docker/rootfs/etc/nginx/conf.d/include/proxy.conf @@ -2,6 +2,4 @@ add_header X-Served-By $host; proxy_set_header X-Forwarded-Scheme $scheme; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $remote_addr; -proxy_set_header X-Real-IP $remote_addr; -proxy_pass $forward_scheme://$server:$port$request_uri; - +proxy_set_header X-Real-IP $remote_addr; \ No newline at end of file diff --git a/docker/rootfs/etc/nginx/nginx.conf b/docker/rootfs/etc/nginx/nginx.conf index 4d5ee901..dd565b6f 100644 --- a/docker/rootfs/etc/nginx/nginx.conf +++ b/docker/rootfs/etc/nginx/nginx.conf @@ -45,8 +45,11 @@ http { log_format proxy '[$time_local] $upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] [Sent-to $server] "$http_user_agent" "$http_referer"'; log_format standard '[$time_local] $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] "$http_user_agent" "$http_referer"'; + log_format cloudwatch escape=json '{"time":"$time_iso8601","filename":"$request_filename","remoteIP":"$remote_addr","host":"$host","request":"$request","query":"$query_string","method":"$request_method","status":"$status","userAgent":"$http_user_agent","referer":"$http_referer"}'; + access_log /data/logs/fallback_access.log proxy; + access_log /data/logs/fallback_access.cloudwatch.log cloudwatch; # Dynamically generated resolvers file include /etc/nginx/conf.d/include/resolvers.conf; From b3e228285d93e447b3584ff0f3493f2f07e57252 Mon Sep 17 00:00:00 2001 From: Nick Craig Date: Wed, 3 May 2023 09:00:28 -0400 Subject: [PATCH 7/8] ocmaster-rebuild --- backend/lib/config.js | 184 ++++++++++++++++++ backend/templates/_access.conf | 25 +++ docker/rootfs/bin/common.sh | 42 ++++ .../s6-rc.d/backend/dependencies.d/prepare | 0 .../rootfs/etc/s6-overlay/s6-rc.d/backend/run | 21 ++ .../etc/s6-overlay/s6-rc.d/backend/type | 1 + .../s6-rc.d/frontend/dependencies.d/prepare | 0 .../etc/s6-overlay/s6-rc.d/frontend/run | 21 ++ .../etc/s6-overlay/s6-rc.d/frontend/type | 1 + .../s6-rc.d/nginx/dependencies.d/prepare | 0 .../rootfs/etc/s6-overlay/s6-rc.d/nginx/run | 9 + .../rootfs/etc/s6-overlay/s6-rc.d/nginx/type | 1 + .../etc/s6-overlay/s6-rc.d/prepare/00-all.sh | 18 ++ .../s6-overlay/s6-rc.d/prepare/10-npmuser.sh | 20 ++ .../s6-overlay/s6-rc.d/prepare/20-paths.sh | 41 ++++ .../s6-rc.d/prepare/30-ownership.sh | 24 +++ .../s6-overlay/s6-rc.d/prepare/40-dynamic.sh | 17 ++ .../etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh | 36 ++++ .../s6-overlay/s6-rc.d/prepare/60-secrets.sh | 30 +++ .../s6-overlay/s6-rc.d/prepare/90-banner.sh | 17 ++ .../s6-rc.d/prepare/dependencies.d/base | 0 .../etc/s6-overlay/s6-rc.d/prepare/type | 1 + .../rootfs/etc/s6-overlay/s6-rc.d/prepare/up | 2 + .../s6-rc.d/user/contents.d/backend | 0 .../s6-rc.d/user/contents.d/frontend | 0 .../s6-overlay/s6-rc.d/user/contents.d/nginx | 0 .../s6-rc.d/user/contents.d/prepare | 0 docker/rootfs/etc/services.d/nginx/finish | 1 - docker/scripts/install-s6 | 38 ++++ docs/guide/README.md | 1 - 30 files changed, 549 insertions(+), 2 deletions(-) create mode 100644 backend/lib/config.js create mode 100644 backend/templates/_access.conf create mode 100644 docker/rootfs/bin/common.sh create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/backend/dependencies.d/prepare create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/backend/type create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/frontend/dependencies.d/prepare create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/frontend/run create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/frontend/type create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/dependencies.d/prepare create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/type create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/00-all.sh create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-npmuser.sh create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/20-paths.sh create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/90-banner.sh create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/dependencies.d/base create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/type create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/up create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/backend create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/frontend create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/nginx create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/prepare delete mode 120000 docker/rootfs/etc/services.d/nginx/finish create mode 100644 docker/scripts/install-s6 delete mode 120000 docs/guide/README.md diff --git a/backend/lib/config.js b/backend/lib/config.js new file mode 100644 index 00000000..caa57fcf --- /dev/null +++ b/backend/lib/config.js @@ -0,0 +1,184 @@ +const fs = require('fs'); +const NodeRSA = require('node-rsa'); +const logger = require('../logger').global; + +const keysFile = '/data/keys.json'; + +let instance = null; + +// 1. Load from config file first (not recommended anymore) +// 2. Use config env variables next +const configure = () => { + const filename = (process.env.NODE_CONFIG_DIR || './config') + '/' + (process.env.NODE_ENV || 'default') + '.json'; + if (fs.existsSync(filename)) { + let configData; + try { + configData = require(filename); + } catch (err) { + // do nothing + } + + if (configData && configData.database) { + logger.info(`Using configuration from file: ${filename}`); + instance = configData; + instance.keys = getKeys(); + return; + } + } + + const envMysqlHost = process.env.DB_MYSQL_HOST || null; + const envMysqlUser = process.env.DB_MYSQL_USER || null; + const envMysqlName = process.env.DB_MYSQL_NAME || null; + if (envMysqlHost && envMysqlUser && envMysqlName) { + // we have enough mysql creds to go with mysql + logger.info('Using MySQL configuration'); + instance = { + database: { + engine: 'mysql', + host: envMysqlHost, + port: process.env.DB_MYSQL_PORT || 3306, + user: envMysqlUser, + password: process.env.DB_MYSQL_PASSWORD, + name: envMysqlName, + }, + keys: getKeys(), + }; + return; + } + + const envSqliteFile = process.env.DB_SQLITE_FILE || '/data/database.sqlite'; + logger.info(`Using Sqlite: ${envSqliteFile}`); + instance = { + database: { + engine: 'knex-native', + knex: { + client: 'sqlite3', + connection: { + filename: envSqliteFile + }, + useNullAsDefault: true + } + }, + keys: getKeys(), + }; +}; + +const getKeys = () => { + // Get keys from file + if (!fs.existsSync(keysFile)) { + generateKeys(); + } else if (process.env.DEBUG) { + logger.info('Keys file exists OK'); + } + try { + return require(keysFile); + } catch (err) { + logger.error('Could not read JWT key pair from config file: ' + keysFile, err); + process.exit(1); + } +}; + +const generateKeys = () => { + logger.info('Creating a new JWT key pair...'); + // Now create the keys and save them in the config. + const key = new NodeRSA({ b: 2048 }); + key.generateKeyPair(); + + const keys = { + key: key.exportKey('private').toString(), + pub: key.exportKey('public').toString(), + }; + + // Write keys config + try { + fs.writeFileSync(keysFile, JSON.stringify(keys, null, 2)); + } catch (err) { + logger.error('Could not write JWT key pair to config file: ' + keysFile + ': ' . err.message); + process.exit(1); + } + logger.info('Wrote JWT key pair to config file: ' + keysFile); +}; + +module.exports = { + + /** + * + * @param {string} key ie: 'database' or 'database.engine' + * @returns {boolean} + */ + has: function(key) { + instance === null && configure(); + const keys = key.split('.'); + let level = instance; + let has = true; + keys.forEach((keyItem) =>{ + if (typeof level[keyItem] === 'undefined') { + has = false; + } else { + level = level[keyItem]; + } + }); + + return has; + }, + + /** + * Gets a specific key from the top level + * + * @param {string} key + * @returns {*} + */ + get: function (key) { + instance === null && configure(); + if (key && typeof instance[key] !== 'undefined') { + return instance[key]; + } + return instance; + }, + + /** + * Is this a sqlite configuration? + * + * @returns {boolean} + */ + isSqlite: function () { + instance === null && configure(); + return instance.database.knex && instance.database.knex.client === 'sqlite3'; + }, + + /** + * Are we running in debug mdoe? + * + * @returns {boolean} + */ + debug: function () { + return !!process.env.DEBUG; + }, + + /** + * Returns a public key + * + * @returns {string} + */ + getPublicKey: function () { + instance === null && configure(); + return instance.keys.pub; + }, + + /** + * Returns a private key + * + * @returns {string} + */ + getPrivateKey: function () { + instance === null && configure(); + return instance.keys.key; + }, + + /** + * @returns {boolean} + */ + useLetsencryptStaging: function () { + return !!process.env.LE_STAGING; + } +}; diff --git a/backend/templates/_access.conf b/backend/templates/_access.conf new file mode 100644 index 00000000..447006c0 --- /dev/null +++ b/backend/templates/_access.conf @@ -0,0 +1,25 @@ +{% if access_list_id > 0 %} + {% if access_list.items.length > 0 %} + # Authorization + auth_basic "Authorization required"; + auth_basic_user_file /data/access/{{ access_list_id }}; + + {% if access_list.pass_auth == 0 %} + proxy_set_header Authorization ""; + {% endif %} + + {% endif %} + + # Access Rules: {{ access_list.clients | size }} total + {% for client in access_list.clients %} + {{client | nginxAccessRule}} + {% endfor %} + deny all; + + # Access checks must... + {% if access_list.satisfy_any == 1 %} + satisfy any; + {% else %} + satisfy all; + {% endif %} +{% endif %} diff --git a/docker/rootfs/bin/common.sh b/docker/rootfs/bin/common.sh new file mode 100644 index 00000000..0bc6468d --- /dev/null +++ b/docker/rootfs/bin/common.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +set -e + +CYAN='\E[1;36m' +BLUE='\E[1;34m' +YELLOW='\E[1;33m' +RED='\E[1;31m' +RESET='\E[0m' +export CYAN BLUE YELLOW RED RESET + +PUID=${PUID:-0} +PGID=${PGID:-0} + +if [[ "$PUID" -ne '0' ]] && [ "$PGID" = '0' ]; then + # set group id to same as user id, + # the user probably forgot to specify the group id and + # it would be rediculous to intentionally use the root group + # for a non-root user + PGID=$PUID +fi + +export PUID PGID + +log_info () { + echo -e "${BLUE}❯ ${CYAN}$1${RESET}" +} + +log_error () { + echo -e "${RED}❯ $1${RESET}" +} + +# The `run` file will only execute 1 line so this helps keep things +# logically separated + +log_fatal () { + echo -e "${RED}--------------------------------------${RESET}" + echo -e "${RED}ERROR: $1${RESET}" + echo -e "${RED}--------------------------------------${RESET}" + /run/s6/basedir/bin/halt + exit 1 +} diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/dependencies.d/prepare b/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/dependencies.d/prepare new file mode 100644 index 00000000..e69de29b diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run new file mode 100644 index 00000000..e8ffa17c --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run @@ -0,0 +1,21 @@ +#!/command/with-contenv bash +# shellcheck shell=bash + +set -e + +. /bin/common.sh + +cd /app || exit 1 + +log_info 'Starting backend ...' + +if [ "${DEVELOPMENT:-}" = 'true' ]; then + s6-setuidgid npmuser yarn install + exec s6-setuidgid npmuser bash -c 'export HOME=/tmp/npmuserhome;node --max_old_space_size=250 --abort_on_uncaught_exception node_modules/nodemon/bin/nodemon.js' +else + while : + do + s6-setuidgid npmuser bash -c 'export HOME=/tmp/npmuserhome;node --abort_on_uncaught_exception --max_old_space_size=250 index.js' + sleep 1 + done +fi diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/type b/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/type new file mode 100644 index 00000000..5883cff0 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/type @@ -0,0 +1 @@ +longrun diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/frontend/dependencies.d/prepare b/docker/rootfs/etc/s6-overlay/s6-rc.d/frontend/dependencies.d/prepare new file mode 100644 index 00000000..e69de29b diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/frontend/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/frontend/run new file mode 100644 index 00000000..1181c53e --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/frontend/run @@ -0,0 +1,21 @@ +#!/command/with-contenv bash +# shellcheck shell=bash + +set -e + +# This service is DEVELOPMENT only. + +if [ "$DEVELOPMENT" = 'true' ]; then + . /bin/common.sh + cd /app/frontend || exit 1 + HOME=/tmp/npmuserhome + export HOME + mkdir -p /app/frontend/dist + chown -R "$PUID:$PGID" /app/frontend/dist + + log_info 'Starting frontend ...' + s6-setuidgid npmuser yarn install + exec s6-setuidgid npmuser yarn watch +else + exit 0 +fi diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/frontend/type b/docker/rootfs/etc/s6-overlay/s6-rc.d/frontend/type new file mode 100644 index 00000000..5883cff0 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/frontend/type @@ -0,0 +1 @@ +longrun diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/dependencies.d/prepare b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/dependencies.d/prepare new file mode 100644 index 00000000..e69de29b diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run new file mode 100644 index 00000000..fa8c1fc5 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run @@ -0,0 +1,9 @@ +#!/command/with-contenv bash +# shellcheck shell=bash + +set -e + +. /bin/common.sh + +log_info 'Starting nginx ...' +exec s6-setuidgid npmuser nginx diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/type b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/type new file mode 100644 index 00000000..5883cff0 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/type @@ -0,0 +1 @@ +longrun diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/00-all.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/00-all.sh new file mode 100644 index 00000000..1d5899e4 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/00-all.sh @@ -0,0 +1,18 @@ +#!/command/with-contenv bash +# shellcheck shell=bash + +set -e + +. /bin/common.sh + +if [ "$(id -u)" != "0" ]; then + log_fatal "This docker container must be run as root, do not specify a user.\nYou can specify PUID and PGID env vars to run processes as that user and group after initialization." +fi + +. /etc/s6-overlay/s6-rc.d/prepare/10-npmuser.sh +. /etc/s6-overlay/s6-rc.d/prepare/20-paths.sh +. /etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh +. /etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh +. /etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh +. /etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh +. /etc/s6-overlay/s6-rc.d/prepare/90-banner.sh diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-npmuser.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-npmuser.sh new file mode 100644 index 00000000..c5cf5435 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-npmuser.sh @@ -0,0 +1,20 @@ +#!/command/with-contenv bash +# shellcheck shell=bash + +set -e + +log_info 'Configuring npmuser ...' + +if id -u npmuser; then + # user already exists + usermod -u "$PUID" npmuser || exit 1 +else + # Add npmuser user + useradd -o -u "$PUID" -U -d /tmp/npmuserhome -s /bin/false npmuser || exit 1 +fi + +usermod -G "$PGID" npmuser || exit 1 +groupmod -o -g "$PGID" npmuser || exit 1 +# Home for npmuser +mkdir -p /tmp/npmuserhome +chown -R "$PUID:$PGID" /tmp/npmuserhome diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/20-paths.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/20-paths.sh new file mode 100644 index 00000000..2f59ef41 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/20-paths.sh @@ -0,0 +1,41 @@ +#!/command/with-contenv bash +# shellcheck shell=bash + +set -e + +log_info 'Checking paths ...' + +# Ensure /data is mounted +if [ ! -d '/data' ]; then + log_fatal '/data is not mounted! Check your docker configuration.' +fi +# Ensure /etc/letsencrypt is mounted +if [ ! -d '/etc/letsencrypt' ]; then + log_fatal '/etc/letsencrypt is not mounted! Check your docker configuration.' +fi + +# Create required folders +mkdir -p \ + /data/nginx \ + /data/custom_ssl \ + /data/logs \ + /data/access \ + /data/nginx/default_host \ + /data/nginx/default_www \ + /data/nginx/proxy_host \ + /data/nginx/redirection_host \ + /data/nginx/stream \ + /data/nginx/dead_host \ + /data/nginx/temp \ + /data/letsencrypt-acme-challenge \ + /run/nginx \ + /tmp/nginx/body \ + /var/log/nginx \ + /var/lib/nginx/cache/public \ + /var/lib/nginx/cache/private \ + /var/cache/nginx/proxy_temp + +touch /var/log/nginx/error.log || true +chmod 777 /var/log/nginx/error.log || true +chmod -R 777 /var/cache/nginx || true +chmod 644 /etc/logrotate.d/nginx-proxy-manager diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh new file mode 100644 index 00000000..684166e1 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh @@ -0,0 +1,24 @@ +#!/command/with-contenv bash +# shellcheck shell=bash + +set -e + +log_info 'Setting ownership ...' + +# root +chown root /tmp/nginx + +# npmuser +chown -R "$PUID:$PGID" /data \ + /etc/letsencrypt \ + /run/nginx \ + /tmp/nginx \ + /var/cache/nginx \ + /var/lib/logrotate \ + /var/lib/nginx \ + /var/log/nginx + +# Don't chown entire /etc/nginx folder as this causes crashes on some systems +chown -R "$PUID:$PGID" /etc/nginx/nginx \ + /etc/nginx/nginx.conf \ + /etc/nginx/conf.d diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh new file mode 100644 index 00000000..0cb9f126 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh @@ -0,0 +1,17 @@ +#!/command/with-contenv bash +# shellcheck shell=bash + +set -e + +log_info 'Dynamic resolvers ...' + +DISABLE_IPV6=$(echo "${DISABLE_IPV6:-}" | tr '[:upper:]' '[:lower:]') + +# Dynamically generate resolvers file, if resolver is IPv6, enclose in `[]` +# thanks @tfmm +if [ "$DISABLE_IPV6" == "true" ] || [ "$DISABLE_IPV6" == "on" ] || [ "$DISABLE_IPV6" == "1" ] || [ "$DISABLE_IPV6" == "yes" ]; +then + echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" { sub(/%.*$/,"",$2); print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf) ipv6=off valid=10s;" > /etc/nginx/conf.d/include/resolvers.conf +else + echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" { sub(/%.*$/,"",$2); print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf) valid=10s;" > /etc/nginx/conf.d/include/resolvers.conf +fi diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh new file mode 100644 index 00000000..bc27eb14 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# This command reads the `DISABLE_IPV6` env var and will either enable +# or disable ipv6 in all nginx configs based on this setting. + +log_info 'IPv6 ...' + +# Lowercase +DISABLE_IPV6=$(echo "${DISABLE_IPV6:-}" | tr '[:upper:]' '[:lower:]') + +process_folder () { + FILES=$(find "$1" -type f -name "*.conf") + SED_REGEX= + + if [ "$DISABLE_IPV6" == "true" ] || [ "$DISABLE_IPV6" == "on" ] || [ "$DISABLE_IPV6" == "1" ] || [ "$DISABLE_IPV6" == "yes" ]; then + # IPV6 is disabled + echo "Disabling IPV6 in hosts in: $1" + SED_REGEX='s/^([^#]*)listen \[::\]/\1#listen [::]/g' + else + # IPV6 is enabled + echo "Enabling IPV6 in hosts in: $1" + SED_REGEX='s/^(\s*)#listen \[::\]/\1listen [::]/g' + fi + + for FILE in $FILES + do + echo "- ${FILE}" + sed -E -i "$SED_REGEX" "$FILE" + done + + # ensure the files are still owned by the npmuser + chown -R "$PUID:$PGID" "$1" +} + +process_folder /etc/nginx/conf.d +process_folder /data/nginx diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh new file mode 100644 index 00000000..faa22acc --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh @@ -0,0 +1,30 @@ +#!/command/with-contenv bash +# shellcheck shell=bash + +set -e + +# in s6, environmental variables are written as text files for s6 to monitor +# search through full-path filenames for files ending in "__FILE" +log_info 'Docker secrets ...' + +for FILENAME in $(find /var/run/s6/container_environment/ | grep "__FILE$"); do + echo "[secret-init] Evaluating ${FILENAME##*/} ..." + + # set SECRETFILE to the contents of the full-path textfile + SECRETFILE=$(cat "${FILENAME}") + # if SECRETFILE exists / is not null + if [[ -f "${SECRETFILE}" ]]; then + # strip the appended "__FILE" from environmental variable name ... + STRIPFILE=$(echo "${FILENAME}" | sed "s/__FILE//g") + # echo "[secret-init] Set STRIPFILE to ${STRIPFILE}" # DEBUG - rm for prod! + + # ... and set value to contents of secretfile + # since s6 uses text files, this is effectively "export ..." + printf $(cat "${SECRETFILE}") > "${STRIPFILE}" + # echo "[secret-init] Set ${STRIPFILE##*/} to $(cat ${STRIPFILE})" # DEBUG - rm for prod!" + echo "Success: ${STRIPFILE##*/} set from ${FILENAME##*/}" + + else + echo "Cannot find secret in ${FILENAME}" + fi +done diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/90-banner.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/90-banner.sh new file mode 100644 index 00000000..7991ddf4 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/90-banner.sh @@ -0,0 +1,17 @@ +#!/command/with-contenv bash +# shellcheck shell=bash + +set -e + +echo " +------------------------------------- + _ _ ____ __ __ +| \ | | _ \| \/ | +| \| | |_) | |\/| | +| |\ | __/| | | | +|_| \_|_| |_| |_| +------------------------------------- +User ID: $PUID +Group ID: $PGID +------------------------------------- +" diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/dependencies.d/base b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/dependencies.d/base new file mode 100644 index 00000000..e69de29b diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/type b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/type new file mode 100644 index 00000000..bdd22a18 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/type @@ -0,0 +1 @@ +oneshot diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/up b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/up new file mode 100644 index 00000000..896a01b6 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/up @@ -0,0 +1,2 @@ +# shellcheck shell=bash +/etc/s6-overlay/s6-rc.d/prepare/00-all.sh diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/backend b/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/backend new file mode 100644 index 00000000..e69de29b diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/frontend b/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/frontend new file mode 100644 index 00000000..e69de29b diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/nginx b/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/nginx new file mode 100644 index 00000000..e69de29b diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/prepare b/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/prepare new file mode 100644 index 00000000..e69de29b diff --git a/docker/rootfs/etc/services.d/nginx/finish b/docker/rootfs/etc/services.d/nginx/finish deleted file mode 120000 index 63b10de4..00000000 --- a/docker/rootfs/etc/services.d/nginx/finish +++ /dev/null @@ -1 +0,0 @@ -/bin/true \ No newline at end of file diff --git a/docker/scripts/install-s6 b/docker/scripts/install-s6 new file mode 100644 index 00000000..5a5a9c9c --- /dev/null +++ b/docker/scripts/install-s6 @@ -0,0 +1,38 @@ +#!/bin/bash -e + +# Note: This script is designed to be run inside a Docker Build for a container + +CYAN='\E[1;36m' +YELLOW='\E[1;33m' +BLUE='\E[1;34m' +GREEN='\E[1;32m' +RESET='\E[0m' + +S6_OVERLAY_VERSION=3.1.4.1 +TARGETPLATFORM=${1:unspecified} + +# Determine the correct binary file for the architecture given +case $TARGETPLATFORM in + linux/arm64) + S6_ARCH=aarch64 + ;; + + linux/arm/v7) + S6_ARCH=armhf + ;; + + *) + S6_ARCH=x86_64 + ;; +esac + +echo -e "${BLUE}❯ ${CYAN}Installing S6-overlay v${S6_OVERLAY_VERSION} for ${YELLOW}${TARGETPLATFORM} (${S6_ARCH})${RESET}" + +curl -L -o '/tmp/s6-overlay-noarch.tar.xz' "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz" +curl -L -o "/tmp/s6-overlay-${S6_ARCH}.tar.xz" "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-${S6_ARCH}.tar.xz" +tar -C / -Jxpf '/tmp/s6-overlay-noarch.tar.xz' +tar -C / -Jxpf "/tmp/s6-overlay-${S6_ARCH}.tar.xz" + +rm -rf "/tmp/s6-overlay-${S6_ARCH}.tar.xz" + +echo -e "${BLUE}❯ ${GREEN}S6-overlay install Complete${RESET}" diff --git a/docs/guide/README.md b/docs/guide/README.md deleted file mode 120000 index fe840054..00000000 --- a/docs/guide/README.md +++ /dev/null @@ -1 +0,0 @@ -../../README.md \ No newline at end of file From ad8c8826b3a9c5a06eb291d09c767ead0ea0238e Mon Sep 17 00:00:00 2001 From: Nick Craig Date: Wed, 3 May 2023 11:14:52 -0400 Subject: [PATCH 8/8] fix jenkinsfile merge conflict and update to shebang --- Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 5bc005d3..830bbdbb 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -34,7 +34,7 @@ pipeline { } steps { script { - env.BUILDX_PUSH_TAGS = "-t docker.io/${IMAGE}:${BUILD_VERSION} -t docker.io/${IMAGE}:${MAJOR_VERSION} -t docker.io/${IMAGE}:latest" + buildxPushTags = "-t docker.io/${IMAGE}:${BUILD_VERSION} -t docker.io/${IMAGE}:${MAJOR_VERSION} -t docker.io/${IMAGE}:latest" } } } @@ -47,7 +47,7 @@ pipeline { steps { script { // Defaults to the Branch name, which is applies to all branches AND pr's - env.BUILDX_PUSH_TAGS = "-t docker.io/${IMAGE}:github-${BRANCH_LOWER}" + buildxPushTags = "-t docker.io/${IMAGE}:github-${BRANCH_LOWER}" } } }