Merge pull request #117 from bitnami/customize_nginx

Adapt NGINX so it can be customized
This commit is contained in:
Juan Ariza Toledano
2019-05-02 17:35:27 +02:00
committed by GitHub
20 changed files with 400 additions and 280 deletions

View File

@@ -2,7 +2,6 @@ FROM bitnami/minideb-extras-base:stretch-r236
LABEL maintainer "Bitnami <containers@bitnami.com>"
ENV BITNAMI_PKG_CHMOD="-R g+rwX" \
BITNAMI_PKG_EXTRA_DIRS="/bitnami/nginx/conf" \
HOME="/" \
OS_ARCH="amd64" \
OS_FLAVOUR="debian-9" \
@@ -11,24 +10,19 @@ ENV BITNAMI_PKG_CHMOD="-R g+rwX" \
# Install required system packages and dependencies
RUN install_packages libc6 libpcre3 libssl1.1 zlib1g
RUN . ./libcomponent.sh && component_unpack "nginx" "1.16.0-0" --checksum b08c5b2a428e2e54726d47e290102496780db1ddd4a0a67bed82da6c34e56784
RUN ln -sf /opt/bitnami/nginx/html /app
RUN ln -sf /dev/stdout /opt/bitnami/nginx/logs/access.log
RUN ln -sf /dev/stderr /opt/bitnami/nginx/logs/error.log
COPY rootfs /
RUN /prepare.sh
RUN /postunpack.sh
ENV BITNAMI_APP_NAME="nginx" \
BITNAMI_IMAGE_VERSION="1.16.0-debian-9-r2" \
NAMI_PREFIX="/.nami" \
NGINX_DAEMON_GROUP="" \
NGINX_DAEMON_USER="" \
NGINX_HTTPS_PORT_NUMBER="443" \
NGINX_HTTP_PORT_NUMBER="8080" \
PATH="/opt/bitnami/nginx/sbin:$PATH"
EXPOSE 8080
EXPOSE 8080 8443
VOLUME [ "/app" "/certs" ]
WORKDIR /app
USER 1001
ENTRYPOINT [ "/entrypoint.sh" ]
CMD [ "/run.sh" ]

View File

@@ -5,3 +5,5 @@ services:
image: 'bitnami/nginx:1.16'
ports:
- '80:8080'
environment:
- NGINX_HTTP_PORT_NUMBER=8080

View File

@@ -61,7 +61,7 @@ nginx_start() {
is_nginx_running && return
debug "Starting NGIX..."
if am_i_root; then
gosu "$NGINX_DAEMON_USER" "${NGINX_BASEDIR}/sbin/nginx" -c "${NGINX_CONFDIR}/nginx.conf"
gosu "${NGINX_DAEMON_USER}" "${NGINX_BASEDIR}/sbin/nginx" -c "${NGINX_CONFDIR}/nginx.conf"
else
"${NGINX_BASEDIR}/sbin/nginx" -c "${NGINX_CONFDIR}/nginx.conf"
fi
@@ -98,6 +98,22 @@ export PATH="${NGINX_BASEDIR}/sbin:$PATH"
EOF
}
########################
# Configure default HTTP port
# Globals:
# NGINX_CONFDIR
# Arguments:
# $1 - (optional) HTTP Port
# Returns:
# None
#########################
nginx_config_http_port() {
local http_port=${1:-8080}
debug "Configuring default HTTP port..."
# TODO: find an appropriate NGINX parser to avoid 'sed calls'
sed -i -E "s/(listen\s+)[0-9]{1,5};/\1${http_port};/g" ${NGINX_CONFDIR}/nginx.conf
}
########################
# Validate settings in NGINX_* env vars
# Globals:
@@ -112,19 +128,21 @@ nginx_validate() {
local validate_port_args=()
! am_i_root && validate_port_args+=("-unprivileged")
if ! err=$(validate_port "${validate_port_args[@]}" "$NGINX_HTTP_PORT_NUMBER"); then
error "An invalid port was specified in the environment variable NGINX_HTTP_PORT_NUMBER: $err"
exit 1
if [[ -n "${NGINX_HTTP_PORT_NUMBER:-}" ]]; then
if ! err=$(validate_port "${validate_port_args[@]}" "${NGINX_HTTP_PORT_NUMBER:-}"); then
error "An invalid port was specified in the environment variable NGINX_HTTP_PORT_NUMBER: $err"
exit 1
fi
fi
for var in "NGINX_DAEMON_USER" "NGINX_DAEMON_GROUP"; do
if am_i_root; then
if [[ -z "${!var}" ]]; then
if [[ -z "${!var:-}" ]]; then
error "The $var environment variable cannot be empty when running as root"
exit 1
fi
else
if [[ -n "${!var}" ]]; then
if [[ -n "${!var:-}" ]]; then
warn "The $var environment variable will be ignored when running as non-root"
fi
fi
@@ -132,7 +150,7 @@ nginx_validate() {
}
########################
# Ensure NGINX is initialized
# Initialize NGINX
# Globals:
# NGINX_*
# Arguments:
@@ -145,29 +163,28 @@ nginx_initialize() {
# Persisted configuration files from old versions
if [[ -f "$NGINX_VOLUME/conf/nginx.conf" ]]; then
warn "'nginx.conf' was found in a legacy location: ${NGINX_VOLUME}/conf/nginx.conf"
warn " Please use ${NGINX_CONFDIR}/nginx.conf instead"
debug "Moving 'nginx.conf' file to new location..."
cp "$NGINX_VOLUME/conf/nginx.conf" "$NGINX_CONFDIR/nginx.conf"
error "A 'nginx.conf' file was found inside '${NGINX_VOLUME}/conf'. This configuration is not supported anymore. Please mount the configuration file at '${NGINX_CONFDIR}/nginx.conf' instead."
exit 1
fi
if ! is_dir_empty "$NGINX_VOLUME/conf/vhosts"; then
warn "Custom vhosts config files were found in a legacy directory: $NGINX_VOLUME/conf/vhosts"
warn " Please use ${NGINX_CONFDIR}/vhosts instead"
debug "Moving vhosts config files to new location..."
cp -r "$NGINX_VOLUME/conf/vhosts" "$NGINX_CONFDIR"
error "Custom server blocks files were found inside '$NGINX_VOLUME/conf/vhosts'. This configuration is not supported anymore. Please mount your custom server blocks config files at '${NGINX_CONFDIR}/server_blocks' instead."
exit 1
fi
if [[ -e "${NGINX_CONFDIR}/nginx.conf" ]]; then
debug "Custom configuration detected. Using it..."
return
if am_i_root; then
debug "Ensure NGINX daemon user/group exists..."
ensure_user_exists "$NGINX_DAEMON_USER" "$NGINX_DAEMON_GROUP"
if [[ -n "${NGINX_DAEMON_USER:-}" ]]; then
chown -R "${NGINX_DAEMON_USER:-}" "${NGINX_CONFDIR}" "$NGINX_TMPDIR"
fi
else
debug "'nginx.conf' not found. Applying bitnami configuration..."
debug "Ensuring expected directories/files exist..."
for dir in "$NGINX_TMPDIR" "$NGINX_CONFDIR" "${NGINX_CONFDIR}/vhosts"; do
ensure_dir_exists "$dir" "$NGINX_DAEMON_USER"
done
debug "Rendering 'nginx.conf.tpl' template..."
render-template "${NGINX_TEMPLATES_DIR}/nginx.conf.tpl" > "${NGINX_CONFDIR}/nginx.conf"
echo 'fastcgi_param HTTP_PROXY "";' >> "${NGINX_CONFDIR}/fastcgi_params"
# The "user" directive makes sense only if the master process runs with super-user privileges
# TODO: find an appropriate NGINX parser to avoid 'sed calls'
sed -i -E "s/(^user)/# \1/g" ${NGINX_CONFDIR}/nginx.conf
fi
debug "Updating 'nginx.conf' based on user configuration..."
if [[ -n "${NGINX_HTTP_PORT_NUMBER:-}" ]]; then
nginx_config_http_port "${NGINX_HTTP_PORT_NUMBER}"
fi
}

View File

@@ -1,6 +0,0 @@
{
"httpPort": "{{$global.env.NGINX_HTTP_PORT_NUMBER}}",
"httpsPort": "{{$global.env.NGINX_HTTPS_PORT_NUMBER}}",
"systemGroup": "{{$global.env.NGINX_DAEMON_GROUP}}",
"systemUser": "{{$global.env.NGINX_DAEMON_USER}}"
}

View File

@@ -1,64 +0,0 @@
# based on http://brainspl.at/nginx.conf.txt
{{#if NGINX_DAEMON_USER}}{{#if NGINX_DAEMON_GROUP}}
user {{NGINX_DAEMON_USER}} {{NGINX_DAEMON_GROUP}};
{{/if}}{{/if}}
worker_processes auto;
error_log "{{NGINX_LOGDIR}}/error.log";
pid "{{NGINX_TMPDIR}}/nginx.pid";
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
add_header X-Frame-Options SAMEORIGIN;
client_body_temp_path "{{NGINX_TMPDIR}}/client_body" 1 2;
proxy_temp_path "{{NGINX_TMPDIR}}/proxy" 1 2;
fastcgi_temp_path "{{NGINX_TMPDIR}}/fastcgi" 1 2;
scgi_temp_path "{{NGINX_TMPDIR}}/scgi" 1 2;
uwsgi_temp_path "{{NGINX_TMPDIR}}/uwsgi" 1 2;
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log "{{NGINX_LOGDIR}}/access.log";
# no sendfile on OSX
sendfile on;
tcp_nopush on;
tcp_nodelay off;
#keepalive_timeout 0;
keepalive_timeout 65;
gzip on;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_proxied any;
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
include "{{NGINX_CONFDIR}}/vhosts/*.conf";
# HTTP Server
server {
# port to listen on. Can also be set to an IP:PORT
listen {{NGINX_HTTP_PORT_NUMBER}};
location /status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
}

View File

@@ -0,0 +1,76 @@
#!/bin/bash
# shellcheck disable=SC1091
# Load libraries
. /libnginx.sh
. /libfs.sh
# Auxiliar Functions
########################
# Ensure non-root user has write permissions on a set of directories
# Globals:
# NGINX_*
# Arguments:
# None
# Returns:
# None
#########################
nginx_configure_permissions() {
for dir in "/bitnami" "$NGINX_VOLUME" "${NGINX_CONFDIR}/server_blocks" "${NGINX_CONFDIR}/bitnami" "$NGINX_BASEDIR" "$NGINX_LOGDIR" "$NGINX_TMPDIR"; do
ensure_dir_exists "$dir"
done
chmod -R g+rwX "$NGINX_VOLUME" "$NGINX_CONFDIR" "$NGINX_TMPDIR" "$NGINX_LOGDIR"
}
########################
# Unset HTTP_PROXY header to protect vs HTTPPOXY vulnerability
# Ref: https://www.digitalocean.com/community/tutorials/how-to-protect-your-server-against-the-httpoxy-vulnerability
# Globals:
# NGINX_*
# Arguments:
# None
# Returns:
# None
#########################
nginx_patch_httpoxy_vulnerability() {
debug "Unsetting HTTP_PROXY header..."
echo '# Unset the HTTP_PROXY header' >> "${NGINX_CONFDIR}/fastcgi_params"
echo 'fastcgi_param HTTP_PROXY "";' >> "${NGINX_CONFDIR}/fastcgi_params"
}
########################
# Prepare directories for users to mount its static files and certificates
# Globals:
# NGINX_*
# Arguments:
# None
# Returns:
# None
#########################
nginx_prepare_directories() {
# Users can mount their html sites at /app
mv "${NGINX_BASEDIR}/html" /app
ln -sf /app "${NGINX_BASEDIR}/html"
# Users can mount their certificates at /certs
ln -sf /certs "${NGINX_CONFDIR}/bitnami/certs"
# Fix to avoid issues for those using the old structure (vhosts)
warn "Creating a symlink to support mounting custom server_blocks at \"${NGINX_CONFDIR}/vhosts\". It will be deprecated in future versions."
ln -sf "${NGINX_CONFDIR}/server_blocks" "${NGINX_CONFDIR}/vhosts"
# Redirect all logging to stdout/stderr
ln -sf /dev/stdout "$NGINX_LOGDIR/access.log"
ln -sf /dev/stderr "$NGINX_LOGDIR/error.log"
}
# Load NGINX environment variables
eval "$(nginx_env)"
# Ensure non-root user has write permissions on a set of directories
nginx_configure_permissions
# Configure default HTTP port
nginx_config_http_port
# Unset HTTP_PROXY header to protect vs HTTPPOXY vulnerability
nginx_patch_httpoxy_vulnerability
# Prepare directories for users to mount its static files and certificates
nginx_prepare_directories

View File

@@ -1,20 +0,0 @@
#!/bin/bash
# shellcheck disable=SC1091
# Load libraries
. /libnginx.sh
# Load NGINX environment variables
eval "$(nginx_env)"
for dir in "/bitnami" "$NGINX_VOLUME" "$NGINX_CONFDIR" "$NGINX_BASEDIR" "$NGINX_TMPDIR"; do
ensure_dir_exists "$dir"
chmod -R g+rwX "$dir"
done
# Users can mount their html sites at /app
ln -sf "$NGINX_BASEDIR/html" /app
# Redirect all logging to stdout/stderr
ln -sf /dev/stdout "$NGINX_LOGDIR/access.log"
ln -sf /dev/stderr "$NGINX_LOGDIR/error.log"

View File

@@ -15,7 +15,7 @@ eval "$(nginx_env)"
info "** Starting NGINX **"
if am_i_root; then
exec gosu "$NGINX_DAEMON_USER" "$NGINX_BASEDIR/sbin/nginx" -c "$NGINX_CONFDIR/nginx.conf" -g "daemon off;"
exec gosu "${NGINX_DAEMON_USER}" "${NGINX_BASEDIR}/sbin/nginx" -c "${NGINX_CONFDIR}/nginx.conf" -g "daemon off; user ${NGINX_DAEMON_USER} ${NGINX_DAEMON_GROUP}"
else
exec "$NGINX_BASEDIR/sbin/nginx" -c "$NGINX_CONFDIR/nginx.conf" -g "daemon off;"
exec "${NGINX_BASEDIR}/sbin/nginx" -c "${NGINX_CONFDIR}/nginx.conf" -g "daemon off;"
fi

View File

@@ -18,6 +18,5 @@ eval "$(nginx_env)"
nginx_validate
# Ensure NGINX is stopped when this script ends
trap "nginx_stop" EXIT
am_i_root && ensure_user_exists "$NGINX_DAEMON_USER" "$NGINX_DAEMON_GROUP"
# Ensure NGINX is initialized
# Initialize NGINX
nginx_initialize

View File

@@ -2,7 +2,6 @@ FROM bitnami/oraclelinux-extras-base:7-r267
LABEL maintainer "Bitnami <containers@bitnami.com>"
ENV BITNAMI_PKG_CHMOD="-R g+rwX" \
BITNAMI_PKG_EXTRA_DIRS="/bitnami/nginx/conf" \
HOME="/" \
OS_ARCH="x86_64" \
OS_FLAVOUR="ol-7" \
@@ -11,24 +10,19 @@ ENV BITNAMI_PKG_CHMOD="-R g+rwX" \
# Install required system packages and dependencies
RUN install_packages glibc keyutils-libs krb5-libs libcom_err libselinux nss-softokn-freebl openssl-libs pcre zlib
RUN . ./libcomponent.sh && component_unpack "nginx" "1.16.0-0" --checksum de3f2e7f973f2d4a60069edfd3b71d7b106bbb54b347bcf6d2781a71a1b65aca
RUN ln -sf /opt/bitnami/nginx/html /app
RUN ln -sf /dev/stdout /opt/bitnami/nginx/logs/access.log
RUN ln -sf /dev/stderr /opt/bitnami/nginx/logs/error.log
COPY rootfs /
RUN /prepare.sh
RUN /postunpack.sh
ENV BITNAMI_APP_NAME="nginx" \
BITNAMI_IMAGE_VERSION="1.16.0-ol-7-r1" \
NAMI_PREFIX="/.nami" \
NGINX_DAEMON_GROUP="" \
NGINX_DAEMON_USER="" \
NGINX_HTTPS_PORT_NUMBER="443" \
NGINX_HTTP_PORT_NUMBER="8080" \
PATH="/opt/bitnami/nginx/sbin:$PATH"
EXPOSE 8080
EXPOSE 8080 8443
VOLUME [ "/app" "/certs" ]
WORKDIR /app
USER 1001
ENTRYPOINT [ "/entrypoint.sh" ]
CMD [ "/run.sh" ]

View File

@@ -5,3 +5,5 @@ services:
image: 'bitnami/nginx:1.16-ol-7'
ports:
- '80:8080'
environment:
- NGINX_HTTP_PORT_NUMBER=8080

View File

@@ -61,7 +61,7 @@ nginx_start() {
is_nginx_running && return
debug "Starting NGIX..."
if am_i_root; then
gosu "$NGINX_DAEMON_USER" "${NGINX_BASEDIR}/sbin/nginx" -c "${NGINX_CONFDIR}/nginx.conf"
gosu "${NGINX_DAEMON_USER}" "${NGINX_BASEDIR}/sbin/nginx" -c "${NGINX_CONFDIR}/nginx.conf"
else
"${NGINX_BASEDIR}/sbin/nginx" -c "${NGINX_CONFDIR}/nginx.conf"
fi
@@ -98,6 +98,22 @@ export PATH="${NGINX_BASEDIR}/sbin:$PATH"
EOF
}
########################
# Configure default HTTP port
# Globals:
# NGINX_CONFDIR
# Arguments:
# $1 - (optional) HTTP Port
# Returns:
# None
#########################
nginx_config_http_port() {
local http_port=${1:-8080}
debug "Configuring default HTTP port..."
# TODO: find an appropriate NGINX parser to avoid 'sed calls'
sed -i -E "s/(listen\s+)[0-9]{1,5};/\1${http_port};/g" ${NGINX_CONFDIR}/nginx.conf
}
########################
# Validate settings in NGINX_* env vars
# Globals:
@@ -112,19 +128,21 @@ nginx_validate() {
local validate_port_args=()
! am_i_root && validate_port_args+=("-unprivileged")
if ! err=$(validate_port "${validate_port_args[@]}" "$NGINX_HTTP_PORT_NUMBER"); then
error "An invalid port was specified in the environment variable NGINX_HTTP_PORT_NUMBER: $err"
exit 1
if [[ -n "${NGINX_HTTP_PORT_NUMBER:-}" ]]; then
if ! err=$(validate_port "${validate_port_args[@]}" "${NGINX_HTTP_PORT_NUMBER:-}"); then
error "An invalid port was specified in the environment variable NGINX_HTTP_PORT_NUMBER: $err"
exit 1
fi
fi
for var in "NGINX_DAEMON_USER" "NGINX_DAEMON_GROUP"; do
if am_i_root; then
if [[ -z "${!var}" ]]; then
if [[ -z "${!var:-}" ]]; then
error "The $var environment variable cannot be empty when running as root"
exit 1
fi
else
if [[ -n "${!var}" ]]; then
if [[ -n "${!var:-}" ]]; then
warn "The $var environment variable will be ignored when running as non-root"
fi
fi
@@ -132,7 +150,7 @@ nginx_validate() {
}
########################
# Ensure NGINX is initialized
# Initialize NGINX
# Globals:
# NGINX_*
# Arguments:
@@ -145,29 +163,28 @@ nginx_initialize() {
# Persisted configuration files from old versions
if [[ -f "$NGINX_VOLUME/conf/nginx.conf" ]]; then
warn "'nginx.conf' was found in a legacy location: ${NGINX_VOLUME}/conf/nginx.conf"
warn " Please use ${NGINX_CONFDIR}/nginx.conf instead"
debug "Moving 'nginx.conf' file to new location..."
cp "$NGINX_VOLUME/conf/nginx.conf" "$NGINX_CONFDIR/nginx.conf"
error "A 'nginx.conf' file was found inside '${NGINX_VOLUME}/conf'. This configuration is not supported anymore. Please mount the configuration file at '${NGINX_CONFDIR}/nginx.conf' instead."
exit 1
fi
if ! is_dir_empty "$NGINX_VOLUME/conf/vhosts"; then
warn "Custom vhosts config files were found in a legacy directory: $NGINX_VOLUME/conf/vhosts"
warn " Please use ${NGINX_CONFDIR}/vhosts instead"
debug "Moving vhosts config files to new location..."
cp -r "$NGINX_VOLUME/conf/vhosts" "$NGINX_CONFDIR"
error "Custom server blocks files were found inside '$NGINX_VOLUME/conf/vhosts'. This configuration is not supported anymore. Please mount your custom server blocks config files at '${NGINX_CONFDIR}/server_blocks' instead."
exit 1
fi
if [[ -e "${NGINX_CONFDIR}/nginx.conf" ]]; then
debug "Custom configuration detected. Using it..."
return
if am_i_root; then
debug "Ensure NGINX daemon user/group exists..."
ensure_user_exists "$NGINX_DAEMON_USER" "$NGINX_DAEMON_GROUP"
if [[ -n "${NGINX_DAEMON_USER:-}" ]]; then
chown -R "${NGINX_DAEMON_USER:-}" "${NGINX_CONFDIR}" "$NGINX_TMPDIR"
fi
else
debug "'nginx.conf' not found. Applying bitnami configuration..."
debug "Ensuring expected directories/files exist..."
for dir in "$NGINX_TMPDIR" "$NGINX_CONFDIR" "${NGINX_CONFDIR}/vhosts"; do
ensure_dir_exists "$dir" "$NGINX_DAEMON_USER"
done
debug "Rendering 'nginx.conf.tpl' template..."
render-template "${NGINX_TEMPLATES_DIR}/nginx.conf.tpl" > "${NGINX_CONFDIR}/nginx.conf"
echo 'fastcgi_param HTTP_PROXY "";' >> "${NGINX_CONFDIR}/fastcgi_params"
# The "user" directive makes sense only if the master process runs with super-user privileges
# TODO: find an appropriate NGINX parser to avoid 'sed calls'
sed -i -E "s/(^user)/# \1/g" ${NGINX_CONFDIR}/nginx.conf
fi
debug "Updating 'nginx.conf' based on user configuration..."
if [[ -n "${NGINX_HTTP_PORT_NUMBER:-}" ]]; then
nginx_config_http_port "${NGINX_HTTP_PORT_NUMBER}"
fi
}

View File

@@ -1,6 +0,0 @@
{
"httpPort": "{{$global.env.NGINX_HTTP_PORT_NUMBER}}",
"httpsPort": "{{$global.env.NGINX_HTTPS_PORT_NUMBER}}",
"systemGroup": "{{$global.env.NGINX_DAEMON_GROUP}}",
"systemUser": "{{$global.env.NGINX_DAEMON_USER}}"
}

View File

@@ -1,64 +0,0 @@
# based on http://brainspl.at/nginx.conf.txt
{{#if NGINX_DAEMON_USER}}{{#if NGINX_DAEMON_GROUP}}
user {{NGINX_DAEMON_USER}} {{NGINX_DAEMON_GROUP}};
{{/if}}{{/if}}
worker_processes auto;
error_log "{{NGINX_LOGDIR}}/error.log";
pid "{{NGINX_TMPDIR}}/nginx.pid";
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
add_header X-Frame-Options SAMEORIGIN;
client_body_temp_path "{{NGINX_TMPDIR}}/client_body" 1 2;
proxy_temp_path "{{NGINX_TMPDIR}}/proxy" 1 2;
fastcgi_temp_path "{{NGINX_TMPDIR}}/fastcgi" 1 2;
scgi_temp_path "{{NGINX_TMPDIR}}/scgi" 1 2;
uwsgi_temp_path "{{NGINX_TMPDIR}}/uwsgi" 1 2;
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log "{{NGINX_LOGDIR}}/access.log";
# no sendfile on OSX
sendfile on;
tcp_nopush on;
tcp_nodelay off;
#keepalive_timeout 0;
keepalive_timeout 65;
gzip on;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_proxied any;
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
include "{{NGINX_CONFDIR}}/vhosts/*.conf";
# HTTP Server
server {
# port to listen on. Can also be set to an IP:PORT
listen {{NGINX_HTTP_PORT_NUMBER}};
location /status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
}

View File

@@ -0,0 +1,76 @@
#!/bin/bash
# shellcheck disable=SC1091
# Load libraries
. /libnginx.sh
. /libfs.sh
# Auxiliar Functions
########################
# Ensure non-root user has write permissions on a set of directories
# Globals:
# NGINX_*
# Arguments:
# None
# Returns:
# None
#########################
nginx_configure_permissions() {
for dir in "/bitnami" "$NGINX_VOLUME" "${NGINX_CONFDIR}/server_blocks" "${NGINX_CONFDIR}/bitnami" "$NGINX_BASEDIR" "$NGINX_LOGDIR" "$NGINX_TMPDIR"; do
ensure_dir_exists "$dir"
done
chmod -R g+rwX "$NGINX_VOLUME" "$NGINX_CONFDIR" "$NGINX_TMPDIR" "$NGINX_LOGDIR"
}
########################
# Unset HTTP_PROXY header to protect vs HTTPPOXY vulnerability
# Ref: https://www.digitalocean.com/community/tutorials/how-to-protect-your-server-against-the-httpoxy-vulnerability
# Globals:
# NGINX_*
# Arguments:
# None
# Returns:
# None
#########################
nginx_patch_httpoxy_vulnerability() {
debug "Unsetting HTTP_PROXY header..."
echo '# Unset the HTTP_PROXY header' >> "${NGINX_CONFDIR}/fastcgi_params"
echo 'fastcgi_param HTTP_PROXY "";' >> "${NGINX_CONFDIR}/fastcgi_params"
}
########################
# Prepare directories for users to mount its static files and certificates
# Globals:
# NGINX_*
# Arguments:
# None
# Returns:
# None
#########################
nginx_prepare_directories() {
# Users can mount their html sites at /app
mv "${NGINX_BASEDIR}/html" /app
ln -sf /app "${NGINX_BASEDIR}/html"
# Users can mount their certificates at /certs
ln -sf /certs "${NGINX_CONFDIR}/bitnami/certs"
# Fix to avoid issues for those using the old structure (vhosts)
warn "Creating a symlink to support mounting custom server_blocks at \"${NGINX_CONFDIR}/vhosts\". It will be deprecated in future versions."
ln -sf "${NGINX_CONFDIR}/server_blocks" "${NGINX_CONFDIR}/vhosts"
# Redirect all logging to stdout/stderr
ln -sf /dev/stdout "$NGINX_LOGDIR/access.log"
ln -sf /dev/stderr "$NGINX_LOGDIR/error.log"
}
# Load NGINX environment variables
eval "$(nginx_env)"
# Ensure non-root user has write permissions on a set of directories
nginx_configure_permissions
# Configure default HTTP port
nginx_config_http_port
# Unset HTTP_PROXY header to protect vs HTTPPOXY vulnerability
nginx_patch_httpoxy_vulnerability
# Prepare directories for users to mount its static files and certificates
nginx_prepare_directories

View File

@@ -1,20 +0,0 @@
#!/bin/bash
# shellcheck disable=SC1091
# Load libraries
. /libnginx.sh
# Load NGINX environment variables
eval "$(nginx_env)"
for dir in "/bitnami" "$NGINX_VOLUME" "$NGINX_CONFDIR" "$NGINX_BASEDIR" "$NGINX_TMPDIR"; do
ensure_dir_exists "$dir"
chmod -R g+rwX "$dir"
done
# Users can mount their html sites at /app
ln -sf "$NGINX_BASEDIR/html" /app
# Redirect all logging to stdout/stderr
ln -sf /dev/stdout "$NGINX_LOGDIR/access.log"
ln -sf /dev/stderr "$NGINX_LOGDIR/error.log"

View File

@@ -15,7 +15,7 @@ eval "$(nginx_env)"
info "** Starting NGINX **"
if am_i_root; then
exec gosu "$NGINX_DAEMON_USER" "$NGINX_BASEDIR/sbin/nginx" -c "$NGINX_CONFDIR/nginx.conf" -g "daemon off;"
exec gosu "${NGINX_DAEMON_USER}" "${NGINX_BASEDIR}/sbin/nginx" -c "${NGINX_CONFDIR}/nginx.conf" -g "daemon off; user ${NGINX_DAEMON_USER} ${NGINX_DAEMON_GROUP}"
else
exec "$NGINX_BASEDIR/sbin/nginx" -c "$NGINX_CONFDIR/nginx.conf" -g "daemon off;"
exec "${NGINX_BASEDIR}/sbin/nginx" -c "${NGINX_CONFDIR}/nginx.conf" -g "daemon off;"
fi

View File

@@ -18,6 +18,5 @@ eval "$(nginx_env)"
nginx_validate
# Ensure NGINX is stopped when this script ends
trap "nginx_stop" EXIT
am_i_root && ensure_user_exists "$NGINX_DAEMON_USER" "$NGINX_DAEMON_GROUP"
# Ensure NGINX is initialized
# Initialize NGINX
nginx_initialize

View File

@@ -75,7 +75,7 @@ $ docker build -t bitnami/nginx:latest https://github.com/bitnami/bitnami-docker
# Hosting a static website
This NGINX Open Source image exposes a volume at `/app`. Content mounted here is served by the default catch-all virtual host.
This NGINX Open Source image exposes a volume at `/app`. Content mounted here is served by the default catch-all server block.
```bash
$ docker run -v /path/to/app:/app bitnami/nginx:latest
@@ -120,13 +120,13 @@ Access your web server in the browser by navigating to [http://localhost:9000](h
# Configuration
## Adding custom virtual hosts
## Adding custom server blocks
The default `nginx.conf` includes virtual hosts placed in `/bitnami/nginx/conf/vhosts/`. You can mount a `my_vhost.conf` file containing your custom virtual hosts at this location.
The default `nginx.conf` includes server blocks placed in `/opt/bitnami/nginx/conf/server_blocks/`. You can mount a `my_server_block.conf` file containing your custom server block at this location.
For example, in order add a vhost for `www.example.com`:
For example, in order add a server block for `www.example.com`:
# Step 1: Write your `my_vhost.conf` file with the following content.
# Step 1: Write your `my_server_block.conf` file with the following content.
```nginx
server {
@@ -141,7 +141,7 @@ server {
```bash
$ docker run --name nginx \
-v /path/to/my_vhost.conf:/opt/bitnami/nginx/conf/vhosts/my_vhost.conf:ro \
-v /path/to/my_server_block.conf:/opt/bitnami/nginx/conf/server_blocks/my_server_block.conf:ro \
bitnami/nginx:latest
```
@@ -156,7 +156,7 @@ services:
ports:
- '80:8080'
volumes:
- /path/to/my_vhost.conf:/opt/bitnami/nginx/conf/vhosts/my_vhost.conf:ro
- /path/to/my_server_block.conf:/opt/bitnami/nginx/conf/server_blocks/my_server_block.conf:ro
```
## Using custom SSL certificates
@@ -168,14 +168,15 @@ services:
In your local computer, create a folder called `certs` and put your certificates files. Make sure you rename both files to `server.crt` and `server.key` respectively:
```bash
$ mkdir /path/to/nginx-persistence/nginx/conf/bitnami/certs -p
$ cp /path/to/certfile.crt /path/to/nginx-persistence/nginx/conf/bitnami/certs/server.crt
$ cp /path/to/keyfile.key /path/to/nginx-persistence/nginx/conf/bitnami/certs/server.key
$ mkdir -p /path/to/nginx-persistence/certs
$ cp /path/to/certfile.crt /path/to/nginx-persistence/certs/server.crt
$ cp /path/to/keyfile.key /path/to/nginx-persistence/certs/server.key
```
### Step 2: Provide a custom Virtual Host for SSL connections
### Step 2: Provide a custom Server Block for SSL connections
Write your `my_server_block.conf` file with the SSL configuration and the relative path to the certificates:
Write your `my_vhost.conf` file with the SSL configuration and the relative path to the certificates.
```nginx
server {
listen 8443 ssl;
@@ -202,8 +203,8 @@ Run the NGINX Open Source image, mounting the certificates directory from your h
```bash
$ docker run --name nginx \
-v /path/to/my_vhost.conf:/opt/bitnami/nginx/conf/vhosts/my_vhost.conf:ro \
-v /path/to/nginx-persistence/nginx/conf/bitnami/certs:/bitnami/nginx/conf/bitnami/certs \
-v /path/to/my_server_block.conf:/opt/bitnami/nginx/conf/server_blocks/my_server_block.conf:ro \
-v /path/to/nginx-persistence/certs:/certs \
bitnami/nginx:latest
```
@@ -219,7 +220,8 @@ services:
- '80:8080'
- '443:8443'
volumes:
- /path/to/nginx-persistence/nginx/conf/bitnami/certs:/bitnami/nginx/conf/bitnami/certs
- /path/to/nginx-persistence/certs:/certs
- /path/to/my_server_block.conf:/opt/bitnami/nginx/conf/server_blocks/my_server_block.conf:ro
```
## Full configuration
@@ -229,7 +231,7 @@ The image looks for configurations in `/opt/bitnami/nginx/conf/nginx.conf`. You
```bash
$ docker run --name nginx \
-v /path/to/your_nginx.conf:/opt/bitnami/nginx/conf/nginx.conf \
-v /path/to/your_nginx.conf:/opt/bitnami/nginx/conf/nginx.conf:ro \
bitnami/nginx:latest
```
@@ -244,12 +246,12 @@ services:
ports:
- '80:8080'
volumes:
- /path/to/your_nginx.conf:/opt/bitnami/nginx/conf/nginx.conf
- /path/to/your_nginx.conf:/opt/bitnami/nginx/conf/nginx.conf:ro
```
# Reverse proxy to other containers
NGINX can be used to reverse proxy to other containers using Docker's linking system. This is particularly useful if you want to serve dynamic content through an NGINX frontend. To do so, [add a virtual host](#adding-custom-virtual-hosts) like the following in the `/opt/bitnami/nginx/conf/vhosts/` folder:
NGINX can be used to reverse proxy to other containers using Docker's linking system. This is particularly useful if you want to serve dynamic content through an NGINX frontend. To do so, [add a server block](#adding-custom-server-blocks) like the following in the `/opt/bitnami/nginx/conf/server_blocks/` folder:
```
server {
@@ -289,6 +291,126 @@ $ docker-compose logs nginx
You can configure the containers [logging driver](https://docs.docker.com/engine/admin/logging/overview/) using the `--log-driver` option if you wish to consume the container logs differently. In the default configuration docker uses the `json-file` driver.
# Understand the structure of this image
The Bitnami NGINX Docker image is built using a Dockerfile with the structure below:
```Dockerfile
FROM bitnami/minideb-extras-base
...
# Install required system packages and dependencies
RUN install_packages xxx yyy zzz
RUN . ./libcomponent.sh && component_unpack "nginx" "a.b.c-0"
...
COPY rootfs /
RUN /prepare.sh
...
ENV BITNAMI_APP_NAME="nginx" ...
EXPOSE 8080 8443
VOLUME /app
VOLUME /certs
WORKDIR /app
USER 1001
...
ENTRYPOINT [ "/entrypoint.sh" ]
CMD [ "/run.sh" ]
```
We can identify several sections within the Dockerfile:
- Components installation.
- Components static configuration.
- Environment variables.
- Ports to be exposed.
- Working directory and user.
- Note that once the user is set to 1001, unprivileged commands cannot be executed anymore.
- Entrypoint and command.
- Take into account these actions are not executed until the container is started.
# Customizing the Bitnami NGINX Docker image
The Bitnami NGINX Docker image is designed to be extended so it can be used as the base image for your custom web applications.
> Note: It's recommended to read the [previous section](#understand-this-image-structure) to understand the Dockerfile structure, before extending this image.
## Extending the Bitnami NGINX Docker image
Before extending this image, please note there are certain configuration settings you can modify using the original image:
- Settings that can be adapted using environment variables. For instance, you can change the port used by NGINX for HTTP setting the environment variable `NGINX_HTTP_PORT_NUMBER`.
- [Adding custom server blocks](#adding-custom-server-blocks).
- [Replacing the 'nginx.conf' file](#full-configuration).
- [Using custom SSL certificates](#using-custom-ssl-certificates).
If your desired customizations cannot be covered using the methods mentioned above, extend the image. To do so, create your own image using a Dockerfile with the format below:
```Dockerfile
FROM bitnami/nginx
## Put your customizations below
...
```
In this example, we provide an extended with the following modifications:
- Install `vim` editor.
- Modify the NGINX configuration file.
- Modify the ports used by NGINX.
- Change the user that runs the container.
```Dockerfile
FROM bitnami/nginx
LABEL maintainer "Bitnami <containers@bitnami.com>"
## Install 'vim'
USER 0 # Required to perform privileged actions
RUN install_packages vim
USER 1001 # Revert to the original non-root user
## Modify 'worker_connections' on NGINX config file to '512'
RUN sed -i -r "s#(\s+worker_connections\s+)[0-9]+;#\1512;#" /opt/bitnami/nginx/conf/nginx.conf
## Modify the ports used by NGINX by default
ENV NGINX_HTTP_PORT_NUMBER=8181 # It is also possible to change this environment variable at runtime
EXPOSE 8181 8443
## Modify the default container user
USER 1002
```
Based on the extended image, you can use a Docker Compose like the one below to add other features:
- Adding custom server block
- Adding custom certificates
- Cloning your web app and serve it trough NGINX
```yaml
version: '2'
services:
nginx:
build: .
ports:
- '80:8181'
- '443:8443'
depends_on:
- cloner
volumes:
- ./config/my_server_block.conf:/opt/bitnami/nginx/conf/conf.d/server_blocks/my_server_block.conf:ro
- ./certs:/certs
- data:/app
cloner:
image: 'bitnami/git:latest'
command:
- clone
- https://github.com/cloudacademy/static-website-example
- /app
volumes:
- data:/app
volumes:
data:
driver: local
```
# Maintenance
## Upgrade this image

View File

@@ -5,3 +5,5 @@ services:
image: 'bitnami/nginx:1.16'
ports:
- '80:8080'
environment:
- NGINX_HTTP_PORT_NUMBER=8080