Compare commits

..

No commits in common. "master" and "3.2.0" have entirely different histories.

33 changed files with 445 additions and 1740 deletions

View File

@ -1,14 +0,0 @@
version: 2.1
jobs:
none:
docker:
- image: alpine:3.10
steps:
- run:
command: echo "Skipping. not implemented"
workflows:
version: 2
mainbuild:
jobs:
- none

8
.gitignore vendored
View File

@ -1,8 +0,0 @@
# Elastic Beanstalk Files
.elasticbeanstalk/*
!.elasticbeanstalk/*.cfg.yml
!.elasticbeanstalk/*.global.yml
# Generated data
volumes

View File

@ -1,3 +1,5 @@
sudo: required
services:
- docker
@ -7,16 +9,14 @@ before_install:
install:
- eval $BUILD
- sleep 30
- sleep 10
env:
- BUILD="mkdir -p ./volumes/app/mattermost/{data,logs,config,plugins} && docker-compose up -d"
- BUILD="docker run -d --name db -e POSTGRES_USER=mmuser -e POSTGRES_PASSWORD=mmuser_password -e POSTGRES_DB=mattermost mattermost-prod-db && sleep 5 && docker run -d --link db -p 80:8000 --name app -e MM_USERNAME=mmuser -e MM_PASSWORD=mmuser_password mattermost-prod-app"
- BUILD="docker-compose up -d"
- BUILD="docker run -d --name db mattermost-prod-db && sleep 5 && docker run -d --link db -p 80:80 --name app mattermost-prod-app"
script:
- curl -sSf http://localhost > /dev/null
- docker ps -a | grep app | grep healthy
- docker ps -a | grep db | grep healthy
after_failure:
- timeout 3s docker-compose logs app db web

View File

@ -1,5 +0,0 @@
# Code Contribution Guidelines
Thank you for your interest in contributing! Please see the [Mattermost Contribution Guide](https://developers.mattermost.com/contribute/getting-started/) which describes the process for making code contributions across Mattermost projects and [join our "Contributors" community channel](https://community.mattermost.com/core/channels/tickets) to ask questions from community members and the Mattermost core team.
When you submit a pull request, it goes through a [code review process outlined here](https://developers.mattermost.com/contribute/getting-started/code-review/).

60
Dockerrun.aws.json Normal file
View File

@ -0,0 +1,60 @@
{
"AWSEBDockerrunVersion": "2",
"volumes": [
{
"name": "app-config",
"host": {
"sourcePath": "/var/app/current/app/mattermost/config"
}
},
{
"name": "app-data",
"host": {
"sourcePath": "/var/app/current/app/mattermost/data"
}
},
{
"name": "db-data",
"host": {
"sourcePath": "/var/app/current/db/mattermost/var/lib/postgresql/data"
}
}
],
"containerDefinitions": [
{
"name": "app",
"image": "mattermost/mattermost-prod-app:latest",
"memory": 128,
"mountPoints": [
{
"sourceVolume": "app-config",
"containerPath": "/mattermost/config"
},
{
"sourceVolume": "app-data",
"containerPath": "/mattermost/data"
}
],
"portMappings": [
{
"hostPort": 80,
"containerPort": 80
}
],
"links": [
"db"
]
},
{
"name": "db",
"image": "mattermost/mattermost-prod-db:latest",
"memory": 128,
"mountPoints": [
{
"sourceVolume": "db-data",
"containerPath": "/var/lib/postgresql/data"
}
]
}
]
}

View File

@ -1,70 +0,0 @@
# Maintainer Guide
This file outlines the current maintainer(s) of this open source project and expectations. It also includes credits to past maintainers and the project creator.
## Project Name
When reference externally, please use this for the short name:
- Production Docker deployment for Mattermost
Please use this long name:
- Production Docker deployment for Mattermost by the Mattermost open source project
## Maintainer(s)
The following people help to maintain this open source project:
| Current Maintainer(s) | Start Date |
|:--------------------------------------|:--------------|
| Carlos Tadeu Panato Junior - @cpanato | Feb 18 2018 |
In case something happens where no maintainers are able to complete their responsibilities, the following sponsoring organization can help find a new maintainer:
| Sponsoring Organization | Start Date |
|:-------------------------------|:--------------|
| Mattermost Open Source Project | Dec 04 2016 |
## Activities
The following is a guide for current, new maintainers and prospective maintainers of this open source project to get started and to understand on-going responsibilities:
### Getting Started
The following steps should be completed by a new maintainer
1. **Add your name** - Create a pull request to add your name, GitHub username and start date to this document.
2. **Subscribe to mailing lists** - To be notified of new releases and security updates of Mattermost, subscribe to the [Mattermost Security Update Mailing List](http://mattermost.us11.list-manage.com/subscribe?u=6cdba22349ae374e188e7ab8e&id=3a93eb6929) and the [Mattermost Insiders Newsletter](http://mattermost.us11.list-manage.com/subscribe?u=6cdba22349ae374e188e7ab8e&id=2add1c8034)
### Updating
When receive a mailing list email about a new security update or major version of Mattermost being released, update the version number of this project by doing the following:
In the **master branch**
- Change the [version number](https://github.com/mattermost/mattermost-docker/blob/master/app/Dockerfile#L6) to the latest release
- Tag the repo
### Issue and Pull Request Review
Maintainer(s) should periodically review pull requests and issues submitted to provide feedback and to merge pull request changes when the maintainer feels the change would be appropriate.
## Credits
PREVIOUS MAINTAINERS
| Maintainer | Start Date | End Date |
|:------------------------|:--------------|:------------|
| Yi EungJun - @npcode | Nov 26 2015 | Nov 30 2016 |
| Pan Luo - @xcompass | Nov 30 2015 | Feb 21 2019 |
| Kyâne Pichou - @pichouk | Jun 01 2017 | Aug 15 2019 |
CREATOR
| Creator | Created Date |
|:-----------------------|:--------------|
| Yi EungJun - @npcode | Nov 26 2015 |

View File

@ -6,8 +6,6 @@
### Install
Make the changes in the config file to reflect your needs (app/mattermost/config/config.json)
```
eb init
eb create prod

293
README.md
View File

@ -1,243 +1,120 @@
# Production Docker deployment for Mattermost
Dockerfiles for Mattermost in production
## WARNING:
The current state of this repository doesn't work out-of-the box since Mattermost server v5.31+ requires PostgreSQL versions of 10 or higher.
We're actively working on a fix to this repository. Until then, please refer to these upgrade instructions: https://github.com/mattermost/mattermost-docker/issues/489#issuecomment-790277661
This project enables a deployment of a Mattermost server in a multi-node production configuration using Docker.
See [README.aws.md](./README.aws.md) if you want to install it on AWS Elastic Beanstalk.
[![Build Status](https://travis-ci.org/mattermost/mattermost-docker.svg?branch=master)](https://travis-ci.org/mattermost/mattermost-docker)
Notes:
- The default Mattermost edition for this repo has changed from Team Edition to Enterprise Edition. Please see [Choose Edition](#choose-edition-to-install) section.
- To install this Docker project on AWS Elastic Beanstalk please see [AWS Elastic Beanstalk Guide](contrib/aws/README.md).
- To run Mattermost on Kubernetes you can start with the [manifest examples in the kubernetes folder](contrib/kubernetes/README.md)
- To install Mattermost without Docker directly onto a Linux-based operating systems, please see [Admin Guide](https://docs.mattermost.com/guides/administrator.html#installing-mattermost).
## Requirements
## Installation using Docker Compose
* [docker]
* [docker-compose]
The following instructions deploy Mattermost in a production configuration using multi-node Docker Compose set up.
## Installation
### Requirements
### Install with SSL certificate
* [docker] (version `1.12+`)
* [docker-compose] (version `1.10.0+` to support Compose file version `3.0`)
1. Open docker-compose.yml and set `MATTERMOST_ENABLE_SSL` to true.
### Choose Edition to Install
```
environment:
- MATTERMOST_ENABLE_SSL=true
```
If you want to install Enterprise Edition, you can skip this section.
2. Put your SSL certificate as `./volumes/cert/cert.pem` and the private key that has
no password as `./volumes/cert/key-no-password.pem`. If you don't have
them you may generate a self-signed SSL certificate.
To install the team edition, change `build: app` to `build:` and uncomment out these lines in `app:` services block to make it look like below in docker-compose.yaml file:
```yaml
app:
build:
context: app
args:
- edition=team
3. Build and run mattermost
docker-compose up -d
4. Open `https://your.domain` with your web browser.
### Install without SSL certificate
1. Open docker-compose.yml and set `MATTERMOST_ENABLE_SSL` to false.
```
environment:
- MATTERMOST_ENABLE_SSL=false
```
2. Build and run mattermost
docker-compose up -d
3. Open `http://your.domain` with your web browser.
## Starting/Stopping
### Start
docker-compose start
### Stop
docker-compose stop
## Removing
### Remove the containers
docker-compose stop && docker-compose rm
### Remove the data and settings of your mattermost instance
sudo rm -rf volumes
## Database Backup
When AWS S3 environment variables are specified on db docker container, it enables [Wal-E](https://github.com/wal-e/wal-e) backup to S3.
```bash
docker run -d --name mattermost-db \
-e AWS_ACCESS_KEY_ID=XXXX \
-e AWS_SECRET_ACCESS_KEY=XXXX \
-e WALE_S3_PREFIX=s3://BUCKET_NAME/PATH \
-e AWS_REGION=us-east-1
-v ./volumes/db/var/lib/postgresql/data:/var/lib/postgresql/data
-v /etc/localtime:/etc/localtime:ro
db
```
The `app` Dockerfile will read the `edition` build argument to install Team (`edition = 'team'`) or Enterprise (`edition != team`) edition.
### Database container
This repository offer a Docker image for the Mattermost database. It is a customized PostgreSQL image that you should configure with following environment variables :
* `POSTGRES_USER`: database username
* `POSTGRES_PASSWORD`: database password
* `POSTGRES_DB`: database name
It is possible to use your own PostgreSQL database, or even use MySQL. But you will need to ensure that Application container can connect to the database (see [Application container](#application-container))
#### AWS
If deploying to AWS, you could also set following variables to enable [Wal-E](https://github.com/wal-e/wal-e) backup to S3 :
* `AWS_ACCESS_KEY_ID`: AWS access key
* `AWS_SECRET_ACCESS_KEY`: AWS secret
* `WALE_S3_PREFIX`: AWS s3 bucket name
* `AWS_REGION`: AWS region
All four environment variables are required. It will enable completed WAL segments sent to archive storage (S3). The base backup and clean up can be done through the following command:
```bash
# Base backup
docker exec mattermost-db su - postgres sh -c "/usr/bin/envdir /etc/wal-e.d/env /usr/bin/wal-e backup-push /var/lib/postgresql/data"
# Keep the most recent 7 base backups and remove the old ones
docker exec mattermost-db su - postgres sh -c "/usr/bin/envdir /etc/wal-e.d/env /usr/bin/wal-e delete --confirm retain 7"
# base backup
docker exec mattermost-db su - postgres sh -c "/usr/bin/envdir /etc/wal-e.d/env /usr/local/bin/wal-e backup-push /var/lib/postgresql/data"
# keep the most recent 7 base backups and remove the old ones
docker exec mattermost-db su - postgres sh -c "/usr/bin/envdir /etc/wal-e.d/env /usr/local/bin/wal-e delete --confirm retain 7"
```
Those tasks can be executed through a cron job or systemd timer.
### Application container
Application container run the Mattermost application. You should configure it with following environment variables :
* `MM_USERNAME`: database username
* `MM_PASSWORD`: database password
* `MM_DBNAME`: database name
If your database use some custom host and port, it is also possible to configure them :
* `DB_HOST`: database host address
* `DB_PORT_NUMBER`: database port
Use this optional variable if your PostgreSQL connection requires encryption (you may need a certificate authority file and/or a certificate revocation list - check the documentation for your database provider). See the [PostgreSQL notes on encrypted connections](https://www.postgresql.org/docs/current/libpq-ssl.html) for recommendations on what values to use when encryption is needed.
* `DB_SSLMODE`: defaults to `disable`, indicating no encryption
PostgreSQL allows two other variables `sslrootcert` and `sslcrl` for connection strings. However these are not broadly supported when the connection string is specified as a URI. If you need these parameters, use the PostgreSQL-specified environment variables
* `PGSSLROOTCERT` specifies the location of CA file
* `PGSSLCRL` specifies the location of a certificate revocation list file
If you use a Mattermost configuration file on a different location than the default one (`/mattermost/config/config.json`) :
* `MM_CONFIG`: configuration file location inside the container.
If you choose to use MySQL instead of PostgreSQL, you should set a different datasource and SQL driver :
* `DB_PORT_NUMBER` : `3306`
* `MM_SQLSETTINGS_DRIVERNAME` : `mysql`
* `MM_SQLSETTINGS_DATASOURCE` : `MM_USERNAME:MM_PASSWORD@tcp(DB_HOST:DB_PORT_NUMBER)/MM_DBNAME?charset=utf8mb4,utf8&readTimeout=30s&writeTimeout=30s`
Don't forget to replace all entries (beginning by `MM_` and `DB_`) in `MM_SQLSETTINGS_DATASOURCE` with the real variables values.
If you want to push Mattermost application to **Cloud Foundry**, use a `manifest.yml` like this one (with external PostgreSQL service):
```
---
applications:
- name: mattermost
docker:
image: mattermost/mattermost-prod-app
instances: 1
memory: 1G
disk_quota: 256M
env:
DB_HOST: database host address
DB_PORT_NUMBER: database port
MM_DBNAME: database name
MM_USERNAME: database username
MM_PASSWORD: database password
```
### Web server container
This image is optional, you should **not** use it when you have your own reverse-proxy. It is a simple front Web server for the Mattermost app container. If you use the provided `docker-compose.yml` file, you don't have to configure anything. But if your application container is reachable on custom host and/or port (eg. if you use a container provider), you should add those two environment variables :
* `APP_HOST`: application host address
* `APP_PORT_NUMBER`: application HTTP port
If you plan to upload large files to your Mattermost instance, Nginx will need to write some temporary files. In that case, the `read_only: true` option on the `web` container should be removed from your `docker-compose.yml` file.
#### Install with SSL certificate
Put your SSL certificate as `./volumes/web/cert/cert.pem` and the private key that has
no password as `./volumes/web/cert/key-no-password.pem`. If you don't have
them you may generate a self-signed SSL certificate.
#### Configure SSO with GitLab
If you are looking for SSO with GitLab and you use self signed certificate you have to add the PKI chain of your authority in app because Alpine doesn't know him. This is required to avoid **Token request failed: certificate signed by unknown authority**
For that uncomment this line and replace with the correct path of your PKI chain:
```
# - <path_to_your_gitlab_pki>/pki_chain.pem:/etc/ssl/certs/pki_chain.pem:ro
```
### Starting/Stopping Docker
#### Start
If you are running docker with non root user, make sure the UID and GID in app/Dockerfile are the same as your current UID/GID
```
mkdir -p ./volumes/app/mattermost/{data,logs,config,plugins}
chown -R 2000:2000 ./volumes/app/mattermost/
docker-compose start
```
#### Stop
```
docker-compose stop
```
### Removing Docker
#### Remove the containers
```
docker-compose stop && docker-compose rm
```
#### Remove the data and settings of your Mattermost instance
```
sudo rm -rf volumes
```
## Update Mattermost to latest version
First, shutdown your containers to back up your data.
```
docker-compose down
```
Back up your mounted volumes to save your data. If you use the default `docker-compose.yml` file proposed on this repository, your data is on `./volumes/` folder.
Then run the following commands.
```
git pull
docker-compose build
docker-compose up -d
```
Your Docker image should now be on the latest Mattermost version.
## Upgrading Mattermost to 4.9+
Docker images for `4.9.0` release introduce some important changes from [PR #241](https://github.com/mattermost/mattermost-docker/pull/241) to improve production use of Mattermost with Docker.
**There are 2 important changes for existing installations**
One important change is that we don't use `root` user by default to run the Mattermost application. So, as explained on [the README](https://github.com/mattermost/mattermost-docker#start), if you use host mounted volume you have to be sure that files on your host server have the correct UID/GID (by default those values are `2000`). In practice, you should just run following commands :
```
mkdir -p ./volumes/app/mattermost/{data,logs,config,plugins}
chown -R 2000:2000 ./volumes/app/mattermost/
```
The second important change is the port used by Mattermost application container. The default port is now `8000`, and existing installations that use port `80` will not work without a little configuration change. You have to open your Mattermost configuration file (`./volumes/app/mattermost/config/config.json` by default) and change the key `ServiceSettings.ListenAddress` to `:8000`.
Also if you use your own web-server/reverse-proxy you need to change its configuration to reach port `8000` of the Mattermost container.
## Upgrading to Team Edition 3.0.x from 2.x
You need to migrate your database before upgrading Mattermost to `3.0.x` from
`2.x`. Run these commands in the latest `mattermost-docker` directory.
```
docker-compose rm -f app
docker-compose build app
docker-compose run app -upgrade_db_30
docker-compose up -d
```
See the [official Upgrade Guide](http://docs.mattermost.com/administration/upgrade.html) for more details.
You need to migrate your database before upgrading mattermost to 3.0.x from
2.x. Run these commands in the latest mattermost-docker directory.
## Installation using Docker Swarm Mode
docker-compose rm -f app
docker-compose build app
docker-compose run app -upgrade_db_30
docker-compose up -d
The following instructions deploy Mattermost in a production configuration using docker swarm mode on one node.
Running containerized applications on multi-node swarms involves specific data portability and replication handling that are not covered here.
### Requirements
* [docker] (1.12.0+)
### Swarm Mode Installation
First, create mattermost directory structure on the docker hosts:
```
mkdir -p /var/lib/mattermost/{cert,config,data,logs,plugins}
```
Then, fire up the stack in your swarm:
```
docker stack deploy -c contrib/swarm/docker-stack.yml mattermost
```
See the [offical Upgrade Guide](http://docs.mattermost.com/administration/upgrade.html) for more details.
## Known Issues
* Do not modify the Listen Address in Service Settings.
* Rarely `app` container fails to start because of "connection refused" to
* Rarely 'app' container fails to start because of "connection refused" to
database. Workaround: Restart the container.
## More information
## More informations
If you want to know how to use docker-compose, see [the overview
page](https://docs.docker.com/compose).
For the server configurations, see [prod-ubuntu.rst] of Mattermost.
For the server configurations, see [prod-ubuntu.rst] of mattermost.
[docker]: http://docs.docker.com/engine/installation/
[docker-compose]: https://docs.docker.com/compose/install/
[prod-ubuntu.rst]: https://docs.mattermost.com/install/install-ubuntu-1604.html
[prod-ubuntu.rst]: https://github.com/mattermost/docs/blob/master/source/install/prod-ubuntu.rst

View File

@ -1,57 +1,15 @@
FROM alpine:3.10
FROM ubuntu:14.04
# Some ENV variables
ENV PATH="/mattermost/bin:${PATH}"
ENV MM_INSTALL_TYPE=docker
RUN apt-get update && apt-get -y install curl netcat
RUN mkdir -p /mattermost/data
# Build argument to set Mattermost edition
ARG edition=enterprise
ARG PUID=2000
ARG PGID=2000
ARG MM_BINARY=
ARG MM_VERSION=5.31.0
RUN curl https://releases.mattermost.com/3.2.0/mattermost-team-3.2.0-linux-amd64.tar.gz | tar -xvz
RUN rm /mattermost/config/config.json
COPY config.template.json /
# Install some needed packages
RUN apk add --no-cache \
ca-certificates \
curl \
jq \
libc6-compat \
libffi-dev \
libcap \
linux-headers \
mailcap \
netcat-openbsd \
xmlsec-dev \
tzdata \
&& rm -rf /tmp/*
COPY docker-entry.sh /
RUN chmod +x /docker-entry.sh
ENTRYPOINT ["/docker-entry.sh"]
# Get Mattermost
RUN mkdir -p /mattermost/data /mattermost/plugins /mattermost/client/plugins \
&& if [ ! -z "$MM_BINARY" ]; then curl $MM_BINARY | tar -xvz ; \
elif [ "$edition" = "team" ] ; then curl https://releases.mattermost.com/$MM_VERSION/mattermost-team-$MM_VERSION-linux-amd64.tar.gz?src=docker-app | tar -xvz ; \
else curl https://releases.mattermost.com/$MM_VERSION/mattermost-$MM_VERSION-linux-amd64.tar.gz?src=docker-app | tar -xvz ; fi \
&& cp /mattermost/config/config.json /config.json.save \
&& rm -rf /mattermost/config/config.json \
&& addgroup -g ${PGID} mattermost \
&& adduser -D -u ${PUID} -G mattermost -h /mattermost -D mattermost \
&& chown -R mattermost:mattermost /mattermost /config.json.save /mattermost/plugins /mattermost/client/plugins \
&& setcap cap_net_bind_service=+ep /mattermost/bin/mattermost
USER mattermost
#Healthcheck to make sure container is ready
HEALTHCHECK CMD curl --fail http://localhost:8000 || exit 1
# Configure entrypoint and command
COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
WORKDIR /mattermost
CMD ["mattermost"]
# Expose port 8000 of the container
EXPOSE 8000
# Declare volumes for mount point directories
VOLUME ["/mattermost/data", "/mattermost/logs", "/mattermost/config", "/mattermost/plugins", "/mattermost/client/plugins"]
EXPOSE 80

95
app/config.template.json Normal file
View File

@ -0,0 +1,95 @@
{
"ServiceSettings": {
"ListenAddress": ":80",
"MaximumLoginAttempts": 10,
"SegmentDeveloperKey": "",
"GoogleDeveloperKey": "",
"EnableOAuthServiceProvider": false,
"EnableIncomingWebhooks": false,
"EnableOutgoingWebhooks": false,
"EnablePostUsernameOverride": false,
"EnablePostIconOverride": false,
"EnableTesting": false,
"EnableSecurityFixAlert": true
},
"TeamSettings": {
"SiteName": "Mattermost",
"MaxUsersPerTeam": 50,
"EnableTeamCreation": true,
"EnableUserCreation": true,
"RestrictCreationToDomains": "",
"RestrictTeamNames": true,
"EnableTeamListing": false
},
"SqlSettings": {
"DriverName": "postgres",
"DataSource": "postgres://MM_USERNAME:MM_PASSWORD@DB_HOST:DB_PORT/MM_DBNAME?sslmode=disable&connect_timeout=10",
"DataSourceReplicas": [],
"MaxIdleConns": 10,
"MaxOpenConns": 10,
"Trace": false,
"AtRestEncryptKey": "7rAh6iwQCkV4cA1Gsg3fgGOXJAQ43QVg"
},
"LogSettings": {
"EnableConsole": false,
"ConsoleLevel": "INFO",
"EnableFile": true,
"FileLevel": "INFO",
"FileFormat": "",
"FileLocation": ""
},
"FileSettings": {
"DriverName": "local",
"Directory": "/mattermost/data/",
"EnablePublicLink": true,
"PublicLinkSalt": "A705AklYF8MFDOfcwh3I488G8vtLlVip",
"ThumbnailWidth": 120,
"ThumbnailHeight": 100,
"PreviewWidth": 1024,
"PreviewHeight": 0,
"ProfileWidth": 128,
"ProfileHeight": 128,
"InitialFont": "luximbi.ttf",
"AmazonS3AccessKeyId": "",
"AmazonS3SecretAccessKey": "",
"AmazonS3Bucket": "",
"AmazonS3Region": ""
},
"EmailSettings": {
"EnableSignUpWithEmail": true,
"SendEmailNotifications": false,
"RequireEmailVerification": false,
"FeedbackName": "",
"FeedbackEmail": "",
"SMTPUsername": "",
"SMTPPassword": "",
"SMTPServer": "",
"SMTPPort": "",
"ConnectionSecurity": "",
"InviteSalt": "bjlSR4QqkXFBr7TP4oDzlfZmcNuH9YoS",
"PasswordResetSalt": "vZ4DcKyVVRlKHHJpexcuXzojkE5PZ5eL",
"ApplePushServer": "",
"ApplePushCertPublic": "",
"ApplePushCertPrivate": ""
},
"RateLimitSettings": {
"EnableRateLimiter": true,
"PerSec": 10,
"MemoryStoreSize": 10000,
"VaryByRemoteAddr": true,
"VaryByHeader": ""
},
"PrivacySettings": {
"ShowEmailAddress": true,
"ShowFullName": true
},
"GitLabSettings": {
"Enable": false,
"Secret": "",
"Id": "",
"Scope": "",
"AuthEndpoint": "",
"TokenEndpoint": "",
"UserApiEndpoint": ""
}
}

33
app/docker-entry.sh Normal file
View File

@ -0,0 +1,33 @@
#!/bin/bash
config=/mattermost/config/config.json
DB_HOST=${DB_HOST:-db}
DB_PORT_5432_TCP_PORT=${DB_PORT_5432_TCP_PORT:-5432}
MM_USERNAME=${MM_USERNAME:-mmuser}
MM_PASSWORD=${MM_PASSWORD:-mmuser_password}
MM_DBNAME=${MM_DBNAME:-mattermost}
echo -ne "Configure database connection..."
if [ ! -f $config ]
then
cp /config.template.json $config
sed -Ei "s/DB_HOST/$DB_HOST/" $config
sed -Ei "s/DB_PORT/$DB_PORT_5432_TCP_PORT/" $config
sed -Ei "s/MM_USERNAME/$MM_USERNAME/" $config
sed -Ei "s/MM_PASSWORD/$MM_PASSWORD/" $config
sed -Ei "s/MM_DBNAME/$MM_DBNAME/" $config
echo OK
else
echo SKIP
fi
echo "Wait until database $DB_HOST:$DB_PORT_5432_TCP_PORT is ready..."
until nc -z $DB_HOST $DB_PORT_5432_TCP_PORT
do
sleep 1
done
# Wait to avoid "panic: Failed to open sql connection pq: the database system is starting up"
sleep 1
echo "Starting platform"
cd /mattermost/bin
./platform $*

View File

@ -1,82 +0,0 @@
#!/bin/sh
# Function to generate a random salt
generate_salt() {
tr -dc 'a-zA-Z0-9' </dev/urandom | fold -w 48 | head -n 1
}
# Read environment variables or set default values
DB_HOST=${DB_HOST:-db}
DB_PORT_NUMBER=${DB_PORT_NUMBER:-5432}
# see https://www.postgresql.org/docs/current/libpq-ssl.html
# for usage when database connection requires encryption
# filenames should be escaped if they contain spaces
# i.e. $(printf %s ${MY_ENV_VAR:-''} | jq -s -R -r @uri)
# the location of the CA file can be set using environment var PGSSLROOTCERT
# the location of the CRL file can be set using PGSSLCRL
# The URL syntax for connection string does not support the parameters
# sslrootcert and sslcrl reliably, so use these PostgreSQL-specified variables
# to set names if using a location other than default
DB_USE_SSL=${DB_USE_SSL:-disable}
MM_DBNAME=${MM_DBNAME:-mattermost}
MM_CONFIG=${MM_CONFIG:-/mattermost/config/config.json}
_1=$(echo "$1" | awk '{ s=substr($0, 0, 1); print s; }')
if [ "$_1" = '-' ]; then
set -- mattermost "$@"
fi
if [ "$1" = 'mattermost' ]; then
# Check CLI args for a -config option
for ARG in "$@"; do
case "$ARG" in
-config=*) MM_CONFIG=${ARG#*=} ;;
esac
done
if [ ! -f "$MM_CONFIG" ]; then
# If there is no configuration file, create it with some default values
echo "No configuration file $MM_CONFIG"
echo "Creating a new one"
# Copy default configuration file
cp /config.json.save "$MM_CONFIG"
# Substitute some parameters with jq
jq '.ServiceSettings.ListenAddress = ":8000"' "$MM_CONFIG" >"$MM_CONFIG.tmp" && mv "$MM_CONFIG.tmp" "$MM_CONFIG"
jq '.LogSettings.EnableConsole = true' "$MM_CONFIG" >"$MM_CONFIG.tmp" && mv "$MM_CONFIG.tmp" "$MM_CONFIG"
jq '.LogSettings.ConsoleLevel = "ERROR"' "$MM_CONFIG" >"$MM_CONFIG.tmp" && mv "$MM_CONFIG.tmp" "$MM_CONFIG"
jq '.FileSettings.Directory = "/mattermost/data/"' "$MM_CONFIG" >"$MM_CONFIG.tmp" && mv "$MM_CONFIG.tmp" "$MM_CONFIG"
jq '.FileSettings.EnablePublicLink = true' "$MM_CONFIG" >"$MM_CONFIG.tmp" && mv "$MM_CONFIG.tmp" "$MM_CONFIG"
jq ".FileSettings.PublicLinkSalt = \"$(generate_salt)\"" "$MM_CONFIG" >"$MM_CONFIG.tmp" && mv "$MM_CONFIG.tmp" "$MM_CONFIG"
jq '.EmailSettings.SendEmailNotifications = false' "$MM_CONFIG" >"$MM_CONFIG.tmp" && mv "$MM_CONFIG.tmp" "$MM_CONFIG"
jq '.EmailSettings.FeedbackEmail = ""' "$MM_CONFIG" >"$MM_CONFIG.tmp" && mv "$MM_CONFIG.tmp" "$MM_CONFIG"
jq '.EmailSettings.SMTPServer = ""' "$MM_CONFIG" >"$MM_CONFIG.tmp" && mv "$MM_CONFIG.tmp" "$MM_CONFIG"
jq '.EmailSettings.SMTPPort = ""' "$MM_CONFIG" >"$MM_CONFIG.tmp" && mv "$MM_CONFIG.tmp" "$MM_CONFIG"
jq ".EmailSettings.InviteSalt = \"$(generate_salt)\"" "$MM_CONFIG" >"$MM_CONFIG.tmp" && mv "$MM_CONFIG.tmp" "$MM_CONFIG"
jq ".EmailSettings.PasswordResetSalt = \"$(generate_salt)\"" "$MM_CONFIG" >"$MM_CONFIG.tmp" && mv "$MM_CONFIG.tmp" "$MM_CONFIG"
jq '.RateLimitSettings.Enable = true' "$MM_CONFIG" >"$MM_CONFIG.tmp" && mv "$MM_CONFIG.tmp" "$MM_CONFIG"
jq '.SqlSettings.DriverName = "postgres"' "$MM_CONFIG" >"$MM_CONFIG.tmp" && mv "$MM_CONFIG.tmp" "$MM_CONFIG"
jq ".SqlSettings.AtRestEncryptKey = \"$(generate_salt)\"" "$MM_CONFIG" >"$MM_CONFIG.tmp" && mv "$MM_CONFIG.tmp" "$MM_CONFIG"
jq '.PluginSettings.Directory = "/mattermost/plugins/"' "$MM_CONFIG" >"$MM_CONFIG.tmp" && mv "$MM_CONFIG.tmp" "$MM_CONFIG"
else
echo "Using existing config file $MM_CONFIG"
fi
# Configure database access
if [ -z "$MM_SQLSETTINGS_DATASOURCE" ] && [ -n "$MM_USERNAME" ] && [ -n "$MM_PASSWORD" ]; then
echo "Configure database connection..."
# URLEncode the password, allowing for special characters
ENCODED_PASSWORD=$(printf %s "$MM_PASSWORD" | jq -s -R -r @uri)
export MM_SQLSETTINGS_DATASOURCE="postgres://$MM_USERNAME:$ENCODED_PASSWORD@$DB_HOST:$DB_PORT_NUMBER/$MM_DBNAME?sslmode=$DB_USE_SSL&connect_timeout=10"
echo "OK"
else
echo "Using existing database connection"
fi
# Wait another second for the database to be properly started.
# Necessary to avoid "panic: Failed to open sql connection pq: the database system is starting up"
sleep 1
echo "Starting mattermost"
fi
exec "$@"

View File

@ -1,5 +0,0 @@
# Elastic Beanstalk Files
.elasticbeanstalk/*
!.elasticbeanstalk/*.cfg.yml
!.elasticbeanstalk/*.global.yml

View File

@ -1,119 +0,0 @@
{
"AWSEBDockerrunVersion": "2",
"volumes": [
{
"name": "app-config",
"host": {
"sourcePath": "/var/app/current/app/mattermost/config"
}
},
{
"name": "app-data",
"host": {
"sourcePath": "/var/app/current/app/mattermost/data"
}
},
{
"name": "app-logs",
"host": {
"sourcePath": "/var/app/current/app/mattermost/logs"
}
},
{
"name": "app-plugins",
"host": {
"sourcePath": "/var/app/current/app/mattermost/plugins"
}
},
{
"name": "db-data",
"host": {
"sourcePath": "/var/app/current/db/mattermost/var/lib/postgresql/data"
}
},
{
"name": "web-cert",
"host": {
"sourcePath": "/var/app/current/web/cert"
}
}
],
"containerDefinitions": [
{
"name": "db",
"image": "mattermost/mattermost-prod-db:latest",
"memory": 128,
"essential": true,
"mountPoints": [
{
"sourceVolume": "db-data",
"containerPath": "/var/lib/postgresql/data"
}
],
"environment": [
{
"name": "POSTGRES_USER",
"value": "mmuser"
}, {
"name": "POSTGRES_PASSWORD",
"value": "mmuser_password"
}, {
"name": "POSTGRES_DB",
"value": "mattermost"
}
]
},
{
"name": "app",
"image": "mattermost/mattermost-prod-app:latest",
"memory": 128,
"essential": true,
"mountPoints": [
{
"sourceVolume": "app-config",
"containerPath": "/mattermost/config"
},
{
"sourceVolume": "app-data",
"containerPath": "/mattermost/data"
},
{
"sourceVolume": "app-logs",
"containerPath": "/mattermost/logs"
},
{
"sourceVolume": "app-plugins",
"containerPath": "/mattermost/plugins"
}
],
"links": [
"db"
]
},
{
"name": "web",
"image": "mattermost/mattermost-prod-web:5.9.0",
"memory": 128,
"essential": true,
"mountPoints": [
{
"sourceVolume": "web-cert",
"containerPath": "/cert"
}
],
"portMappings": [
{
"hostPort": 80,
"containerPort": 80
},
{
"hostPort": 443,
"containerPort": 443
}
],
"links": [
"app"
]
}
]
}

View File

@ -1,413 +0,0 @@
{
"ServiceSettings": {
"SiteURL": "",
"WebsocketURL": "",
"LicenseFileLocation": "",
"ListenAddress": ":8000",
"ConnectionSecurity": "",
"TLSCertFile": "",
"TLSKeyFile": "",
"TLSMinVer": "1.2",
"TLSStrictTransport": false,
"TLSStrictTransportMaxAge": 63072000,
"TLSOverwriteCiphers": [],
"UseLetsEncrypt": false,
"LetsEncryptCertificateCacheFile": "./config/letsencrypt.cache",
"Forward80To443": false,
"ReadTimeout": 300,
"WriteTimeout": 300,
"MaximumLoginAttempts": 10,
"GoroutineHealthThreshold": -1,
"GoogleDeveloperKey": "",
"EnableOAuthServiceProvider": false,
"EnableIncomingWebhooks": true,
"EnableOutgoingWebhooks": true,
"EnableCommands": true,
"EnableOnlyAdminIntegrations": true,
"EnablePostUsernameOverride": false,
"EnablePostIconOverride": false,
"EnableAPIv3": false,
"EnableLinkPreviews": false,
"EnableTesting": false,
"EnableDeveloper": false,
"EnableSecurityFixAlert": true,
"EnableInsecureOutgoingConnections": false,
"AllowedUntrustedInternalConnections": "",
"EnableMultifactorAuthentication": false,
"EnforceMultifactorAuthentication": false,
"EnableUserAccessTokens": false,
"AllowCorsFrom": "",
"CorsExposedHeaders": "",
"CorsAllowCredentials": false,
"CorsDebug": false,
"AllowCookiesForSubdomains": false,
"SessionLengthWebInDays": 30,
"SessionLengthMobileInDays": 30,
"SessionLengthSSOInDays": 30,
"SessionCacheInMinutes": 10,
"SessionIdleTimeoutInMinutes": 0,
"WebsocketSecurePort": 443,
"WebsocketPort": 80,
"WebserverMode": "gzip",
"EnableCustomEmoji": false,
"EnableEmojiPicker": true,
"EnableGifPicker": false,
"GfycatApiKey": "2_KtH_W5",
"GfycatApiSecret": "3wLVZPiswc3DnaiaFoLkDvB4X0IV6CpMkj4tf2inJRsBY6-FnkT08zGmppWFgeof",
"RestrictCustomEmojiCreation": "all",
"RestrictPostDelete": "all",
"AllowEditPost": "always",
"PostEditTimeLimit": -1,
"ExperimentalEnableAuthenticationTransfer": true,
"TimeBetweenUserTypingUpdatesMilliseconds": 5000,
"EnablePostSearch": true,
"EnableUserTypingMessages": true,
"EnableChannelViewedMessages": true,
"EnableUserStatuses": true,
"ClusterLogTimeoutMilliseconds": 2000,
"EnablePreviewFeatures": true,
"CloseUnusedDirectMessages": false,
"EnableTutorial": true,
"ExperimentalEnableDefaultChannelLeaveJoinMessages": true,
"ExperimentalGroupUnreadChannels": "disabled",
"ExperimentalChannelOrganization": false,
"ImageProxyType": "",
"ImageProxyOptions": "",
"ImageProxyURL": "",
"EnableAPITeamDeletion": false,
"ExperimentalEnableHardenedMode": false,
"EnableEmailInvitations": false
},
"TeamSettings": {
"SiteName": "Mattermost",
"MaxUsersPerTeam": 50,
"EnableTeamCreation": true,
"EnableUserCreation": true,
"EnableOpenServer": false,
"EnableUserDeactivation": false,
"RestrictCreationToDomains": "",
"EnableCustomBrand": false,
"CustomBrandText": "",
"CustomDescriptionText": "",
"RestrictDirectMessage": "any",
"RestrictTeamInvite": "all",
"RestrictPublicChannelManagement": "all",
"RestrictPrivateChannelManagement": "all",
"RestrictPublicChannelCreation": "all",
"RestrictPrivateChannelCreation": "all",
"RestrictPublicChannelDeletion": "all",
"RestrictPrivateChannelDeletion": "all",
"RestrictPrivateChannelManageMembers": "all",
"EnableXToLeaveChannelsFromLHS": false,
"UserStatusAwayTimeout": 300,
"MaxChannelsPerTeam": 2000,
"MaxNotificationsPerChannel": 1000,
"EnableConfirmNotificationsToChannel": true,
"TeammateNameDisplay": "username",
"ExperimentalViewArchivedChannels": false,
"ExperimentalEnableAutomaticReplies": false,
"ExperimentalHideTownSquareinLHS": false,
"ExperimentalTownSquareIsReadOnly": false,
"ExperimentalPrimaryTeam": "",
"ExperimentalDefaultChannels": ""
},
"DisplaySettings": {
"CustomUrlSchemes": [],
"ExperimentalTimezone": false
},
"ClientRequirements": {
"AndroidLatestVersion": "",
"AndroidMinVersion": "",
"DesktopLatestVersion": "",
"DesktopMinVersion": "",
"IosLatestVersion": "",
"IosMinVersion": ""
},
"SqlSettings": {
"DriverName": "postgres",
"DataSource": "postgres://mmuser:mmuser_password@db:5432/mattermost?sslmode=disable&connect_timeout=10",
"DataSourceReplicas": [],
"DataSourceSearchReplicas": [],
"MaxIdleConns": 20,
"ConnMaxLifetimeMilliseconds": 3600000,
"MaxOpenConns": 300,
"Trace": false,
"AtRestEncryptKey": "",
"QueryTimeout": 30
},
"LogSettings": {
"EnableConsole": true,
"ConsoleLevel": "DEBUG",
"ConsoleJson": true,
"EnableFile": true,
"FileLevel": "INFO",
"FileJson": true,
"FileLocation": "",
"EnableWebhookDebugging": true,
"EnableDiagnostics": true
},
"PasswordSettings": {
"MinimumLength": 5,
"Lowercase": false,
"Number": false,
"Uppercase": false,
"Symbol": false
},
"FileSettings": {
"EnableFileAttachments": true,
"EnableMobileUpload": true,
"EnableMobileDownload": true,
"MaxFileSize": 52428800,
"DriverName": "local",
"Directory": "./data/",
"EnablePublicLink": false,
"PublicLinkSalt": "",
"InitialFont": "nunito-bold.ttf",
"AmazonS3AccessKeyId": "",
"AmazonS3SecretAccessKey": "",
"AmazonS3Bucket": "",
"AmazonS3Region": "",
"AmazonS3Endpoint": "s3.amazonaws.com",
"AmazonS3SSL": true,
"AmazonS3SignV2": false,
"AmazonS3SSE": false,
"AmazonS3Trace": false
},
"EmailSettings": {
"EnableSignUpWithEmail": true,
"EnableSignInWithEmail": true,
"EnableSignInWithUsername": true,
"SendEmailNotifications": true,
"UseChannelInEmailNotifications": false,
"RequireEmailVerification": false,
"FeedbackName": "",
"FeedbackEmail": "test@example.com",
"FeedbackOrganization": "",
"EnableSMTPAuth": false,
"SMTPUsername": "",
"SMTPPassword": "",
"SMTPServer": "dockerhost",
"SMTPPort": "2500",
"ConnectionSecurity": "",
"InviteSalt": "",
"SendPushNotifications": true,
"PushNotificationServer": "https://push-test.mattermost.com",
"PushNotificationContents": "generic",
"EnableEmailBatching": false,
"EmailBatchingBufferSize": 256,
"EmailBatchingInterval": 30,
"EnablePreviewModeBanner": true,
"SkipServerCertificateVerification": false,
"EmailNotificationContentsType": "full",
"LoginButtonColor": "",
"LoginButtonBorderColor": "",
"LoginButtonTextColor": ""
},
"RateLimitSettings": {
"Enable": false,
"PerSec": 10,
"MaxBurst": 100,
"MemoryStoreSize": 10000,
"VaryByRemoteAddr": true,
"VaryByUser": false,
"VaryByHeader": ""
},
"PrivacySettings": {
"ShowEmailAddress": true,
"ShowFullName": true
},
"SupportSettings": {
"TermsOfServiceLink": "https://about.mattermost.com/default-terms/",
"PrivacyPolicyLink": "https://about.mattermost.com/default-privacy-policy/",
"AboutLink": "https://about.mattermost.com/default-about/",
"HelpLink": "https://about.mattermost.com/default-help/",
"ReportAProblemLink": "https://about.mattermost.com/default-report-a-problem/",
"SupportEmail": "feedback@mattermost.com"
},
"AnnouncementSettings": {
"EnableBanner": false,
"BannerText": "",
"BannerColor": "#f2a93b",
"BannerTextColor": "#333333",
"AllowBannerDismissal": true
},
"ThemeSettings": {
"EnableThemeSelection": true,
"DefaultTheme": "default",
"AllowCustomThemes": true,
"AllowedThemes": []
},
"TimezoneSettings": {
"SupportedTimezonesPath": "timezones.json"
},
"GitLabSettings": {
"Enable": false,
"Secret": "",
"Id": "",
"Scope": "",
"AuthEndpoint": "",
"TokenEndpoint": "",
"UserApiEndpoint": ""
},
"GoogleSettings": {
"Enable": false,
"Secret": "",
"Id": "",
"Scope": "profile email",
"AuthEndpoint": "https://accounts.google.com/o/oauth2/v2/auth",
"TokenEndpoint": "https://www.googleapis.com/oauth2/v4/token",
"UserApiEndpoint": "https://www.googleapis.com/plus/v1/people/me"
},
"Office365Settings": {
"Enable": false,
"Secret": "",
"Id": "",
"Scope": "User.Read",
"AuthEndpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
"TokenEndpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/token",
"UserApiEndpoint": "https://graph.microsoft.com/v1.0/me"
},
"LdapSettings": {
"Enable": false,
"EnableSync": false,
"LdapServer": "",
"LdapPort": 389,
"ConnectionSecurity": "",
"BaseDN": "",
"BindUsername": "",
"BindPassword": "",
"UserFilter": "",
"FirstNameAttribute": "",
"LastNameAttribute": "",
"EmailAttribute": "",
"UsernameAttribute": "",
"NicknameAttribute": "",
"IdAttribute": "",
"PositionAttribute": "",
"LoginIdAttribute": "",
"SyncIntervalMinutes": 60,
"SkipCertificateVerification": false,
"QueryTimeout": 60,
"MaxPageSize": 0,
"LoginFieldName": "",
"LoginButtonColor": "",
"LoginButtonBorderColor": "",
"LoginButtonTextColor": ""
},
"ComplianceSettings": {
"Enable": false,
"Directory": "./data/",
"EnableDaily": false
},
"LocalizationSettings": {
"DefaultServerLocale": "en",
"DefaultClientLocale": "en",
"AvailableLocales": ""
},
"SamlSettings": {
"Enable": false,
"EnableSyncWithLdap": false,
"EnableSyncWithLdapIncludeAuth": false,
"Verify": true,
"Encrypt": true,
"IdpUrl": "",
"IdpDescriptorUrl": "",
"AssertionConsumerServiceURL": "",
"ScopingIDPProviderId": "",
"ScopingIDPName": "",
"IdpCertificateFile": "",
"PublicCertificateFile": "",
"PrivateKeyFile": "",
"IdAttribute": "",
"FirstNameAttribute": "",
"LastNameAttribute": "",
"EmailAttribute": "",
"UsernameAttribute": "",
"NicknameAttribute": "",
"LocaleAttribute": "",
"PositionAttribute": "",
"LoginButtonText": "SAML",
"LoginButtonColor": "",
"LoginButtonBorderColor": "",
"LoginButtonTextColor": ""
},
"NativeAppSettings": {
"AppDownloadLink": "https://about.mattermost.com/downloads/",
"AndroidAppDownloadLink": "https://about.mattermost.com/mattermost-android-app/",
"IosAppDownloadLink": "https://about.mattermost.com/mattermost-ios-app/"
},
"ClusterSettings": {
"Enable": false,
"ClusterName": "",
"OverrideHostname": "",
"UseIpAddress": true,
"UseExperimentalGossip": false,
"ReadOnlyConfig": true,
"GossipPort": 8074,
"StreamingPort": 8075,
"MaxIdleConns": 100,
"MaxIdleConnsPerHost": 128,
"IdleConnTimeoutMilliseconds": 90000
},
"MetricsSettings": {
"Enable": false,
"BlockProfileRate": 0,
"ListenAddress": ":8067"
},
"ExperimentalSettings": {
"ClientSideCertEnable": false,
"ClientSideCertCheck": "secondary",
"EnablePostMetadata": false
},
"AnalyticsSettings": {
"MaxUsersForStatistics": 2500
},
"ElasticsearchSettings": {
"ConnectionUrl": "http://dockerhost:9200",
"Username": "elastic",
"Password": "changeme",
"EnableIndexing": false,
"EnableSearching": false,
"Sniff": true,
"PostIndexReplicas": 1,
"PostIndexShards": 1,
"AggregatePostsAfterDays": 365,
"PostsAggregatorJobStartTime": "03:00",
"IndexPrefix": "",
"LiveIndexingBatchSize": 1,
"BulkIndexingTimeWindowSeconds": 3600,
"RequestTimeoutSeconds": 30
},
"DataRetentionSettings": {
"EnableMessageDeletion": false,
"EnableFileDeletion": false,
"MessageRetentionDays": 365,
"FileRetentionDays": 365,
"DeletionJobStartTime": "02:00"
},
"MessageExportSettings": {
"EnableExport": false,
"DailyRunTime": "01:00",
"ExportFromTimestamp": 0,
"FileLocation": "export",
"BatchSize": 10000,
"GlobalRelaySettings": {
"CustomerType": "A9",
"SmtpUsername": "",
"SmtpPassword": "",
"EmailAddress": ""
}
},
"JobSettings": {
"RunJobs": true,
"RunScheduler": true
},
"PluginSettings": {
"Enable": true,
"EnableUploads": false,
"Directory": "./plugins",
"ClientDirectory": "./client/plugins",
"Plugins": {},
"PluginStates": {}
}
}

View File

@ -1,110 +0,0 @@
Mattermost on Kubernetes
=======
You can use these manifests as a starting point to run Mattermost on Kubernetes.
If you already have a Kubernetes cluster you can skip this first step.
### Start local Kubernetes cluster
To get started we can use [minikube](https://github.com/kubernetes/minikube/) to run a local kubernetes cluster.
Download and install minikube and any dependancies for your operating system (see minikube readme). You will also need to install [kubectl](http://kubernetes.io/docs/user-guide/prereqs/).
Start the minikube VM and Kubernetes API server
```
minikube start
```
### Start a Postgres database
#### WARNING: The database is not backup up and will lose all data if the pod is restarted. Consider using a [persistent volume](http://kubernetes.io/docs/user-guide/persistent-volumes/) for storing pgdata
This will run a postgres deployment with default values for database name, username, and password.
```
kubectl run postgres --image=postgres:9 \
--env="POSTGRES_PASSWORD=mmuser_password" \
--env="POSTGRES_DB=mattermost" \
--env="POSTGRES_USER=mmuser"
```
Expose the postgres database as a service named "db"
```
kubectl expose deployment postgres \
--name=db \
--port 5432 \
--target-port 5432
```
### Run Mattermost container
The Mattermost application is split into three manifests.
First, create the secret which will set the environment varibles for the main application container. If you changed the values for the Postgres container you will also need to set the values in mattermost.secret.yaml using the [manual steps for creating a secret](http://kubernetes.io/docs/user-guide/secrets/#creating-a-secret-manually).
```
kubectl create -f mattermost.secret.yaml
```
Next create the Mattermost deployment (main application) with
```
kubectl create -f mattermost.deployment.yaml
```
You should check that the pod started successfully with
```
kubectl get po -l app=mattermost
NAME READY STATUS RESTARTS AGE
mattermost-app-1605216003-fvnz1 1/1 Running 0 44m
```
Finally, you can expose the application with a service so you can easily access the application from a web browser. The example service is using a `type: NodePort` which means it will be exposed on a random high port on your cluster nodes (or minikube VM if you're using minikube). If you are running your Kubernetes cluster in AWS or GCE you should change the type to loadBalancer.
```
kubectl create -f mattermost.svc.yaml
```
Now you can get your VM's IP address with
```
minikube ip
192.168.99.100
```
and the exposed port for the application with
```
kubectl describe svc mattermost
Name: mattermost
Namespace: default
Labels: <none>
Selector: app=mattermost,tier=app
Type: NodePort
IP: 10.0.0.194
Port: http 80/TCP
NodePort: http 32283/TCP
Endpoints: 172.17.0.4:8000
Session Affinity: None
No events.
```
Make sure the Endpoints shows an IP address. This should correlate to the pod IP started by the deployment.
Now browse to your node IP and exposed NodePort in your browser to view the application or test it with curl
```
curl -L http://192.168.99.100:32283
```
### Optional steps
* If you want your data to be persistent you will need to make persistent volumes for Mattermost and Postgres. This requires adding a [securityContext](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#discussion) to the deployment to set `runAsUser: 2000`, `runAsGroup: 2000` and `fsGroup: 2000`.
* If you want to change advanced settings for the mattermost container you can make a [configMap](http://blog.kubernetes.io/2016/04/configuration-management-with-containers.html) for the /mattermost/config/config.json file
* If you want the application exposed on port 80 you can either specify the port in the service manifest or use an [ingress controller](http://kubernetes.io/docs/user-guide/ingress/#ingress-controllers) and an ingress map for the mattermost service. A sample ingress map would be
```
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: mattermost
spec:
rules:
- host: mattermost
http:
paths:
- backend:
serviceName: mattermost
servicePort: 80
```

View File

@ -1,61 +0,0 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: mattermost-app
labels:
app: mattermost
tier: app
namespace: default
spec:
replicas: 1
template:
metadata:
name: mattermost-app
labels:
app: mattermost
tier: app
spec:
containers:
- name: mattermost-app
image: "mattermost/mattermost-prod-app:5.14.1"
env:
- name: DB_HOST
valueFrom:
secretKeyRef:
name: mattermost.env
key: db-host
- name: DB_PORT_NUMBER
valueFrom:
secretKeyRef:
name: mattermost.env
key: db-port
- name: MM_USERNAME
valueFrom:
secretKeyRef:
name: mattermost.env
key: mm-username
- name: MM_PASSWORD
valueFrom:
secretKeyRef:
name: mattermost.env
key: mm-password
- name: MM_DBNAME
valueFrom:
secretKeyRef:
name: mattermost.env
key: mm-dbname
volumeMounts:
# optional persistent storage
#- name: appdata
#mountPath: /mattermost/data
- name: etclocaltime
mountPath: /etc/localtime
readOnly: true
volumes:
# optional persistent storage
#- name: appdata
#persistentVolumeClaim:
# claimName: mattermost-app
- name: etclocaltime
hostPath:
path: /etc/localtime

View File

@ -1,19 +0,0 @@
kind: Secret
apiVersion: v1
metadata:
name: mattermost.env
namespace: default
type: Opaque
data:
# see http://kubernetes.io/docs/user-guide/secrets/#creating-a-secret-using-kubectl-create-secret
# for creating secrets manually
# db
db-host: ZGI=
# 5432
db-port: NTQzMg==
# mmuser
mm-username: bW11c2Vy
# mmuser_password
mm-password: bW11c2VyX3Bhc3N3b3Jk
# mattermost
mm-dbname: bWF0dGVybW9zdA==

View File

@ -1,15 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: mattermost
namespace: default
spec:
type: NodePort
ports:
- port: 80
targetPort: 8000
protocol: TCP
name: http
selector:
app: mattermost
tier: app

View File

@ -1,135 +0,0 @@
# This file allows you to run mattermost within your docker swarm mode cluster
# for more informations check: https://docs.docker.com/engine/swarm/
#
# Simply run:
#
# `docker stack up [STACK NAME] -c docker-stack-traefik.yml`
#
# In this case `mm` is going to be stack name, so the command will be:
#
# `docker stack up mm -c docker-stack-traefik.yml`
#
# From now on all the services that belong to this stack will be prefixed with `mm_`
# this file defines 3 services, these are going to be mm_db, mm_app and mm_web,
# each of these names is the service's hostname as well, they can communicate
# with each other easily by using the hostname instead of the ip or exposing ports to the host.
#
# As a side note, images tagged as latest are pulled by default,
# that means there's no need to use `image:latest`
#
# use latest compose v3.3 file format for optimal compatibility with latest docker release and swarm features.
# see https://docs.docker.com/compose/compose-file/compose-versioning/#version-3
# and https://docs.docker.com/compose/compose-file/compose-versioning/#version-33
# and https://docs.docker.com/compose/compose-file/compose-versioning/#upgrading
version: '3.3'
networks:
# network for App <-> DB transactions
mm-in:
driver: overlay
internal: true
# this network faces the outside world
mm-out:
driver: overlay
internal: false
volumes:
mm-dbdata:
traefik-certs:
services:
db:
# use official mattermost prod-db image
image: mattermost/mattermost-prod-db
networks:
- mm-in
volumes:
# use a named-volume for data persistency
- mm-dbdata:/var/lib/postgresql/data
- /etc/localtime:/etc/localtime:ro
environment:
- POSTGRES_USER=mmuser
- POSTGRES_PASSWORD=mmuser_password
- POSTGRES_DB=mattermost
# uncomment the following to enable backup
# - AWS_ACCESS_KEY_ID=XXXX
# - AWS_SECRET_ACCESS_KEY=XXXX
# - WALE_S3_PREFIX=s3://BUCKET_NAME/PATH
# - AWS_REGION=us-east-1
deploy:
restart_policy:
condition: on-failure
app:
# use official mattermost prod-app image
image: mattermost/mattermost-prod-app:5.13.0
networks:
- mm-in
- mm-out
volumes:
- /var/lib/mattermost/config:/mattermost/config:rw
- /var/lib/mattermost/data:/mattermost/data:rw
- /var/lib/mattermost/logs:/mattermost/logs:rw
- /var/lib/mattermost/plugins:/mattermost/plugins:rw
- /etc/localtime:/etc/localtime:ro
environment:
# use service's hostname
- DB_HOST=mm_db
# talk to the port within the overlay network
# without (over)exposing ports
- DB_PORT_NUMBER=5432
- MM_USERNAME=mmuser
- MM_PASSWORD=mmuser_password
- MM_DBNAME=mattermost
# pass the edition to be used, default is enterprise
# setting this env var will make the app use the team edition
- edition=team
# in case your config is not in default location
# - MM_CONFIG=/mattermost/config/config.json
deploy:
labels:
- "traefik.backend.loadbalancer.sticky=true"
- "traefik.backend.loadbalancer.swarm=true"
# the backend service needs a name
- "traefik.backend=mmapp"
# network is prefixed `mm_` as well
- "traefik.docker.network=mm_mm-out"
# generate a TLS cert for this domain
- "traefik.entrypoints=https"
- "traefik.frontend.passHostHeader=true"
# add your domain below here
- "traefik.frontend.rule=Host:mattermost.domain.com"
- "traefik.port=80"
restart_policy:
condition: on-failure
web:
# use official traefik image
image: traefik
ports:
- "80:80"
# you can view the traefik's dashboard in http://localhost:8080
- "8080:8080"
- "443:443"
networks:
- mm-out
command: >
--acme
--acme.email="[ADD YOUR EMAIL HERE]"
--acme.entrypoint=https --acme.onhostrule
--acme.storage="acme/certs.json"
--acme.acmelogging
--web
--docker
--docker.domain=docker.localhost
--docker.swarmmode
--docker.watch
--logLevel=DEBUG
volumes:
# traefik needs the docker socket in order to work properly
- /var/run/docker.sock:/var/run/docker.sock
# no traefik config file is being used
# you can deep further in the traefik docs
# http://docs.traefik.io/user-guide/examples/
- /dev/null:/traefik.toml
# use a named-volume for certs persistency
- traefik-certs:/acme
deploy:
restart_policy:
condition: on-failure

View File

@ -1,108 +0,0 @@
# This file allows you to run mattermost within your docker swarm mode cluster
# for more informations check: https://docs.docker.com/engine/swarm/
#
# Simply run:
#
# `docker stack up [STACK NAME] -c docker-stack.yml`
#
# In this case `mattermost` is going to be stack name, so the command will be:
#
# `docker stack up mattermost -c docker-stack.yml`
#
# From now on all the services that belong to this stack will be prefixed with `mattermost_`
# this file defines 3 services, these are going to be mattermost_db, mattermost_app and mattermost_web,
# each of these names is the service's hostname as well, they can communicate
# with each other easily by using the hostname instead of the ip or exposing ports to the host.
#
# As a side note, images tagged as latest are pulled by default,
# that means there's no need to use `image:latest`
#
# use latest compose v3.3 file format for optimal compatibility with latest docker release and swarm features.
# see https://docs.docker.com/compose/compose-file/compose-versioning/#version-3
# and https://docs.docker.com/compose/compose-file/compose-versioning/#version-33
# and https://docs.docker.com/compose/compose-file/compose-versioning/#upgrading
version: '3.3'
networks:
# network for App <-> DB transactions
mm-in:
driver: overlay
internal: true
# this network faces the outside world
mm-out:
driver: overlay
internal: false
volumes:
mm-dbdata:
services:
db:
# use official mattermost prod-db image
image: mattermost/mattermost-prod-db
networks:
- mm-in
volumes:
# use a named-volume for data persistency
- mm-dbdata:/var/lib/postgresql/data
- /etc/localtime:/etc/localtime:ro
environment:
- POSTGRES_USER=mmuser
- POSTGRES_PASSWORD=mmuser_password
- POSTGRES_DB=mattermost
# uncomment the following to enable backup
# - AWS_ACCESS_KEY_ID=XXXX
# - AWS_SECRET_ACCESS_KEY=XXXX
# - WALE_S3_PREFIX=s3://BUCKET_NAME/PATH
# - AWS_REGION=us-east-1
deploy:
restart_policy:
condition: on-failure
app:
# use official mattermost prod-app image
image: mattermost/mattermost-prod-app:5.13.0
networks:
- mm-in
- mm-out
volumes:
- /var/lib/mattermost/config:/mattermost/config:rw
- /var/lib/mattermost/data:/mattermost/data:rw
- /var/lib/mattermost/logs:/mattermost/logs:rw
- /var/lib/mattermost/plugins:/mattermost/plugins:rw
- /etc/localtime:/etc/localtime:ro
environment:
# use service's hostname
- DB_HOST=db
# talk to the port within the overlay network
# without (over)exposing ports
- DB_PORT_NUMBER=5432
- MM_USERNAME=mmuser
- MM_PASSWORD=mmuser_password
- MM_DBNAME=mattermost
# pass the edition to be used, default is enterprise
# setting this env var will make the app use the team edition
- edition=team
# in case your config is not in default location
# - MM_CONFIG=/mattermost/config/config.json
deploy:
restart_policy:
condition: on-failure
web:
# use official mattermost prod-web image
image: mattermost/mattermost-prod-web
ports:
- "80:80"
- "443:443"
networks:
- mm-out
volumes:
# This directory must have cert files
- /var/lib/mattermost/cert:/cert:ro
- /etc/localtime:/etc/localtime:ro
environment:
# use app service's hostname
- APP_HOST=app
# talk to the port within the overlay network
# without (over)exposing ports
- APP_PORT_NUMBER=80
deploy:
restart_policy:
condition: on-failure

View File

@ -1,33 +1,19 @@
FROM postgres:9.4-alpine
FROM postgres:9.4
ENV DEFAULT_TIMEZONE UTC
RUN apt-get update \
&& apt-get install -y python-dev lzop pv daemontools curl build-essential \
&& curl --silent --show-error --retry 5 https://bootstrap.pypa.io/get-pip.py | python \
&& pip install wal-e \
&& apt-get remove -y build-essential python-dev \
&& apt-get autoremove -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# 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 make_db.sh /docker-entrypoint-initdb.d/
ADD setup-wale.sh /docker-entrypoint-initdb.d/
COPY docker-entrypoint1.sh /
RUN chmod +x /docker-entrypoint1.sh
# Add wale script
COPY setup-wale.sh /docker-entrypoint-initdb.d/
ENTRYPOINT ["/docker-entrypoint1.sh"]
#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"]

44
db/docker-entrypoint1.sh Executable file
View File

@ -0,0 +1,44 @@
#!/bin/bash
# if wal backup is not enabled, use minimal wal logging to reduce disk space
: ${WAL_LEVEL:=minimal}
: ${ARCHIVE_MODE:=off}
# PGDATA is defined in upstream postgres dockerfile
function update_conf () {
if [ -f $PGDATA/postgresql.conf ]; then
sed -i "s/wal_level =.*$/wal_level = $WAL_LEVEL/g" $PGDATA/postgresql.conf
sed -i "s/archive_mode =.*$/archive_mode = $ARCHIVE_MODE/g" $PGDATA/postgresql.conf
fi
}
if [ "${1:0:1}" = '-' ]; then
set -- postgres "$@"
fi
if [ "$1" = 'postgres' ]; then
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."
update_conf
. /docker-entrypoint.sh
exit
fi
done
umask u=rwx,g=rx,o=
mkdir -p /etc/wal-e.d/env
for v in ${VARS[@]}; do
echo "${!v}" > /etc/wal-e.d/env/$v
done
chown -R root:postgres /etc/wal-e.d
WAL_LEVEL=archive
ARCHIVE_MODE=on
update_conf
. /docker-entrypoint.sh
fi

View File

@ -1,62 +0,0 @@
#!/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

12
db/make_db.sh Normal file
View File

@ -0,0 +1,12 @@
#!/bin/bash
set -e
MM_USERNAME=${MM_USERNAME:-mmuser}
MM_PASSWORD=${MM_PASSWORD:-mmuser_password}
MM_DBNAME=${MM_DBNAME:-mattermost}
psql -v ON_ERROR_STOP=1 --username "postgres" <<- EOSQL
CREATE DATABASE $MM_DBNAME;
CREATE USER $MM_USERNAME WITH PASSWORD '$MM_PASSWORD';
GRANT ALL PRIVILEGES ON DATABASE $MM_DBNAME to $MM_USERNAME;
EOSQL

14
db/setup-wale.sh Executable file → Normal file
View File

@ -1,7 +1,11 @@
#!/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
# wal-e specific
echo "wal_level = $WAL_LEVEL" >> $PGDATA/postgresql.conf
echo "archive_mode = $ARCHIVE_MODE" >> $PGDATA/postgresql.conf
echo "archive_command = 'envdir /etc/wal-e.d/env /usr/local/bin/wal-e wal-push %p'" >> $PGDATA/postgresql.conf
echo "archive_timeout = 60" >> $PGDATA/postgresql.conf
# no cron in the image, use systemd timer on host instead
#su - postgres -c "crontab -l | { cat; echo \"0 3 * * * /usr/bin/envdir /etc/wal-e.d/env /usr/local/bin/wal-e backup-push /var/lib/postgresql/data\"; } | crontab -"
#su - postgres -c "crontab -l | { cat; echo \"0 4 * * * /usr/bin/envdir /etc/wal-e.d/env /usr/local/bin/wal-e delete --confirm retain 7\"; } | crontab -"

100
docker-compose.yml Executable file → Normal file
View File

@ -1,67 +1,33 @@
version: "3"
services:
db:
build: db
read_only: true
restart: unless-stopped
volumes:
- ./volumes/db/var/lib/postgresql/data:/var/lib/postgresql/data
- /etc/localtime:/etc/localtime:ro
environment:
- POSTGRES_USER=mmuser
- POSTGRES_PASSWORD=mmuser_password
- POSTGRES_DB=mattermost
# uncomment the following to enable backup
# - AWS_ACCESS_KEY_ID=XXXX
# - AWS_SECRET_ACCESS_KEY=XXXX
# - WALE_S3_PREFIX=s3://BUCKET_NAME/PATH
# - AWS_REGION=us-east-1
app:
build:
context: app
# uncomment following lines for team edition or change UID/GID
# args:
# - edition=team
# - PUID=1000
# - PGID=1000
# - MM_VERSION=5.31
restart: unless-stopped
volumes:
- ./volumes/app/mattermost/config:/mattermost/config:rw
- ./volumes/app/mattermost/data:/mattermost/data:rw
- ./volumes/app/mattermost/logs:/mattermost/logs:rw
- ./volumes/app/mattermost/plugins:/mattermost/plugins:rw
- ./volumes/app/mattermost/client-plugins:/mattermost/client/plugins:rw
- /etc/localtime:/etc/localtime:ro
# When you want to use SSO with GitLab, you have to add the cert pki chain of GitLab inside Alpine
# to avoid Token request failed: certificate signed by unknown authority (link: https://github.com/mattermost/mattermost-server/issues/13059)
# - <path_to_your_gitlab_pki>/pki_chain.pem:/etc/ssl/certs/pki_chain.pem:ro
environment:
# set same as db credentials and dbname
- MM_USERNAME=mmuser
- MM_PASSWORD=mmuser_password
- MM_DBNAME=mattermost
# use the credentials you've set above, in the format:
# MM_SQLSETTINGS_DATASOURCE=postgres://${MM_USERNAME}:${MM_PASSWORD}@db:5432/${MM_DBNAME}?sslmode=disable&connect_timeout=10
- MM_SQLSETTINGS_DATASOURCE=postgres://mmuser:mmuser_password@db:5432/mattermost?sslmode=disable&connect_timeout=10
# in case your config is not in default location
#- MM_CONFIG=/mattermost/config/config.json
web:
build: web
ports:
- "80:8080"
- "443:8443"
read_only: true
restart: unless-stopped
volumes:
# This directory must have cert files if you want to enable SSL
- ./volumes/web/cert:/cert:ro
- /etc/localtime:/etc/localtime:ro
cap_drop:
- ALL
db:
build: db
volumes:
- ./volumes/db/var/lib/postgresql/data:/var/lib/postgresql/data
- /etc/localtime:/etc/localtime:ro
# uncomment the following to enable backup
#environment:
# - AWS_ACCESS_KEY_ID=XXXX
# - AWS_SECRET_ACCESS_KEY=XXXX
# - WALE_S3_PREFIX=s3://BUCKET_NAME/PATH
# - AWS_REGION=us-east-1
app:
build: app
links:
- db:db
volumes:
- ./volumes/app/mattermost/config:/mattermost/config:rw
- ./volumes/app/mattermost/data:/mattermost/data:rw
- /etc/localtime:/etc/localtime:ro
web:
build: web
ports:
- "80:80"
- "443:443"
links:
- app:app
volumes:
# This directory must have cert files
- ./volumes/web/cert:/cert:ro
- /etc/localtime:/etc/localtime:ro
environment:
- MATTERMOST_ENABLE_SSL=false
- PLATFORM_PORT_80_TCP_PORT=80

View File

@ -1,40 +1,22 @@
FROM nginxinc/nginx-unprivileged:mainline-alpine
FROM ubuntu:14.04
USER root
RUN apt-get update && apt-get install -y nginx
# Remove default configuration and add our custom Nginx configuration files
RUN rm /etc/nginx/conf.d/default.conf \
&& apk add --no-cache curl
RUN rm /etc/nginx/sites-enabled/default
COPY ["./mattermost", "./mattermost-ssl", "/etc/nginx/sites-available/"]
COPY mattermost /etc/nginx/sites-available/
COPY mattermost-ssl /etc/nginx/sites-available/
ADD docker-entry.sh /
# Add and setup entrypoint
COPY entrypoint.sh /
RUN chmod +x /docker-entry.sh
RUN chown -R nginx:nginx /etc/nginx/sites-available && \
chown -R nginx:nginx /var/cache/nginx && \
chown -R nginx:nginx /var/log/nginx && \
chown -R nginx:nginx /etc/nginx/conf.d && \
chown nginx:nginx entrypoint.sh
RUN touch /var/run/nginx.pid && \
chown -R nginx:nginx /var/run/nginx.pid
# You can see the logs using `docker-compose logs web`.
RUN ln -sf /dev/stdout /var/log/nginx/access.log
RUN ln -sf /dev/stderr /var/log/nginx/error.log
COPY ./security.conf /etc/nginx/conf.d/
# Define working directory.
WORKDIR /etc/nginx
RUN chown -R nginx:nginx /etc/nginx/conf.d/security.conf
RUN chmod u+x /entrypoint.sh
RUN sed -i "/^http {/a \ proxy_buffering off;\n" /etc/nginx/nginx.conf
RUN sed -i '/temp_path/d' /etc/nginx/nginx.conf \
&& sed -i 's!/tmp/nginx.pid!/var/run/nginx.pid!g' /etc/nginx/nginx.conf
USER nginx
#Healthcheck to make sure container is ready
HEALTHCHECK CMD curl --fail http://localhost:8080 || exit 1
ENTRYPOINT ["/entrypoint.sh"]
VOLUME ["/var/run", "/etc/nginx/conf.d/", "/var/cache/nginx/"]
ENTRYPOINT /docker-entry.sh
EXPOSE 80 443

9
web/docker-entry.sh Normal file
View File

@ -0,0 +1,9 @@
#!/bin/bash
echo Starting Nginx
sed -Ei "s/APP_PORT/$PLATFORM_PORT_80_TCP_PORT/" /etc/nginx/sites-available/mattermost
sed -Ei "s/APP_PORT/$PLATFORM_PORT_80_TCP_PORT/" /etc/nginx/sites-available/mattermost-ssl
if [ "$MATTERMOST_ENABLE_SSL" = true ]; then
ssl="-ssl"
fi
ln -s /etc/nginx/sites-available/mattermost$ssl /etc/nginx/sites-enabled/mattermost
nginx -g 'daemon off;'

View File

@ -1,24 +0,0 @@
#!/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;'

View File

@ -1,39 +1,17 @@
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
default $http_x_forwarded_proto;
'' $scheme;
}
server {
listen 8080;
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%};
}
listen 80;
location / {
gzip on;
gzip off;
client_max_body_size 50M;
proxy_set_header Connection "";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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-Forwarded-Proto $scheme;
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%};
proxy_pass http://app:APP_PORT;
}
}

57
web/mattermost-ssl Executable file → Normal file
View File

@ -1,59 +1,34 @@
server {
listen 8080 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 80;
# server_name mattermost.example.com;
# return 301 https://$server_name$request_uri;
# }
server {
listen 8443 ssl http2;
listen 443;
ssl on;
ssl_certificate /cert/cert.pem;
ssl_certificate_key /cert/key-no-password.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1.2 TLSv1.3;
# Please update the ciphers in this file every 6 months.
# https://ssl-config.mozilla.org/
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
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%};
}
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:MEDIUM:!SSLv2:!PSK:!SRP:!ADH:!AECDH;
ssl_prefer_server_ciphers on;
location / {
gzip on;
gzip off;
proxy_set_header X-Forwarded-Ssl on;
client_max_body_size 50M;
proxy_set_header Connection "";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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-Forwarded-Proto $scheme;
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%};
proxy_pass http://app:APP_PORT;
}
}
# See https://docs.mattermost.com/install/install-ubuntu-1604.html#configuring-nginx-with-ssl-and-http-2 for the SSL configuration
# See https://github.com/mattermost/docs/blob/master/source/install/prod-ubuntu.rst for the SSL configuration

View File

@ -1,22 +0,0 @@
# 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";