提交 17fbbabf 编写于 作者: T TommyLike 提交者: Gitee

!2 mail dockerfile cleanup

Merge pull request !2 from TommyLike/feature/clean-up
.idea/*
\ No newline at end of file
.idea/*
.interpreter/*
\ No newline at end of file
......@@ -2,18 +2,24 @@
### Brief Introduction
This repository houses the scripts for community infrastruture, you are welcome to join us. any contribution will be appreciated.
This repository houses the scripts for community infrastructure, you are welcome to join us. any contribution will be appreciated.
### Structure
```
|__environment --house the scripts of basic infrastructure.
|__mail --house the scripts of mail list system
|__website --house the scripts of CD system
|__docs --house the design docs
|__assets --house the basic assets. e.g. images.
```
Currently, all systems are running in huaweicloud CCE engine as container, we appreciate anyone who is will to contribute your infrastructure resource into our community. thanks.
### Mail
Currently, all systems are running in huaweicloud CCE engine as container, we appreciate anyone who are will to contribute your infrastructure resource into our community. thanks.
Our mail list system is based on (Mailman + Exim4 + Postgres), thanks to maxking, our first version of system
is based on his [dockerfile](https://github.com/maxking/docker-mailman) on mailman suite.
### License
......
# Postgres Dockerfile
We use postgres' official 9.6-alpine docker image, see [here](https://hub.docker.com/_/postgres?tab=tags).
\ No newline at end of file
FROM ubuntu:14.04
LABEL version="1.0.0"
LABEL maintainer="tommylikehu@gmail.com"
LABEL maintainer="developer@openeuler.org"
ENV TINI_VERSION v0.14.0
RUN set -x \
......@@ -20,8 +20,5 @@ RUN set -x \
RUN apt-get update && apt-get install -y exim4 && rm -rf /var/lib/apt/lists/*
ADD update-exim4.conf.conf /etc/exim4/
RUN sudo update-exim4.conf
EXPOSE 25
CMD ["tini", "--", "exim", "-bd", "-v"]
\ No newline at end of file
# Exim4 Dockerfile
This dockerfile used to create the exim4 image used for mail list system, as a reminder all of
the related exim4 config files(25_mm3_macros/55_mm3_transport/455_mm3_router/etc) are been added via
a configmap when initialize the deployments, therefore it's not presence in dockerfile.
\ No newline at end of file
FROM alpine:3.8
MAINTAINER Abhilash Raj
#Add startup script to container
COPY docker-entrypoint.sh /usr/local/bin/
#Install all required packages, add user for executing mailman and set execution rights for startup script
RUN apk update \
&& apk add --virtual build-deps gcc python3-dev musl-dev postgresql-dev \
libffi-dev \
&& apk add --no-cache bash su-exec postgresql-client mysql-client curl python py3-setuptools \
&& python3 -m pip install -U pip \
&& python3 -m pip install psycopg2 \
mailman==3.2.2 \
mailman-hyperkitty==1.1.0 \
pymysql \
&& apk del build-deps \
&& adduser -S mailman
# Change the working directory.
WORKDIR /opt/mailman
#Expose the ports for the api (8001) and lmtp (8024)
EXPOSE 8001 8024
ENV MAILMAN_CONFIG_FILE /etc/mailman.cfg
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["master", "--force"]
FROM alpine:3.8
MAINTAINER Abhilash Raj
#Add startup script to container
COPY docker-entrypoint.sh /usr/local/bin/
# Set the commits that we are building.
ARG CORE_REF
ARG MM3_HK_REF
#Install all required packages, add user for executing mailman and set execution
#rights for startup script
RUN apk update \
&& apk add --no-cache --virtual build-deps gcc python3-dev musl-dev \
postgresql-dev git libffi-dev \
&& apk add --no-cache bash su-exec postgresql-client mysql-client curl python3 py3-setuptools \
&& python3 -m pip install -U psycopg2 pymysql \
git+https://gitlab.com/mailman/mailman@${CORE_REF} \
git+https://gitlab.com/mailman/mailman-hyperkitty@${MM3_HK_REF} \
&& apk del build-deps \
&& adduser -S mailman
# Change the working directory.
WORKDIR /opt/mailman
#Expose the ports for the api (8001) and lmtp (8024)
EXPOSE 8001 8024
# Set the default configuration file.
ENV MAILMAN_CONFIG_FILE /etc/mailman.cfg
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["master"]
Mailman3 Core Docker Image
==========================
When you spawn off this container, you must mount `/opt/mailman` to the
container. Mailman's `var` directory will also be stored here so that it can
persist across different sessions and containers. Any configuration at
`/opt/mailman/core/mailman-extra.cfg` (on the host) will be added to the mailman's default
generated confifguration (See below).
It is not advised to run multiple mailman processes on the same host sharing the
same `/opt/mailman` (`/opt/mailman/core` on the host) directory as this will
almost certainly be dangerous.
Configuration
=============
These are the variables that you MUST change before deploying:
- `HYPERKITTY_API_KEY`: Hyperkitty's API Key, should be set to the same value as
set for the mailman-core.
- `DATABASE_URL`: URL of the type
`driver://user:password@hostname:port/databasename` for the django to use. If
not set, the default is set to
`sqlite:///opt/mailman-web-data/mailmanweb.db`. The standard
docker-compose.yaml comes with it set to a postgres database. It is not must
to change this if you are happy with postgresql.
- `DATABASE_TYPE`: It's value can be one of `sqlite`, `postgres` or `mysql` as
these are the only three database types that Mailman 3 supports. It's defualt
value is set to `sqlite` along with the default database class and default
database url above.
- `DATABASE_CLASS`: Default value is
`mailman.database.sqlite.SQLiteDatabase`. The values for this can be found in
the mailman's documentation [here][11].
These are the variables that you don't need to change if you are using a
standard version of docker-compose.yaml from this repository.
- `MM_HOSTNAME`: Which IP should Core bind to for REST API and LMTP. If not
defined output for `hostname -i` command is used.
- `MAILMAN_REST_PORT`: Which port should Core use for the REST API. If not defined
the default is `8001`.
- `MAILMAN_REST_USER`: Which username should Core use for the REST API. If not
defined the default is `restadmin`.
- `MAILMAN_REST_PASSWORD`: Which password should Core use for the REST API. If
not defined the default is `restpass`.
- `MTA`: Mail Transfer Agent to use. Either `exim` or `postfix`. Default value is `exim`.
- `SMTP_HOST`: IP Address/hostname from which you will be sending
emails. Default value is `172.19.199.1`, which is the address of the Host OS.
- `SMTP_PORT`: Port used for SMTP. Default is `25`.
- `HYPERKITTY_URL`: Default value is `http://mailman-web:8000/hyperkitty`
Running Mailman-Core
====================
It is highly recomended that you run this image along with the
docker-compose.yaml file provided at the [github repo][1] of this
image. However, it is possibel to run this image as a standalone container if
you want just a mailman-core.
```bash
$ mkdir -p /opt/mailman/core
$ docker run -it -e "HYPERKITTY_API_KEY=changeme" -h mailman-core -v /opt/mailman/core:/opt/mailman mailman-core
```
However, if you don't provide the environment `DATABASE_URL`, the database _may_
not be persistant. All the configuration options are explained in more detail.
If you need mode advanced configuration for mailman, you can create
`/opt/mailman/mailman.cfg` and it be added to the configuration inside the
container. Note that, anything inside this configuration will override the
settings provided via the environment variables and their default values.
By default, the following settings are generated:
```
# mailman.cfg
[mta]
incoming: mailman.mta.exim4.LMTP
outgoing: mailman.mta.deliver.deliver
lmtp_host: $MM_HOSTNAME
lmtp_port: 8024
smtp_host: $SMTP_HOST
smtp_port: $SMTP_PORT
configuration: python:mailman.config.exim4
[runner.retry]
sleep_time: 10s
[webservice]
hostname: $MM_HOSTNAME
port: $MAILMAN_REST_PORT
admin_user: $MAILMAN_REST_USER
admin_pass: $MAILMAN_REST_PASSWORD
[archiver.hyperkitty]
class: mailman_hyperkitty.Archiver
enable: yes
configuration: /etc/mailman-hyperkitty.cfg
[database]
class: $DATABASE_CLASS
url: $DATABASE_URL
```
```
# mailman-hyperkitty.cfg
[general]
base_url: $HYPERKITTY_URL
api_key: $HYPERKITTY_API_KEY
```
MTA
===
You can use Postfix or [Exim][2] with this image to send emails. Mailman Core
can interact with any modern MTA which can deliver emails over LMTP. The
documentation for Mailman Core has configuration settigs for using them.
Only Exim and Postfix has been tested with these images and are supported as of
now. There _might_ be some limitations with using other MTAs in a containerized
environments. Contributions are welcome for anything additional needed to
support other MTAs.
To setup Exim or Posfix, checkout the [documentation][3].
[1]: https://github.com/maxking/docker-mailman
[2]: http://www.exim.org
[3]: https://asynchronous.in/docker-mailman#setting-up-your-mta
# Place this file at
# /etc/exim4/conf.d/main/25_mm3_macros
domainlist mm3_domains=MY_DOMAIN_NAME
MM3_LMTP_HOST=172.19.199.2
MM3_LMTP_PORT=8024
MM3_HOME=/opt/mailman/core/var
################################################################
# The configuration below is boilerplate:
# you should not need to change it.
# The path to the list receipt (used as the required file when
# matching list addresses)
MM3_LISTCHK=MM3_HOME/lists/${local_part}.${domain}
# Place this file at
# /etc/exim4/conf.d/router/455_mm3_router
mailman3_router:
driver = accept
domains = +mm3_domains
require_files = MM3_LISTCHK
local_part_suffix_optional
local_part_suffix = -admin : \
-bounces : -bounces+* : \
-confirm : -confirm+* : \
-join : -leave : \
-owner : -request : \
-subscribe : -unsubscribe
transport = mailman3_transport
# Place this file at
# /etc/exim4/conf.d/transport/55_mm3_transport
mailman3_transport:
debug_print = "Email for mailman"
driver = smtp
protocol = lmtp
allow_localhost
hosts = MM3_LMTP_HOST
port = MM3_LMTP_PORT
rcpt_include_affixes = true
[general]
# This is your HyperKitty installation, preferably on the localhost. This
# address will be used by Mailman to forward incoming emails to HyperKitty
# for archiving. It does not need to be publicly available, in fact it's
# better if it is not.
base_url: http://mailman-web:8000/hyperkitty/
# Shared API key, must be the identical to the value in HyperKitty's
# settings.
api_key: ASmallAPIKey
[mta]
incoming: mailman.mta.exim4.LMTP
outgoing: mailman.mta.deliver.deliver
lmtp_host: mailman-core
lmtp_port: 8024
smtp_host: 172.19.199.1
smtp_port: 25
configuration: python:mailman.config.exim4
# [archiver.mhonarc]
# enable: yes
# [archiver.mail_archive]
# enable: yes
# [archiver.prototype]
# enable: yes
[runner.retry]
sleep_time: 10s
[shell]
use_ipython: yes
[webservice]
hostname: mailman-core
[archiver.hyperkitty]
class: mailman_hyperkitty.Archiver
enable: yes
configuration: /opt/mailman/mailman-hyperkitty.cfg
[database]
class: mailman.database.postgresql.PostgreSQLDatabase
url: postgres://mailman:mailmanpass@database/mailmandb
#! /bin/bash
set -e
function wait_for_postgres () {
# Check if the postgres database is up and accepting connections before
# moving forward.
# TODO: Use python3's psycopg2 module to do this in python3 instead of
# installing postgres-client in the image.
until psql $DATABASE_URL -c '\l'; do
>&2 echo "Postgres is unavailable - sleeping"
sleep 1
done
>&2 echo "Postgres is up - continuing"
}
function wait_for_mysql () {
# Check if MySQL is up and accepting connections.
HOSTNAME=$(python3 -c "from urllib.parse import urlparse; o = urlparse('$DATABASE_URL'); print(o.hostname);")
until mysqladmin ping --host "$HOSTNAME" --silent; do
>&2 echo "MySQL is unavailable - sleeping"
sleep 1
done
>&2 echo "MySQL is up - continuing"
}
# Empty the config file.
echo "# This file is autogenerated at container startup." > /etc/mailman.cfg
# Check if $MM_HOSTNAME is set, if not, set it to the value returned by
# `hostname -i` command to set it to whatever IP address is assigned to the
# container.
if [[ ! -v MM_HOSTNAME ]]; then
export MM_HOSTNAME=`hostname -i`
fi
if [[ ! -v SMTP_HOST ]]; then
export SMTP_HOST='172.19.199.1'
fi
if [[ ! -v SMTP_PORT ]]; then
export SMTP_PORT=25
fi
# Check if REST port, username, and password are set, if not, set them
# to default values.
if [[ ! -v MAILMAN_REST_PORT ]]; then
export MAILMAN_REST_PORT='8001'
fi
if [[ ! -v MAILMAN_REST_USER ]]; then
export MAILMAN_REST_USER='restadmin'
fi
if [[ ! -v MAILMAN_REST_PASSWORD ]]; then
export MAILMAN_REST_PASSWORD='restpass'
fi
function setup_database () {
if [[ ! -v DATABASE_URL ]]
then
echo "Environemnt variable DATABASE_URL should be defined..."
exit 1
fi
# Translate mysql:// urls to mysql+mysql:// backend:
if [[ "$DATABASE_URL" == mysql://* ]]; then
DATABASE_URL="mysql+pymysql://${DATABASE_URL:8}"
echo "Database URL was automatically rewritten to: $DATABASE_URL"
fi
# If DATABASE_CLASS is not set, guess it for common databases:
if [ -z "$DATABASE_CLASS" ]; then
if [[ ("$DATABASE_URL" == mysql:*) ||
("$DATABASE_URL" == mysql+*) ]]; then
DATABASE_CLASS=mailman.database.mysql.MySQLDatabase
fi
if [[ ("$DATABASE_URL" == postgres:*) ||
("$DATABASE_URL" == postgres+*) ]]; then
DATABASE_CLASS=mailman.database.postgresql.PostgreSQLDatabase
fi
fi
cat >> /etc/mailman.cfg <<EOF
[database]
class: $DATABASE_CLASS
url: $DATABASE_URL
EOF
}
# Check if $DATABASE_URL is defined, if not, use a standard sqlite database.
#
# If the $DATABASE_URL is defined and is postgres, check if it is available
# yet. Do not start the container before the postgresql boots up.
#
# TODO: If the $DATABASE_URL is defined and is mysql, check if the database is
# available before the container boots up.
#
# TODO: Check the database type and detect if it is up based on that. For now,
# assume that postgres is being used if DATABASE_URL is defined.
if [[ ! -v DATABASE_URL ]]; then
echo "DATABASE_URL is not defined. Using sqlite database..."
else
setup_database
fi
if [[ "$DATABASE_TYPE" = 'postgres' ]]
then
wait_for_postgres
elif [[ "$DATABASE_TYPE" = 'mysql' ]]
then
wait_for_mysql
fi
# Generate a basic mailman.cfg.
cat >> /etc/mailman.cfg << EOF
[runner.retry]
sleep_time: 10s
[webservice]
hostname: $MM_HOSTNAME
port: $MAILMAN_REST_PORT
admin_user: $MAILMAN_REST_USER
admin_pass: $MAILMAN_REST_PASSWORD
[archiver.hyperkitty]
class: mailman_hyperkitty.Archiver
enable: yes
configuration: /etc/mailman-hyperkitty.cfg
EOF
# Generate a basic configuration to use exim
cat > /tmp/exim-mailman.cfg <<EOF
[mta]
incoming: mailman.mta.exim4.LMTP
outgoing: mailman.mta.deliver.deliver
lmtp_host: $MM_HOSTNAME
lmtp_port: 8024
smtp_host: $SMTP_HOST
smtp_port: $SMTP_PORT
configuration: python:mailman.config.exim4
EOF
cat > /etc/postfix-mailman.cfg << EOF
[postfix]
transport_file_type: regex
# While in regex mode, postmap_command is never used, a placeholder
# is added here so that it doesn't break anything.
postmap_command: true
EOF
# Generate a basic configuration to use postfix.
cat > /tmp/postfix-mailman.cfg <<EOF
[mta]
incoming: mailman.mta.postfix.LMTP
outgoing: mailman.mta.deliver.deliver
lmtp_host: $MM_HOSTNAME
lmtp_port: 8024
smtp_host: $SMTP_HOST
smtp_port: $SMTP_PORT
configuration: /etc/postfix-mailman.cfg
EOF
if [ "$MTA" == "exim" ]
then
echo "Using Exim configuration"
cat /tmp/exim-mailman.cfg >> /etc/mailman.cfg
elif [ "$MTA" == "postfix" ]
then
echo "Using Postfix configuration"
cat /tmp/postfix-mailman.cfg >> /etc/mailman.cfg
else
echo "No MTA environment variable found, defaulting to Exim"
cat /tmp/exim-mailman.cfg >> /etc/mailman.cfg
fi
rm -f /tmp/{postfix,exim}-mailman.cfg
if [[ -e /opt/mailman/mailman-extra.cfg ]]
then
echo "Found configuration file at /opt/mailman/mailman-extra.cfg"
cat /opt/mailman/mailman-extra.cfg >> /etc/mailman.cfg
fi
if [[ ! -v HYPERKITTY_API_KEY ]]; then
echo "HYPERKITTY_API_KEY not defined, please set this environment variable..."
echo "exiting..."
exit 1
fi
if [[ ! -v HYPERKITTY_URL ]]; then
echo "HYPERKITTY_URL not set, using the default value of http://mailman-web:8000/hyperkitty"
export HYPERKITTY_URL="http://mailman-web:8000/hyperkitty/"
fi
# Generate a basic mailman-hyperkitty.cfg.
cat > /etc/mailman-hyperkitty.cfg <<EOF
[general]
base_url: $HYPERKITTY_URL
api_key: $HYPERKITTY_API_KEY
EOF
# Generate the LMTP files for postfix if needed.
mailman aliases
# Now chown the places where mailman wants to write stuff.
chown -R mailman /opt/mailman
exec su-exec mailman "$@"
# Place this file at
# /etc/exim4/conf.d/main/25_mm3_macros
domainlist mm3_domains=MY_DOMAIN_NAME
MM3_LMTP_HOST=172.19.199.2
MM3_LMTP_PORT=8024
MM3_HOME=/opt/mailman/core/var
################################################################
# The configuration below is boilerplate:
# you should not need to change it.
# The path to the list receipt (used as the required file when
# matching list addresses)
MM3_LISTCHK=MM3_HOME/lists/${local_part}.${domain}
# Place this file at
# /etc/exim4/conf.d/router/455_mm3_router
mailman3_router:
driver = accept
domains = +mm3_domains
require_files = MM3_LISTCHK
local_part_suffix_optional
local_part_suffix = -admin : \
-bounces : -bounces+* : \
-confirm : -confirm+* : \
-join : -leave : \
-owner : -request : \
-subscribe : -unsubscribe
transport = mailman3_transport
# Place this file at
# /etc/exim4/conf.d/transport/55_mm3_transport
mailman3_transport:
debug_print = "Email for mailman"
driver = smtp
protocol = lmtp
allow_localhost
hosts = MM3_LMTP_HOST
port = MM3_LMTP_PORT
rcpt_include_affixes = true
# /etc/exim4/update-exim4.conf.conf
#
# Edit this file and /etc/mailname by hand and execute update-exim4.conf
# yourself or use 'dpkg-reconfigure exim4-config'
#
# Please note that this is _not_ a dpkg-conffile and that automatic changes
# to this file might happen. The code handling this will honor your local
# changes, so this is usually fine, but will break local schemes that mess
# around with multiple versions of the file.
#
# update-exim4.conf uses this file to determine variable values to generate
# exim configuration macros for the configuration file.
#
# Most settings found in here do have corresponding questions in the
# Debconf configuration, but not all of them.
#
# This is a Debian specific file
# Remark on configuration `dc_eximconfig_configtype`:
# Used to configure type for the mail server.
# 1. internet site; mail is sent and received directly using SMTP
# 2. mail sent by smarthost; received via SMTP or fetchmail
# 3. mail sent by smarthost; no local mail
# 4. local delivery only; not on a network
# 5. no configuration at this time
dc_eximconfig_configtype='internet'
# Remark on configuration `dc_other_hostnames`:
# The 'mail name' is the domain name used to 'qualify' mail addresses without a domain name.
# This name will also be used by other programs. It should be the single, fully qualified domain name (FQDN).
# Thus, if a mail address on the local host is foo@example.org, the correct value for this option would be example.org.
# This name won't appear on From: lines of outgoing messages if rewriting is enabled.
dc_other_hostnames='tommylike.me;'
# Remark on configuration `dc_local_interfaces`:
# Please enter a semicolon-separated list of IP addresses. The Exim SMTP listener daemon will listen on all IP addresses listed here.
# An empty value will cause Exim to listen for connections on all available network interfaces.
dc_local_interfaces=''
# Remark on configuration `dc_readhost`:
# Please enter a semicolon-separated list of recipient domains for which this machine should consider itself the final destination. These domains are commonly called 'local domains'. The local hostname (local.tommylike.me) and 'localhost' are always added to the list given here.
# By default all local domains will be treated identically. If both a.example and b.example are local domains, acc@a.example and acc@b.example will be delivered to the same final destination. If different domain names should be treated differently, it is necessary
# to edit the config files afterwards. │ Other destinations for which mail is accepted:
dc_readhost='tommylike.me'
# Remark on configuration `dc_relay_domains`:
# Please enter a semicolon-separated list of recipient domains for which this system will relay mail, for example as a fallback MX or mail gateway.
# This means that this system will accept mail for these domains from anywhere on the Internet and deliver them according to local delivery rules.
dc_relay_domains='*.mail-suit-service.default.svc.cluster.local'
# Remark on configuration `dc_minimaldns`:
dc_minimaldns='false'
# Remark on configuration `dc_relay_nets`:
# Please enter a semicolon-separated list of IP address ranges for which this system will unconditionally relay mail, functioning as a smarthost.
# You should use the standard address/prefix format (e.g. 194.222.242.0/24 or 5f03:1200:836f::/48).
# If this system should not be a smarthost for any other host, leave this list blank.
# dc_relay_nets='172.19.199.3; 172.19.199.2;'
# Remark on configuration `dc_smarthost`:
dc_smarthost=''
# Remark on configuration `CFILEMODE`:
CFILEMODE='644'
# Remark on configuration `dc_use_split_config`:
dc_use_split_config='true'
# Remark on configuration `dc_hide_mailname`:
dc_hide_mailname=''
# Remark on configuration `dc_mailname_in_oh`:
dc_mailname_in_oh='true'
# Remark on configuration `dc_localdelivery`:
dc_localdelivery='mail_spool'
\ No newline at end of file
FROM maxking/mailman-web:0.2.3
COPY static /opt/mailman-web/static
EXPOSE 8000 8080
# Use stop signal for uwsgi server
STOPSIGNAL SIGINT
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["uwsgi", "--ini", "/opt/mailman-web/uwsgi.ini"]
\ No newline at end of file
Mailman 3 Web UI
================
This image consists of Mailman3's Web UI(Postorius) and Archiver
(Hyperkitty). This image is built from latest sources on [gitlab][1]. In future,
latest and stable releases will be seperate. I am looking forward to the release
of Mailman Suite 3.1 before that.
Configuration
=============
These are the settings that you MUST change before deploying:
- `SERVE_FROM_DOMAIN`: The domain name from which Django will be served. To be
added to `ALLOWED_HOSTS` in django settings. Default value is not set. This
also replaces Django's default `example.com` SITE and becomes the default SITE
(with SITE_ID=1).
- `HYPERKITTY_API_KEY`: Hyperkitty's API Key, should be set to the same value as
set for the mailman-core.
- `MAILMAN_ADMIN_USER`: The username for the admin user to be created by default.
- `MAILMAN_ADMIN_EMAIL`: The email for the admin user to be created by default.
- `SECRET_KEY`: Django's secret key, mainly used for signing cookies and others.
These are the settings that are set to sane default and you do not need to
change them unless you know what you want.
- `DATABASE_URL`: URL of the type
`driver://user:password@hostname:port/databasename` for the django to use. If
not set, the default is set to
`sqlite:///opt/mailman-web-data/mailmanweb.db`. The standard
docker-compose.yaml comes with it set to a postgres database. It is not must
to change this if you are happy with postgresql.
- `MAILMAN_REST_URL`: The URL to the Mailman core's REST API server. Defaut
value is `http://mailman-core:8001`.
- `MAILMAN_REST_USER`: Mailman's REST API username. Default value is `restadmin`
- `MAILMAN_REST_PASSWORD`: Mailman's REST API user's password. Default value is
`restpass`
- `MAILMAN_HOST_IP`: IP of the Container from which Mailman will send emails to
hyperkitty (django). Set to `172.19.199.2` by default.
- `SMTP_HOST`: IP Address/hostname from which you will be sending
emails. Default value is `172.19.199.1`, which is the address of the Host OS.
- `SMTP_PORT`: Port used for SMTP. Default is `25`.
- `SMTP_HOST_USER`: Used for SMTP authentication. Default is an empty string.
- `SMTP_HOST_PASSWORD`: Default is an empty string.
- `SMTP_USE_TLS`: Specifies wheather the SMTP connection is encrypted
via TLS. Default is `False`.
- `DJANGO_LOG_URL`: Path to the django's log file. Defaults to
`/opt/mailman-web-data/logs/mailmanweb.log`.
- `DJANGO_ALLOWED_HOSTS`: Entry to add to ALLOWED_HOSTS in Django
configuration. This is a separate configuration from`SERVE_FROM_DOMAIN` as
latter is used for other purposes too.
- `POSTORIUS_TEMPLATE_BASE_URL`: The base url at which the `mailman-web`
container can be reached from `mailman-core` container. This is set to
`http://mailman-web:8000` by default so that Core can fetch templates from
Web.
Running
=======
It is highly recommended that you run this using the [docker-compose.yaml][2]
provided in the [github repo][3] of this project. You will need to proxy the
requests the container that you create with this image using an actual web
server like Nginx. The [github repo][3] provides the setup instructions for
Nginx.
Since the setup has `USE_SSL` set to `True` in django's `settings.py`, you may
also want to get a SSL certificate if you don't already have one. [Lets
Encrypt][4] provides free SSL certiticates for everyone and there are _some_
instructions about that also.
After the first run, you can create a superuser for django using the following
command:
```bash
$ docker exec -it mailman-web python manage.py createsuperuser
```
[1]: https://gitlab.com/mailman
[3]: https://github.com/maxking/docker-mailman/
[2]: https://github.com/maxking/docker-mailman/blob/master/docker-compose.yaml
[4]: https://letsencrypt.org
FROM alpine:3.8
MAINTAINER Abhilash Raj
# Add needed files for uwsgi server + settings for django
COPY mailman-web /opt/mailman-web
# Add startup script to container
COPY docker-entrypoint.sh /usr/local/bin/
# Install packages and dependencies for postorius and hyperkitty Add user for
# executing apps, change ownership for uwsgi+django files and set execution
# rights for management script
RUN set -ex \
&& apk add --no-cache --virtual .build-deps gcc libc-dev linux-headers \
postgresql-dev mariadb-dev python3-dev libffi-dev \
&& apk add --no-cache --virtual .mailman-rundeps bash sassc \
postgresql-client mysql-client py-mysqldb curl mailcap \
python3 py3-setuptools xapian-core xapian-bindings-python3 libffi \
&& python3 -m pip install -U django==2.1.5 pip \
&& python3 -m pip install mailmanclient==3.2.2 \
postorius==1.2.4 \
hyperkitty==1.2.2 \
django-mailman3==1.2.0 \
whoosh \
uwsgi \
psycopg2 \
dj-database-url \
mysqlclient \
typing \
xapian-haystack \
&& apk del .build-deps \
&& addgroup -S mailman \
&& adduser -S -G mailman mailman \
&& chown -R mailman /opt/mailman-web/ \
&& chmod u+x /opt/mailman-web/manage.py
WORKDIR /opt/mailman-web
# Expose port 8000 for http and port 8080 for uwsgi
# (see web/mailman-web/uwsgi.ini#L2-L4)
EXPOSE 8000 8080
# Use stop signal for uwsgi server
STOPSIGNAL SIGINT
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["uwsgi", "--ini", "/opt/mailman-web/uwsgi.ini"]
FROM alpine:3.8
MAINTAINER Abhilash Raj
# Add needed files for uwsgi server + settings for django
COPY mailman-web /opt/mailman-web
# Add startup script to container
COPY docker-entrypoint.sh /usr/local/bin/
ARG POSTORIUS_REF
ARG HYPERKITTY_REF
ARG DJ_MM3_REF
ARG CLIENT_REF
# Install packages and dependencies for postorius and hyperkitty Add user for
# executing apps, change ownership for uwsgi+django files and set execution
# rights for management script
RUN set -ex \
&& apk add --no-cache --virtual .build-deps gcc libc-dev linux-headers git \
postgresql-dev mariadb-dev python3-dev libffi-dev \
&& apk add --no-cache --virtual .mailman-rundeps bash sassc \
python3 py3-setuptools postgresql-client mysql-client py-mysqldb\
curl mailcap xapian-core xapian-bindings-python3 libffi \
&& python3 -m pip install -U \
git+https://gitlab.com/mailman/mailmanclient@${CLIENT_REF} \
git+https://gitlab.com/mailman/postorius@${POSTORIUS_REF} \
git+https://gitlab.com/mailman/hyperkitty@${HYPERKITTY_REF} \
whoosh \
uwsgi \
psycopg2 \
dj-database-url \
mysqlclient \
xapian-haystack \
&& python3 -m pip install -U 'Django<2.2' \
&& python3 -m pip install -U \
git+https://gitlab.com/mailman/django-mailman3@${DJ_MM3_REF} \
&& apk del .build-deps \
&& addgroup -S mailman \
&& adduser -S -G mailman mailman \
&& chown -R mailman /opt/mailman-web/ \
&& chmod u+x /opt/mailman-web/manage.py
WORKDIR /opt/mailman-web
# Expose port 8000 for http and port 8080 for uwsgi
# (see web/mailman-web/uwsgi.ini#L2-L4)
EXPOSE 8000 8080
# Use stop signal for uwsgi server
STOPSIGNAL SIGINT
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["uwsgi", "--ini", "/opt/mailman-web/uwsgi.ini"]
#! /bin/bash
set -e
function wait_for_postgres () {
# Check if the postgres database is up and accepting connections before
# moving forward.
# TODO: Use python's psycopg2 module to do this in python instead of
# installing postgres-client in the image.
until psql $DATABASE_URL -c '\l'; do
>&2 echo "Postgres is unavailable - sleeping"
sleep 1
done
>&2 echo "Postgres is up - continuing"
}
function wait_for_mysql () {
# Check if MySQL is up and accepting connections.
HOSTNAME=$(python3 <<EOF
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse
o = urlparse('$DATABASE_URL')
print(o.hostname)
EOF
)
until mysqladmin ping --host "$HOSTNAME" --silent; do
>&2 echo "MySQL is unavailable - sleeping"
sleep 1
done
>&2 echo "MySQL is up - continuing"
}
function check_or_create () {
# Check if the path exists, if not, create the directory.
if [[ ! -e dir ]]; then
echo "$1 does not exist, creating ..."
mkdir "$1"
fi
}
# function postgres_ready(){
# python << END
# import sys
# import psycopg2
# try:
# conn = psycopg2.connect(dbname="$POSTGRES_DB", user="$POSTGRES_USER", password="$POSTGRES_PASSWORD", host="postgres")
# except psycopg2.OperationalError:
# sys.exit(-1)
# sys.exit(0)
# END
# }
# Check if $SECRET_KEY is defined, if not, bail out.
if [[ ! -v SECRET_KEY ]]; then
echo "SECRET_KEY is not defined. Aborting."
exit 1
fi
# Check if $DATABASE_URL is defined, if not, use a standard sqlite database.
#
# If the $DATABASE_URL is defined and is postgres, check if it is available
# yet. Do not start the container before the postgresql boots up.
#
# If the $DATABASE_URL is defined and is mysql, check if the database is
# available before the container boots up.
#
# TODO: Check the database type and detect if it is up based on that. For now,
# assume that postgres is being used if DATABASE_URL is defined.
if [[ ! -v DATABASE_URL ]]; then
echo "DATABASE_URL is not defined. Using sqlite database..."
export DATABASE_URL=sqlite://mailmanweb.db
export DATABASE_TYPE='sqlite'
fi
if [[ "$DATABASE_TYPE" = 'postgres' ]]
then
wait_for_postgres
elif [[ "$DATABASE_TYPE" = 'mysql' ]]
then
wait_for_mysql
fi
# Check if we are in the correct directory before running commands.
if [[ ! $(pwd) == '/opt/mailman-web' ]]; then
echo "Running in the wrong directory...switching to /opt/mailman-web"
cd /opt/mailman-web
fi
# Check if the logs directory is setup.
if [[ ! -e /opt/mailman-web-data/logs/mailmanweb.log ]]; then
echo "Creating log file for mailman web"
mkdir -p /opt/mailman-web-data/logs/
touch /opt/mailman-web-data/logs/mailmanweb.log
fi
if [[ ! -e /opt/mailman-web-data/logs/uwsgi.log ]]; then
echo "Creating log file for uwsgi.."
touch /opt/mailman-web-data/logs/uwsgi.log
fi
# Check if the settings_local.py file exists, if yes, copy it too.
if [[ -e /opt/mailman-web-data/settings_local.py ]]; then
echo "Copying settings_local.py ..."
cp /opt/mailman-web-data/settings_local.py /opt/mailman-web/settings_local.py
chown mailman:mailman /opt/mailman-web/settings_local.py
else
echo "settings_local.py not found, it is highly recommended that you provide one"
echo "Using default configuration to run."
fi
# Collect static for the django installation.
python3 manage.py collectstatic --noinput
# Migrate all the data to the database if this is a new installation, otherwise
# this command will upgrade the database.
python3 manage.py migrate
# If MAILMAN_ADMIN_USER and MAILMAN_ADMIN_EMAIL is defined create a new
# superuser for Django. There is no password setup so it can't login yet unless
# the password is reset.
if [[ -v MAILMAN_ADMIN_USER ]] && [[ -v MAILMAN_ADMIN_EMAIL ]];
then
echo "Creating admin user $MAILMAN_ADMIN_USER ..."
python3 manage.py createsuperuser --noinput --username "$MAILMAN_ADMIN_USER"\
--email "$MAILMAN_ADMIN_EMAIL" 2> /dev/null || \
echo "Superuser $MAILMAN_ADMIN_USER already exists"
fi
# If SERVE_FROM_DOMAIN is defined then rename the default `example.com`
# domain to the defined domain.
if [[ -v SERVE_FROM_DOMAIN ]];
then
echo "Setting $SERVE_FROM_DOMAIN as the default domain ..."
python3 manage.py shell -c \
"from django.contrib.sites.models import Site; Site.objects.filter(domain='example.com').update(domain='$SERVE_FROM_DOMAIN', name='$SERVE_FROM_DOMAIN')"
fi
# Create a mailman user with the specific UID and GID and do not create home
# directory for it. Also chown the logs directory to write the files.
chown mailman:mailman /opt/mailman-web-data -R
exec $@
#!/usr/bin/env python3
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
# -*- coding: utf-8 -*-
# Copyright (C) 1998-2016 by the Free Software Foundation, Inc.
#
# This file is part of Mailman Suite.
#
# Mailman Suite is free sofware: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# Mailman Suite is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
# You should have received a copy of the GNU General Public License along
# with Mailman Suite. If not, see <http://www.gnu.org/licenses/>.
"""
Django Settings for Mailman Suite (hyperkitty + postorius)
For more information on this file, see
https://docs.djangoproject.com/en/1.8/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
import dj_database_url
import sys
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get('SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ADMINS = (
('Mailman Suite Admin', 'root@localhost'),
)
SITE_ID = 1
# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.8/ref/settings/#allowed-hosts
ALLOWED_HOSTS = [
"localhost", # Archiving API from Mailman, keep it.
# "lists.your-domain.org",
# Add here all production URLs you may have.
"mailman-web",
"172.19.199.3",
os.environ.get('SERVE_FROM_DOMAIN'),
os.environ.get('DJANGO_ALLOWED_HOSTS'),
]
# Mailman API credentials
MAILMAN_REST_API_URL = os.environ.get('MAILMAN_REST_URL', 'http://mailman-core:8001')
MAILMAN_REST_API_USER = os.environ.get('MAILMAN_REST_USER', 'restadmin')
MAILMAN_REST_API_PASS = os.environ.get('MAILMAN_REST_PASSWORD', 'restpass')
MAILMAN_ARCHIVER_KEY = os.environ.get('HYPERKITTY_API_KEY')
MAILMAN_ARCHIVER_FROM = (os.environ.get('MAILMAN_HOST_IP', '172.19.199.2'),)
# Application definition
INSTALLED_APPS = [
'hyperkitty',
'postorius',
'django_mailman3',
# Uncomment the next line to enable the admin:
'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'django_gravatar',
'compressor',
'haystack',
'django_extensions',
'django_q',
'allauth',
'allauth.account',
'allauth.socialaccount',
'django_mailman3.lib.auth.fedora',
'allauth.socialaccount.providers.openid',
'allauth.socialaccount.providers.github',
'allauth.socialaccount.providers.gitlab',
'allauth.socialaccount.providers.google',
]
# Optionally include paintstore, if it was installed with Hyperkitty.
# TODO: Remove this after a new version of Hyperkitty is released and
# neither the stable nor the rolling version needs it.
try:
import paintstore
INSTALLED_APPS.append('paintstore')
except ImportError:
pass
_MIDDLEWARE = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django_mailman3.middleware.TimezoneMiddleware',
'postorius.middleware.PostoriusMiddleware',
)
# Use old-style Middleware class in Python 2 and released versions of
# Django-mailman3 don't support new style middlewares.
if sys.version_info < (3, 0):
MIDDLEWARE_CLASSES = _MIDDLEWARE
else:
MIDDLEWARE = _MIDDLEWARE
ROOT_URLCONF = 'urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.template.context_processors.csrf',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'django_mailman3.context_processors.common',
'hyperkitty.context_processors.common',
'postorius.context_processors.postorius',
],
},
},
]
WSGI_APPLICATION = 'wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
# This uses $DATABASE_URL from the environment variable to create a
# django-style-config-dict.
# https://github.com/kennethreitz/dj-database-url
DATABASES = {
'default': dj_database_url.config(conn_max_age=600)
}
# If you're behind a proxy, use the X-Forwarded-Host header
# See https://docs.djangoproject.com/en/1.8/ref/settings/#use-x-forwarded-host
USE_X_FORWARDED_HOST = True
# Password validation
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME':
'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME':
'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME':
'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME':
'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_ROOT = '/opt/mailman-web-data/static'
STATIC_URL = '/static/'
# Additional locations of static files
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'compressor.finders.CompressorFinder',
)
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
LOGIN_URL = 'account_login'
LOGIN_REDIRECT_URL = 'list_index'
LOGOUT_URL = 'account_logout'
# Use SERVE_FROM_DOMAIN as the default domain in the email.
hostname = os.environ.get('SERVE_FROM_DOMAIN', 'localhost.local')
DEFAULT_FROM_EMAIL = 'postorius@{}'.format(hostname)
SERVER_EMAIL = 'root@{}'.format(hostname)
# Change this when you have a real email backend
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = os.environ.get('SMTP_HOST', '172.19.199.1')
EMAIL_PORT = os.environ.get('SMTP_PORT', 25)
EMAIL_HOST_USER = os.environ.get('SMTP_HOST_USER', '')
EMAIL_HOST_PASSWORD = os.environ.get('SMTP_HOST_PASSWORD', '')
EMAIL_USE_TLS = os.environ.get('SMTP_USE_TLS', False)
# Compatibility with Bootstrap 3
from django.contrib.messages import constants as messages # flake8: noqa
MESSAGE_TAGS = {
messages.ERROR: 'danger'
}
#
# Social auth
#
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
)
# Django Allauth
ACCOUNT_AUTHENTICATION_METHOD = "username_email"
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
# You probably want https in production, but this is a dev setup file
ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https"
ACCOUNT_UNIQUE_EMAIL = True
SOCIALACCOUNT_PROVIDERS = {
'openid': {
'SERVERS': [
dict(id='yahoo',
name='Yahoo',
openid_url='http://me.yahoo.com'),
],
},
'google': {
'SCOPE': ['profile', 'email'],
'AUTH_PARAMS': {'access_type': 'online'},
},
'facebook': {
'METHOD': 'oauth2',
'SCOPE': ['email'],
'FIELDS': [
'email',
'name',
'first_name',
'last_name',
'locale',
'timezone',
],
'VERSION': 'v2.4',
},
}
# django-compressor
# https://pypi.python.org/pypi/django_compressor
#
COMPRESS_PRECOMPILERS = (
('text/less', 'lessc {infile} {outfile}'),
('text/x-scss', 'sassc -t compressed {infile} {outfile}'),
('text/x-sass', 'sassc -t compressed {infile} {outfile}'),
)
# On a production setup, setting COMPRESS_OFFLINE to True will bring a
# significant performance improvement, as CSS files will not need to be
# recompiled on each requests. It means running an additional "compress"
# management command after each code upgrade.
# http://django-compressor.readthedocs.io/en/latest/usage/#offline-compression
# COMPRESS_OFFLINE = True
#
# Full-text search engine
#
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
'PATH': "/opt/mailman-web-data/fulltext_index",
# You can also use the Xapian engine, it's faster and more accurate,
# but requires another library.
# http://django-haystack.readthedocs.io/en/v2.4.1/installing_search_engines.html#xapian
# Example configuration for Xapian:
#'ENGINE': 'xapian_backend.XapianEngine'
},
}
import sys
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
},
'file':{
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
#'class': 'logging.handlers.WatchedFileHandler',
'filename': os.environ.get('DJANGO_LOG_URL','/opt/mailman-web-data/logs/mailmanweb.log'),
'formatter': 'verbose',
},
'console': {
'class': 'logging.StreamHandler',
'formatter': 'simple',
'level': 'INFO',
'stream': sys.stdout,
},
# TODO: use an environment variable $DJ_LOG_URL to configure the logging
# using an environment variable.
},
'loggers': {
'django.request': {
'handlers': ['mail_admins', 'file'],
'level': 'INFO',
'propagate': True,
},
'django': {
'handlers': ['file'],
'level': 'INFO',
'propagate': True,
},
'hyperkitty': {
'handlers': ['file'],
'level': 'INFO',
'propagate': True,
},
'postorius': {
'handlers': ['file'],
'level': 'INFO',
'propagate': True
},
},
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(process)d %(name)s %(message)s'
},
'simple': {
'format': '%(levelname)s %(message)s'
},
},
#'root': {
# 'handlers': ['file'],
# 'level': 'INFO',
#},
}
if os.environ.get('LOG_TO_CONSOLE') == 'yes':
LOGGING['loggers']['django']['handlers'].append('console')
LOGGING['loggers']['django.request']['handlers'].append('console')
# HyperKitty-specific
#
# Only display mailing-lists from the same virtual host as the webserver
FILTER_VHOST = False
Q_CLUSTER = {
'timeout': 300,
'save_limit': 100,
'orm': 'default',
}
POSTORIUS_TEMPLATE_BASE_URL = os.environ.get('POSTORIUS_TEMPLATE_BASE_URL', 'http://mailman-web:8000')
try:
from settings_local import *
except ImportError:
pass
# -*- coding: utf-8 -*-
# Copyright (C) 1998-2016 by the Free Software Foundation, Inc.
#
# This file is part of Postorius.
#
# Postorius is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# Postorius is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# Postorius. If not, see <http://www.gnu.org/licenses/>.
from django.conf.urls import include, url
from django.contrib import admin
from django.urls import reverse_lazy
from django.views.generic import RedirectView
urlpatterns = [
url(r'^$', RedirectView.as_view(
url=reverse_lazy('list_index'),
permanent=True)),
url(r'^postorius/', include('postorius.urls')),
url(r'^hyperkitty/', include('hyperkitty.urls')),
url(r'', include('django_mailman3.urls')),
url(r'^accounts/', include('allauth.urls')),
# Django admin
url(r'^admin/', admin.site.urls),
]
[uwsgi]
# Port on which uwsgi will be listening.
uwsgi-socket = 0.0.0.0:8080
http-socket = 0.0.0.0:8000
#Enable threading for python
enable-threads = true
# Move to the directory wher the django files are.
chdir = /opt/mailman-web
# Use the wsgi file provided with the django project.
wsgi-file = wsgi.py
# Setup default number of processes and threads per process.
master = true
process = 4
# Drop privielges and don't run as root.
uid = mailman
gid = mailman
# Setup the django_q related worker processes.
attach-daemon = ./manage.py qcluster
# Setup hyperkitty's cron jobs.
unique-cron = -1 -1 -1 -1 -1 ./manage.py runjobs minutely
unique-cron = -15 -1 -1 -1 -1 ./manage.py runjobs quarter_hourly
unique-cron = 0 -1 -1 -1 -1 ./manage.py runjobs hourly
unique-cron = 0 0 -1 -1 -1 ./manage.py runjobs daily
unique-cron = 0 0 1 -1 -1 ./manage.py runjobs monthly
unique-cron = 0 0 -1 -1 0 ./manage.py runjobs weekly
unique-cron = 0 0 1 1 -1 ./manage.py runjobs yearly
# Setup the request log.
req-logger = file:/opt/mailman-web-data/logs/uwsgi.log
# Log cron seperately.
logger = cron file:/opt/mailman-web-data/logs/uwsgi-cron.log
log-route = cron uwsgi-cron
# Log qcluster commands seperately.
logger = qcluster file:/opt/mailman-web-data/logs/uwsgi-qcluster.log
log-route = qcluster uwsgi-daemons
# Last log and it logs the rest of the stuff.
logger = file:/opt/mailman-web-data/logs/uwsgi-error.log
"""
WSGI config for HyperKitty project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/{{ docs_version }}/howto/deployment/wsgi/
"""
import os
# import sys
# import site
# For some unknown reason, sometimes mod_wsgi fails to set the python paths to
# the virtualenv, with the 'python-path' option. You can do it here too.
#
# # Remember original sys.path.
# prev_sys_path = list(sys.path)
# # Add here, for the settings module
# site.addsitedir(os.path.abspath(os.path.dirname(__file__)))
# # Add the virtualenv
# venv = os.path.join(os.path.abspath(os.path.dirname(__file__)),
# '..', 'lib', 'python2.6', 'site-packages')
# site.addsitedir(venv)
# # Reorder sys.path so new directories at the front.
# new_sys_path = []
# for item in list(sys.path):
# if item not in prev_sys_path:
# new_sys_path.append(item)
# sys.path.remove(item)
# sys.path[:0] = new_sys_path
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
application = get_wsgi_application()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册