Merge branch 'main' into fix_sqlite-url

This commit is contained in:
Abhilash Raj
2024-06-08 06:29:18 +05:30
committed by GitHub
27 changed files with 262 additions and 147 deletions

View File

@@ -7,7 +7,7 @@ jobs:
type: string type: string
default: "no" default: "no"
machine: machine:
image: ubuntu-2004:202010-01 image: default
environment: environment:
DOCKER_BUILDKIT: 1 DOCKER_BUILDKIT: 1
BUILDKIT_PROGRESS: plain BUILDKIT_PROGRESS: plain
@@ -37,11 +37,16 @@ jobs:
DB: mysql DB: mysql
name: MySQL Test name: MySQL Test
command: bash tests/test.sh command: bash tests/test.sh
- deploy: - run:
name: Deploy name: Run version
command: | command: |
python3 --version python3 --version
python3 deploy.py python3 deploy.py
- store_artifacts:
path: /opt/mailman/web/logs/
- store_artifacts:
path: /opt/mailman/core/var/logs
workflows: workflows:
version: 2 version: 2

34
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,34 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "docker" # See documentation for possible values
directory: "/core" # Location of package manifests
schedule:
interval: "weekly"
- package-ecosystem: "docker" # See documentation for possible values
directory: "/web" # Location of package manifests
schedule:
interval: "weekly"
- package-ecosystem: "docker" # See documentation for possible values
directory: "/postorius" # Location of package manifests
schedule:
interval: "weekly"
# Enable version updates for Actions
- package-ecosystem: "github-actions"
# Look for `.github/workflows` in the `root` directory
directory: "/"
# Check for updates once a week
schedule:
interval: "weekly"
- package-ecosystem: "pip"
directory: "/core"
schedule:
interval: "daily"
- package-ecosystem: "pip"
directory: "/web"
schedule:
interval: "daily"

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout main - name: Checkout main
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Deploy docs - name: Deploy docs
uses: mhausenblas/mkdocs-deploy-gh-pages@master uses: mhausenblas/mkdocs-deploy-gh-pages@master

28
.github/workflows/stale.yml vendored Normal file
View File

@@ -0,0 +1,28 @@
# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
#
# You can adjust the behavior by modifying this file.
# For more information, see:
# https://github.com/actions/stale
name: Mark stale issues and pull requests
on:
schedule:
- cron: '19 22 * * *'
jobs:
stale:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v9
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue has not been updated for more than 1year'
stale-pr-message: 'This Pull Request has not been updated for more than 1year'
stale-issue-label: 'no-issue-activity'
stale-pr-label: 'no-pr-activity'
days-before-stale: 365

View File

@@ -54,25 +54,21 @@ Releases will follow the following rules:
## Container Registries ## Container Registries
The container images are available from multiple container registries. Do specify an [explicit version tag](https://hub.docker.com/r/maxking/mailman-web/tags?page=1&ordering=last_updated&name=0.) (e.g. `0.4.5` , MAJOR.MINOR like `0.4` also works as floating tag pointing to latest patch version) as tag `latest` is **not** updated anymore.
The container images are available from multiple container registries:
### Mailman Core ### Mailman Core
- `ghcr.io/maxking/mailman-core` - `ghcr.io/maxking/mailman-core`
- `quay.io/maxking/mailman-core`
- `docker.io/maxking/mailman-core` - `docker.io/maxking/mailman-core`
### Mailman Web ### Mailman Web
- `ghcr.io/maxking/mailman-web` - `ghcr.io/maxking/mailman-web`
- `quay.io/maxking/mailman-web`
- `docker.io/maxking/mailman-web` - `docker.io/maxking/mailman-web`
### Postorius ### Postorius
- `ghcr.io/maxking/postorius` - `ghcr.io/maxking/postorius`
- `quay.io/maxking/postorius`
- `docker.io/maxking/postorius` - `docker.io/maxking/postorius`
## Rolling Releases ## Rolling Releases
@@ -214,6 +210,10 @@ These are the variables that you MUST change in your docker-compose.yaml before
- `DATABASE_CLASS`: Default value is - `DATABASE_CLASS`: Default value is
`mailman.database.sqlite.SQLiteDatabase`. The values for this can be found in `mailman.database.sqlite.SQLiteDatabase`. The values for this can be found in
the mailman's documentation [here][11]. the mailman's documentation [here][11].
- `SMTP_HOST` : outgoing host for SMTP connections
- `SMTP_PORT` : use this port. 25, 587, whatever your host asks for.
- `SMTP_HOST_USER`: authenticate this user
- `SMTP_HOST_PASSWORD`: and use this password
For more details on how to configure this image, please look [Mailman-core's For more details on how to configure this image, please look [Mailman-core's
Readme](core/) Readme](core/)

View File

@@ -1,26 +1,30 @@
# syntax = docker/dockerfile:1.3 # syntax = docker/dockerfile:1.3
FROM alpine:3.12 # Use 3.15 for Core since it has Python 3.9
FROM alpine:3.19
#Add startup script to container # Add requirements file.
COPY docker-entrypoint.sh /usr/local/bin/ COPY requirements.txt /tmp/
#Install all required packages, add user for executing mailman and set execution rights for startup script #Install all required packages, add user for executing mailman and set execution rights for startup script
RUN --mount=type=cache,target=/root/.cache \ RUN --mount=type=cache,target=/root/.cache \
apk update \ apk update \
&& apk add --virtual build-deps gcc python3-dev musl-dev postgresql-dev \ && apk add --virtual build-deps gcc python3-dev musl-dev postgresql-dev \
libffi-dev \ libffi-dev \
# Mailman html to plaintext conversion uses lynx.
# psutil needs linux-headers to compile on musl c library. # psutil needs linux-headers to compile on musl c library.
&& apk add --no-cache bash su-exec postgresql-client mysql-client curl python3 py3-pip linux-headers py-cryptography mariadb-connector-c \ && apk add --no-cache bash su-exec postgresql-client mysql-client curl python3 py3-pip linux-headers py-cryptography mariadb-connector-c lynx tzdata \
&& python3 -m pip install -U pip setuptools wheel \ && python3 -m pip install --break-system-packages -U pip setuptools wheel \
&& python3 -m pip install psycopg2 \ && python3 -m pip install --break-system-packages psycopg2 \
gunicorn==19.9.0 \ gunicorn==19.9.0 \
mailman==3.3.5 \
mailman-hyperkitty==1.2.0 \
pymysql \ pymysql \
'sqlalchemy<1.4.0' \ -r /tmp/requirements.txt \
'importlib-resources<6.0.0' \
&& apk del build-deps \ && apk del build-deps \
&& adduser -S mailman && adduser -S mailman
#Add startup script to container
COPY docker-entrypoint.sh /usr/local/bin/
# Change the working directory. # Change the working directory.
WORKDIR /opt/mailman WORKDIR /opt/mailman

View File

@@ -1,29 +1,30 @@
# syntax = docker/dockerfile:1.3 # syntax = docker/dockerfile:1.3
FROM alpine:3.12 # Use 3.15 for Core since it has Python 3.9
FROM alpine:3.19
#Add startup script to container
COPY docker-entrypoint.sh /usr/local/bin/
# Set the commits that we are building. # Set the commits that we are building.
ARG CORE_REF ARG CORE_REF
ARG MM3_HK_REF ARG MM3_HK_REF
#Install all required packages, add user for executing mailman and set execution #Install all required packages, add user for executing mailman and set execution
#rights for startup script #rights for startup script
RUN --mount=type=cache,target=/root/.cache \ RUN --mount=type=cache,target=/root/.cache \
apk update \ apk update \
&& apk add --no-cache --virtual build-deps gcc python3-dev musl-dev \ && apk add --no-cache --virtual build-deps gcc python3-dev musl-dev \
postgresql-dev git libffi-dev \ postgresql-dev git libffi-dev g++ \
&& apk add --no-cache bash su-exec postgresql-client mysql-client curl python3 py3-pip linux-headers py-cryptography mariadb-connector-c \ && apk add --no-cache bash su-exec postgresql-client mysql-client \
&& python3 -m pip install -U psycopg2 pymysql setuptools wheel \ curl python3 py3-pip linux-headers py-cryptography mariadb-connector-c tzdata \
&& python3 -m pip install \ && python3 -m pip install -U --break-system-packages psycopg2 pymysql setuptools wheel \
&& python3 -m pip install --break-system-packages \
git+https://gitlab.com/mailman/mailman \ git+https://gitlab.com/mailman/mailman \
git+https://gitlab.com/mailman/mailman-hyperkitty \ git+https://gitlab.com/mailman/mailman-hyperkitty \
gunicorn==19.9.0 \ gunicorn==19.9.0 \
&& apk del build-deps \ && apk del build-deps \
&& adduser -S mailman && adduser -S mailman
#Add startup script to container
COPY docker-entrypoint.sh /usr/local/bin/
# Change the working directory. # Change the working directory.
WORKDIR /opt/mailman WORKDIR /opt/mailman

View File

@@ -6,7 +6,7 @@ function wait_for_postgres () {
# moving forward. # moving forward.
# TODO: Use python3's psycopg2 module to do this in python3 instead of # TODO: Use python3's psycopg2 module to do this in python3 instead of
# installing postgres-client in the image. # installing postgres-client in the image.
until psql $DATABASE_URL -c '\l'; do until psql -P pager=off $DATABASE_URL -c '\l'; do
>&2 echo "Postgres is unavailable - sleeping" >&2 echo "Postgres is unavailable - sleeping"
sleep 1 sleep 1
done done
@@ -67,7 +67,7 @@ function setup_database () {
# Translate mysql:// urls to mysql+mysql:// backend: # Translate mysql:// urls to mysql+mysql:// backend:
if [[ "$DATABASE_URL" == mysql://* ]]; then if [[ "$DATABASE_URL" == mysql://* ]]; then
DATABASE_URL="mysql+pymysql://${DATABASE_URL:8}" DATABASE_URL="mysql+pymysql://${DATABASE_URL:8}"
echo "Database URL was automatically rewritten to: $DATABASE_URL" echo "Database URL prefix was automatically rewritten to: mysql+pymysql://"
fi fi
# If DATABASE_CLASS is not set, guess it for common databases: # If DATABASE_CLASS is not set, guess it for common databases:
@@ -142,6 +142,8 @@ lmtp_host: $MM_HOSTNAME
lmtp_port: 8024 lmtp_port: 8024
smtp_host: $SMTP_HOST smtp_host: $SMTP_HOST
smtp_port: $SMTP_PORT smtp_port: $SMTP_PORT
smtp_user: $SMTP_HOST_USER
smtp_pass: $SMTP_HOST_PASSWORD
configuration: python:mailman.config.exim4 configuration: python:mailman.config.exim4
EOF EOF
@@ -163,6 +165,8 @@ lmtp_host: $MM_HOSTNAME
lmtp_port: 8024 lmtp_port: 8024
smtp_host: $SMTP_HOST smtp_host: $SMTP_HOST
smtp_port: $SMTP_PORT smtp_port: $SMTP_PORT
smtp_user: $SMTP_HOST_USER
smtp_pass: $SMTP_HOST_PASSWORD
configuration: /etc/postfix-mailman.cfg configuration: /etc/postfix-mailman.cfg
EOF EOF

5
core/requirements.txt Normal file
View File

@@ -0,0 +1,5 @@
# This is a separate file from Dockerfile so that we can use dependabot
# for version updates that isn't supported for contents inside the
# Dockerfile.
mailman==3.3.9
mailman-hyperkitty==1.2.1

View File

@@ -2,9 +2,10 @@ version: '2'
services: services:
mailman-core: mailman-core:
image: maxking/mailman-core:0.4 image: maxking/mailman-core:0.4 # Use a specific version tag (tag latest is not published)
container_name: mailman-core container_name: mailman-core
hostname: mailman-core hostname: mailman-core
restart: unless-stopped
volumes: volumes:
- /opt/mailman/core:/opt/mailman/ - /opt/mailman/core:/opt/mailman/
stop_grace_period: 30s stop_grace_period: 30s
@@ -13,9 +14,8 @@ services:
depends_on: depends_on:
- database - database
environment: environment:
- DATABASE_URL=mysql+pymysql://mailman:mailmanpass@database/mailmandb?charset=utf8mb4&use_unicode=1 - DATABASE_URL=mysql+pymysql://mailman:mailmanpass@database/mailmandb?charset=utf8mb4&use_unicode=1 # Do use mysql+pymysql:// here
- DATABASE_TYPE=mysql - DATABASE_TYPE=mysql
- DATABASE_CLASS=mailman.database.mysql.MySQLDatabase
- HYPERKITTY_API_KEY=someapikey - HYPERKITTY_API_KEY=someapikey
ports: ports:
- "127.0.0.1:8001:8001" # API - "127.0.0.1:8001:8001" # API
@@ -24,9 +24,10 @@ services:
mailman: mailman:
mailman-web: mailman-web:
image: maxking/mailman-web:0.4 image: maxking/mailman-web:0.4 # Use a specific version tag (tag latest is not published)
container_name: mailman-web container_name: mailman-web
hostname: mailman-web hostname: mailman-web
restart: unless-stopped
depends_on: depends_on:
- database - database
links: links:
@@ -36,7 +37,7 @@ services:
- /opt/mailman/web:/opt/mailman-web-data - /opt/mailman/web:/opt/mailman-web-data
environment: environment:
- DATABASE_TYPE=mysql - DATABASE_TYPE=mysql
- DATABASE_URL=mysql://mailman:mailmanpass@database/mailmandb?charset=utf8mb4 - DATABASE_URL=mysql://mailman:mailmanpass@database/mailmandb?charset=utf8mb4 # Do use mysql:// here
- HYPERKITTY_API_KEY=someapikey - HYPERKITTY_API_KEY=someapikey
- SECRET_KEY=thisisaverysecretkey - SECRET_KEY=thisisaverysecretkey
- DYLD_LIBRARY_PATH=/usr/local/mysql/lib/ - DYLD_LIBRARY_PATH=/usr/local/mysql/lib/
@@ -66,4 +67,4 @@ networks:
driver: default driver: default
config: config:
- -
subnet: 172.19.199.0/24 subnet: 172.19.199.0/24

View File

@@ -2,9 +2,10 @@ version: '2'
services: services:
mailman-core: mailman-core:
image: maxking/mailman-core:0.4 image: maxking/mailman-core:0.4 # Use a specific version tag (tag latest is not published)
container_name: mailman-core container_name: mailman-core
hostname: mailman-core hostname: mailman-core
restart: unless-stopped
volumes: volumes:
- /opt/mailman/core:/opt/mailman/ - /opt/mailman/core:/opt/mailman/
stop_grace_period: 30s stop_grace_period: 30s
@@ -23,9 +24,10 @@ services:
mailman: mailman:
mailman-web: mailman-web:
image: maxking/postorius:0.4 image: maxking/postorius:0.4 # Use a specific version tag (tag latest is not published)
container_name: mailman-web container_name: mailman-web
hostname: mailman-web hostname: mailman-web
restart: unless-stopped
depends_on: depends_on:
- database - database
links: links:
@@ -63,4 +65,4 @@ networks:
driver: default driver: default
config: config:
- -
subnet: 172.19.199.0/24 subnet: 172.19.199.0/24

View File

@@ -2,9 +2,10 @@ version: '2'
services: services:
mailman-core: mailman-core:
image: maxking/mailman-core:0.4 image: maxking/mailman-core:0.4 # Use a specific version tag (tag latest is not published)
container_name: mailman-core container_name: mailman-core
hostname: mailman-core hostname: mailman-core
restart: unless-stopped
volumes: volumes:
- /opt/mailman/core:/opt/mailman/ - /opt/mailman/core:/opt/mailman/
stop_grace_period: 30s stop_grace_period: 30s
@@ -13,7 +14,7 @@ services:
depends_on: depends_on:
- database - database
environment: environment:
- DATABASE_URL=postgres://mailman:mailmanpass@database/mailmandb - DATABASE_URL=postgresql://mailman:mailmanpass@database/mailmandb
- DATABASE_TYPE=postgres - DATABASE_TYPE=postgres
- DATABASE_CLASS=mailman.database.postgresql.PostgreSQLDatabase - DATABASE_CLASS=mailman.database.postgresql.PostgreSQLDatabase
- HYPERKITTY_API_KEY=someapikey - HYPERKITTY_API_KEY=someapikey
@@ -24,9 +25,10 @@ services:
mailman: mailman:
mailman-web: mailman-web:
image: maxking/mailman-web:0.4 image: maxking/mailman-web:0.4 # Use a specific version tag (tag latest is not published)
container_name: mailman-web container_name: mailman-web
hostname: mailman-web hostname: mailman-web
restart: unless-stopped
depends_on: depends_on:
- database - database
links: links:
@@ -36,7 +38,7 @@ services:
- /opt/mailman/web:/opt/mailman-web-data - /opt/mailman/web:/opt/mailman-web-data
environment: environment:
- DATABASE_TYPE=postgres - DATABASE_TYPE=postgres
- DATABASE_URL=postgres://mailman:mailmanpass@database/mailmandb - DATABASE_URL=postgresql://mailman:mailmanpass@database/mailmandb
- HYPERKITTY_API_KEY=someapikey - HYPERKITTY_API_KEY=someapikey
ports: ports:
- "127.0.0.1:8000:8000" # HTTP - "127.0.0.1:8000:8000" # HTTP
@@ -49,7 +51,7 @@ services:
- POSTGRES_DB=mailmandb - POSTGRES_DB=mailmandb
- POSTGRES_USER=mailman - POSTGRES_USER=mailman
- POSTGRES_PASSWORD=mailmanpass - POSTGRES_PASSWORD=mailmanpass
image: postgres:9.6-alpine image: postgres:12-alpine
volumes: volumes:
- /opt/mailman/database:/var/lib/postgresql/data - /opt/mailman/database:/var/lib/postgresql/data
networks: networks:
@@ -62,4 +64,4 @@ networks:
driver: default driver: default
config: config:
- -
subnet: 172.19.199.0/24 subnet: 172.19.199.0/24

View File

@@ -1,34 +1,36 @@
# syntax = docker/dockerfile:1.3 # syntax = docker/dockerfile:1.3
FROM alpine:3.12 FROM alpine:3.20.0
# 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 # Install packages and dependencies for postorius and hyperkitty Add user for
# executing apps, change ownership for uwsgi+django files and set execution # executing apps, change ownership for uwsgi+django files and set execution
# rights for management script # rights for management script
RUN --mount=type=cache,target=/root/.cache \ RUN --mount=type=cache,target=/root/.cache \
set -ex \ set -ex \
&& apk add --no-cache --virtual .build-deps gcc libc-dev linux-headers \ && apk add --no-cache --virtual .build-deps gcc libc-dev linux-headers libldap \
postgresql-dev mariadb-dev mariadb-connector-c python3-dev libffi-dev openldap-dev cargo rust \ postgresql-dev mariadb-dev mariadb-connector-c python3-dev libffi-dev openldap-dev cargo rust \
&& apk add --no-cache --virtual .mailman-rundeps bash sassc \ && apk add --no-cache --virtual .mailman-rundeps bash sassc tzdata \
postgresql-client mysql-client py3-mysqlclient curl mailcap gettext \ postgresql-client mysql-client py3-mysqlclient curl mailcap gettext \
python3 py3-pip libffi libuuid pcre-dev py-cryptography \ python3 py3-pip libffi libuuid pcre-dev py-cryptography \
&& python3 -m pip install -U 'Django<3.2' pip setuptools wheel \ && python3 -m pip install --break-system-packages -U 'Django<4.3' pip setuptools wheel \
&& python3 -m pip install postorius==1.3.6 \ && python3 -m pip install --break-system-packages postorius==1.3.10 \
uwsgi \ uwsgi \
'psycopg2<2.9' \ psycopg2 \
dj-database-url \ dj-database-url \
mysqlclient \ mysqlclient \
typing \ typing \
django-auth-ldap \ django-auth-ldap \
python-memcached \ python-memcached \
tzdata \
&& apk del .build-deps \ && apk del .build-deps \
&& addgroup -S mailman \ && addgroup -S mailman \
&& adduser -S -G mailman mailman \ && adduser -S -G mailman mailman
&& chown -R mailman /opt/mailman-web/ \
# 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/
RUN chown -R mailman /opt/mailman-web/ \
&& chmod u+x /opt/mailman-web/manage.py && chmod u+x /opt/mailman-web/manage.py
WORKDIR /opt/mailman-web WORKDIR /opt/mailman-web

View File

@@ -1,10 +1,5 @@
# syntax = docker/dockerfile:1.3 # syntax = docker/dockerfile:1.3
FROM alpine:3.12 FROM alpine:3.20.0
# 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 POSTORIUS_REF
ARG DJ_MM3_REF ARG DJ_MM3_REF
@@ -15,28 +10,34 @@ ARG CLIENT_REF
# rights for management script # rights for management script
RUN --mount=type=cache,target=/root/.cache \ RUN --mount=type=cache,target=/root/.cache \
set -ex \ set -ex \
&& apk add --no-cache --virtual .build-deps gcc libc-dev linux-headers \ && apk add --no-cache --virtual .build-deps gcc libc-dev linux-headers libldap \
postgresql-dev mariadb-dev mariadb-connector-c python3-dev libffi-dev git cargo rust \ postgresql-dev mariadb-dev mariadb-connector-c python3-dev libffi-dev git cargo rust \
&& apk add --no-cache --virtual .mailman-rundeps bash sassc \ && apk add --no-cache --virtual .mailman-rundeps bash sassc tzdata \
postgresql-client mysql-client py3-mysqlclient curl mailcap \ postgresql-client mysql-client py3-mysqlclient curl mailcap \
python3 py3-pip libffi gettext py-cryptography \ python3 py3-pip libffi gettext py-cryptography \
&& python3 -m pip install -U pip setuptools wheel \ && python3 -m pip install --break-system-packages -U pip setuptools wheel \
&& python3 -m pip install -U \ && python3 -m pip install --break-system-packages -U \
git+https://gitlab.com/mailman/mailmanclient \ git+https://gitlab.com/mailman/mailmanclient \
git+https://gitlab.com/mailman/postorius \ git+https://gitlab.com/mailman/postorius \
uwsgi \ uwsgi \
'psycopg2<2.9' \ psycopg2 \
dj-database-url \ dj-database-url \
mysqlclient \ mysqlclient \
typing \ typing \
django-utils-six \ django-utils-six \
&& python3 -m pip install -U 'Django<3.2' \ && python3 -m pip install --break-system-packages -U 'Django<4.3' \
&& python3 -m pip install -U \ && python3 -m pip install --break-system-packages -U \
git+https://gitlab.com/mailman/django-mailman3 \ git+https://gitlab.com/mailman/django-mailman3 \
&& apk del .build-deps \ && apk del .build-deps \
&& addgroup -S mailman \ && addgroup -S mailman \
&& adduser -S -G mailman mailman \ && adduser -S -G mailman mailman
&& chown -R mailman /opt/mailman-web/ \
# 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/
RUN chown -R mailman /opt/mailman-web/ \
&& chmod u+x /opt/mailman-web/manage.py && chmod u+x /opt/mailman-web/manage.py
WORKDIR /opt/mailman-web WORKDIR /opt/mailman-web

View File

@@ -7,7 +7,7 @@ function wait_for_postgres () {
# moving forward. # moving forward.
# TODO: Use python's psycopg2 module to do this in python instead of # TODO: Use python's psycopg2 module to do this in python instead of
# installing postgres-client in the image. # installing postgres-client in the image.
until psql $DATABASE_URL -c '\l'; do until psql -P pager=off $DATABASE_URL -c '\l'; do
>&2 echo "Postgres is unavailable - sleeping" >&2 echo "Postgres is unavailable - sleeping"
sleep 1 sleep 1
done done

View File

@@ -46,16 +46,14 @@ ADMINS = (
SITE_ID = 1 SITE_ID = 1
# Hosts/domain names that are valid for this site; required if DEBUG is False # 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 # See https://docs.djangoproject.com/en/3.1/ref/settings/#allowed-hosts
ALLOWED_HOSTS = [ ALLOWED_HOSTS = [
"localhost", # Archiving API from Mailman, keep it. "localhost", # Archiving API from Mailman, keep it.
# "lists.your-domain.org",
# Add here all production URLs you may have.
"mailman-web", "mailman-web",
gethostbyname("mailman-web"), gethostbyname("mailman-web"),
os.environ.get('SERVE_FROM_DOMAIN'), os.environ.get('SERVE_FROM_DOMAIN'),
os.environ.get('DJANGO_ALLOWED_HOSTS'),
] ]
ALLOWED_HOSTS.extend(os.getenv("DJANGO_ALLOWED_HOSTS", "").split(","))
# Mailman API credentials # Mailman API credentials
MAILMAN_REST_API_URL = os.environ.get('MAILMAN_REST_URL', 'http://mailman-core:8001') MAILMAN_REST_API_URL = os.environ.get('MAILMAN_REST_URL', 'http://mailman-core:8001')
@@ -78,6 +76,7 @@ DEFAULT_APPS = [
'django.contrib.sites', 'django.contrib.sites',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'django.contrib.humanize',
'django_gravatar', 'django_gravatar',
'allauth', 'allauth',
'allauth.account', 'allauth.account',
@@ -101,6 +100,7 @@ MIDDLEWARE = (
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
'django_mailman3.middleware.TimezoneMiddleware', 'django_mailman3.middleware.TimezoneMiddleware',
'allauth.account.middleware.AccountMiddleware',
'postorius.middleware.PostoriusMiddleware', 'postorius.middleware.PostoriusMiddleware',
) )
@@ -143,6 +143,11 @@ DATABASES = {
'default': dj_database_url.config(conn_max_age=600) 'default': dj_database_url.config(conn_max_age=600)
} }
# Avoid Django 3.2+ warning
# https://github.com/maxking/docker-mailman/issues/595
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
# If you're behind a proxy, use the X-Forwarded-Host header # 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 # See https://docs.djangoproject.com/en/1.8/ref/settings/#use-x-forwarded-host
USE_X_FORWARDED_HOST = True USE_X_FORWARDED_HOST = True

View File

@@ -16,19 +16,18 @@
# You should have received a copy of the GNU General Public License along with # You should have received a copy of the GNU General Public License along with
# Postorius. If not, see <http://www.gnu.org/licenses/>. # Postorius. If not, see <http://www.gnu.org/licenses/>.
from django.conf.urls import include
from django.conf.urls import include, url
from django.contrib import admin from django.contrib import admin
from django.urls import reverse_lazy from django.urls import re_path, reverse_lazy
from django.views.generic import RedirectView from django.views.generic import RedirectView
urlpatterns = [ urlpatterns = [
url(r'^$', RedirectView.as_view( re_path(r'^$', RedirectView.as_view(
url=reverse_lazy('list_index'), url=reverse_lazy('list_index'),
permanent=True)), permanent=True)),
url(r'^postorius/', include('postorius.urls')), re_path(r'postorius/', include('postorius.urls')),
url(r'', include('django_mailman3.urls')), re_path(r'', include('django_mailman3.urls')),
url(r'^accounts/', include('allauth.urls')), re_path(r'accounts/', include('allauth.urls')),
# Django admin # Django admin
url(r'^admin/', admin.site.urls), re_path(r'^admin/', admin.site.urls),
] ]

View File

@@ -3,7 +3,7 @@
uwsgi-socket = 0.0.0.0:8080 uwsgi-socket = 0.0.0.0:8080
http-socket = 0.0.0.0:8000 http-socket = 0.0.0.0:8000
# Move to the directory wher the django files are. # Move to the directory where the django files are.
chdir = /opt/mailman-web chdir = /opt/mailman-web
# Use the wsgi file provided with the django project. # Use the wsgi file provided with the django project.
@@ -14,7 +14,7 @@ master = true
processes = 2 processes = 2
threads = 2 threads = 2
# Drop privielges and don't run as root. # Drop privileges and don't run as root.
uid = mailman uid = mailman
gid = mailman gid = mailman

View File

@@ -8,3 +8,4 @@ services:
image: maxking/mailman-web:rolling image: maxking/mailman-web:rolling
environment: environment:
- SECRET_KEY=abcdefghijklmnopqrstuv - SECRET_KEY=abcdefghijklmnopqrstuv
- SERVE_FROM_DOMAIN=araj.me

View File

@@ -1,42 +1,44 @@
# syntax = docker/dockerfile:1.3 # syntax = docker/dockerfile:1.3
FROM alpine:3.12 FROM alpine:3.20.0
# Add needed files for uwsgi server + settings for django # Add requirements file.
COPY mailman-web /opt/mailman-web COPY requirements.txt /tmp/
# Add startup script to container
COPY docker-entrypoint.sh /usr/local/bin/
# Install packages and dependencies for postorius and hyperkitty Add user for # Install packages and dependencies for postorius and hyperkitty Add user for
# executing apps, change ownership for uwsgi+django files and set execution # executing apps, change ownership for uwsgi+django files and set execution
# rights for management script # rights for management script
RUN --mount=type=cache,target=/root/.cache \ RUN --mount=type=cache,target=/root/.cache \
set -ex \ set -ex \
&& apk add --no-cache --virtual .build-deps gcc libc-dev linux-headers \ && apk add --no-cache --virtual .build-deps gcc libc-dev linux-headers libldap \
postgresql-dev mariadb-dev mariadb-connector-c python3-dev libffi-dev openldap-dev cargo rust \ postgresql-dev mariadb-dev mariadb-connector-c python3-dev libffi-dev openldap-dev cargo rust \
&& apk add --no-cache --virtual .mailman-rundeps bash sassc \ && apk add --no-cache --virtual .mailman-rundeps bash sassc tzdata \
postgresql-client mysql-client py3-mysqlclient curl mailcap gettext \ postgresql-client mysql-client py3-mysqlclient curl mailcap gettext \
python3 py3-pip xapian-core xapian-bindings-python3 libffi pcre-dev py-cryptography \ python3 py3-pip xapian-core xapian-bindings-python3 libffi pcre-dev py-cryptography \
&& python3 -m pip install -U 'Django<3.2' pip setuptools wheel \ && python3 -m pip install --break-system-packages -U 'Django<4.3' pip setuptools wheel \
&& pip install mailmanclient==3.3.3 \ && pip install --break-system-packages -r /tmp/requirements.txt \
postorius==1.3.6 \
hyperkitty==1.3.5 \
django-mailman3==1.3.7 \
mistune==2.0.0rc1 \
whoosh \ whoosh \
uwsgi \ uwsgi \
'psycopg2<2.9' \ psycopg2 \
dj-database-url \ dj-database-url \
mysqlclient \ mysqlclient \
typing \ typing \
xapian-haystack \ xapian-haystack \
django-auth-ldap \ django-auth-ldap \
python-memcached \ pymemcache \
diskcache \ diskcache \
django-utils-six \ django-utils-six \
tzdata \
'django-allauth[socialaccount,openid]' \
&& apk del .build-deps \ && apk del .build-deps \
&& addgroup -S mailman \ && addgroup -S mailman \
&& adduser -S -G mailman mailman \ && adduser -S -G mailman mailman
&& chown -R mailman /opt/mailman-web/ \
# 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/
RUN chown -R mailman /opt/mailman-web/ \
&& chmod u+x /opt/mailman-web/manage.py && chmod u+x /opt/mailman-web/manage.py
WORKDIR /opt/mailman-web WORKDIR /opt/mailman-web

View File

@@ -1,10 +1,5 @@
# syntax = docker/dockerfile:1.3 # syntax = docker/dockerfile:1.3
FROM alpine:3.12 FROM alpine:3.20.0
# 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 POSTORIUS_REF
ARG HYPERKITTY_REF ARG HYPERKITTY_REF
@@ -16,34 +11,42 @@ ARG CLIENT_REF
# rights for management script # rights for management script
RUN --mount=type=cache,target=/root/.cache \ RUN --mount=type=cache,target=/root/.cache \
set -ex \ set -ex \
&& apk add --no-cache --virtual .build-deps gcc libc-dev linux-headers git \ && apk add --no-cache --virtual .build-deps gcc libc-dev linux-headers git libldap \
postgresql-dev mariadb-dev mariadb-connector-c python3-dev libffi-dev openldap-dev cargo rust \ postgresql-dev mariadb-dev mariadb-connector-c python3-dev libffi-dev openldap-dev cargo rust \
&& apk add --no-cache --virtual .mailman-rundeps bash sassc pcre-dev \ && apk add --no-cache --virtual .mailman-rundeps bash sassc pcre-dev tzdata \
python3 py3-pip postgresql-client mysql-client py3-mysqlclient \ python3 py3-pip postgresql-client mysql-client py3-mysqlclient \
curl mailcap xapian-core xapian-bindings-python3 libffi gettext py-cryptography \ curl mailcap xapian-core xapian-bindings-python3 libffi gettext py-cryptography \
&& python3 -m pip install -U pip setuptools wheel \ && python3 -m pip install --break-system-packages -U pip setuptools wheel \
&& python3 -m pip install -U \ && python3 -m pip install --break-system-packages -U \
git+https://gitlab.com/mailman/mailmanclient \ git+https://gitlab.com/mailman/mailmanclient \
git+https://gitlab.com/mailman/postorius \ git+https://gitlab.com/mailman/postorius \
git+https://gitlab.com/mailman/hyperkitty \ git+https://gitlab.com/mailman/hyperkitty \
whoosh \ whoosh \
uwsgi \ uwsgi \
'psycopg2<2.9' \ psycopg2 \
dj-database-url \ dj-database-url \
mysqlclient \ mysqlclient \
xapian-haystack \ xapian-haystack \
django-auth-ldap \ django-auth-ldap \
python-memcached \ pymemcache \
tzdata \
diskcache \ diskcache \
django-utils-six \ django-utils-six \
&& python3 -m pip install -U 'Django<3.2' \ 'django-allauth[socialaccount,openid]' \
&& python3 -m pip install -U \ && python3 -m pip install --break-system-packages -U 'Django<4.3' \
&& python3 -m pip install --break-system-packages -U \
git+https://gitlab.com/mailman/django-mailman3 \ git+https://gitlab.com/mailman/django-mailman3 \
&& apk del .build-deps \ && apk del .build-deps \
&& addgroup -S mailman \ && addgroup -S mailman \
&& adduser -S -G mailman mailman \ && adduser -S -G mailman mailman
&& chown -R mailman /opt/mailman-web/ \
&& chmod u+x /opt/mailman-web/manage.py # 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/
RUN chown -R mailman /opt/mailman-web/ \
&& chmod u+x /opt/mailman-web/manage.py
WORKDIR /opt/mailman-web WORKDIR /opt/mailman-web

View File

@@ -56,16 +56,16 @@ change them unless you know what you want.
- `SMTP_HOST_PASSWORD`: Default is an empty string. - `SMTP_HOST_PASSWORD`: Default is an empty string.
- `SMTP_USE_TLS`: Specifies wheather the SMTP connection is encrypted - `SMTP_USE_TLS`: Specifies wheather the SMTP connection is encrypted
via TLS. Default is `False`. via TLS. Default is `False`. (`EMAIL_USE_TLS`/`EMAIL_USE_SSL` are mutually exclusive, so only set one of those settings.)
- `SMTP_USE_SSL`: Specifies wheather the SMTP connection is encrypted - `SMTP_USE_SSL`: Specifies wheather the SMTP connection is encrypted
via SSL. Default is `False`. via SSL. Default is `False`. (EMAIL_USE_TLS/EMAIL_USE_SSL are mutually exclusive, so only set one of those settings.)
- `DJANGO_LOG_URL`: Path to the django's log file. Defaults to - `DJANGO_LOG_URL`: Path to the django's log file. Defaults to
`/opt/mailman-web-data/logs/mailmanweb.log`. `/opt/mailman-web-data/logs/mailmanweb.log`.
- `DJANGO_ALLOWED_HOSTS`: Entry to add to ALLOWED_HOSTS in Django - `DJANGO_ALLOWED_HOSTS`: Entry to add to ALLOWED_HOSTS in Django
configuration. This is a separate configuration from`SERVE_FROM_DOMAIN` as configuration. Format as comma-separated list (no whitespace). This is a separate configuration from`SERVE_FROM_DOMAIN` as
latter is used for other purposes too. latter is used for other purposes too.
- `POSTORIUS_TEMPLATE_BASE_URL`: The base url at which the `mailman-web` - `POSTORIUS_TEMPLATE_BASE_URL`: The base url at which the `mailman-web`

View File

@@ -7,7 +7,7 @@ function wait_for_postgres () {
# moving forward. # moving forward.
# TODO: Use python's psycopg2 module to do this in python instead of # TODO: Use python's psycopg2 module to do this in python instead of
# installing postgres-client in the image. # installing postgres-client in the image.
until psql $DATABASE_URL -c '\l'; do until psql -P pager=off $DATABASE_URL -c '\l'; do
>&2 echo "Postgres is unavailable - sleeping" >&2 echo "Postgres is unavailable - sleeping"
sleep 1 sleep 1
done done
@@ -118,12 +118,12 @@ echo "Compiling locale files in $SITE_DIR"
cd $SITE_DIR && /opt/mailman-web/manage.py compilemessages && cd - cd $SITE_DIR && /opt/mailman-web/manage.py compilemessages && cd -
# Compress static files. # Compress static files.
python3 manage.py compress --force python3 /opt/mailman-web/manage.py compress --force
# Migrate all the data to the database if this is a new installation, otherwise # Migrate all the data to the database if this is a new installation, otherwise
# this command will upgrade the database. # this command will upgrade the database.
python3 manage.py migrate python3 /opt/mailman-web/manage.py migrate
# If MAILMAN_ADMIN_USER and MAILMAN_ADMIN_EMAIL is defined create a new # 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 # superuser for Django. There is no password setup so it can't login yet unless
@@ -131,7 +131,7 @@ python3 manage.py migrate
if [[ -v MAILMAN_ADMIN_USER ]] && [[ -v MAILMAN_ADMIN_EMAIL ]]; if [[ -v MAILMAN_ADMIN_USER ]] && [[ -v MAILMAN_ADMIN_EMAIL ]];
then then
echo "Creating admin user $MAILMAN_ADMIN_USER ..." echo "Creating admin user $MAILMAN_ADMIN_USER ..."
python3 manage.py createsuperuser --noinput --username "$MAILMAN_ADMIN_USER"\ python3 /opt/mailman-web/manage.py createsuperuser --noinput --username "$MAILMAN_ADMIN_USER"\
--email "$MAILMAN_ADMIN_EMAIL" 2> /dev/null || \ --email "$MAILMAN_ADMIN_EMAIL" 2> /dev/null || \
echo "Superuser $MAILMAN_ADMIN_USER already exists" echo "Superuser $MAILMAN_ADMIN_USER already exists"
fi fi
@@ -141,7 +141,7 @@ fi
if [[ -v SERVE_FROM_DOMAIN ]]; if [[ -v SERVE_FROM_DOMAIN ]];
then then
echo "Setting $SERVE_FROM_DOMAIN as the default domain ..." echo "Setting $SERVE_FROM_DOMAIN as the default domain ..."
python3 manage.py shell -c \ python3 /opt/mailman-web/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')" "from django.contrib.sites.models import Site; Site.objects.filter(domain='example.com').update(domain='$SERVE_FROM_DOMAIN', name='$SERVE_FROM_DOMAIN')"
fi fi

View File

@@ -29,7 +29,7 @@ https://docs.djangoproject.com/en/1.8/ref/settings/
import os import os
import dj_database_url import dj_database_url
import sys import sys
from socket import gethostbyname from socket import gethostbyname, gaierror
BASE_DIR = os.path.dirname(os.path.abspath(__file__)) BASE_DIR = os.path.dirname(os.path.abspath(__file__))
@@ -49,14 +49,17 @@ SITE_ID = 1
# See https://docs.djangoproject.com/en/3.1/ref/settings/#allowed-hosts # See https://docs.djangoproject.com/en/3.1/ref/settings/#allowed-hosts
ALLOWED_HOSTS = [ ALLOWED_HOSTS = [
"localhost", # Archiving API from Mailman, keep it. "localhost", # Archiving API from Mailman, keep it.
# "lists.your-domain.org",
# Add here all production URLs you may have.
"mailman-web", "mailman-web",
gethostbyname("mailman-web"),
os.environ.get('SERVE_FROM_DOMAIN'), os.environ.get('SERVE_FROM_DOMAIN'),
os.environ.get('DJANGO_ALLOWED_HOSTS'),
] ]
try:
ALLOWED_HOSTS.append(gethostbyname("mailman-web")) # only add if this resolves
except gaierror:
pass
ALLOWED_HOSTS.extend(os.getenv("DJANGO_ALLOWED_HOSTS", "").split(","))
# Mailman API credentials # Mailman API credentials
MAILMAN_REST_API_URL = os.environ.get('MAILMAN_REST_URL', 'http://mailman-core:8001') 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_USER = os.environ.get('MAILMAN_REST_USER', 'restadmin')
@@ -81,6 +84,7 @@ DEFAULT_APPS = [
'django.contrib.sites', 'django.contrib.sites',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'django.contrib.humanize',
'rest_framework', 'rest_framework',
'django_gravatar', 'django_gravatar',
'compressor', 'compressor',
@@ -109,6 +113,7 @@ MIDDLEWARE = (
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
'allauth.account.middleware.AccountMiddleware',
'django_mailman3.middleware.TimezoneMiddleware', 'django_mailman3.middleware.TimezoneMiddleware',
'postorius.middleware.PostoriusMiddleware', 'postorius.middleware.PostoriusMiddleware',
) )
@@ -151,6 +156,11 @@ DATABASES = {
'default': dj_database_url.config(conn_max_age=600) 'default': dj_database_url.config(conn_max_age=600)
} }
# Avoid Django 3.2+ warning
# https://github.com/maxking/docker-mailman/issues/595
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
# If you're behind a proxy, use the X-Forwarded-Host header # 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 # See https://docs.djangoproject.com/en/1.8/ref/settings/#use-x-forwarded-host
USE_X_FORWARDED_HOST = True USE_X_FORWARDED_HOST = True
@@ -178,7 +188,7 @@ AUTH_PASSWORD_VALIDATORS = [
LANGUAGE_CODE = 'en-us' LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC' TIME_ZONE = os.environ.get('TZ', 'UTC')
USE_I18N = True USE_I18N = True

View File

@@ -16,20 +16,19 @@
# You should have received a copy of the GNU General Public License along with # You should have received a copy of the GNU General Public License along with
# Postorius. If not, see <http://www.gnu.org/licenses/>. # Postorius. If not, see <http://www.gnu.org/licenses/>.
from django.conf.urls import include
from django.conf.urls import include, url
from django.contrib import admin from django.contrib import admin
from django.urls import reverse_lazy from django.urls import path, reverse_lazy
from django.views.generic import RedirectView from django.views.generic import RedirectView
urlpatterns = [ urlpatterns = [
url(r'^$', RedirectView.as_view( path(r'', RedirectView.as_view(
url=reverse_lazy('list_index'), url=reverse_lazy('list_index'),
permanent=True)), permanent=True)),
url(r'^postorius/', include('postorius.urls')), path(r'postorius/', include('postorius.urls')),
url(r'^hyperkitty/', include('hyperkitty.urls')), path(r'hyperkitty/', include('hyperkitty.urls')),
url(r'', include('django_mailman3.urls')), path(r'', include('django_mailman3.urls')),
url(r'^accounts/', include('allauth.urls')), path(r'accounts/', include('allauth.urls')),
# Django admin # Django admin
url(r'^admin/', admin.site.urls), path(r'admin/', admin.site.urls),
] ]

View File

@@ -3,10 +3,13 @@
uwsgi-socket = 0.0.0.0:8080 uwsgi-socket = 0.0.0.0:8080
http-socket = 0.0.0.0:8000 http-socket = 0.0.0.0:8000
#Enable threading for python # Enable threading for python
enable-threads = true enable-threads = true
# Move to the directory wher the django files are. # Setting uwsgi buffer size to what Apache2 supports.
buffer-size = 8190
# Move to the directory where the django files are.
chdir = /opt/mailman-web chdir = /opt/mailman-web
# Use the wsgi file provided with the django project. # Use the wsgi file provided with the django project.
@@ -17,7 +20,7 @@ master = true
processes = 2 processes = 2
threads = 2 threads = 2
# Drop privielges and don't run as root. # Drop privileges and don't run as root.
uid = mailman uid = mailman
gid = mailman gid = mailman

4
web/requirements.txt Normal file
View File

@@ -0,0 +1,4 @@
mailmanclient==3.3.5
postorius==1.3.10
hyperkitty==1.3.9
django-mailman3==1.3.11