diff --git a/docker/Dockerfile b/docker/Dockerfile index f243208c..34ee5c44 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -13,6 +13,7 @@ ARG BUILD_DATE ENV SUPPRESS_NO_CONFIG_WARNING=1 ENV S6_FIX_ATTRS_HIDDEN=1 +ENV S6_BEHAVIOUR_IF_STAGE2_FAILS=1 ENV NODE_ENV=production RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \ @@ -31,7 +32,6 @@ EXPOSE 80 EXPOSE 81 EXPOSE 443 -COPY docker/rootfs / ADD backend /app ADD frontend/dist /app/frontend COPY global /app/global @@ -39,10 +39,13 @@ COPY global /app/global WORKDIR /app RUN yarn install +# add late to limit cache-busting by modifications +COPY docker/rootfs / + # Remove frontend service not required for prod, dev nginx config as well RUN rm -rf /etc/services.d/frontend RUN rm -f /etc/nginx/conf.d/dev.conf VOLUME [ "/data", "/etc/letsencrypt" ] -CMD [ "/init" ] +ENTRYPOINT [ "/init" ] HEALTHCHECK --interval=5s --timeout=3s CMD /bin/check-health diff --git a/docker/dev/Dockerfile b/docker/dev/Dockerfile index 45ee534c..1e4bdad8 100644 --- a/docker/dev/Dockerfile +++ b/docker/dev/Dockerfile @@ -27,6 +27,6 @@ EXPOSE 80 EXPOSE 81 EXPOSE 443 -CMD [ "/init" ] +ENTRYPOINT [ "/init" ] -HEALTHCHECK --interval=5s --timeout=3s CMD /bin/check-health +HEALTHCHECK --interval=5s --timeout=3s CMD /bin/check-health \ No newline at end of file diff --git a/docker/rootfs/etc/cont-init.d/.gitignore b/docker/rootfs/etc/cont-init.d/.gitignore index d6b7ef32..f04f0f6e 100644 --- a/docker/rootfs/etc/cont-init.d/.gitignore +++ b/docker/rootfs/etc/cont-init.d/.gitignore @@ -1,2 +1,3 @@ * !.gitignore +!*.sh diff --git a/docker/rootfs/etc/cont-init.d/01_s6-secret-init.sh b/docker/rootfs/etc/cont-init.d/01_s6-secret-init.sh new file mode 100644 index 00000000..f145807a --- /dev/null +++ b/docker/rootfs/etc/cont-init.d/01_s6-secret-init.sh @@ -0,0 +1,29 @@ +#!/usr/bin/with-contenv bash +# ref: https://github.com/linuxserver/docker-baseimage-alpine/blob/master/root/etc/cont-init.d/01-envfile + +# in s6, environmental variables are written as text files for s6 to monitor +# seach through full-path filenames for files ending in "__FILE" +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}) + # SECRETFILE=${FILENAME} + # echo "[secret-init] Set SECRETFILE to ${SECRETFILE}" # DEBUG - rm for prod! + + # 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 "[secret-init] Success! ${STRIPFILE##*/} set from ${FILENAME##*/}" + + else + echo "[secret-init] cannot find secret in ${FILENAME}" + fi +done diff --git a/docs/advanced-config/README.md b/docs/advanced-config/README.md index 7c622d59..962c3422 100644 --- a/docs/advanced-config/README.md +++ b/docs/advanced-config/README.md @@ -1,5 +1,66 @@ # Advanced Configuration +## Docker Secrets + +This image supports the use of Docker secrets to import from file and keep sensitive usernames or passwords from being passed or preserved in plaintext. + +You can set any environment variable from a file by appending `__FILE` (double-underscore FILE) to the environmental variable name. + +```yml +version: "3.7" + +secrets: + # Secrets are single-line text files where the sole content is the secret + # Paths in this example assume that secrets are kept in local folder called ".secrets" + DB_ROOT_PWD: + file: .secrets/db_root_pwd.txt + MYSQL_PWD: + file: .secrets/mysql_pwd.txt + +services: + app: + image: 'jc21/nginx-proxy-manager:latest' + restart: always + ports: + # Public HTTP Port: + - '80:80' + # Public HTTPS Port: + - '443:443' + # Admin Web Port: + - '81:81' + environment: + # These are the settings to access your db + DB_MYSQL_HOST: "db" + DB_MYSQL_PORT: 3306 + DB_MYSQL_USER: "npm" + # DB_MYSQL_PASSWORD: "npm" # use secret instead + DB_MYSQL_PASSWORD__FILE: /run/secrets/MYSQL_PWD + DB_MYSQL_NAME: "npm" + # If you would rather use Sqlite uncomment this + # and remove all DB_MYSQL_* lines above + # DB_SQLITE_FILE: "/data/database.sqlite" + # Uncomment this if IPv6 is not enabled on your host + # DISABLE_IPV6: 'true' + volumes: + - ./data:/data + - ./letsencrypt:/etc/letsencrypt + depends_on: + - db + db: + image: jc21/mariadb-aria + restart: always + environment: + # MYSQL_ROOT_PASSWORD: "npm" # use secret instead + MYSQL_ROOT_PASSWORD__FILE: /run/secrets/DB_ROOT_PWD + MYSQL_DATABASE: "npm" + MYSQL_USER: "npm" + # MYSQL_PASSWORD: "npm" # use secret instead + MYSQL_PASSWORD__FILE: /run/secrets/MYSQL_PWD + volumes: + - ./data/mysql:/var/lib/mysql +``` + + ## Disabling IPv6 On some docker hosts IPv6 may not be enabled. In these cases, the following message may be seen in the log: