Compare commits
41 Commits
v2.0.0
...
f7a6d924d9
| Author | SHA1 | Date | |
|---|---|---|---|
| f7a6d924d9 | |||
| 16f302c3fd | |||
| a6107f7e25 | |||
| 03e0631964 | |||
| 4d5f3fa809 | |||
| fb81443cba | |||
| 92c0217374 | |||
| 750ad05d06 | |||
| 0db9675bc4 | |||
| dd7ef19d88 | |||
| 810cbd44b7 | |||
| 2b583ad7e0 | |||
| 4a1c1e5153 | |||
| 2b55ae11f4 | |||
| 49fa74159b | |||
| 3548d88b63 | |||
| a1e2911dc0 | |||
| a2b08d5a72 | |||
| 85ff24faaf | |||
| 2e2c93b2b1 | |||
| e208d22664 | |||
| bc2a34ddd8 | |||
| a3c6656764 | |||
| b2582b9bad | |||
| 1ee8b8bf03 | |||
| 8c5bbe8d9c | |||
| 60f79fdd45 | |||
| f1faf3fedf | |||
| 4ded854631 | |||
| 8890e662b0 | |||
| a4cebd5216 | |||
| f6efb86f2a | |||
| e499b7982c | |||
| 1c608859e7 | |||
| 7ea21e2cc4 | |||
| d045d098d9 | |||
| 287830ffe7 | |||
| 75b2eb1662 | |||
| c263bf1f40 | |||
| dc336de922 | |||
| 2940251df1 |
+36
-21
@@ -10,17 +10,17 @@
|
|||||||
|
|
||||||
# Documents
|
# Documents
|
||||||
*.bibtex text diff=bibtex
|
*.bibtex text diff=bibtex
|
||||||
*.doc diff=astextplain
|
*.doc diff=astextplain
|
||||||
*.DOC diff=astextplain
|
*.DOC diff=astextplain
|
||||||
*.docx diff=astextplain
|
*.docx diff=astextplain
|
||||||
*.DOCX diff=astextplain
|
*.DOCX diff=astextplain
|
||||||
*.dot diff=astextplain
|
*.dot diff=astextplain
|
||||||
*.DOT diff=astextplain
|
*.DOT diff=astextplain
|
||||||
*.pdf diff=astextplain
|
*.pdf diff=astextplain
|
||||||
*.PDF diff=astextplain
|
*.PDF diff=astextplain
|
||||||
*.rtf diff=astextplain
|
*.rtf diff=astextplain
|
||||||
*.RTF diff=astextplain
|
*.RTF diff=astextplain
|
||||||
*.md text eol=lf
|
*.md text diff=markdown
|
||||||
*.tex text diff=tex
|
*.tex text diff=tex
|
||||||
*.adoc text
|
*.adoc text
|
||||||
*.textile text
|
*.textile text
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
*.tsv text
|
*.tsv text
|
||||||
*.txt text
|
*.txt text
|
||||||
*.sql text
|
*.sql text
|
||||||
|
*.ps1 text eol=crlf
|
||||||
|
|
||||||
# Graphics
|
# Graphics
|
||||||
*.png binary
|
*.png binary
|
||||||
@@ -53,7 +54,22 @@
|
|||||||
# These are explicitly windows files and should use crlf
|
# These are explicitly windows files and should use crlf
|
||||||
*.bat text eol=crlf
|
*.bat text eol=crlf
|
||||||
*.cmd text eol=crlf
|
*.cmd text eol=crlf
|
||||||
*.ps1 text eol=crlf
|
|
||||||
|
# web frontend stack -- force LF so SRI hashes are always correct
|
||||||
|
*.html text eol=lf
|
||||||
|
*.htm text eol=lf
|
||||||
|
*.css text eol=lf
|
||||||
|
*.min.css text eol=lf
|
||||||
|
*.js text eol=lf
|
||||||
|
*.min.js text eol=lf
|
||||||
|
|
||||||
|
# Visual Studio projects (Rider also)
|
||||||
|
*.cs diff=csharp
|
||||||
|
*.sln merge=union
|
||||||
|
*.csproj merge=union
|
||||||
|
*.vbproj merge=union
|
||||||
|
*.fsproj merge=union
|
||||||
|
*.dbproj merge=union
|
||||||
|
|
||||||
# Serialisation
|
# Serialisation
|
||||||
*.json text
|
*.json text
|
||||||
@@ -66,19 +82,18 @@
|
|||||||
*.7z binary
|
*.7z binary
|
||||||
*.gz binary
|
*.gz binary
|
||||||
*.tar binary
|
*.tar binary
|
||||||
|
*.tgz binary
|
||||||
*.zip binary
|
*.zip binary
|
||||||
|
|
||||||
# nginx files
|
# Text files where line endings should be preserved
|
||||||
*.conf text eol=lf
|
*.patch -text
|
||||||
|
|
||||||
#
|
#
|
||||||
# Exclude files from exporting
|
# Exclude files from exporting
|
||||||
# only export helper scripts
|
|
||||||
#
|
#
|
||||||
|
|
||||||
.gitattributes export-ignore
|
.gitattributes export-ignore
|
||||||
.gitignore export-ignore
|
.gitignore export-ignore
|
||||||
.vscode export-ignore
|
.gitkeep export-ignore
|
||||||
.idea export-ignore
|
.idea export-ignore
|
||||||
build export-ignore
|
.vscode export-ignore
|
||||||
README.md export-ignore
|
|
||||||
|
|||||||
+72
-7
@@ -1,10 +1,75 @@
|
|||||||
.vscode/*
|
### JetBrains template
|
||||||
!.vscode/settings.json
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||||
!.vscode/tasks.json
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
!.vscode/launch.json
|
|
||||||
!.vscode/extensions.json
|
# User-specific stuff
|
||||||
!.vscode/numbered-bookmarks.json
|
.idea/**/workspace.xml
|
||||||
*.code-workspace
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/usage.statistics.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Gradle and Maven with auto-import
|
||||||
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
|
# auto-import.
|
||||||
|
# .idea/artifacts
|
||||||
|
# .idea/compiler.xml
|
||||||
|
# .idea/jarRepositories.xml
|
||||||
|
# .idea/modules.xml
|
||||||
|
# .idea/*.iml
|
||||||
|
# .idea/modules
|
||||||
|
# *.iml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-*/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
# Editor-based Rest Client
|
||||||
|
.idea/httpRequests
|
||||||
|
|
||||||
|
# Android studio 3.1+ serialized cache file
|
||||||
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
# don't track my testing params file
|
# don't track my testing params file
|
||||||
ab-nginx.params
|
ab-nginx.params
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ContentModelUserStore">
|
<component name="UserContentModel">
|
||||||
<attachedFolders />
|
<attachedFolders />
|
||||||
<explicitIncludes />
|
<explicitIncludes />
|
||||||
<explicitExcludes />
|
<explicitExcludes />
|
||||||
|
|||||||
-7
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="RIDER_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<content url="file://$MODULE_DIR$/../.." />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
Generated
+9
-2
@@ -2,11 +2,18 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="CommitMessageInspectionProfile">
|
<component name="CommitMessageInspectionProfile">
|
||||||
<profile version="1.0">
|
<profile version="1.0">
|
||||||
<inspection_tool class="BodyLimit" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="BodyLimit" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="SubjectBodySeparation" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="SubjectBodySeparation" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||||
<inspection_tool class="SubjectLimit" enabled="true" level="ERROR" enabled_by_default="true" />
|
<inspection_tool class="SubjectLimit" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
</profile>
|
</profile>
|
||||||
</component>
|
</component>
|
||||||
|
<component name="GitSharedSettings">
|
||||||
|
<option name="FORCE_PUSH_PROHIBITED_PATTERNS">
|
||||||
|
<list>
|
||||||
|
<option value="master main" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# ab-nginx
|
# ab-nginx
|
||||||
|
|
||||||
Containerized fully-functional implementation of NGINX running on Alpine **as a fully NON-ROOT user**. The container by default is a 'blank slate' that just serves files out of the box. Changing configuration, server blocks and content is accomplished with bind-mounts using a sensible, simple directory structure. The container auto-detects mounted certificates and switches to TLS automatically. [Helper scripts](https://git.asifbacchus.app/ab-docker/ab-nginx/releases) in the git repo make certificate mounting easier, allow for custom docker networks and more. The container by default can be used as a Let’s Encrypt endpoint with tools like certbot.
|
Containerized fully-functional implementation of NGINX running on Alpine **as a fully NON-ROOT user**. The container by default is a 'blank slate' that just serves files out of the box. Changing configuration, server blocks and content is accomplished with bind-mounts using a sensible, simple directory structure. The container auto-detects mounted certificates and switches to TLS automatically. [Helper scripts](https://git.asifbacchus.dev/ab-docker/ab-nginx/releases) in the git repo make certificate mounting easier, allow for custom docker networks and more. The container by default can be used as a Let’s Encrypt endpoint with tools like certbot.
|
||||||
|
|
||||||
## Contents
|
## Contents
|
||||||
|
|
||||||
@@ -24,27 +24,27 @@ Containerized fully-functional implementation of NGINX running on Alpine **as a
|
|||||||
|
|
||||||
## Alternate repository
|
## Alternate repository
|
||||||
|
|
||||||
Throughout this document, I reference my repository on DockerHub (`asifbacchus/ab-nginx:tag`). You may also feel free to pull directly from my private registry instead, especially if you need signed containers. Simply use `docker.asifbacchus.app/nginx/ab-nginx:tag`. I usually sign major dot-version releases (1.18, 1.19, etc.) as well as the 'latest' image.
|
Throughout this document, I reference my repository on DockerHub (`asifbacchus/ab-nginx:tag`). You may also feel free to pull directly from my private registry instead, especially if you need signed containers. Simply use `docker.asifbacchus.dev/nginx/ab-nginx:tag`. I usually sign major dot-version releases (1.18, 1.19, etc.) as well as the 'latest' image.
|
||||||
|
|
||||||
## Documentation and scripts
|
## Documentation and scripts
|
||||||
|
|
||||||
Check out the [repo wiki](https://git.asifbacchus.app/ab-docker/ab-nginx/wiki) for detailed examples and documentation about the container and the [helper scripts](https://git.asifbacchus.app/ab-docker/ab-nginx/releases) which are located [here](https://git.asifbacchus.app/ab-docker/ab-nginx/releases).
|
Check out the [repo wiki](https://git.asifbacchus.dev/ab-docker/ab-nginx/wiki) for detailed examples and documentation about the container and the [helper scripts](https://git.asifbacchus.dev/ab-docker/ab-nginx/releases) which are located [here](https://git.asifbacchus.dev/ab-docker/ab-nginx/releases).
|
||||||
|
|
||||||
## Permissions
|
## Permissions
|
||||||
|
|
||||||
The container does **NOT** run under the root account. It runs under a user named *www-docker* with a UID of 8080. **This means any files you mount into the container need to be readable (and/or writable depending on your use-case) by UID 8080**. This does not mean just content files, it also includes configurations, server-blocks and *certificates*! Before mounting your files, ensure this is the case. There are more detailed instructions in the [wiki](https://git.asifbacchus.app/ab-docker/ab-nginx/wiki) if you need help setting file permissions.
|
The container does **NOT** run under the root account. It runs under a user named *www-docker* with a UID of 8080. **This means any files you mount into the container need to be readable (and/or writable depending on your use-case) by UID 8080**. This does not mean just content files, it also includes configurations, server-blocks and *certificates*! Before mounting your files, ensure this is the case. There are more detailed instructions in the [wiki](https://git.asifbacchus.dev/ab-docker/ab-nginx/wiki) if you need help setting file permissions.
|
||||||
|
|
||||||
This is a significant change versus most other NGINX implementations/containers where the main process is run as root
|
This is a significant change versus most other NGINX implementations/containers where the main process is run as root
|
||||||
and the *worker processes* run as a limited user. In those cases, permissions don’t matter since NGINX can always use
|
and the *worker processes* run as a limited user. In those cases, permissions don’t matter since NGINX can always use
|
||||||
the root account to read any files (and especially certificates!) it needs. Please understand this difference.
|
the root account to read any files (and especially certificates!) it needs. Please understand this difference.
|
||||||
|
|
||||||
If you need to change the UID, then you’ll need to rebuild the container using
|
If you need to change the UID, then you’ll need to rebuild the container using
|
||||||
the [Dockerfile in the git repo](https://git.asifbacchus.app/ab-docker/ab-nginx). The process would be something like
|
the [Dockerfile in the git repo](https://git.asifbacchus.dev/ab-docker/ab-nginx). The process would be something like
|
||||||
this:
|
this:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# clone the repo
|
# clone the repo
|
||||||
git clone https://git.asifbacchus.app/ab-docker/ab-nginx
|
git clone https://git.asifbacchus.dev/ab-docker/ab-nginx
|
||||||
|
|
||||||
# change to the proper directory and build the container
|
# change to the proper directory and build the container
|
||||||
cd ab-nginx/build
|
cd ab-nginx/build
|
||||||
@@ -82,7 +82,7 @@ All configuration is in the `/etc/nginx` directory and its children. Here is the
|
|||||||
├── ssl_certs.conf – (hard-coded for the container, best not to touch)
|
├── ssl_certs.conf – (hard-coded for the container, best not to touch)
|
||||||
```
|
```
|
||||||
|
|
||||||
Locations with \**starred descriptions** are designed to be overwritten via bind-mounts to customize the container. For more details on all of these files and what they do, please refer to the [repo wiki](https://git.asifbacchus.app/ab-docker/ab-nginx/wiki). **Remember that UID 8080 needs to be able to read any files you choose to bind-mount over the container defaults!**
|
Locations with \**starred descriptions** are designed to be overwritten via bind-mounts to customize the container. For more details on all of these files and what they do, please refer to the [repo wiki](https://git.asifbacchus.dev/ab-docker/ab-nginx/wiki). **Remember that UID 8080 needs to be able to read any files you choose to bind-mount over the container defaults!**
|
||||||
|
|
||||||
## Quick-start
|
## Quick-start
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ docker restart ab-nginx
|
|||||||
|
|
||||||
If you want the container to ignore a specific set of configuration options, say you’re testing something, then rename the file with those configuration options using any extension other than *.conf*. I usually use *.conf.disabled*. Restart the container and that file will be ignored.
|
If you want the container to ignore a specific set of configuration options, say you’re testing something, then rename the file with those configuration options using any extension other than *.conf*. I usually use *.conf.disabled*. Restart the container and that file will be ignored.
|
||||||
|
|
||||||
More details and examples are found in the [wiki](https://git.asifbacchus.app/ab-docker/ab-nginx/wiki).
|
More details and examples are found in the [wiki](https://git.asifbacchus.dev/ab-docker/ab-nginx/wiki).
|
||||||
|
|
||||||
### Mounting server-blocks
|
### Mounting server-blocks
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ docker run -d --name ab-nginx --restart unless-stopped \
|
|||||||
asifbacchus/ab-nginx
|
asifbacchus/ab-nginx
|
||||||
```
|
```
|
||||||
|
|
||||||
More details and examples are found in the [wiki](https://git.asifbacchus.app/ab-docker/ab-nginx/wiki).
|
More details and examples are found in the [wiki](https://git.asifbacchus.dev/ab-docker/ab-nginx/wiki).
|
||||||
|
|
||||||
## TLS
|
## TLS
|
||||||
|
|
||||||
@@ -186,9 +186,9 @@ The container will load a secure configuration automatically, require SSL connec
|
|||||||
|
|
||||||
You may have noticed I also specified the `SERVER_NAMES` variable. This is necessary or SSL will not work since the hostname the server responds to must match the certificate being presented. **Make sure you set this environment variable to match your certificates!** N.B. If you are using your own server-blocks, then this environment variable is **NOT** required – it is only used by the container when auto-configuring the default server-blocks.
|
You may have noticed I also specified the `SERVER_NAMES` variable. This is necessary or SSL will not work since the hostname the server responds to must match the certificate being presented. **Make sure you set this environment variable to match your certificates!** N.B. If you are using your own server-blocks, then this environment variable is **NOT** required – it is only used by the container when auto-configuring the default server-blocks.
|
||||||
|
|
||||||
If you want to integrate with Let's Encrypt, please refer to the [wiki](https://git.asifbacchus.app/ab-docker/ab-nginx/wiki).
|
If you want to integrate with Let's Encrypt, please refer to the [wiki](https://git.asifbacchus.dev/ab-docker/ab-nginx/wiki).
|
||||||
|
|
||||||
Finally, I’d remind you once again that UID 8080 must be able to read your certificate files! It is common practice to restrict the private key to root readability only (i.e. chown root:root & chmod 600/400) but, that would stop the NGINX user in the container from reading it and NGINX will exit with an error. I address ways to allow your certificate files to remain secure but still readable by the NGINX user in the [wiki](https://git.asifbacchus.app/ab-docker/ab-nginx/wiki).
|
Finally, I’d remind you once again that UID 8080 must be able to read your certificate files! It is common practice to restrict the private key to root readability only (i.e. chown root:root & chmod 600/400) but, that would stop the NGINX user in the container from reading it and NGINX will exit with an error. I address ways to allow your certificate files to remain secure but still readable by the NGINX user in the [wiki](https://git.asifbacchus.dev/ab-docker/ab-nginx/wiki).
|
||||||
|
|
||||||
## Environment variables
|
## Environment variables
|
||||||
|
|
||||||
@@ -248,8 +248,8 @@ docker logs -n 10 -f ab-nginx
|
|||||||
|
|
||||||
## Final thoughts
|
## Final thoughts
|
||||||
|
|
||||||
I think that's everything to get you going if you are already familiar with docker and with NGINX in general. If you need more help, please [refer to the wiki](https://git.asifbacchus.app/ab-docker/ab-nginx/wiki). I've explained everything there in detail. Also, check out the [helper scripts](https://git.asifbacchus.app/ab-docker/ab-nginx/releases) especially if you are deploying certificates. The scripts take care of all the docker command-lines for you so you have much less typing!
|
I think that's everything to get you going if you are already familiar with docker and with NGINX in general. If you need more help, please [refer to the wiki](https://git.asifbacchus.dev/ab-docker/ab-nginx/wiki). I've explained everything there in detail. Also, check out the [helper scripts](https://git.asifbacchus.dev/ab-docker/ab-nginx/releases) especially if you are deploying certificates. The scripts take care of all the docker command-lines for you so you have much less typing!
|
||||||
|
|
||||||
If I've forgotten anything, you find any bugs or you have suggestions, please file an issue either on my private [git server ](https://git.asifbachus.app/ab-docker/ab-nginx) or on [github](https://github.com/asifbacchus/ab-nginx). Also, I am *not* affiliated with NGINX in any way, so please **do not** bother them with any issues you find with this container. Bother me instead, I actually enjoy it!
|
If I've forgotten anything, you find any bugs or you have suggestions, please file an issue either on my private [git server ](https://git.asifbacchus.dev/ab-docker/ab-nginx) or on [github](https://github.com/asifbacchus/ab-nginx). Also, I am *not* affiliated with NGINX in any way, so please **do not** bother them with any issues you find with this container. Bother me instead, I actually enjoy it!
|
||||||
|
|
||||||
**All the best and have fun!**
|
**All the best and have fun!**
|
||||||
|
|||||||
+38
-17
@@ -1,10 +1,17 @@
|
|||||||
FROM nginx:mainline-alpine
|
#
|
||||||
|
# build AB-NGINX container (based on NGINX mainline)
|
||||||
|
#
|
||||||
|
|
||||||
# default uid for nginx user
|
ARG NGINX_VERSION=1.21.1
|
||||||
|
FROM nginx:${NGINX_VERSION}-alpine
|
||||||
|
ARG NGINX_VERSION
|
||||||
|
|
||||||
|
# default uid and gid for nginx user
|
||||||
ARG UID=8080
|
ARG UID=8080
|
||||||
|
ARG GID=8080
|
||||||
|
|
||||||
# create nginx user
|
# create nginx user
|
||||||
RUN addgroup --gid ${UID} www-docker \
|
RUN addgroup --gid ${GID} www-docker \
|
||||||
&& adduser \
|
&& adduser \
|
||||||
-S \
|
-S \
|
||||||
-h /home/www-docker \
|
-h /home/www-docker \
|
||||||
@@ -15,11 +22,13 @@ RUN addgroup --gid ${UID} www-docker \
|
|||||||
www-docker
|
www-docker
|
||||||
|
|
||||||
# add libcap, allow nginx to bind to ports <1024, extract fun error pages & create LetsEncrypt challenge directory outside webroot
|
# add libcap, allow nginx to bind to ports <1024, extract fun error pages & create LetsEncrypt challenge directory outside webroot
|
||||||
RUN apk --no-cache add libcap \
|
RUN apk --update --no-cache add \
|
||||||
|
libcap \
|
||||||
|
openssl \
|
||||||
&& setcap 'cap_net_bind_service=+ep' /usr/sbin/nginx \
|
&& setcap 'cap_net_bind_service=+ep' /usr/sbin/nginx \
|
||||||
&& cd /usr/share/nginx \
|
&& cd /usr/share/nginx \
|
||||||
&& rm -rf html/* \
|
&& rm -rf html/* \
|
||||||
&& wget -O /tmp/errorpages.tar.gz https://git.asifbacchus.app/asif/fun-errorpages/archive/v1.0.tar.gz \
|
&& wget -O /tmp/errorpages.tar.gz https://git.asifbacchus.dev/asif/fun-errorpages/archive/v1.0.tar.gz \
|
||||||
&& tar -xzf /tmp/errorpages.tar.gz -C /tmp \
|
&& tar -xzf /tmp/errorpages.tar.gz -C /tmp \
|
||||||
&& mv /tmp/fun-errorpages/errorpages ./ \
|
&& mv /tmp/fun-errorpages/errorpages ./ \
|
||||||
&& rm -rf /tmp/* \
|
&& rm -rf /tmp/* \
|
||||||
@@ -28,22 +37,29 @@ RUN apk --no-cache add libcap \
|
|||||||
&& mkdir /usr/share/nginx/letsencrypt
|
&& mkdir /usr/share/nginx/letsencrypt
|
||||||
|
|
||||||
# health check
|
# health check
|
||||||
HEALTHCHECK --interval=60s --timeout=5s --start-period=30s --retries=3 \
|
HEALTHCHECK \
|
||||||
|
--interval=10s \
|
||||||
|
--timeout=5s \
|
||||||
|
--start-period=60s \
|
||||||
|
--retries=3 \
|
||||||
CMD curl --fail http://127.0.0.1:9000/nginx_status || exit 1
|
CMD curl --fail http://127.0.0.1:9000/nginx_status || exit 1
|
||||||
|
|
||||||
# standardized labels
|
# standardized labels
|
||||||
LABEL author="Asif Bacchus <asif@bacchus.cloud>"
|
MAINTAINER Asif Bacchus <asif@bacchus.cloud>
|
||||||
LABEL maintainer="Asif Bacchus <asif@bacchus.cloud>"
|
LABEL maintainer="Asif Bacchus <asif@bacchus.cloud>"
|
||||||
|
LABEL dev.asifbacchus.docker.internalName="ab-nginx"
|
||||||
LABEL org.opencontainers.image.author="Asif Bacchus <asif@bacchus.cloud>"
|
LABEL org.opencontainers.image.author="Asif Bacchus <asif@bacchus.cloud>"
|
||||||
LABEL org.opencontainers.image.url="https://git.asifbacchus.app/ab-docker/ab-nginx"
|
LABEL org.opencontainers.image.url="https://git.asifbacchus.dev/ab-docker/ab-nginx"
|
||||||
LABEL org.opencontainers.image.documentation="https://git.asifbacchus.app/ab-docker/ab-nginx/wiki"
|
LABEL org.opencontainers.image.documentation="https://git.asifbacchus.dev/ab-docker/ab-nginx/wiki"
|
||||||
LABEL org.opencontainers.image.source="https://git.asifbacchus.app/ab-docker/ab-nginx.git"
|
LABEL org.opencontainers.image.source="https://git.asifbacchus.dev/ab-docker/ab-nginx.git"
|
||||||
LABEL org.opencontainers.image.vendor="NGINX"
|
LABEL org.opencontainers.image.vendor="NGINX"
|
||||||
LABEL org.opencontainers.image.title="ab-nginx"
|
LABEL org.opencontainers.image.title="ab-nginx"
|
||||||
LABEL org.opencontainers.image.description="NGINX-mainline-alpine with more logical file location layout and automatic SSL set up if certificates are provided."
|
LABEL org.opencontainers.image.description="NGINX-mainline-alpine with more logical file location layout and automatic SSL set up if certificates are provided."
|
||||||
|
|
||||||
# copy configuration files
|
# copy configuration files and utility scripts
|
||||||
COPY entrypoint.sh /entrypoint.sh
|
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||||
|
COPY generate-cert.sh /usr/local/bin/generate-cert
|
||||||
|
COPY selfsigned.cnf /etc/selfsigned.cnf
|
||||||
COPY config /etc/nginx/
|
COPY config /etc/nginx/
|
||||||
COPY sites /etc/nginx/sites/
|
COPY sites /etc/nginx/sites/
|
||||||
COPY webroot /usr/share/nginx/html/
|
COPY webroot /usr/share/nginx/html/
|
||||||
@@ -59,7 +75,9 @@ RUN chown -R www-docker:www-docker /usr/share/nginx \
|
|||||||
&& find /etc/nginx -type d -exec chmod 750 {} \; \
|
&& find /etc/nginx -type d -exec chmod 750 {} \; \
|
||||||
&& find /etc/nginx -type f -exec chmod 640 {} \; \
|
&& find /etc/nginx -type f -exec chmod 640 {} \; \
|
||||||
&& chown www-docker:www-docker /var/cache/nginx \
|
&& chown www-docker:www-docker /var/cache/nginx \
|
||||||
&& chown www-docker:www-docker /var/log/nginx
|
&& chown www-docker:www-docker /var/log/nginx \
|
||||||
|
&& chmod 644 /etc/selfsigned.cnf \
|
||||||
|
&& chmod 755 /usr/local/bin/generate-cert /usr/local/bin/entrypoint.sh
|
||||||
USER www-docker
|
USER www-docker
|
||||||
WORKDIR /usr/share/nginx/html
|
WORKDIR /usr/share/nginx/html
|
||||||
|
|
||||||
@@ -73,7 +91,7 @@ ENV HSTS=FALSE
|
|||||||
ENV TLS13_ONLY=FALSE
|
ENV TLS13_ONLY=FALSE
|
||||||
|
|
||||||
# entrypoint script
|
# entrypoint script
|
||||||
ENTRYPOINT [ "/entrypoint.sh" ]
|
ENTRYPOINT [ "/usr/local/bin/entrypoint.sh" ]
|
||||||
|
|
||||||
# run NGINX by default
|
# run NGINX by default
|
||||||
STOPSIGNAL SIGQUIT
|
STOPSIGNAL SIGQUIT
|
||||||
@@ -81,8 +99,11 @@ CMD [ "nginx", "-g", "daemon off;" ]
|
|||||||
|
|
||||||
# add build date and version labels
|
# add build date and version labels
|
||||||
ARG BUILD_DATE
|
ARG BUILD_DATE
|
||||||
LABEL org.opencontainers.image.version="1.19.6"
|
ARG GIT_COMMIT
|
||||||
LABEL app.asifbacchus.docker.internalVersion="4.0"
|
ARG INTERNAL_VERSION
|
||||||
|
LABEL org.opencontainers.image.revision=${GIT_COMMIT}
|
||||||
|
LABEL org.opencontainers.image.version=${NGINX_VERSION}
|
||||||
|
LABEL dev.asifbacchus.docker.internalVersion=${INTERNAL_VERSION}-${NGINX_VERSION}
|
||||||
LABEL org.opencontainers.image.created=${BUILD_DATE}
|
LABEL org.opencontainers.image.created=${BUILD_DATE}
|
||||||
|
|
||||||
#EOF
|
#EOF
|
||||||
|
|||||||
+21
-2
@@ -54,8 +54,20 @@ fi
|
|||||||
if [ -f "/certs/fullchain.pem" ]; then
|
if [ -f "/certs/fullchain.pem" ]; then
|
||||||
# activate SSL configuration as appropriate and only if certs exist
|
# activate SSL configuration as appropriate and only if certs exist
|
||||||
if [ "$TLS13_ONLY" = 'FALSE' ]; then
|
if [ "$TLS13_ONLY" = 'FALSE' ]; then
|
||||||
if [ -f "/certs/fullchain.pem" ] && [ -f "/certs/privkey.pem" ] && [ -f "/certs/chain.pem" ] && [ -f "/certs/dhparam.pem" ]; then
|
if [ -f "/certs/fullchain.pem" ] && [ -f "/certs/privkey.pem" ] && [ -f "/certs/chain.pem" ]; then
|
||||||
printf "Certificates found. Securing deployment using TLS 1.2\n"
|
printf "Certificates found. Securing deployment using TLS 1.2\n"
|
||||||
|
|
||||||
|
# check for dhparam file and generate, if necessary
|
||||||
|
if ! [ -f "/certs/dhparam.pem" ]; then
|
||||||
|
printf "Diffie-Hellman Parameters not found... generating (using Digital Signature Algorithm instead of Diffie-Hellman)...\n"
|
||||||
|
if ! openssl dhparam -dsaparam -out /certs/dhparam.pem 4096; then
|
||||||
|
printf "\n\nUnable to generate 'dhparam.pem'. Is your '/certs' directory writable by this container?\n"
|
||||||
|
printf "TLS version 1.2 requires DHParams (or DSAParams) in order to function securely. Exiting.\n\n"
|
||||||
|
exit 101
|
||||||
|
fi
|
||||||
|
printf "\nDSA-Params generated successfully\n"
|
||||||
|
fi
|
||||||
|
|
||||||
# activate shared SSL configuration file
|
# activate shared SSL configuration file
|
||||||
if [ -f "/etc/nginx/ssl-config/mozIntermediate_ssl.conf.disabled" ]; then
|
if [ -f "/etc/nginx/ssl-config/mozIntermediate_ssl.conf.disabled" ]; then
|
||||||
mv /etc/nginx/ssl-config/mozIntermediate_ssl.conf.disabled \
|
mv /etc/nginx/ssl-config/mozIntermediate_ssl.conf.disabled \
|
||||||
@@ -123,4 +135,11 @@ fi
|
|||||||
printf "\nSetup complete...Container ready...\n"
|
printf "\nSetup complete...Container ready...\n"
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|
||||||
#EOF
|
|
||||||
|
# exit return codes
|
||||||
|
# 10x certificate generation errors
|
||||||
|
# 101 unable to generate DSA-parameters
|
||||||
|
# 102 unable to generate private key
|
||||||
|
# 103 unable to generate self-signed certificate
|
||||||
|
|
||||||
|
#EOF
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# generate a self-signed certificate
|
||||||
|
#
|
||||||
|
|
||||||
|
# check for null hostname
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
printf "\nPlease supply a hostname for the generated certificate as a parameter to this script. Exiting.\n\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# update openssl configuration file
|
||||||
|
sed -e "s/{CERT_HOSTNAME}/$1/" /etc/selfsigned.cnf > /tmp/selfsigned.cnf
|
||||||
|
|
||||||
|
printf "\nGenerating self-signed certificate for '%s':\n" "$1"
|
||||||
|
|
||||||
|
# create placeholder files to set permissions
|
||||||
|
if ! touch /certs/fullchain.pem && chmod 644 /certs/fullchain.pem; then
|
||||||
|
printf "\nUnable to write to '/certs', is it mounted writable by this container?\n\n"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
touch /certs/privkey.pem && chmod 640 /certs/privkey.pem
|
||||||
|
|
||||||
|
# generate certificate
|
||||||
|
if ! openssl req -new -x509 -days 365 -nodes -out /certs/fullchain.pem -keyout /certs/privkey.pem -config /tmp/selfsigned.cnf; then
|
||||||
|
printf "\nUnable to generate certificate. Is the '/certs' directory writable by this container?\n\n"
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
\cp /certs/fullchain.pem /certs/chain.pem
|
||||||
|
|
||||||
|
# print user notification
|
||||||
|
printf "\n\nA self-signed certificate has been generated and saved in the location mounted to '/certs' in this container.\n"
|
||||||
|
printf "The certificate and private key are PEM formatted with names 'fullchain.pem' and 'privkey.pem', respectively.\n"
|
||||||
|
printf "Remember to import 'fullchain.pem' to the trusted store on any client machines or you will get warnings.\n\n"
|
||||||
|
|
||||||
|
# exit gracefully
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# exit codes
|
||||||
|
# 0: normal exit, no errors
|
||||||
|
# 1: invalid or missing parameters
|
||||||
|
# 2: unable to write to certs directory
|
||||||
|
# 3: unable to generate certificate
|
||||||
|
|
||||||
|
#EOF
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
default_bits = 4096
|
||||||
|
default_md = sha256
|
||||||
|
distinguished_name = dn
|
||||||
|
req_extensions = san
|
||||||
|
x509_extensions = san
|
||||||
|
prompt = no
|
||||||
|
|
||||||
|
[dn]
|
||||||
|
organizationName = AB-NGINX Webserver
|
||||||
|
CN = {CERT_HOSTNAME}
|
||||||
|
|
||||||
|
[san]
|
||||||
|
subjectAltName = @alt_names
|
||||||
|
|
||||||
|
[alt_names]
|
||||||
|
DNS.1 = {CERT_HOSTNAME}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# generate checksums from provided path suitable for use by 'update.sh'
|
||||||
|
#
|
||||||
|
|
||||||
|
# check for missing path to helper files, otherwise strip trailing slash
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
printf "\nPlease supply path to helper files. Exiting.\n\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
srcDir="${1%/}"
|
||||||
|
|
||||||
|
# verify path exists and is accessible
|
||||||
|
if ! [ -d "$srcDir" ]; then
|
||||||
|
printf "\nUnable to find or read supplied path to helper files. Exiting.\n\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# generate checksum file
|
||||||
|
\rm -f "${srcDir}/checksums.sha256"
|
||||||
|
find "${srcDir}/" -type f -exec sha256sum {} + >>"${srcDir}/checksums.sha256"
|
||||||
|
sed -i "s+$srcDir/++g" "${srcDir}/checksums.sha256"
|
||||||
|
|
||||||
|
# exit gracefully
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
#EOF
|
||||||
@@ -6,6 +6,23 @@
|
|||||||
###
|
###
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Container options
|
||||||
|
#
|
||||||
|
|
||||||
|
# Specify a particular tag to 'version pin' the ab-nginx container.
|
||||||
|
TAG=latest
|
||||||
|
|
||||||
|
# Specify a runtime UID and GID for the container user. This is useful to
|
||||||
|
# ensure the container can read and/or write to locations on the host or
|
||||||
|
# has access to files shared between members of a container stack.
|
||||||
|
# REQUIRED: NO
|
||||||
|
# DEFAULT: NGINX_UID=8080, NGINX_GID=8080
|
||||||
|
# VALID OPTIONS: any permissible and available UID/GID value
|
||||||
|
NGINX_UID=8080
|
||||||
|
NGINX_GID=8080
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Network options
|
# Network options
|
||||||
#
|
#
|
||||||
@@ -16,7 +33,7 @@
|
|||||||
# REQUIRED: NO
|
# REQUIRED: NO
|
||||||
# DEFAULT: nginx_network
|
# DEFAULT: nginx_network
|
||||||
# VALID OPTIONS: network names acceptable to the docker engine
|
# VALID OPTIONS: network names acceptable to the docker engine
|
||||||
#NETWORK=nginx_network
|
NETWORK=nginx_network
|
||||||
|
|
||||||
# If you want to specify a particular IP subnet for the network to be created
|
# If you want to specify a particular IP subnet for the network to be created
|
||||||
# as per the above variable, specify it here. Again, if you don't know what
|
# as per the above variable, specify it here. Again, if you don't know what
|
||||||
@@ -24,7 +41,7 @@
|
|||||||
# REQUIRED: NO
|
# REQUIRED: NO
|
||||||
# DEFAULT: '172.31.254.0/24'
|
# DEFAULT: '172.31.254.0/24'
|
||||||
# VALID OPTIONS: subnet in CIDR format
|
# VALID OPTIONS: subnet in CIDR format
|
||||||
#SUBNET='172.31.254.0/24'
|
SUBNET='172.31.254.0/24'
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -38,7 +55,7 @@
|
|||||||
# REQUIRED: NO
|
# REQUIRED: NO
|
||||||
# DEFAULT: Etc/UTC
|
# DEFAULT: Etc/UTC
|
||||||
# VALID OPTIONS: IANA time zones in TZ format
|
# VALID OPTIONS: IANA time zones in TZ format
|
||||||
#TZ=Etc/UTC
|
TZ=Etc/UTC
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -55,7 +72,8 @@
|
|||||||
#
|
#
|
||||||
# REQUIRED: YES, if using SSL and default server-blocks
|
# REQUIRED: YES, if using SSL and default server-blocks
|
||||||
# DEFAULT: "_"
|
# DEFAULT: "_"
|
||||||
#HOSTNAMES="domain.tld www.domain.tld server.domain.tld alt.domain.tld"
|
# EXAMPLE: HOSTNAMES="domain.tld www.domain.tld server.domain.tld alt.domain.tld"
|
||||||
|
HOSTNAMES="_"
|
||||||
|
|
||||||
# Ports to listen on:
|
# Ports to listen on:
|
||||||
# If you need to use ports other than HTTP=80 and HTTPS=443, remember to set up
|
# If you need to use ports other than HTTP=80 and HTTPS=443, remember to set up
|
||||||
@@ -65,8 +83,8 @@
|
|||||||
# you use here.
|
# you use here.
|
||||||
# REQUIRED: NO
|
# REQUIRED: NO
|
||||||
# DEFAULTS: 80 and 443, respectively
|
# DEFAULTS: 80 and 443, respectively
|
||||||
#HTTP_PORT=80
|
HTTP_PORT=80
|
||||||
#HTTPS_PORT=443
|
HTTPS_PORT=443
|
||||||
|
|
||||||
# Access logging (global preference):
|
# Access logging (global preference):
|
||||||
# Unless overridden in a server/location block, access logging will be handled
|
# Unless overridden in a server/location block, access logging will be handled
|
||||||
@@ -74,7 +92,7 @@
|
|||||||
# REQUIRED: NO
|
# REQUIRED: NO
|
||||||
# DEFAULT: OFF
|
# DEFAULT: OFF
|
||||||
# VALID OPTIONS: 'ON' or 'OFF'
|
# VALID OPTIONS: 'ON' or 'OFF'
|
||||||
#ACCESS_LOG=OFF
|
ACCESS_LOG=OFF
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -89,7 +107,7 @@
|
|||||||
# Only files with a ".conf" extension will be loaded! If you want to disable a
|
# Only files with a ".conf" extension will be loaded! If you want to disable a
|
||||||
# file, simply change its extension (i.e. '.conf.disabled').
|
# file, simply change its extension (i.e. '.conf.disabled').
|
||||||
#
|
#
|
||||||
# REMEMBER: Your configuration files must be readable by UID 8080!
|
# REMEMBER: Your configuration files must be readable by the container UID/GID!
|
||||||
CONFIG_DIR=$(pwd)/config
|
CONFIG_DIR=$(pwd)/config
|
||||||
|
|
||||||
# Specify a directory containing your NGINX server-block configurations (if any)
|
# Specify a directory containing your NGINX server-block configurations (if any)
|
||||||
@@ -103,7 +121,7 @@ CONFIG_DIR=$(pwd)/config
|
|||||||
# Only files with a ".conf" extension will be loaded! If you want to disable a
|
# Only files with a ".conf" extension will be loaded! If you want to disable a
|
||||||
# file, simply change its extension (i.e. '.conf.disabled').
|
# file, simply change its extension (i.e. '.conf.disabled').
|
||||||
#
|
#
|
||||||
# REMEMBER: Your server-block files must be readable by UID 8080!
|
# REMEMBER: Your server-block files must be readable by the container UID/GID!
|
||||||
SERVERS_DIR=$(pwd)/sites
|
SERVERS_DIR=$(pwd)/sites
|
||||||
|
|
||||||
# Specify a directory containing 'snippets' of NGINX code you want/need to
|
# Specify a directory containing 'snippets' of NGINX code you want/need to
|
||||||
@@ -114,11 +132,11 @@ SERVERS_DIR=$(pwd)/sites
|
|||||||
# instead of having to type the same thing many times.
|
# instead of having to type the same thing many times.
|
||||||
|
|
||||||
# This is totally optional! Comment this variable to disable it.
|
# This is totally optional! Comment this variable to disable it.
|
||||||
# REMEMBER: Your snippets must be readable by UID 8080!
|
# REMEMBER: Your snippets must be readable by the container UID/GID!
|
||||||
SNIPPETS_DIR=$(pwd)/snippets
|
SNIPPETS_DIR=$(pwd)/snippets
|
||||||
|
|
||||||
# Specify a directory with the content you want to serve.
|
# Specify a directory with the content you want to serve.
|
||||||
# REMEMBER: This directory must be readable by UID 8080!
|
# REMEMBER: This directory must be readable by the container UID/GID!
|
||||||
WEBROOT_DIR=/var/www
|
WEBROOT_DIR=/var/www
|
||||||
|
|
||||||
|
|
||||||
@@ -131,26 +149,27 @@ WEBROOT_DIR=/var/www
|
|||||||
# REQUIRED: NO
|
# REQUIRED: NO
|
||||||
# DEFAULT: FALSE
|
# DEFAULT: FALSE
|
||||||
# VALID OPTIONS: 'TRUE', 'FALSE'
|
# VALID OPTIONS: 'TRUE', 'FALSE'
|
||||||
#HSTS=FALSE
|
HSTS=FALSE
|
||||||
|
|
||||||
# TLS 1.3 mode:
|
# TLS 1.3 mode:
|
||||||
# If 'FALSE' (default), NGINX will accept both TLS 1.2 and 1.3 connections.
|
# If 'FALSE' (default), NGINX will accept both TLS 1.2 and 1.3 connections.
|
||||||
# If 'TRUE', only TLS 1.3 connections will be accepted.
|
# If 'TRUE', only TLS 1.3 connections will be accepted.
|
||||||
#TLS13_ONLY=FALSE
|
TLS13_ONLY=FALSE
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Certificate files
|
# Certificate files
|
||||||
#
|
#
|
||||||
# If you are mounting symlinks you MUST specify the full path of the symlink so
|
# If you are mounting symlinks you MUST specify the full path of the symlink so
|
||||||
# the target is resolved! DH (Diffie-Hellman Parameters file) is only required
|
# the target is resolved!
|
||||||
# if using TLS 1.2.
|
|
||||||
#
|
#
|
||||||
# REMEMBER: ALL files must be readble by UID 8080!
|
# REMEMBER: ALL files must be readable by container UID/GID!
|
||||||
#SSL_CERT=/path/to/your/ssl-certificate/fullchain.pem
|
# EXAMPLES:
|
||||||
#SSL_KEY=/path/to/your/ssl-private-key/privkey.pem
|
# SSL_CERT=/path/to/your/ssl-certificate/fullchain.pem
|
||||||
#SSL_CHAIN=/path/to/your/ssl-certificate-chain/chain.pem
|
# SSL_KEY=/path/to/your/ssl-private-key/privkey.pem
|
||||||
#DH=/path/to/your/diffie-hellman-parameters-file/dhparam.pem
|
# SSL_CHAIN=/path/to/your/ssl-certificate-chain/chain.pem
|
||||||
|
SSL_CERT=""
|
||||||
|
SSL_KEY=""
|
||||||
|
SSL_CHAIN=""
|
||||||
|
|
||||||
|
#EOF
|
||||||
#EOF
|
|
||||||
|
|||||||
+288
-212
@@ -4,120 +4,239 @@
|
|||||||
# start ab-nginx container using params file variables
|
# start ab-nginx container using params file variables
|
||||||
#
|
#
|
||||||
|
|
||||||
|
#
|
||||||
# text formatting presets
|
# text formatting presets
|
||||||
if command -v tput >/dev/null; then
|
if command -v tput >/dev/null; then
|
||||||
cyan=$(tput bold)$(tput setaf 6)
|
cyan=$(tput bold)$(tput setaf 6)
|
||||||
err=$(tput bold)$(tput setaf 1)
|
err=$(tput bold)$(tput setaf 1)
|
||||||
magenta=$(tput sgr0)$(tput setaf 5)
|
magenta=$(tput sgr0)$(tput setaf 5)
|
||||||
norm=$(tput sgr0)
|
norm=$(tput sgr0)
|
||||||
yellow=$(tput sgr0)$(tput setaf 3)
|
yellow=$(tput sgr0)$(tput setaf 3)
|
||||||
width=$(tput cols)
|
width=$(tput cols)
|
||||||
else
|
else
|
||||||
cyan=''
|
cyan=''
|
||||||
err=''
|
err=''
|
||||||
magenta=''
|
magenta=''
|
||||||
norm=''
|
norm=''
|
||||||
yellow=''
|
yellow=''
|
||||||
width=80
|
width=80
|
||||||
fi
|
fi
|
||||||
|
|
||||||
### parameter defaults
|
#
|
||||||
shell=false
|
# parameter defaults
|
||||||
|
doShell=false
|
||||||
|
doStatus=false
|
||||||
|
doStop=false
|
||||||
|
removeStopped=false
|
||||||
container_name="ab-nginx"
|
container_name="ab-nginx"
|
||||||
NETWORK='nginx_network'
|
NETWORK='nginx_network'
|
||||||
SUBNET='172.31.254.0/24'
|
SUBNET='172.31.254.0/24'
|
||||||
HTTP_PORT=80
|
HTTP_PORT=80
|
||||||
HTTPS_PORT=443
|
HTTPS_PORT=443
|
||||||
unset CONFIG_DIR
|
CONFIG_DIR=""
|
||||||
unset SERVERS_DIR
|
SERVERS_DIR=""
|
||||||
unset WEBROOT_DIR
|
WEBROOT_DIR=""
|
||||||
unset vmount
|
volumeMounts=""
|
||||||
|
stopErr=0
|
||||||
### functions
|
removeErr=0
|
||||||
|
|
||||||
|
#
|
||||||
|
# functions
|
||||||
checkExist() {
|
checkExist() {
|
||||||
if [ "$1" = 'file' ]; then
|
if [ "$1" = 'file' ]; then
|
||||||
if [ ! -f "$2" ]; then
|
if [ ! -f "$2" ]; then
|
||||||
printf "%s\nCannot find file: '$2'. Exiting.\n%s" "$err" "$norm"
|
printf "%s\nCannot find file: '$2'. Exiting.\n%s" "$err" "$norm"
|
||||||
exit 3
|
exit 1
|
||||||
|
fi
|
||||||
|
elif [ "$1" = 'dir' ]; then
|
||||||
|
if [ ! -d "$2" ]; then
|
||||||
|
printf "%s\nCannot find directory: '$2'. Exiting.\n$%s" "$err" "$norm"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
elif [ "$1" = 'dir' ]; then
|
return 0
|
||||||
if [ ! -d "$2" ]; then
|
|
||||||
printf "%s\nCannot find directory: '$2'. Exiting.\n$%s" "$err" "$norm"
|
|
||||||
exit 3
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scriptHelp() {
|
scriptHelp() {
|
||||||
printf "\n%s%1000s\n" "$magenta" | tr " " "-" | cut -c -$width
|
# header and description
|
||||||
printf "%s" "$norm"
|
printf "\n%s" "$magenta"
|
||||||
textblock "This is a simple helper script so you can avoid typing lengthy commands when working with the ab-nginx container."
|
printf '%.0s-' $(seq "$width")
|
||||||
textblock "The script reads the contents of 'ab-nginx.params' and constructs various 'docker run' commands based on that file. The biggest time-saver is working with certificates. If they are specified in the params file, the script will automatically bind-mount them so nginx serves content via SSL by default."
|
printf "\n%s" "$norm"
|
||||||
newline
|
textBlock "This is a simple helper script so you can avoid typing lengthy commands when working with the ab-nginx container."
|
||||||
textblock "If you run the script with no parameters, it will execute the container 'normally': Run in detached mode with nginx automatically launched. If you specified certificates, nginx will serve over SSL by default."
|
textBlock "The script reads the contents of 'ab-nginx.params' and constructs various 'docker run' commands based on that file. The biggest time-saver is working with certificates. If they are specified in the params file, the script will automatically bind-mount them so nginx serves content via SSL by default."
|
||||||
textblock "Note: Containers (except shell) are always set to restart 'unless-stopped'. You must remove them manually if desired."
|
newline
|
||||||
printf "%s" "$magenta"
|
|
||||||
newline
|
# explanatory text
|
||||||
textblock "The script has the following (optional) parameters:"
|
textBlock "If you run the script with no parameters, it will execute the container 'normally': Run in detached mode with nginx automatically launched. If you specified certificates, nginx will serve over SSL by default."
|
||||||
textblockParam 'parameter in cyan' 'default in yellow'
|
textBlock "Note: Containers (except shell) are always set to restart 'unless-stopped'. You must remove them manually if desired."
|
||||||
newline
|
printf "%s" "$magenta"
|
||||||
textblockParam '-n|--name' 'ab-nginx'
|
newline
|
||||||
textblock "Change the name of the container. This is cosmetic and does not affect operation in any way."
|
|
||||||
newline
|
# parameters
|
||||||
textblockParam '-s|--shell' 'off: run in detached mode'
|
textBlock "The script has the following (optional) parameters:"
|
||||||
textblock "Enter the container using an interactive POSIX shell. This happens after startup operations but *before* nginx is actually started. This is a great way to see configuration changes possibly stopping nginx from starting normally."
|
textBlockParam 'parameter in cyan' 'default in yellow'
|
||||||
printf "%s" "$yellow"
|
newline
|
||||||
newline
|
textBlockParam '-n|--name' 'ab-nginx'
|
||||||
textblock "More information can be found at: https://git.asifbacchus.app/ab-docker/ab-nginx/wiki"
|
textBlock "Set the name of the container, otherwise the default will be used."
|
||||||
printf "%s%1000s\n" "$magenta" | tr " " "-" | cut -c -$width
|
newline
|
||||||
exit 0
|
textBlockParam '-s|--shell' 'off: run in detached mode'
|
||||||
|
textBlock "Enter the container using an interactive ASH/BusyBox shell. This happens after startup operations but *before* nginx is actually started. This is a great way to see configuration changes possibly stopping nginx from starting normally."
|
||||||
|
newline
|
||||||
|
textBlockParam '--status'
|
||||||
|
textBlock "Run a search for all AB-NGINX containers and display their name and status."
|
||||||
|
newline
|
||||||
|
textBlockParam '--stop'
|
||||||
|
textBlock "Stops the container specified by the '--name' parameter or with the default name 'ab-nginx'."
|
||||||
|
newline
|
||||||
|
textBlockParam '--remove | --stop-remove'
|
||||||
|
textBlock "Stops and removes the container specified by the '--name' parameter or with the default name 'ab-nginx'."
|
||||||
|
|
||||||
|
# footer
|
||||||
|
newline
|
||||||
|
printf "%s" "$yellow"
|
||||||
|
textBlock"More information can be found at: https://git.asifbacchus.dev/ab-docker/ab-nginx/wiki"
|
||||||
|
printf "\n%s" "$magenta"
|
||||||
|
printf '%.0s-' $(seq "$width")
|
||||||
|
printf "\n%s" "$norm"
|
||||||
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
newline() {
|
newline() {
|
||||||
printf "\n"
|
printf "\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
textblock() {
|
textBlock() {
|
||||||
printf "%s\n" "$1" | fold -w "$width" -s
|
printf "%s\n" "$1" | fold -w "$width" -s
|
||||||
}
|
}
|
||||||
|
|
||||||
textblockParam() {
|
textBlockParam() {
|
||||||
if [ -z "$2" ]; then
|
if [ -z "$2" ]; then
|
||||||
# no default
|
# no default
|
||||||
printf "%s%s%s\n" "$cyan" "$1" "$norm"
|
printf "%s%s%s\n" "$cyan" "$1" "$norm"
|
||||||
else
|
else
|
||||||
# default param provided
|
# default param provided
|
||||||
printf "%s%s %s(%s)%s\n" "$cyan" "$1" "$yellow" "$2" "$norm"
|
printf "%s%s %s(%s)%s\n" "$cyan" "$1" "$yellow" "$2" "$norm"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
### pre-requisite checks
|
#
|
||||||
|
# pre-requisite checks
|
||||||
|
|
||||||
# is docker installed?
|
# is docker installed?
|
||||||
if ! command -v docker > /dev/null; then
|
if ! command -v docker >/dev/null; then
|
||||||
printf "%s\nCannot find docker... is it installed?\n%s" "$err" "$norm"
|
printf "%s\nCannot find docker... is it installed?\n%s" "$err" "$norm"
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# is user root or in the docker group?
|
# is user root or in the docker group?
|
||||||
if [ ! "$(id -u)" -eq 0 ]; then
|
if [ ! "$(id -u)" -eq 0 ]; then
|
||||||
if ! id -Gn | grep docker >/dev/null; then
|
if ! id -Gn | grep docker >/dev/null; then
|
||||||
printf "%s\nYou must either be root or in the 'docker' group to run this script since you must be able to actually start the container! Exiting.\n$%s" "$err" "$norm"
|
printf "%s\nYou must either be root or in the 'docker' group to run this script since you must be able to actually start the container! Exiting.\n$%s" "$err" "$norm"
|
||||||
exit 2
|
exit 3
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# process startup parameters
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
-h | -\? | --help)
|
||||||
|
# display help
|
||||||
|
scriptHelp
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-s | --shell)
|
||||||
|
# start shell instead of default CMD
|
||||||
|
doShell=true
|
||||||
|
;;
|
||||||
|
-n | --name)
|
||||||
|
# container name
|
||||||
|
if [ -z "$2" ]; then
|
||||||
|
printf "%s\nNo container name specified. Exiting.\n%s" "$err" "$norm"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
container_name="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--status)
|
||||||
|
# find containers and check their status
|
||||||
|
doStatus=true
|
||||||
|
;;
|
||||||
|
--stop)
|
||||||
|
# stop named container
|
||||||
|
doStop=true
|
||||||
|
;;
|
||||||
|
--remove | --stop-remove)
|
||||||
|
# stop and remove named container
|
||||||
|
doStop=true
|
||||||
|
removeStopped=true
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
printf "%s\nUnknown option: %s\n" "$err" "$1"
|
||||||
|
printf "Use '--help' for valid options.\n\n%s" "$norm"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
#
|
||||||
|
# status check
|
||||||
|
if [ "$doStatus" = "true" ]; then
|
||||||
|
printf "\nFound the following AB-NGINX containers:\n"
|
||||||
|
docker ps -a --filter "label=dev.asifbacchus.docker.internalName=ab-nginx"
|
||||||
|
printf "\n"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# stop container
|
||||||
|
if [ "$doStop" = "true" ]; then
|
||||||
|
printf "\nStopping container '%s'... " "$container_name"
|
||||||
|
|
||||||
|
# ensure container exists
|
||||||
|
if ! docker inspect "$container_name" >/dev/null 2>&1; then
|
||||||
|
printf "[ERROR]: No container with that name found.\n\n"
|
||||||
|
exit 11
|
||||||
|
fi
|
||||||
|
|
||||||
|
# stop and/or remove container
|
||||||
|
if ! docker stop "$container_name" >/dev/null 2>&1; then stopErr=1; fi
|
||||||
|
if [ "$removeStopped" = "true" ] && [ "$stopErr" -eq 0 ]; then
|
||||||
|
if ! docker rm "$container_name" >/dev/null 2>&1; then removeErr=1; fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# update status message
|
||||||
|
if [ "$stopErr" -eq 1 ]; then
|
||||||
|
printf "[ERROR]: Unable to stop container. Please try removing it manually.\n\n"
|
||||||
|
exit 12
|
||||||
|
fi
|
||||||
|
if [ "$removeErr" -eq 1 ]; then
|
||||||
|
printf "[STOPPED]\n"
|
||||||
|
printf "[ERROR]: Unable to remove container. Please try removing it manually.\n\n"
|
||||||
|
exit 13
|
||||||
|
fi
|
||||||
|
if [ "$removeStopped" = "true" ]; then
|
||||||
|
printf "[REMOVED]\n\n"
|
||||||
|
else
|
||||||
|
printf "[STOPPED]\n\n"
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# run container
|
||||||
|
|
||||||
# does the params file exist?
|
# does the params file exist?
|
||||||
checkExist 'file' './ab-nginx.params'
|
checkExist 'file' './ab-nginx.params'
|
||||||
|
|
||||||
# read .params file
|
# read .params file
|
||||||
|
# shellcheck source=ab-nginx.params.template
|
||||||
. "./ab-nginx.params"
|
. "./ab-nginx.params"
|
||||||
|
|
||||||
# fix case of TLS13_ONLY var
|
# fix case of TLS13_ONLY var
|
||||||
if [ "$TLS13_ONLY" ]; then
|
if [ "$TLS13_ONLY" ]; then
|
||||||
TLS13_ONLY=$(printf "%s" "$TLS13_ONLY" | tr "[:lower:]" "[:upper:]")
|
TLS13_ONLY=$(printf "%s" "$TLS13_ONLY" | tr "[:lower:]" "[:upper:]")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# check for certs if using SSL
|
# check for certs if using SSL
|
||||||
@@ -125,175 +244,132 @@ if [ "$SSL_CERT" ]; then checkExist 'file' "$SSL_CERT"; fi
|
|||||||
if [ "$SSL_KEY" ]; then checkExist 'file' "$SSL_KEY"; fi
|
if [ "$SSL_KEY" ]; then checkExist 'file' "$SSL_KEY"; fi
|
||||||
if [ "$SSL_CHAIN" ]; then checkExist 'file' "$SSL_CHAIN"; fi
|
if [ "$SSL_CHAIN" ]; then checkExist 'file' "$SSL_CHAIN"; fi
|
||||||
|
|
||||||
# check for DHparam if using TLS1.2
|
|
||||||
if [ "$SSL_CERT" ] && [ "$TLS13_ONLY" = 'FALSE' ]; then
|
|
||||||
if [ -z "$DH" ]; then
|
|
||||||
printf "%s\nA DHparam file must be specified when using TLS 1.2. Exiting.%s\n" "$err" "$norm"
|
|
||||||
exit 5
|
|
||||||
else
|
|
||||||
checkExist 'file' "$DH"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# check if specified config directory exists
|
# check if specified config directory exists
|
||||||
if [ "$CONFIG_DIR" ]; then
|
if [ "$CONFIG_DIR" ]; then
|
||||||
checkExist 'dir' "$CONFIG_DIR"
|
checkExist 'dir' "$CONFIG_DIR"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# check if specified server-block directory exists
|
# check if specified server-block directory exists
|
||||||
if [ "$SERVERS_DIR" ]; then
|
if [ "$SERVERS_DIR" ]; then
|
||||||
checkExist 'dir' "$SERVERS_DIR"
|
checkExist 'dir' "$SERVERS_DIR"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# check if specified webroot directory exists
|
# check if specified webroot directory exists
|
||||||
if [ "$WEBROOT_DIR" ]; then
|
if [ "$WEBROOT_DIR" ]; then
|
||||||
checkExist 'dir' "$WEBROOT_DIR"
|
checkExist 'dir' "$WEBROOT_DIR"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# set up volume mounts
|
# set up volume mounts
|
||||||
if [ "$CONFIG_DIR" ]; then
|
if [ "$CONFIG_DIR" ]; then
|
||||||
vmount="$vmount -v $CONFIG_DIR:/etc/nginx/config"
|
volumeMounts="${volumeMounts} -v $CONFIG_DIR:/etc/nginx/config"
|
||||||
fi
|
fi
|
||||||
if [ "$SERVERS_DIR" ]; then
|
if [ "$SERVERS_DIR" ]; then
|
||||||
vmount="$vmount -v $SERVERS_DIR:/etc/nginx/sites"
|
volumeMounts="${volumeMounts} -v $SERVERS_DIR:/etc/nginx/sites"
|
||||||
fi
|
fi
|
||||||
if [ "$SNIPPETS_DIR" ]; then
|
if [ "$SNIPPETS_DIR" ]; then
|
||||||
vmount="$vmount -v $SNIPPETS_DIR:/etc/nginx/snippets"
|
volumeMounts="${volumeMounts} -v $SNIPPETS_DIR:/etc/nginx/snippets"
|
||||||
fi
|
fi
|
||||||
if [ "$WEBROOT_DIR" ]; then
|
if [ "$WEBROOT_DIR" ]; then
|
||||||
vmount="$vmount -v $WEBROOT_DIR:/usr/share/nginx/html"
|
volumeMounts="${volumeMounts} -v $WEBROOT_DIR:/usr/share/nginx/html"
|
||||||
fi
|
fi
|
||||||
# trim leading whitespace
|
# trim leading whitespace
|
||||||
vmount=${vmount##[[:space:]]}
|
volumeMounts=${volumeMounts##[[:space:]]}
|
||||||
|
|
||||||
# handle null HOSTNAMES
|
# handle null HOSTNAMES
|
||||||
if [ -z "$HOSTNAMES" ]; then HOSTNAMES="_"; fi
|
if [ -z "$HOSTNAMES" ]; then HOSTNAMES="_"; fi
|
||||||
|
|
||||||
# process startup parameters
|
|
||||||
while [ $# -gt 0 ]; do
|
|
||||||
case "$1" in
|
|
||||||
-h | -\? | --help)
|
|
||||||
# display help
|
|
||||||
scriptHelp
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
-s | --shell)
|
|
||||||
# start shell instead of default CMD
|
|
||||||
shell=true
|
|
||||||
;;
|
|
||||||
-n | --name)
|
|
||||||
# container name
|
|
||||||
if [ -z "$2" ]; then
|
|
||||||
printf "%s\nNo container name specified. Exiting.\n%s" "$err" "$norm"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
container_name="$2"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
printf "%s\nUnknown option: %s\n" "$err" "$1"
|
|
||||||
printf "Use '--help' for valid options.\n\n%s" "$norm"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
|
|
||||||
# create network if it doesn't already exist
|
# create network if it doesn't already exist
|
||||||
docker network inspect ${NETWORK} >/dev/null 2>&1 ||
|
docker network inspect ${NETWORK} >/dev/null 2>&1 ||
|
||||||
docker network create \
|
docker network create \
|
||||||
--attachable \
|
--attachable \
|
||||||
--driver=bridge \
|
--driver=bridge \
|
||||||
--subnet=${SUBNET} \
|
--subnet=${SUBNET} \
|
||||||
${NETWORK}
|
${NETWORK}
|
||||||
|
|
||||||
# run without TLS
|
# run without TLS
|
||||||
if [ -z "$SSL_CERT" ]; then
|
if [ -z "$SSL_CERT" ]; then
|
||||||
if [ $shell = 'true' ]; then
|
if [ "$doShell" = 'true' ]; then
|
||||||
# exec shell
|
# exec shell
|
||||||
printf "%s\nRunning SHELL on %s...%s\n" "$cyan" "$container_name" "$norm"
|
printf "%s\nRunning SHELL on %s...%s\n" "$cyan" "$container_name" "$norm"
|
||||||
docker run --rm -it --name "${container_name}" \
|
# shellcheck disable=SC2086
|
||||||
--env-file ab-nginx.params \
|
docker run --rm -it --name "${container_name}" \
|
||||||
-e SERVER_NAMES="$HOSTNAMES" \
|
--env-file ab-nginx.params \
|
||||||
$vmount \
|
--user="${NGINX_UID:-8080}:${NGINX_GID:-8080}" \
|
||||||
--network=${NETWORK} \
|
-e SERVER_NAMES="$HOSTNAMES" \
|
||||||
-p ${HTTP_PORT}:80 \
|
${volumeMounts} \
|
||||||
docker.asifbacchus.app/nginx/ab-nginx:latest /bin/sh
|
--network=${NETWORK} \
|
||||||
else
|
-p ${HTTP_PORT}:80 \
|
||||||
# exec normally
|
docker.asifbacchus.dev/nginx/ab-nginx:latest /bin/sh
|
||||||
printf "%s\nRunning NGINX on %s...%s\n" "$cyan" "$container_name" "$norm"
|
else
|
||||||
docker run -d --name "${container_name}" \
|
# exec normally
|
||||||
--env-file ab-nginx.params \
|
printf "%s\nRunning NGINX on %s...%s\n" "$cyan" "$container_name" "$norm"
|
||||||
-e SERVER_NAMES="$HOSTNAMES" \
|
# shellcheck disable=SC2086
|
||||||
$vmount \
|
docker run -d --name "${container_name}" \
|
||||||
--network=${NETWORK} \
|
--env-file ab-nginx.params \
|
||||||
-p ${HTTP_PORT}:80 \
|
--user="${NGINX_UID:-8080}:${NGINX_GID:-8080}" \
|
||||||
--restart unless-stopped \
|
-e SERVER_NAMES="$HOSTNAMES" \
|
||||||
docker.asifbacchus.app/nginx/ab-nginx:latest
|
${volumeMounts} \
|
||||||
fi
|
--network=${NETWORK} \
|
||||||
# run with TLS1.2
|
-p ${HTTP_PORT}:80 \
|
||||||
elif [ "$SSL_CERT" ] && [ "$TLS13_ONLY" = 'FALSE' ]; then
|
--restart unless-stopped \
|
||||||
if [ $shell = 'true' ]; then
|
docker.asifbacchus.dev/nginx/ab-nginx:${TAG:-latest}
|
||||||
# exec shell
|
fi
|
||||||
printf "%s\nRunning SHELL on %s (TLS 1.2)...%s\n" "$cyan" "$container_name" "$norm"
|
# run with TLS
|
||||||
docker run --rm -it --name "${container_name}" \
|
else
|
||||||
--env-file ab-nginx.params \
|
if [ "$doShell" = 'true' ]; then
|
||||||
-e SERVER_NAMES="$HOSTNAMES" \
|
if [ "$TLS13_ONLY" = 'FALSE' ]; then
|
||||||
$vmount \
|
printf "%s\nRunning SHELL on %s (TLS 1.2)...%s\n" "$cyan" "$container_name" "$norm"
|
||||||
--network=${NETWORK} \
|
else
|
||||||
-v "$SSL_CERT":/certs/fullchain.pem:ro \
|
printf "%s\nRunning SHELL on %s (TLS 1.3)...%s\n" "$cyan" "$container_name" "$norm"
|
||||||
-v "$SSL_KEY":/certs/privkey.pem:ro \
|
fi
|
||||||
-v "$SSL_CHAIN":/certs/chain.pem:ro \
|
# shellcheck disable=SC2086
|
||||||
-v "$DH":/certs/dhparam.pem:ro \
|
docker run --rm -it --name "${container_name}" \
|
||||||
-p ${HTTP_PORT}:80 -p ${HTTPS_PORT}:443 \
|
--env-file ab-nginx.params \
|
||||||
docker.asifbacchus.app/nginx/ab-nginx:latest /bin/sh
|
--user="${NGINX_UID:-8080}:${NGINX_GID:-8080}" \
|
||||||
else
|
-e SERVER_NAMES="$HOSTNAMES" \
|
||||||
# exec normally
|
${volumeMounts} \
|
||||||
printf "%s\nRunning NGINX on %s (TLS 1.2)...%s\n" "$cyan" "$container_name" "$norm"
|
--network=${NETWORK} \
|
||||||
docker run -d --name "${container_name}" \
|
-v "$SSL_CERT":/certs/fullchain.pem:ro \
|
||||||
--env-file ab-nginx.params \
|
-v "$SSL_KEY":/certs/privkey.pem:ro \
|
||||||
-e SERVER_NAMES="$HOSTNAMES" \
|
-v "$SSL_CHAIN":/certs/chain.pem:ro \
|
||||||
$vmount \
|
-p ${HTTP_PORT}:80 -p ${HTTPS_PORT}:443 \
|
||||||
--network=${NETWORK} \
|
docker.asifbacchus.dev/nginx/ab-nginx:${TAG:-latest} /bin/sh
|
||||||
-v "$SSL_CERT":/certs/fullchain.pem:ro \
|
else
|
||||||
-v "$SSL_KEY":/certs/privkey.pem:ro \
|
if [ "$TLS13_ONLY" = 'FALSE' ]; then
|
||||||
-v "$SSL_CHAIN":/certs/chain.pem:ro \
|
printf "%s\nRunning NGINX on %s (TLS 1.2)...%s\n" "$cyan" "$container_name" "$norm"
|
||||||
-v "$DH":/certs/dhparam.pem:ro \
|
else
|
||||||
-p ${HTTP_PORT}:80 -p ${HTTPS_PORT}:443 \
|
printf "%s\nRunning NGINX on %s (TLS 1.3)...%s\n" "$cyan" "$container_name" "$norm"
|
||||||
--restart unless-stopped \
|
fi
|
||||||
docker.asifbacchus.app/nginx/ab-nginx:latest
|
# shellcheck disable=SC2086
|
||||||
fi
|
docker run -d --name "${container_name}" \
|
||||||
# run with TLS1.3
|
--env-file ab-nginx.params \
|
||||||
elif [ "$SSL_CERT" ] && [ "$TLS13_ONLY" = 'TRUE' ]; then
|
--user="${NGINX_UID:-8080}:${NGINX_GID:-8080}" \
|
||||||
if [ $shell = 'true' ]; then
|
-e SERVER_NAMES="$HOSTNAMES" \
|
||||||
# exec shell
|
${volumeMounts} \
|
||||||
printf "%s\nRunning SHELL on %s (TLS 1.3)...%s\n" "$cyan" "$container_name" "$norm"
|
--network=${NETWORK} \
|
||||||
docker run --rm -it --name "${container_name}" \
|
-v "$SSL_CERT":/certs/fullchain.pem:ro \
|
||||||
--env-file ab-nginx.params \
|
-v "$SSL_KEY":/certs/privkey.pem:ro \
|
||||||
-e SERVER_NAMES="$HOSTNAMES" \
|
-v "$SSL_CHAIN":/certs/chain.pem:ro \
|
||||||
$vmount \
|
-p ${HTTP_PORT}:80 -p ${HTTPS_PORT}:443 \
|
||||||
--network=${NETWORK} \
|
--restart unless-stopped \
|
||||||
-v "$SSL_CERT":/certs/fullchain.pem:ro \
|
docker.asifbacchus.dev/nginx/ab-nginx:${TAG:-latest}
|
||||||
-v "$SSL_KEY":/certs/privkey.pem:ro \
|
fi
|
||||||
-v "$SSL_CHAIN":/certs/chain.pem:ro \
|
|
||||||
-p ${HTTP_PORT}:80 -p ${HTTPS_PORT}:443 \
|
|
||||||
docker.asifbacchus.app/nginx/ab-nginx:latest /bin/sh
|
|
||||||
else
|
|
||||||
# exec normally
|
|
||||||
printf "%s\nRunning NGINX on %s (TLS 1.3)...%s\n" "$cyan" "$container_name" "$norm"
|
|
||||||
docker run -d --name "${container_name}" \
|
|
||||||
--env-file ab-nginx.params \
|
|
||||||
-e SERVER_NAMES="$HOSTNAMES" \
|
|
||||||
$vmount \
|
|
||||||
--network=${NETWORK} \
|
|
||||||
-v "$SSL_CERT":/certs/fullchain.pem:ro \
|
|
||||||
-v "$SSL_KEY":/certs/privkey.pem:ro \
|
|
||||||
-v "$SSL_CHAIN":/certs/chain.pem:ro \
|
|
||||||
-p ${HTTP_PORT}:80 -p ${HTTPS_PORT}:443 \
|
|
||||||
--restart unless-stopped \
|
|
||||||
docker.asifbacchus.app/nginx/ab-nginx:latest
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
### exit gracefully
|
#
|
||||||
exit 0
|
# exit with code from docker
|
||||||
|
exit "$?"
|
||||||
|
|
||||||
|
#
|
||||||
|
# exit return codes
|
||||||
|
# 0: normal exit, no errors
|
||||||
|
# 1: missing or invalid parameter
|
||||||
|
# 2: cannot find docker
|
||||||
|
# 3: incorrect permissions to access docker
|
||||||
|
# 1x: operation errors
|
||||||
|
# 11 no container found with specified name
|
||||||
|
# 12 unable to stop container
|
||||||
|
# 13 unable to remove container
|
||||||
|
# other refer to docker exit codes
|
||||||
|
|
||||||
|
#EOF
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
- Place all your server block configuration files in this directory
|
- Place all your server block configuration files in this directory
|
||||||
- This path should be bind-mounted to the container at:
|
- This path should be bind-mounted to the container at:
|
||||||
'/etc/nginx/sites'
|
'/etc/nginx/sites'
|
||||||
- this bind-mount will override the test pages included in the container by
|
- this bind-mount will override the default server configurations
|
||||||
default.
|
included in the container by default.
|
||||||
- All files should begin in the 'server' configuration context
|
- All files should begin in the 'server' configuration context
|
||||||
- ONLY files that end with '.conf' will be processed!
|
- ONLY files that end with '.conf' will be processed!
|
||||||
- if you want to keep a file for reference or disable it temporarily,
|
- if you want to keep a file for reference or disable it temporarily,
|
||||||
simply change the extension. I like using '.conf.disabled'.
|
simply change the extension. I like using '.conf.disabled'.
|
||||||
- If you don't want to use this directory, you can bind-mount any other
|
- If you don't want to use this directory, you can bind-mount any other
|
||||||
directory you want to '/etc/nginx/sites/'
|
directory you want to '/etc/nginx/sites/'
|
||||||
|
|||||||
+215
-182
@@ -1,83 +1,87 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
### update script for ab-nginx container and utility scripts
|
#
|
||||||
# version 2.0.0
|
# update script for ab-nginx container and utility scripts
|
||||||
# script by Asif Bacchus
|
# version 2.1.0
|
||||||
###
|
# script by Asif Bacchus
|
||||||
|
#
|
||||||
|
|
||||||
### functions
|
#
|
||||||
|
# functions
|
||||||
errMsg() {
|
errMsg() {
|
||||||
printf "\n%s%s%s\n\n" "$err" "$1" "$norm"
|
printf "\n%s%s%s\n\n" "$err" "$1" "$norm"
|
||||||
exit 1
|
[ -n "$2" ] && exit "$2" || exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
errNotify() {
|
errNotify() {
|
||||||
printf "%s[ERROR]%s\n" "$err" "$norm"
|
printf "%s[ERROR]%s\n" "$err" "$norm"
|
||||||
}
|
}
|
||||||
|
|
||||||
okMsg() {
|
okMsg() {
|
||||||
printf "%s%s%s\n\n" "$ok" "$1" "$norm"
|
printf "%s%s%s\n\n" "$ok" "$1" "$norm"
|
||||||
}
|
}
|
||||||
|
|
||||||
okNotify() {
|
okNotify() {
|
||||||
printf "%s[OK]%s\n" "$ok" "$norm"
|
printf "%s[OK]%s\n" "$ok" "$norm"
|
||||||
}
|
}
|
||||||
|
|
||||||
scriptHelp() {
|
scriptHelp() {
|
||||||
textNewline
|
textNewline
|
||||||
textblock "Update ${containerName} container and helper script files"
|
textBlock "Update ${containerName} container and helper script files"
|
||||||
textblock "${bold}Usage: ${localScriptName} [parameters]${norm}"
|
textBlock "${bold}Usage: ${localScriptName} [parameters]${norm}"
|
||||||
textNewline
|
textNewline
|
||||||
textblock "If run with no parameters, the script will update both the container and the helper script files, including this update script."
|
textBlock "If run with no parameters, the script will update both the container and the helper script files, including this update script."
|
||||||
textblockHeader " parameters "
|
textBlockHeader " parameters "
|
||||||
textblockParam "-h|-?|--help" "Display this help screen."
|
textBlockParam "-h|-?|--help" "Display this help screen."
|
||||||
textblockParam "-c|--container|--container-only" "Update the docker container only."
|
textBlockParam "-c|--container|--container-only" "Update the docker container only."
|
||||||
textblockParam "-s|--scripts|--scripts-only" "Update the helper scripts (including this update script) only."
|
textBlockParam "-s|--scripts|--scripts-only" "Update the helper scripts (including this update script) only."
|
||||||
textNewline
|
textNewline
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
textblock() {
|
textBlock() {
|
||||||
printf "%s\n" "$1" | fold -w "$width" -s
|
printf "%s\n" "$1" | fold -w "$width" -s
|
||||||
}
|
}
|
||||||
|
|
||||||
textblockHeader() {
|
textBlockHeader() {
|
||||||
printf "\n%s***%s***%s\n" "$header" "$1" "$norm"
|
printf "\n%s***%s***%s\n" "$header" "$1" "$norm"
|
||||||
}
|
}
|
||||||
|
|
||||||
textblockParam() {
|
textBlockParam() {
|
||||||
printf "%s%-35s%s%s\n" "$info" "$1" "$2" "$norm"
|
printf "%s%-35s%s%s\n" "$info" "$1" "$2" "$norm"
|
||||||
}
|
}
|
||||||
|
|
||||||
textNewline() {
|
textNewline() {
|
||||||
printf "\n"
|
printf "\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
### text formatting presets
|
#
|
||||||
|
# text formatting presets
|
||||||
if command -v tput >/dev/null 2>&1; then
|
if command -v tput >/dev/null 2>&1; then
|
||||||
bold=$(tput bold)
|
bold=$(tput bold)
|
||||||
err=$(tput bold)$(tput setaf 1)
|
err=$(tput bold)$(tput setaf 1)
|
||||||
info=$(tput bold)$(tput setaf 6)
|
info=$(tput bold)$(tput setaf 6)
|
||||||
header=$(tput bold)$(tput setaf 5)
|
header=$(tput bold)$(tput setaf 5)
|
||||||
norm=$(tput sgr0)
|
norm=$(tput sgr0)
|
||||||
ok=$(tput sgr0)$(tput setaf 2)
|
ok=$(tput sgr0)$(tput setaf 2)
|
||||||
warn=$(tput bold)$(tput setaf 3)
|
warn=$(tput bold)$(tput setaf 3)
|
||||||
width=$(tput cols)
|
width=$(tput cols)
|
||||||
else
|
else
|
||||||
bold=''
|
bold=''
|
||||||
err=''
|
err=''
|
||||||
info=''
|
info=''
|
||||||
header=''
|
header=''
|
||||||
norm=''
|
norm=''
|
||||||
ok=''
|
ok=''
|
||||||
warn=''
|
warn=''
|
||||||
width=80
|
width=80
|
||||||
fi
|
fi
|
||||||
|
|
||||||
### pre-requisites
|
#
|
||||||
|
# pre-requisites
|
||||||
# check if wget is installed
|
# check if wget is installed
|
||||||
if ! command -v wget >/dev/null 2>&1; then
|
if ! command -v wget >/dev/null 2>&1; then
|
||||||
errMsg "Sorry, this script requires that 'wget' is installed in order to download updates. Exiting."
|
errMsg "Sorry, this script requires that 'wget' is installed in order to download updates. Exiting."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# zero counters
|
# zero counters
|
||||||
@@ -90,8 +94,8 @@ updateSuccess=0
|
|||||||
# reference constants
|
# reference constants
|
||||||
dockerNamespace='nginx'
|
dockerNamespace='nginx'
|
||||||
containerName='ab-nginx'
|
containerName='ab-nginx'
|
||||||
containerUpdatePath="docker.asifbacchus.app/$dockerNamespace/$containerName:latest"
|
containerUpdatePath="docker.asifbacchus.dev/$dockerNamespace/$containerName:latest"
|
||||||
server="https://asifbacchus.app/updates/docker/$dockerNamespace/$containerName/"
|
server="https://asifbacchus.dev/public/docker/$dockerNamespace/$containerName/"
|
||||||
checksumFilename='checksums.sha256'
|
checksumFilename='checksums.sha256'
|
||||||
|
|
||||||
# operation triggers
|
# operation triggers
|
||||||
@@ -102,149 +106,178 @@ doScriptUpdate=1
|
|||||||
localScriptName="$(basename "$0")"
|
localScriptName="$(basename "$0")"
|
||||||
repoScriptName='update.sh'
|
repoScriptName='update.sh'
|
||||||
|
|
||||||
### process startup parameters
|
#
|
||||||
|
# process startup parameters
|
||||||
while [ $# -gt 0 ]; do
|
while [ $# -gt 0 ]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
-h | -\? | --help)
|
-h | -\? | --help)
|
||||||
# display inline help
|
# display inline help
|
||||||
scriptHelp
|
scriptHelp
|
||||||
;;
|
;;
|
||||||
-s | --scripts | --scripts-only)
|
-s | --scripts | --scripts-only)
|
||||||
# update scripts only, skip docker container update
|
# update scripts only, skip docker container update
|
||||||
doDockerUpdate=0
|
doDockerUpdate=0
|
||||||
;;
|
;;
|
||||||
-c | --container | --container-only)
|
-c | --container | --container-only)
|
||||||
# update docker container only, skip script update
|
# update docker container only, skip script update
|
||||||
doScriptUpdate=0
|
doScriptUpdate=0
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
printf "%s\nUnknown option: %s\n" "$err" "$1"
|
printf "%s\nUnknown option: %s\n" "$err" "$1"
|
||||||
printf "%sUse '--help' for valid options%s\n\n" "$info" "$norm"
|
printf "%sUse '--help' for valid options%s\n\n" "$info" "$norm"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
### update container
|
#
|
||||||
|
# update container
|
||||||
if [ "$doDockerUpdate" -eq 1 ]; then
|
if [ "$doDockerUpdate" -eq 1 ]; then
|
||||||
# check if docker is installed
|
# check if docker is installed
|
||||||
if ! command -v docker >/dev/null 2>&1; then
|
if ! command -v docker >/dev/null 2>&1; then
|
||||||
errMsg "Sorry, it appears that docker is not installed on this machine! Exiting."
|
errMsg "Sorry, it appears that docker is not installed on this machine! Exiting." 2
|
||||||
fi
|
|
||||||
|
|
||||||
# is user root or in the docker group?
|
|
||||||
if [ ! "$(id -u)" -eq 0 ]; then
|
|
||||||
if ! id -Gn | grep docker >/dev/null; then
|
|
||||||
errMsg "You must either be root or in the 'docker' group to pull container updates."
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
printf "%s\n*** Updating %s container ***\n\n%s" "$info" "$containerName" "$norm"
|
|
||||||
if ! docker pull "$containerUpdatePath"; then
|
|
||||||
errMsg "There was an error updating the container. Try again later."
|
|
||||||
else
|
|
||||||
okMsg "Container updated!"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
### update scripts
|
|
||||||
if [ "$doScriptUpdate" -eq 1 ]; then
|
|
||||||
printf "%s*** Updating %s service scripts ***%s\n" "$info" "$containerName" "$norm"
|
|
||||||
|
|
||||||
## download latest checksums
|
|
||||||
printf "Getting latest checksums... "
|
|
||||||
if ! wget --quiet --tries=3 --timeout=10 -N "${server}${checksumFilename}"; then
|
|
||||||
errNotify
|
|
||||||
errMsg "Unable to download checksums. Try again later."
|
|
||||||
else
|
|
||||||
okNotify
|
|
||||||
fi
|
|
||||||
|
|
||||||
## check for updates to this script
|
|
||||||
printf "Checking for updates to this script... "
|
|
||||||
repoScriptChecksum=$(grep "$repoScriptName" "$checksumFilename" | grep -o '^\S*')
|
|
||||||
localScriptChecksum=$(sha256sum "$localScriptName" | grep -o '^\S*')
|
|
||||||
if [ "$localScriptChecksum" = "$repoScriptChecksum" ]; then
|
|
||||||
printf "[NONE]\n"
|
|
||||||
else
|
|
||||||
printf "[AVAILABLE]\n"
|
|
||||||
printf "Getting updated script... "
|
|
||||||
# download updated script
|
|
||||||
if ! wget --quiet --tries=3 --timeout=10 -O "update.sh.tmp" "${server}${repoScriptName}"; then
|
|
||||||
errNotify
|
|
||||||
# delete failed download as necessary
|
|
||||||
rm -f ./update.sh.tmp 2>/dev/null
|
|
||||||
errMsg "Unable to download script update. Try again later."
|
|
||||||
else
|
|
||||||
# verify download
|
|
||||||
dlScriptChecksum=$(sha256sum "update.sh.tmp" | grep -o '^\S*')
|
|
||||||
if ! [ "$dlScriptChecksum" = "$repoScriptChecksum" ]; then
|
|
||||||
printf "[ERROR]\n"
|
|
||||||
# delete corrupt download as necessary
|
|
||||||
rm -f ./update.sh.tmp 2>/dev/null
|
|
||||||
errMsg "Checksum mismatch! Try again later."
|
|
||||||
else
|
|
||||||
okNotify
|
|
||||||
printf "\n%s*** This script has been updated. Please re-run it to load the updated version of this file. ***%s\n\n" "$warn" "$norm"
|
|
||||||
# overwrite this script with updated script
|
|
||||||
mv -f ./update.sh.tmp "$localScriptName"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
## update files
|
|
||||||
while IFS=' ' read -r field1 field2; do
|
|
||||||
printf "\nChecking '%s' for updates... " "$field2"
|
|
||||||
updateFilename="$field2"
|
|
||||||
repoFileChecksum="$field1"
|
|
||||||
if [ -f "$updateFilename" ]; then
|
|
||||||
localFileChecksum=$(sha256sum "$updateFilename" | grep -o '^\S*')
|
|
||||||
else
|
|
||||||
localFileChecksum=0
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# update file if necessary
|
# is user root or in the docker group?
|
||||||
if ! [ "$localFileChecksum" = "$repoFileChecksum" ]; then
|
if [ ! "$(id -u)" -eq 0 ]; then
|
||||||
printf "[AVAILABLE]\n"
|
if ! id -Gn | grep docker >/dev/null; then
|
||||||
updatesAvailable=$((updatesAvailable + 1))
|
errMsg "You must either be root or in the 'docker' group to pull container updates." 2
|
||||||
# download update
|
|
||||||
printf "Downloading updated '%s'... " "$updateFilename"
|
|
||||||
if ! wget --quiet --tries=3 --timeout=10 -O "$updateFilename.tmp" "${server}${updateFilename}"; then
|
|
||||||
errNotify
|
|
||||||
downloadFailed=$((downloadFailed + 1))
|
|
||||||
# delete failed download file as necessary
|
|
||||||
rm -f "$updateFilename.tmp" 2>&1
|
|
||||||
else
|
|
||||||
okNotify
|
|
||||||
downloadSuccess=$((downloadSuccess + 1))
|
|
||||||
# verify download
|
|
||||||
printf "Verifying '%s'... " "$updateFilename"
|
|
||||||
localFileChecksum=$(sha256sum "$updateFilename.tmp" | grep -o '^\S*')
|
|
||||||
if ! [ "$localFileChecksum" = "$repoFileChecksum" ]; then
|
|
||||||
errNotify
|
|
||||||
updateFailed=$((updateFailed + 1))
|
|
||||||
# delete corrupted download file as necessary
|
|
||||||
rm -f "$updateFilename.tmp" 2>&1
|
|
||||||
else
|
|
||||||
okNotify
|
|
||||||
updateSuccess=$((updateSuccess + 1))
|
|
||||||
# overwrite old version of file
|
|
||||||
mv -f "$updateFilename.tmp" "$updateFilename"
|
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
else
|
|
||||||
printf "[NONE]\n"
|
|
||||||
fi
|
fi
|
||||||
done <"$checksumFilename"
|
|
||||||
|
printf "%s\n*** Updating %s container ***\n\n%s" "$info" "$containerName" "$norm"
|
||||||
|
if ! docker pull "$containerUpdatePath"; then
|
||||||
|
errMsg "There was an error updating the container. Try again later." 31
|
||||||
|
else
|
||||||
|
okMsg "Container updated!"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
### display results
|
#
|
||||||
|
# update scripts
|
||||||
if [ "$doScriptUpdate" -eq 1 ]; then
|
if [ "$doScriptUpdate" -eq 1 ]; then
|
||||||
printf "\n%s*** Results ***%s\n" "$info" "$norm"
|
printf "%s*** Updating %s service scripts ***%s\n" "$info" "$containerName" "$norm"
|
||||||
printf "\tUpdates: %s available\n" "$updatesAvailable"
|
|
||||||
printf "\tDownloads: %s%s successful%s, %s%s failed%s\n" "$ok" "$downloadSuccess" "$norm" "$err" "$downloadFailed" "$norm"
|
## download latest checksums
|
||||||
printf "\tUpdates: %s%s applied%s, %s%s failed%s\n" "$ok" "$updateSuccess" "$norm" "$err" "$updateFailed" "$norm"
|
printf "Getting latest checksums... "
|
||||||
|
if ! wget --quiet --tries=3 --timeout=10 -N "${server}${checksumFilename}"; then
|
||||||
|
errNotify
|
||||||
|
errMsg "Unable to download checksums. Try again later." 41
|
||||||
|
else
|
||||||
|
okNotify
|
||||||
|
fi
|
||||||
|
|
||||||
|
## check for updates to this script
|
||||||
|
printf "Checking for updates to this script... "
|
||||||
|
repoScriptChecksum=$(grep "$repoScriptName" "$checksumFilename" | grep -o '^\S*')
|
||||||
|
localScriptChecksum=$(sha256sum "$localScriptName" | grep -o '^\S*')
|
||||||
|
if [ "$localScriptChecksum" = "$repoScriptChecksum" ]; then
|
||||||
|
printf "[NONE]\n"
|
||||||
|
else
|
||||||
|
printf "[AVAILABLE]\n"
|
||||||
|
printf "Getting updated script... "
|
||||||
|
# download updated script
|
||||||
|
if ! wget --quiet --tries=3 --timeout=10 -O "update.sh.tmp" "${server}${repoScriptName}"; then
|
||||||
|
errNotify
|
||||||
|
# delete failed download as necessary
|
||||||
|
rm -f ./update.sh.tmp 2>/dev/null
|
||||||
|
errMsg "Unable to download script update. Try again later." 42
|
||||||
|
else
|
||||||
|
# verify download
|
||||||
|
dlScriptChecksum=$(sha256sum "update.sh.tmp" | grep -o '^\S*')
|
||||||
|
if ! [ "$dlScriptChecksum" = "$repoScriptChecksum" ]; then
|
||||||
|
printf "[ERROR]\n"
|
||||||
|
# delete corrupt download as necessary
|
||||||
|
rm -f ./update.sh.tmp 2>/dev/null
|
||||||
|
errMsg "Checksum mismatch! Try again later." 42
|
||||||
|
else
|
||||||
|
okNotify
|
||||||
|
printf "\n%s*** This script has been updated. Please re-run it to load the updated version of this file. ***%s\n\n" "$warn" "$norm"
|
||||||
|
# overwrite this script with updated script
|
||||||
|
mv -f ./update.sh.tmp "$localScriptName"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
## update files
|
||||||
|
while IFS=' ' read -r field1 field2; do
|
||||||
|
printf "\nChecking '%s' for updates... " "$field2"
|
||||||
|
updateFilename="$field2"
|
||||||
|
repoFileChecksum="$field1"
|
||||||
|
if [ -f "$updateFilename" ]; then
|
||||||
|
localFileChecksum=$(sha256sum "$updateFilename" | grep -o '^\S*')
|
||||||
|
else
|
||||||
|
localFileChecksum=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# update file if necessary
|
||||||
|
if ! [ "$localFileChecksum" = "$repoFileChecksum" ]; then
|
||||||
|
printf "[AVAILABLE]\n"
|
||||||
|
updatesAvailable=$((updatesAvailable + 1))
|
||||||
|
# download update
|
||||||
|
printf "Downloading updated '%s'... " "$updateFilename"
|
||||||
|
if ! wget --quiet --tries=3 --timeout=10 -O "$updateFilename.tmp" "${server}${updateFilename}"; then
|
||||||
|
errNotify
|
||||||
|
downloadFailed=$((downloadFailed + 1))
|
||||||
|
# delete failed download file as necessary
|
||||||
|
rm -f "$updateFilename.tmp" 2>&1
|
||||||
|
else
|
||||||
|
okNotify
|
||||||
|
downloadSuccess=$((downloadSuccess + 1))
|
||||||
|
# verify download
|
||||||
|
printf "Verifying '%s'... " "$updateFilename"
|
||||||
|
localFileChecksum=$(sha256sum "$updateFilename.tmp" | grep -o '^\S*')
|
||||||
|
if ! [ "$localFileChecksum" = "$repoFileChecksum" ]; then
|
||||||
|
errNotify
|
||||||
|
updateFailed=$((updateFailed + 1))
|
||||||
|
# delete corrupted download file as necessary
|
||||||
|
rm -f "$updateFilename.tmp" 2>&1
|
||||||
|
else
|
||||||
|
okNotify
|
||||||
|
updateSuccess=$((updateSuccess + 1))
|
||||||
|
# overwrite old version of file
|
||||||
|
mv -f "$updateFilename.tmp" "$updateFilename"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
printf "[NONE]\n"
|
||||||
|
fi
|
||||||
|
done <"$checksumFilename"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exit 0
|
#
|
||||||
|
# display results
|
||||||
|
if [ "$doScriptUpdate" -eq 1 ]; then
|
||||||
|
printf "\n%s*** Results ***%s\n" "$info" "$norm"
|
||||||
|
printf "\tUpdates: %s available\n" "$updatesAvailable"
|
||||||
|
printf "\tDownloads: %s%s successful%s, %s%s failed%s\n" "$ok" "$downloadSuccess" "$norm" "$err" "$downloadFailed" "$norm"
|
||||||
|
printf "\tUpdates: %s%s applied%s, %s%s failed%s\n" "$ok" "$updateSuccess" "$norm" "$err" "$updateFailed" "$norm"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# exit
|
||||||
|
if [ "$downloadFailed" -gt 0 ]; then
|
||||||
|
exit 43
|
||||||
|
elif [ "$updateFailed" -gt 0 ]; then
|
||||||
|
exit 44
|
||||||
|
else
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
# this is a trap for mis-coding... should never get an exit code 99!
|
||||||
|
exit 99
|
||||||
|
|
||||||
|
#
|
||||||
|
# exit return codes
|
||||||
|
# 0: normal exit, no errors
|
||||||
|
# 1: missing or invalid parameter
|
||||||
|
# 2: docker not found or no docker permissions
|
||||||
|
# 31: unable to update docker container
|
||||||
|
# 4x: helper files errors
|
||||||
|
# 41: unable to download checksums
|
||||||
|
# 42: update script: unable to download or bad checksum
|
||||||
|
# 43: update helpers: unable to download
|
||||||
|
# 44: update helpers: bad checksum, no update
|
||||||
|
# 99: coding mistake trap -- this return code should never happen!
|
||||||
|
|
||||||
|
#EOF
|
||||||
|
|||||||
Reference in New Issue
Block a user