init: yolks for GMod 64-bit and Stalwart Mail Server
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
FROM debian:bookworm-slim
|
||||
|
||||
LABEL author="RefoselTeam" maintainer="admin@refoseltw.ru"
|
||||
|
||||
LABEL org.opencontainers.image.source="https://gitea.refoseltw.ru/RefoselTeamWork/yolks"
|
||||
LABEL org.opencontainers.image.licenses=MIT
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Install dependencies
|
||||
RUN apt update \
|
||||
&& apt upgrade -y \
|
||||
&& apt install -y \
|
||||
curl \
|
||||
gnupg \
|
||||
ca-certificates \
|
||||
tini \
|
||||
tzdata \
|
||||
unzip \
|
||||
git \
|
||||
&& apt clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Stalwart Mail Server
|
||||
RUN curl -sSL https://stalw.art/install.sh | bash
|
||||
|
||||
# Create directories
|
||||
RUN mkdir -p /home/container/stalwart-mail \
|
||||
&& mkdir -p /home/container/stalwart-mail/data \
|
||||
&& mkdir -p /home/container/stalwart-mail/certs \
|
||||
&& mkdir -p /home/container/stalwart-mail/logs
|
||||
|
||||
# Setup user
|
||||
RUN useradd -m -d /home/container -s /bin/bash container \
|
||||
&& chown -R container:container /home/container
|
||||
|
||||
USER container
|
||||
ENV USER=container HOME=/home/container
|
||||
WORKDIR /home/container
|
||||
|
||||
EXPOSE 8080 465 587 993 995 4190
|
||||
|
||||
STOPSIGNAL SIGINT
|
||||
|
||||
COPY --chown=container:container ./entrypoint.sh /entrypoint.sh
|
||||
COPY --chown=container:container ./config.toml /entrypoint-config.toml
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/usr/bin/tini", "-g", "--"]
|
||||
CMD ["/entrypoint.sh"]
|
||||
@@ -0,0 +1,260 @@
|
||||
[storage]
|
||||
data = "{{STORAGE_DATA}}"
|
||||
logs = "{{STORAGE_LOGS}}"
|
||||
queue = "{{STORAGE_DATA}}/queue"
|
||||
blobs = "{{STORAGE_DATA}}/blobs"
|
||||
|
||||
[lookup]
|
||||
default = "internal"
|
||||
|
||||
[lookup.internal]
|
||||
hostname = "{{MAIL_HOSTNAME}}"
|
||||
domain = "{{MAIL_DOMAIN}}"
|
||||
|
||||
[smtp]
|
||||
hostname = "{{MAIL_HOSTNAME}}"
|
||||
bind = ["0.0.0.0:{{SMTP_PORT}}", "[::]:{{SMTP_PORT}}"]
|
||||
concurrency.remote = 10
|
||||
max-message-size = 52428800
|
||||
|
||||
[smtp.auth]
|
||||
directory = "internal"
|
||||
|
||||
[smtp.session]
|
||||
ehlo-required = true
|
||||
max-recipients = 100
|
||||
|
||||
[imap]
|
||||
bind = ["0.0.0.0:{{IMAP_PORT}}", "[::]:{{IMAP_PORT}}"]
|
||||
max-connections = 50
|
||||
|
||||
[jmap]
|
||||
bind = ["0.0.0.0:8081", "[::]:8081"]
|
||||
|
||||
[http]
|
||||
bind = ["0.0.0.0:{{HTTP_PORT}}", "[::]:{{HTTP_PORT}}"]
|
||||
url = "http://{{MAIL_HOSTNAME}}:{{HTTP_PORT}}"
|
||||
|
||||
[http.auth]
|
||||
directory = "internal"
|
||||
|
||||
[manager]
|
||||
enable = true
|
||||
|
||||
[metrics]
|
||||
enable = true
|
||||
|
||||
[submission]
|
||||
bind = ["0.0.0.0:{{SUBMISSION_PORT}}", "[::]:{{SUBMISSION_PORT}}"]
|
||||
|
||||
[sieve]
|
||||
bind = ["0.0.0.0:{{MANAGESIEVE_PORT}}", "[::]:{{MANAGESIEVE_PORT}}"]
|
||||
|
||||
[acme]
|
||||
enable = false
|
||||
|
||||
[dkim]
|
||||
domain = "{{MAIL_DOMAIN}}"
|
||||
selector = "stalwart"
|
||||
|
||||
[authentication]
|
||||
directory = "internal"
|
||||
fail2ban = true
|
||||
|
||||
[authentication.directory.internal]
|
||||
enable = true
|
||||
class = "internal"
|
||||
|
||||
[authentication.directory.internal.config]
|
||||
backend = "rocksdb"
|
||||
path = "{{STORAGE_DATA}}/auth"
|
||||
|
||||
[authentication.directory.internal.config.password.schemes]
|
||||
argon2 = true
|
||||
bcrypt = true
|
||||
sha512 = true
|
||||
|
||||
[authentication.directory.internal.config.password.max]
|
||||
iterations = 10
|
||||
size = 32
|
||||
|
||||
[authentication.directory.internal.config.password.force]
|
||||
iterations = false
|
||||
size = false
|
||||
|
||||
[authentication.directory.internal.config.throttling]
|
||||
max-auth-per-ip = 10
|
||||
max-errors-per-ip = 10
|
||||
window-secs = 600
|
||||
|
||||
[authentication.directory.internal.config.heartbeat]
|
||||
enable = false
|
||||
interval-secs = 0
|
||||
|
||||
[authentication.fallback]
|
||||
enable = true
|
||||
|
||||
[authentication.fallback.class]
|
||||
enable = true
|
||||
require-scope = false
|
||||
|
||||
[authentication.fallback.class.config]
|
||||
verify-email = false
|
||||
verify-subaddress = false
|
||||
|
||||
[authentication.fallback.class.config.domain]
|
||||
names = []
|
||||
catch-all = false
|
||||
tag-plus = true
|
||||
tag-hyphen = false
|
||||
|
||||
[authentication.fallback.class.config.oidc]
|
||||
enable = false
|
||||
discovery-url = ""
|
||||
client-id = ""
|
||||
client-secret = ""
|
||||
allow-signup = false
|
||||
scopes = ["openid", "email", "profile"]
|
||||
grant-type = "authorization-code"
|
||||
auth-url = ""
|
||||
token-url = ""
|
||||
userinfo-url = ""
|
||||
jwt-key = ""
|
||||
jwk-url = ""
|
||||
|
||||
[storage.data]
|
||||
type = "rocksdb"
|
||||
path = "{{STORAGE_DATA}}/data"
|
||||
|
||||
[storage.logs]
|
||||
type = "rocksdb"
|
||||
path = "{{STORAGE_DATA}}/logs"
|
||||
|
||||
[storage.queue]
|
||||
type = "rocksdb"
|
||||
path = "{{STORAGE_DATA}}/queue"
|
||||
|
||||
[storage.blobs]
|
||||
type = "rocksdb"
|
||||
path = "{{STORAGE_DATA}}/blobs"
|
||||
|
||||
[storage.fts]
|
||||
type = "rocksdb"
|
||||
path = "{{STORAGE_DATA}}/fts"
|
||||
|
||||
[storage.privacy]
|
||||
type = "rocksdb"
|
||||
path = "{{STORAGE_DATA}}/privacy"
|
||||
|
||||
[storage.counters]
|
||||
type = "rocksdb"
|
||||
path = "{{STORAGE_DATA}}/counters"
|
||||
|
||||
[storage.pool]
|
||||
type = "rocksdb"
|
||||
path = "{{STORAGE_DATA}}/pool"
|
||||
|
||||
[storage.cache]
|
||||
type = "rocksdb"
|
||||
path = "{{STORAGE_DATA}}/cache"
|
||||
|
||||
[storage.envelope]
|
||||
type = "rocksdb"
|
||||
path = "{{STORAGE_DATA}}/envelope"
|
||||
|
||||
[storage.index]
|
||||
type = "rocksdb"
|
||||
path = "{{STORAGE_DATA}}/index"
|
||||
|
||||
[storage.spam-filter]
|
||||
type = "rocksdb"
|
||||
path = "{{STORAGE_DATA}}/spam-filter"
|
||||
|
||||
[storage.in-memory]
|
||||
type = "memory"
|
||||
|
||||
[storage.static]
|
||||
type = "memory"
|
||||
|
||||
[repository]
|
||||
default = "rocksdb"
|
||||
|
||||
[repository.rocksdb]
|
||||
driver = "rocksdb"
|
||||
|
||||
[smtp.queue]
|
||||
retry = [60, 300, 900, 3600, 7200, 21600, 43200]
|
||||
max-retries = 10
|
||||
max-size = 52428800
|
||||
notify = ["postmaster@{{MAIL_DOMAIN}}"]
|
||||
path = "{{STORAGE_DATA}}/queue"
|
||||
|
||||
[smtp.queue.remote]
|
||||
concurrency = 10
|
||||
timeout = 300
|
||||
|
||||
[smtp.outgoing]
|
||||
max-helo = 5
|
||||
max-recipients = 100
|
||||
max-connection-age = 600
|
||||
max-connections = 10
|
||||
greeting-delay = 0
|
||||
|
||||
[smtp.dkim]
|
||||
sign = ["{{MAIL_DOMAIN}}"]
|
||||
keys = []
|
||||
|
||||
[smtp.dmarc]
|
||||
reject = false
|
||||
allow-unsigned = true
|
||||
tag-only = false
|
||||
|
||||
[smtp.spam-filter]
|
||||
enable = true
|
||||
path = "{{STORAGE_DATA}}/spam-filter"
|
||||
|
||||
[smtp.auth.rate-limit]
|
||||
max-per-ip = 10
|
||||
window-secs = 600
|
||||
|
||||
[http.dashboard]
|
||||
enable = true
|
||||
|
||||
[http.api]
|
||||
enable = true
|
||||
|
||||
[http.webmail]
|
||||
enable = false
|
||||
|
||||
[http.static]
|
||||
enable = true
|
||||
|
||||
[http.cors]
|
||||
allow-origin = "*"
|
||||
allow-methods = ["GET", "POST", "PUT", "DELETE"]
|
||||
allow-headers = ["Content-Type", "Authorization"]
|
||||
max-age = 3600
|
||||
|
||||
[http.tls]
|
||||
enable = false
|
||||
certificate = ""
|
||||
private-key = ""
|
||||
|
||||
[logging]
|
||||
level = "info"
|
||||
|
||||
[logging.channel.smtp]
|
||||
enable = true
|
||||
level = "info"
|
||||
|
||||
[logging.channel.auth]
|
||||
enable = true
|
||||
level = "info"
|
||||
|
||||
[logging.channel.store]
|
||||
enable = false
|
||||
level = "info"
|
||||
|
||||
[logging.channel.http]
|
||||
enable = true
|
||||
level = "info"
|
||||
@@ -0,0 +1,86 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Wait for the container to fully initialize
|
||||
sleep 1
|
||||
|
||||
# Default the TZ environment variable to UTC.
|
||||
TZ=${TZ:-UTC}
|
||||
export TZ
|
||||
|
||||
# Switch to the container's working directory
|
||||
cd /home/container || exit 1
|
||||
|
||||
# Stalwart paths
|
||||
STALWART_HOME="/home/container/stalwart-mail"
|
||||
STALWART_CONFIG="${STALWART_HOME}/config.toml"
|
||||
STALWART_DATA="${STALWART_HOME}/data"
|
||||
STALWART_CERTS="${STALWART_HOME}/certs"
|
||||
STALWART_LOGS="${STALWART_HOME}/logs"
|
||||
|
||||
# Create config from template if not exists
|
||||
if [ ! -f "${STALWART_CONFIG}" ]; then
|
||||
echo "Generating Stalwart configuration..."
|
||||
cp /entrypoint-config.toml "${STALWART_CONFIG}"
|
||||
|
||||
# Replace placeholders with environment variables
|
||||
sed -i "s|{{MAIL_DOMAIN}}|${MAIL_DOMAIN:-mail.example.com}|g" "${STALWART_CONFIG}"
|
||||
sed -i "s|{{MAIL_HOSTNAME}}|${MAIL_HOSTNAME:-$(hostname)|g" "${STALWART_CONFIG}"
|
||||
sed -i "s|{{ADMIN_EMAIL}}|${ADMIN_EMAIL:-admin@${MAIL_DOMAIN:-mail.example.com}}|g" "${STALWART_CONFIG}"
|
||||
sed -i "s|{{HTTP_PORT}}|${HTTP_PORT:-8080}|g" "${STALWART_CONFIG}"
|
||||
sed -i "s|{{SMTP_PORT}}|${SMTP_PORT:-465}|g" "${STALWART_CONFIG}"
|
||||
sed -i "s|{{SUBMISSION_PORT}}|${SUBMISSION_PORT:-587}|g" "${STALWART_CONFIG}"
|
||||
sed -i "s|{{IMAP_PORT}}|${IMAP_PORT:-993}|g" "${STALWART_CONFIG}"
|
||||
sed -i "s|{{MANAGESIEVE_PORT}}|${MANAGESIEVE_PORT:-4190}|g" "${STALWART_CONFIG}"
|
||||
sed -i "s|{{STORAGE_DATA}}|${STALWART_DATA}|g" "${STALWART_CONFIG}"
|
||||
sed -i "s|{{STORAGE_LOGS}}|${STALWART_LOGS}|g" "${STALWART_CONFIG}"
|
||||
|
||||
echo "Configuration generated."
|
||||
fi
|
||||
|
||||
# Generate admin password if not set
|
||||
if [ ! -f "${STALWART_HOME}/.admin_created" ]; then
|
||||
ADMIN_PASS=${ADMIN_PASSWORD:-$(openssl rand -base64 16)}
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo " Stalwart Mail Server"
|
||||
echo "=========================================="
|
||||
echo " Admin URL: http://${SERVER_IP:-0.0.0.0}:${HTTP_PORT:-8080}"
|
||||
echo " Admin Email: ${ADMIN_EMAIL:-admin@${MAIL_DOMAIN:-mail.example.com}}"
|
||||
echo " Admin Pass: ${ADMIN_PASS}"
|
||||
echo "=========================================="
|
||||
echo " IMPORTANT: Save these credentials!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Create admin account
|
||||
/home/container/stalwart-mail/bin/stalwart-mail --config "${STALWART_CONFIG}" --write-config
|
||||
|
||||
touch "${STALWART_HOME}/.admin_created"
|
||||
fi
|
||||
|
||||
# Clone Git repos if GIT_REPOS is set (for custom configs, filters, etc.)
|
||||
if [ ! -z "${GIT_REPOS}" ]; then
|
||||
IFS=',' read -ra REPOS <<< "$GIT_REPOS"
|
||||
for repo in "${REPOS[@]}"; do
|
||||
repo=$(echo "$repo" | xargs)
|
||||
if [ ! -z "$repo" ]; then
|
||||
REPO_NAME=$(basename "$repo" .git)
|
||||
CLONE_DIR="${STALWART_HOME}/plugins/${REPO_NAME}"
|
||||
if [ -d "${CLONE_DIR}/.git" ]; then
|
||||
echo "Updating plugin: ${REPO_NAME}..."
|
||||
cd "${CLONE_DIR}" && git pull && cd /home/container
|
||||
else
|
||||
echo "Cloning plugin: ${REPO_NAME}..."
|
||||
mkdir -p "${STALWART_HOME}/plugins"
|
||||
git clone "$repo" "${CLONE_DIR}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Replace Startup Variables
|
||||
MODIFIED_STARTUP=$(echo ${STARTUP} | sed -e 's/{{/${/g' -e 's/}}/}/g')
|
||||
echo -e ":/home/container$ ${MODIFIED_STARTUP}"
|
||||
|
||||
# Run the Server
|
||||
eval ${MODIFIED_STARTUP}
|
||||
Reference in New Issue
Block a user