Inboxen のインストールに嵌まったので、そのメモ。 といっても、Web 画面に辿り着くのは、簡単で、Postfix の設定に手こずった。

まずインストール/実行用のアカウント inboxen を作成し、pyenv で Python 3.10.9 をインストール。

pyenv install 3.10.9

リポジトリをクローン。

git clone https://github.com/Inboxen/Inboxen.git

pip を実行。gunicorn もインストールする。

cd Inboxen
pip install -r requirements.txt
pip install gunicorn

inboxen.config を作成する。

cp -i inboxen/config_defaults.yaml inboxen.config
vi inboxen.config

inboxen.config の内容は以下のようにした。

secret_key: "secret"
admins:
  - - Koichi MATSUMOTO
    - mzch@example.com
allowed_hosts: ['example.com','www.example.com']
cache:
  backend: "django.core.cache.backends.filebased.FileBasedCache"
  location: "inboxen_cache"
  timeout: 300
database:
    host: "127.0.0.1"
    name: "inboxen"
    password: "password"
    port: "5432"
    user: "inboxen"
debug: false
enable_registration: false
inbox_length: 6
language_code: "en-gb"
media_root: "media_content"
per_user_email_quota: 0
ratelimits:
    inbox:
        count: 100
        window: 1440
    login:
        count: 5
        window: 60
    register:
        count: 5
        window: 30
    single_email:
        count: 100
        window: 60
server_email: "no-reply@example.com"
site_name: "mzch Inboxen"
source_link: "https://github.com/Inboxen/Inboxen"
static_root: "static_content"
tasks:
    always_eager: false
    broker_url: "amqp://guest:guest@localhost:5672//"
    concurrency: 3
    liberation:
        path: "liberation_store"
        sendfile_backend: "django_sendfile.backends.simple"
time_zone: "UTC"

データベースのマイグレーションを行い、super user を作成する。

python manage.py migrate
python manage.py createsuperuser

css や、js ファイルを作成して、collectstatic する。

npm install
npx grunt
python manage.py compilemessages
python manage.py collectstatic

gunicorn 起動スクリプトを作成。

#! /bin/sh

PORT=9090
WORKERS=2
THREADS=4
LOGLEVEL=info

HOME=/srv/inboxen

LOGDIR=$HOME/logs
RUNDIR=$HOME/run

if [ -d "$HOME/.pyenv/bin" ] ; then
    PATH="$HOME/.pyenv/bin:$PATH"
    eval "$(pyenv init -)"
fi

cd $HOME/Inboxen

OPTS=
OPTS=$OPTS" --access-logfile "$LOGDIR"/access.log"
OPTS=$OPTS" --error-logfile "$LOGDIR"/error.log"
OPTS=$OPTS" --log-level "$LOGLEVEL
OPTS=$OPTS" --name Inboxen"
OPTS=$OPTS" --pid "$RUNDIR"/inboxen.pid"
OPTS=$OPTS" --bind 127.0.0.1:"$PORT
OPTS=$OPTS" --workers "$WORKERS
OPTS=$OPTS" --threads "$THREADS

exec gunicorn $OPTS inboxen.wsgi

salmoncelery プロセス起動スクリプトを作成。

#! /bin/sh

HOME=/srv/inboxen

LOGDIR=$HOME/logs
RUNDIR=$HOME/run

if [ -d "$HOME/.pyenv/bin" ] ; then
    PATH="$HOME/.pyenv/bin:$PATH"
    eval "$(pyenv init -)"
fi

cd $HOME/Inboxen

DJANGO_SETTINGS_MODULE=inboxen.settings
export DJANGO_SETTINGS_MODULE
celery -A inboxen worker -l warn --events --detach -Ofair -f $LOGDIR/celery-worker.log --pidfile $RUNDIR/worker.pid
celery -A inboxen beat -l warn --detach -f $LOGDIR/celery-beat.log --pidfile $RUNDIR/beat.pid

SALMON_SETTINGS_MODULE=inboxen.router.config.settings
export SALMON_SETTINGS_MODULE
salmon start --pid $RUNDIR/router.pid --boot inboxen.router.config.boot

RabbitMQ をインストール。

sudo apt install rabbitmq-server

systemd 用の service ファイルを作成。

  • inboxen.service
[Unit]
Description=Inboxen
After=network.target

[Service]
Type=simple
User=inboxen
WorkingDirectory=/srv/inboxen
ExecStart=/srv/inboxen/start.sh
PrivateTmp=true
Restart=on-abort

[Install]
WantedBy=multi-user.target
  • inboxen-worker.service
[Unit]
Description=Inboxen Workers
After=network.target

[Service]
Type=forking
User=inboxen
WorkingDirectory=/srv/inboxen
ExecStart=/srv/inboxen/worker.sh
PrivateTmp=true
Restart=on-abort

[Install]
WantedBy=multi-user.target

Inboxen を起動する。

systemctl enable inboxen
systemctl enable inboxen-worker
systemctl start inboxen
systemctl start inboxen-worker

Apache を設定

<VirtualHost *:80>
	ServerName example.com
	ServerAlias www.example.com
	RewriteEngine On
	RewriteCond %{SERVER_NAME} =example.com [OR]
	RewriteCond %{SERVER_NAME} =www.example.com
	RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

<IfModule mod_ssl.c>
<VirtualHost *:443>

	ServerName example.com
	ServerAlias www.example.com
	ServerAdmin webmaster@example.com

	Include /etc/letsencrypt/options-ssl-apache.conf
	SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
	SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

	RewriteEngine On
	RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
	RewriteRule ^(.*)$ https://%1$1 [R=301,L]

	Alias /static/ /srv/inboxen/Inboxen/static_content/
	<Directory "/srv/inboxen/Inboxen/static_content">
		Require all granted
	</Directory>

	RequestHeader set X-Forwarded-Proto "https"
	ProxyRequests Off
	ProxyPreserveHost On

	RewriteEngine On
	RewriteCond %{HTTP:Connection} Upgrade [NC]
	RewriteCond %{HTTP:Upgrade} websocket [NC]
	RewriteRule ^/(.*) ws://127.0.0.1:9090/$1 [P,L]

	ProxyPass /static !
	ProxyPass / http://127.0.0.1:9090/
	ProxyPassReverse / http://127.0.0.1:9090/

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>
</IfModule>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

もしくは、Nginx

server {
        listen 80;
        listen [::]:80;
        server_name example.com www.example.com;
        if ($host = example.com) {
        	return 301 https://$host$request_uri;
        }
        if ($host = www.example.com) {
        	return 301 https://$host$request_uri;
        }
        return 404;
}

server {

        listen [::]:443 http2 ssl;
        listen 443 http2 ssl;

        server_name example.com www.example.com;

        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

        if ($host = www.example.com) {
                return 301 https://example.com$request_uri;
        }

        # You can increase the limit if your need to.
        client_max_body_size 512M;

        location /static {
                alias /srv/inboxen/Inboxen/static_content;
        }

        location / {
                proxy_pass http://127.0.0.1:9090;
                proxy_http_version 1.1;
                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 https;
                proxy_set_header X-Nginx-Proxy true;
                proxy_redirect off;
        }

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;
}

# vim: syntax=nginx ts=4 sw=4 sts=4 sr noet

Postfix 用の postgresql パッケージをインストール。

sudo apt install postfix-pgsql

Postfix の main.cf に以下の行を挿入。

relay_domains = pgsql:/etc/postfix/relay_domains_maps.cf
transport_maps = pgsql:/etc/postfix/relay_maps.cf

/etc/postfix/relay_domains_maps.cf を作成。

user     = inboxen
password = password
hosts    = 127.0.0.1
dbname   = inboxen
query    = SELECT domain FROM inboxen_domain WHERE domain = '%s' AND enabled = true

/etc/postfix/relay_maps.cf を作成。

user     = inboxen
password = password
hosts    = 127.0.0.1
dbname   = inboxen
query    = SELECT 'smtp:[::1]:8823'  FROM inboxen_domain WHERE domain = '%s' AND enabled = true

postfix reload を実行。

デフォルトの設定だと、IPv6 のローカルアドレス ::1salmon が待機しているので、環境が違う場合は適宜読み替えが必要。

また、作成した super userだが、2FA (二段階認証) を有効にしないと管理画面にアクセスできない。ログインしたら、忘れずに 2FA を有効にする。

[2023/01/03 改訂]