12 changed files with 280 additions and 15 deletions
@ -0,0 +1,33 @@ |
|||||||
|
FROM postgres:9.4-alpine |
||||||
|
|
||||||
|
ENV DEFAULT_TIMEZONE UTC |
||||||
|
|
||||||
|
# Install some packages to use WAL |
||||||
|
RUN echo "azure<5.0.0" > pip-constraints.txt |
||||||
|
RUN apk add --no-cache \ |
||||||
|
build-base \ |
||||||
|
curl \ |
||||||
|
libc6-compat \ |
||||||
|
libffi-dev \ |
||||||
|
linux-headers \ |
||||||
|
python-dev \ |
||||||
|
py-pip \ |
||||||
|
py-cryptography \ |
||||||
|
pv \ |
||||||
|
libressl-dev \ |
||||||
|
&& pip install --upgrade pip \ |
||||||
|
&& pip --no-cache-dir install -c pip-constraints.txt 'wal-e<1.0.0' envdir \ |
||||||
|
&& rm -rf /var/cache/apk/* /tmp/* /var/tmp/* |
||||||
|
|
||||||
|
# Add wale script |
||||||
|
COPY setup-wale.sh /docker-entrypoint-initdb.d/ |
||||||
|
|
||||||
|
#Healthcheck to make sure container is ready |
||||||
|
HEALTHCHECK CMD pg_isready -U $POSTGRES_USER -d $POSTGRES_DB || exit 1 |
||||||
|
|
||||||
|
# Add and configure entrypoint and command |
||||||
|
COPY entrypoint.sh / |
||||||
|
ENTRYPOINT ["/entrypoint.sh"] |
||||||
|
CMD ["postgres"] |
||||||
|
|
||||||
|
VOLUME ["/var/run/postgresql", "/usr/share/postgresql/", "/var/lib/postgresql/data", "/tmp", "/etc/wal-e.d/env"] |
||||||
@ -0,0 +1,62 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
# if wal-e backup is not enabled, use minimal wal-e logging to reduce disk space |
||||||
|
export WAL_LEVEL=${WAL_LEVEL:-minimal} |
||||||
|
export ARCHIVE_MODE=${ARCHIVE_MODE:-off} |
||||||
|
export ARCHIVE_TIMEOUT=${ARCHIVE_TIMEOUT:-60} |
||||||
|
|
||||||
|
function update_conf () { |
||||||
|
wal=$1 |
||||||
|
# PGDATA is defined in upstream postgres dockerfile |
||||||
|
config_file=$PGDATA/postgresql.conf |
||||||
|
|
||||||
|
# Check if configuration file exists. If not, it probably means that database is not initialized yet |
||||||
|
if [ ! -f $config_file ]; then |
||||||
|
return |
||||||
|
fi |
||||||
|
# Reinitialize config |
||||||
|
sed -i "s/log_timezone =.*$//g" $PGDATA/postgresql.conf |
||||||
|
sed -i "s/timezone =.*$//g" $PGDATA/postgresql.conf |
||||||
|
sed -i "s/wal_level =.*$//g" $config_file |
||||||
|
sed -i "s/archive_mode =.*$//g" $config_file |
||||||
|
sed -i "s/archive_timeout =.*$//g" $config_file |
||||||
|
sed -i "s/archive_command =.*$//g" $config_file |
||||||
|
|
||||||
|
# Configure wal-e |
||||||
|
if [ "$wal" = true ] ; then |
||||||
|
/docker-entrypoint-initdb.d/setup-wale.sh |
||||||
|
fi |
||||||
|
echo "log_timezone = $DEFAULT_TIMEZONE" >> $config_file |
||||||
|
echo "timezone = $DEFAULT_TIMEZONE" >> $config_file |
||||||
|
} |
||||||
|
|
||||||
|
if [ "${1:0:1}" = '-' ]; then |
||||||
|
set -- postgres "$@" |
||||||
|
fi |
||||||
|
|
||||||
|
if [ "$1" = 'postgres' ]; then |
||||||
|
# Check wal-e variables |
||||||
|
wal_enable=true |
||||||
|
VARS=(AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY WALE_S3_PREFIX AWS_REGION) |
||||||
|
for v in ${VARS[@]}; do |
||||||
|
if [ "${!v}" = "" ]; then |
||||||
|
echo "$v is required for Wal-E but not set. Skipping Wal-E setup." |
||||||
|
wal_enable=false |
||||||
|
fi |
||||||
|
done |
||||||
|
|
||||||
|
# Setup wal-e env variables |
||||||
|
if [ "$wal_enable" = true ] ; then |
||||||
|
for v in ${VARS[@]}; do |
||||||
|
export $v="${!v}" |
||||||
|
done |
||||||
|
WAL_LEVEL=archive |
||||||
|
ARCHIVE_MODE=on |
||||||
|
fi |
||||||
|
|
||||||
|
# Update postgresql configuration |
||||||
|
update_conf $wal_enable |
||||||
|
|
||||||
|
# Run the postgresql entrypoint |
||||||
|
docker-entrypoint.sh postgres |
||||||
|
fi |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
# wal-e specific configuration |
||||||
|
echo "wal_level = $WAL_LEVEL" >> $PGDATA/postgresql.conf |
||||||
|
echo "archive_mode = $ARCHIVE_MODE" >> $PGDATA/postgresql.conf |
||||||
|
echo "archive_command = '/usr/bin/wal-e wal-push %p'" >> $PGDATA/postgresql.conf |
||||||
|
echo "archive_timeout = $ARCHIVE_TIMEOUT" >> $PGDATA/postgresql.conf |
||||||
@ -0,0 +1,19 @@ |
|||||||
|
FROM nginx:mainline-alpine |
||||||
|
|
||||||
|
# Remove default configuration and add our custom Nginx configuration files |
||||||
|
RUN rm /etc/nginx/conf.d/default.conf \ |
||||||
|
&& apk add --no-cache curl |
||||||
|
|
||||||
|
COPY ["./mattermost", "./mattermost-ssl", "/etc/nginx/sites-available/"] |
||||||
|
COPY ./security.conf /etc/nginx/conf.d/ |
||||||
|
|
||||||
|
# Add and setup entrypoint |
||||||
|
COPY entrypoint.sh / |
||||||
|
|
||||||
|
#Healthcheck to make sure container is ready |
||||||
|
HEALTHCHECK CMD curl --fail http://localhost:80 || exit 1 |
||||||
|
|
||||||
|
ENTRYPOINT ["/entrypoint.sh"] |
||||||
|
|
||||||
|
VOLUME ["/var/run", "/etc/nginx/conf.d/", "/var/cache/nginx/"] |
||||||
|
|
||||||
@ -0,0 +1,24 @@ |
|||||||
|
#!/bin/sh |
||||||
|
|
||||||
|
# Define default value for app container hostname and port |
||||||
|
APP_HOST=${APP_HOST:-app} |
||||||
|
APP_PORT_NUMBER=${APP_PORT_NUMBER:-8000} |
||||||
|
|
||||||
|
# Check if SSL should be enabled (if certificates exists) |
||||||
|
if [ -f "/cert/cert.pem" -a -f "/cert/key-no-password.pem" ]; then |
||||||
|
echo "found certificate and key, linking ssl config" |
||||||
|
ssl="-ssl" |
||||||
|
else |
||||||
|
echo "linking plain config" |
||||||
|
fi |
||||||
|
# Ensure that the configuration file is not present before linking. |
||||||
|
test -w /etc/nginx/conf.d/mattermost.conf && rm /etc/nginx/conf.d/mattermost.conf |
||||||
|
# Linking Nginx configuration file |
||||||
|
ln -s -f /etc/nginx/sites-available/mattermost$ssl /etc/nginx/conf.d/mattermost.conf |
||||||
|
|
||||||
|
# Setup app host and port on configuration file |
||||||
|
sed -i "s/{%APP_HOST%}/${APP_HOST}/g" /etc/nginx/conf.d/mattermost.conf |
||||||
|
sed -i "s/{%APP_PORT%}/${APP_PORT_NUMBER}/g" /etc/nginx/conf.d/mattermost.conf |
||||||
|
|
||||||
|
# Run Nginx |
||||||
|
exec nginx -g 'daemon off;' |
||||||
@ -0,0 +1,39 @@ |
|||||||
|
map $http_x_forwarded_proto $proxy_x_forwarded_proto { |
||||||
|
default $http_x_forwarded_proto; |
||||||
|
'' $scheme; |
||||||
|
} |
||||||
|
|
||||||
|
server { |
||||||
|
listen 80; |
||||||
|
|
||||||
|
location ~ /api/v[0-9]+/(users/)?websocket$ { |
||||||
|
proxy_set_header Upgrade $http_upgrade; |
||||||
|
proxy_set_header Connection "upgrade"; |
||||||
|
client_max_body_size 50M; |
||||||
|
proxy_set_header Host $http_host; |
||||||
|
proxy_set_header X-Real-IP $remote_addr; |
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
||||||
|
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; |
||||||
|
proxy_set_header X-Frame-Options SAMEORIGIN; |
||||||
|
proxy_buffers 256 16k; |
||||||
|
proxy_buffer_size 16k; |
||||||
|
proxy_read_timeout 600s; |
||||||
|
proxy_pass http://{%APP_HOST%}:{%APP_PORT%}; |
||||||
|
} |
||||||
|
|
||||||
|
location / { |
||||||
|
gzip on; |
||||||
|
|
||||||
|
client_max_body_size 50M; |
||||||
|
proxy_set_header Connection ""; |
||||||
|
proxy_set_header Host $http_host; |
||||||
|
proxy_set_header X-Real-IP $remote_addr; |
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
||||||
|
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; |
||||||
|
proxy_set_header X-Frame-Options SAMEORIGIN; |
||||||
|
proxy_buffers 256 16k; |
||||||
|
proxy_buffer_size 16k; |
||||||
|
proxy_read_timeout 600s; |
||||||
|
proxy_pass http://{%APP_HOST%}:{%APP_PORT%}; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,57 @@ |
|||||||
|
server { |
||||||
|
listen 80 default_server; |
||||||
|
server_name _; |
||||||
|
return 301 https://$host$request_uri; |
||||||
|
} |
||||||
|
|
||||||
|
map $http_x_forwarded_proto $proxy_x_forwarded_proto { |
||||||
|
default $http_x_forwarded_proto; |
||||||
|
'' $scheme; |
||||||
|
} |
||||||
|
|
||||||
|
server { |
||||||
|
listen 443 ssl http2; |
||||||
|
|
||||||
|
ssl_certificate /cert/cert.pem; |
||||||
|
ssl_certificate_key /cert/key-no-password.pem; |
||||||
|
ssl_session_timeout 5m; |
||||||
|
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; |
||||||
|
ssl_ciphers HIGH:MEDIUM:!SSLv2:!PSK:!SRP:!ADH:!AECDH; |
||||||
|
ssl_prefer_server_ciphers on; |
||||||
|
|
||||||
|
location ~ /api/v[0-9]+/(users/)?websocket$ { |
||||||
|
proxy_set_header Upgrade $http_upgrade; |
||||||
|
proxy_set_header X-Forwarded-Ssl on; |
||||||
|
proxy_set_header Connection "upgrade"; |
||||||
|
|
||||||
|
client_max_body_size 50M; |
||||||
|
proxy_set_header Host $http_host; |
||||||
|
proxy_set_header X-Real-IP $remote_addr; |
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
||||||
|
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; |
||||||
|
proxy_set_header X-Frame-Options SAMEORIGIN; |
||||||
|
proxy_buffers 256 16k; |
||||||
|
proxy_buffer_size 16k; |
||||||
|
proxy_read_timeout 600s; |
||||||
|
proxy_pass http://{%APP_HOST%}:{%APP_PORT%}; |
||||||
|
} |
||||||
|
|
||||||
|
location / { |
||||||
|
gzip on; |
||||||
|
proxy_set_header X-Forwarded-Ssl on; |
||||||
|
|
||||||
|
client_max_body_size 50M; |
||||||
|
proxy_set_header Connection ""; |
||||||
|
proxy_set_header Host $http_host; |
||||||
|
proxy_set_header X-Real-IP $remote_addr; |
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
||||||
|
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; |
||||||
|
proxy_set_header X-Frame-Options SAMEORIGIN; |
||||||
|
proxy_buffers 256 16k; |
||||||
|
proxy_buffer_size 16k; |
||||||
|
proxy_read_timeout 600s; |
||||||
|
proxy_pass http://{%APP_HOST%}:{%APP_PORT%}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
# See https://docs.mattermost.com/install/install-ubuntu-1604.html#configuring-nginx-with-ssl-and-http-2 for the SSL configuration |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
# don't send the nginx version number in error pages and Server header |
||||||
|
server_tokens off; |
||||||
|
|
||||||
|
# config to don't allow the browser to render the page inside an frame or iframe |
||||||
|
# and avoid clickjacking http://en.wikipedia.org/wiki/Clickjacking |
||||||
|
# if you need to allow [i]frames, you can use SAMEORIGIN or even set an uri with ALLOW-FROM uri |
||||||
|
# https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options |
||||||
|
add_header X-Frame-Options SAMEORIGIN; |
||||||
|
|
||||||
|
# when serving user-supplied content, include a X-Content-Type-Options: nosniff header along with the Content-Type: header, |
||||||
|
# to disable content-type sniffing on some browsers. |
||||||
|
# https://www.owasp.org/index.php/List_of_useful_HTTP_headers |
||||||
|
# currently supported in IE > 8 http://blogs.msdn.com/b/ie/archive/2008/09/02/ie8-security-part-vi-beta-2-update.aspx |
||||||
|
# http://msdn.microsoft.com/en-us/library/ie/gg622941(v=vs.85).aspx |
||||||
|
# 'soon' on Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=471020 |
||||||
|
add_header X-Content-Type-Options nosniff; |
||||||
|
|
||||||
|
# This header enables the Cross-site scripting (XSS) filter built into most recent web browsers. |
||||||
|
# It's usually enabled by default anyway, so the role of this header is to re-enable the filter for |
||||||
|
# this particular website if it was disabled by the user. |
||||||
|
# https://www.owasp.org/index.php/List_of_useful_HTTP_headers |
||||||
|
add_header X-XSS-Protection "1; mode=block"; |
||||||
Loading…
Reference in new issue