Remove old file

master
andryyy 2016-12-14 15:56:30 +01:00
parent 2aca3e0d30
commit 9e8a003508
28 changed files with 259 additions and 493 deletions

1
.env 120000
View File

@ -0,0 +1 @@
mailcow.conf

View File

@ -1,16 +0,0 @@
#!/bin/bash
. mailcow.conf
openssl dhparam -out data/assets/ssl/dhparams.pem 2048
docker run \
--rm \
-v ${PWD}/data/assets/ssl:/certs \
ehazlett/certm \
-d /certs ca generate -o=mailcow
docker run \
--rm \
-v ${PWD}/data/assets/ssl:/certs \
ehazlett/certm \
-d /certs client generate --common-name=${MAILCOW_HOSTNAME} -o=mailcow

View File

@ -1,13 +0,0 @@
#!/bin/bash
. mailcow.conf
if [[ -z $(docker network ls --filter "name=${DOCKER_NETWORK}" -q) ]]; then
docker network create ${DOCKER_NETWORK} --subnet ${DOCKER_SUBNET}
else
if [[ $(docker network inspect mailcow-network --format='{{range .IPAM.Config}}{{.Subnet}}{{end}}' 2> /dev/null) != ${DOCKER_SUBNET} ]]; then
echo "ERROR: mailcow network exists, but has wrong subnet!"
exit 1
fi
echo "Correct mailcow network exists, skipped..."
exit 0
fi

View File

@ -1,19 +0,0 @@
#!/bin/bash
. mailcow.conf
NAME="pdns-mailcow"
echo "Stopping and removing containers with name tag ${NAME}..."
if [[ ! -z $(docker ps -af "name=${NAME}" -q) ]]; then
docker stop $(docker ps -af "name=${NAME}" -q)
docker rm $(docker ps -af "name=${NAME}" -q)
fi
docker run \
-v ${PWD}/data/conf/pdns/:/etc/powerdns/ \
--network=${DOCKER_NETWORK} \
-h pdns \
--network-alias=pdns \
--name ${NAME} \
-d andryyy/mailcow-dockerized:pdns

View File

@ -1,104 +0,0 @@
#!/bin/bash
. mailcow.conf
NAME="mariadb-mailcow"
reconf() {
echo "Installing database schema (this will not overwrite existing data)"
echo "It may take a while for MariaDB to warm up, please wait..."
echo docker exec ${NAME} mysql -u${DBUSER} -p${DBPASS} ${DBNAME}
until docker exec ${NAME} /bin/bash -c "mysql -u'${DBUSER}' -p'${DBPASS}' ${DBNAME} < /assets/init.sql"; do
echo "Trying again in 2 seconds..."
sleep 2
done
echo "Done."
}
dump() {
DATE=$(date +"%Y%m%d_%H%M%S")
echo "Creating dump file ./backup_${DBNAME}_${DATE}.sql"
docker exec -it ${NAME} /bin/bash mysqldump --default-character-set=utf8mb4 -u${DBUSER} -p${DBPASS} ${DBNAME} > backup_${DBNAME}_${DATE}.sql
}
restore() {
echo "Restoring dump file ${2}..."
docker exec -i ${NAME} mysql -u${DBUSER} -p${DBPASS} ${DBNAME} < ${1}
}
insert_admin() {
echo 'Setting mailcow UI admin login to "admin:moohoo"...'
echo "It may take a while for MariaDB to warm up, please wait..."
until docker exec ${NAME} /bin/bash -c "mysql -u'${DBUSER}' -p'${DBPASS}' ${DBNAME} < /assets/pw.sql"; do
echo "Trying again in 2 seconds..."
sleep 2
done
echo "Done."
}
client() {
echo "==============================="
echo "DB: ${DBNAME} - USER: ${DBUSER}"
echo "==============================="
docker exec -it ${NAME} mysql -u${DBUSER} -p${DBPASS} ${DBNAME}
}
if [[ ${1} == "--init-schema" ]]; then
reconf
exit 0
elif [[ ${1} == "--dump" ]]; then
dump
exit 0
elif [[ ${1} == "--restore" ]]; then
if [[ -z ${2} || ! -f ${2} ]]; then
echo "Invalid input file"
exit 1
fi
restore ${2}
exit 0
elif [[ ${1} == "--client" ]]; then
client
exit 0
elif [[ ${1} == "--reset-admin" ]]; then
insert_admin
exit 0
elif [[ ! -z ${1} ]]; then
echo "Unknown parameter"
exit 1
fi
echo "Stopping and removing containers with name tag ${NAME}..."
if [[ ! -z $(docker ps -af "name=${NAME}" -q) ]]; then
docker stop $(docker ps -af "name=${NAME}" -q)
docker rm $(docker ps -af "name=${NAME}" -q)
fi
if [[ ! -z "$(docker images -q mariadb:${DBVERS})" ]]; then
read -r -p "Found image locally. Delete local image and repull? [y/N] " response
response=${response,,}
if [[ $response =~ ^(yes|y)$ ]]; then
docker rmi mariadb:${DBVERS}
fi
fi
docker run \
-v ${PWD}/data/db/mysql/:/var/lib/mysql/ \
-v ${PWD}/data/conf/mysql/:/etc/mysql/conf.d/:ro \
-v ${PWD}/data/assets/mysql:/assets:ro \
--name=${NAME} \
--network=${DOCKER_NETWORK} \
-h mysql \
--network-alias=mysql \
-e MYSQL_ROOT_PASSWORD=${DBROOT} \
-e MYSQL_DATABASE=${DBNAME} \
-e MYSQL_USER=${DBUSER} \
-e MYSQL_PASSWORD=${DBPASS} \
-d mariadb:${DBVERS}
reconf
read -r -p "Do you want to reset mailcow admin to admin:moohoo? [y/N] " response
response=${response,,}
if [[ $response =~ ^(yes|y)$ ]]; then
insert_admin
fi

View File

@ -1,39 +0,0 @@
#!/bin/bash
. mailcow.conf
NAME="redis-mailcow"
client() {
docker exec -it ${NAME} /bin/bash -c "redis-cli"
}
if [[ ${1} == "--client" ]]; then
client
exit 0
elif [[ ! -z ${1} ]]; then
echo "Unknown parameter"
exit 1
fi
echo "Stopping and removing containers with name tag ${NAME}..."
if [[ ! -z $(docker ps -af "name=${NAME}" -q) ]]; then
docker stop $(docker ps -af "name=${NAME}" -q)
docker rm $(docker ps -af "name=${NAME}" -q)
fi
if [[ ! -z "$(docker images -q redis:${DBVERS})" ]]; then
read -r -p "Found image locally. Delete local image and repull? [y/N] " response
response=${response,,}
if [[ $response =~ ^(yes|y)$ ]]; then
docker rmi redis:${DBVERS}
fi
fi
docker run \
-v ${PWD}/data/db/redis/:/data/ \
--network=${DOCKER_NETWORK} \
--network-alias=redis \
-h redis \
--name=${NAME} \
-d redis:${REDISVERS} --appendonly yes

View File

@ -1,36 +0,0 @@
#!/bin/bash
. mailcow.conf
NAME="rspamd-mailcow"
PDNS_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' pdns-mailcow 2> /dev/null)
if [[ ! ${PDNS_IP} =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Cannot determine Powerdns Recursor ip address. Is the container running?"
exit 1
fi
echo "Stopping and removing containers with name tag ${NAME}..."
if [[ ! -z $(docker ps -af "name=${NAME}" -q) ]]; then
docker stop $(docker ps -af "name=${NAME}" -q)
docker rm $(docker ps -af "name=${NAME}" -q)
fi
# Needs network-alias because of different dns
docker run \
-v ${PWD}/data/conf/rspamd/override.d/:/etc/rspamd/override.d:ro \
-v ${PWD}/data/conf/rspamd/local.d/:/etc/rspamd/local.d:ro \
-v ${PWD}/data/conf/rspamd/lua/:/etc/rspamd/lua/:ro \
-v ${PWD}/data/dkim/txt/:/etc/rspamd/dkim/txt/:ro \
-v ${PWD}/data/dkim/keys/:/etc/rspamd/dkim/keys/:ro \
--dns=${PDNS_IP} \
--dns-search=${DOCKER_NETWORK} \
--network=${DOCKER_NETWORK} \
--network-alias=rspamd \
-h rspamd \
--name ${NAME} \
-d andryyy/mailcow-dockerized:rspamd
/bin/bash ./fix-permissions.sh

View File

@ -1,28 +0,0 @@
#!/bin/bash
. mailcow.conf
NAME="php-fpm-mailcow"
if [[ ! -z $(docker ps -af "name=${NAME}" -q) ]]; then
docker stop $(docker ps -af "name=${NAME}" -q)
docker rm $(docker ps -af "name=${NAME}" -q)
fi
if [[ ! -z "$(docker images -q php:${PHPVERS})" ]]; then
read -r -p "Found image locally. Delete local image and repull? [y/N] " response
response=${response,,}
if [[ $response =~ ^(yes|y)$ ]]; then
docker rmi php:${PHPVERS}
fi
fi
docker run \
-v ${PWD}/data/web:/web:ro \
-v ${PWD}/data/conf/rspamd/dynmaps:/dynmaps:ro \
-v ${PWD}/data/dkim/:/shared/dkim/ \
-d --network=${DOCKER_NETWORK} \
--name ${NAME} \
--network-alias=phpfpm \
-h phpfpm \
andryyy/mailcow-dockerized:phpfpm

View File

@ -1,22 +0,0 @@
#!/bin/bash
. mailcow.conf
NAME="sogo-mailcow"
echo "Stopping and removing containers with name tag ${NAME}..."
if [[ ! -z $(docker ps -af "name=${NAME}" -q) ]]; then
docker stop $(docker ps -af "name=${NAME}" -q)
docker rm $(docker ps -af "name=${NAME}" -q)
fi
docker run \
-v ${PWD}/data/conf/sogo/:/etc/sogo/ \
--name ${NAME} \
--network=${DOCKER_NETWORK} \
--network-alias sogo \
-h sogo \
-e DBNAME=${DBNAME} \
-e DBUSER=${DBUSER} \
-e DBPASS=${DBPASS} \
-d -t andryyy/mailcow-dockerized:sogo

View File

@ -1,19 +0,0 @@
#!/bin/bash
. mailcow.conf
NAME="rmilter-mailcow"
echo "Stopping and removing containers with name tag ${NAME}..."
if [[ ! -z $(docker ps -af "name=${NAME}" -q) ]]; then
docker stop $(docker ps -af "name=${NAME}" -q)
docker rm $(docker ps -af "name=${NAME}" -q)
fi
docker run \
-v ${PWD}/data/conf/rmilter/:/etc/rmilter.conf.d/:ro \
--network=${DOCKER_NETWORK} \
-h rmilter \
--network-alias=rmilter \
--name ${NAME} \
-d andryyy/mailcow-dockerized:rmilter

View File

@ -1,30 +0,0 @@
#!/bin/bash
source mailcow.conf
NAME="dovecot-mailcow"
echo "Stopping and removing containers with name tag ${NAME}..."
if [[ ! -z $(docker ps -af "name=${NAME}" -q) ]]; then
docker stop $(docker ps -af "name=${NAME}" -q)
docker rm $(docker ps -af "name=${NAME}" -q)
fi
sed -i "/^connect/c\connect = \"host=mysql dbname=${DBNAME} user=${DBUSER} password=${DBPASS}\"" data/conf/dovecot/sql/*
docker run \
-p ${IMAP_PORT}:143 \
-p ${IMAPS_PORT}:993 \
-p ${POP_PORT}:110 \
-p ${POPS_PORT}:995 \
-p ${SIEVE_PORT}:4190\
-v ${PWD}/data/conf/dovecot:/etc/dovecot:ro \
-v ${PWD}/data/vmail:/var/vmail \
-v ${PWD}/data/assets/ssl:/etc/ssl/mail/:ro \
--name ${NAME} \
--network=${DOCKER_NETWORK} \
--network-alias dovecot \
-h ${MAILCOW_HOSTNAME} \
-d andryyy/mailcow-dockerized:dovecot
/bin/bash ./fix-permissions.sh

View File

@ -1,35 +0,0 @@
#!/bin/bash
. mailcow.conf
NAME="postfix-mailcow"
PDNS_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' pdns-mailcow 2> /dev/null)
if [[ ! ${PDNS_IP} =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Cannot determine Powerdns Recursor ip address. Is the container running?"
exit 1
fi
echo "Stopping and removing containers with name tag ${NAME}..."
if [[ ! -z $(docker ps -af "name=${NAME}" -q) ]]; then
docker stop $(docker ps -af "name=${NAME}" -q)
docker rm $(docker ps -af "name=${NAME}" -q)
fi
sed -i "/^user/c\user = ${DBUSER}" data/conf/postfix/sql/*
sed -i "/^password/c\password = ${DBPASS}" data/conf/postfix/sql/*
sed -i "/^dbname/c\dbname = ${DBNAME}" data/conf/postfix/sql/*
docker run \
-p ${SMTP_PORT}:25 \
-p ${SMTPS_PORT}:465 \
-p ${SUBMISSION_PORT}:587 \
-v ${PWD}/data/conf/postfix:/opt/postfix/conf:ro \
-v ${PWD}/data/assets/ssl:/etc/ssl/mail/:ro \
--dns=${PDNS_IP} \
--dns-search=${DOCKER_NETWORK} \
--name ${NAME} \
--network=${DOCKER_NETWORK} \
--network-alias postfix \
-h ${MAILCOW_HOSTNAME} \
-d andryyy/mailcow-dockerized:postfix

View File

@ -1,26 +0,0 @@
#!/bin/bash
. mailcow.conf
NAME="memcached-mailcow"
echo "Stopping and removing containers with name tag ${NAME}..."
if [[ ! -z $(docker ps -af "name=${NAME}" -q) ]]; then
docker stop $(docker ps -af "name=${NAME}" -q)
docker rm $(docker ps -af "name=${NAME}" -q)
fi
if [[ ! -z "$(docker images -q rmilter)" ]]; then
read -r -p "Found image locally. Delete local image and repull? [y/N] " response
response=${response,,}
if [[ $response =~ ^(yes|y)$ ]]; then
docker rmi memcached
fi
fi
docker run \
--network=${DOCKER_NETWORK} \
-h memcached \
--network-alias=memcached \
--name=${NAME} \
-d memcached

View File

@ -1,30 +0,0 @@
#!/bin/bash
. mailcow.conf
NAME="nginx-mailcow"
echo "Stopping and removing containers with name tag ${NAME}..."
if [[ ! -z $(docker ps -af "name=${NAME}" -q) ]]; then
docker stop $(docker ps -af "name=${NAME}" -q)
docker rm $(docker ps -af "name=${NAME}" -q)
fi
sed -i "s#database_name.*#database_name = \"${DBNAME}\";#" data/web/inc/vars.inc.php
sed -i "s#database_user.*#database_user = \"${DBUSER}\";#" data/web/inc/vars.inc.php
sed -i "s#database_pass.*#database_pass = \"${DBPASS}\";#" data/web/inc/vars.inc.php
docker run \
-p 443:443 \
--expose 8081 \
--name ${NAME} \
-v ${PWD}/data/web:/web:ro \
-v ${PWD}/data/conf/rspamd/dynmaps:/dynmaps:ro \
-v ${PWD}/data/assets/ssl/:/etc/ssl/mail/:ro \
-v ${PWD}/data/conf/nginx/:/etc/nginx/conf.d/:ro \
--network=${DOCKER_NETWORK} \
-h nginx \
--network-alias=nginx \
-d andryyy/mailcow-dockerized:nginx
/bin/bash ./fix-permissions.sh

View File

@ -21,10 +21,10 @@ All configurations were written with security in mind.
| redis-mailcow | Redis | redis | - | 6379/tcp | | redis-mailcow | Redis | redis | - | 6379/tcp |
| memcached-mailcow | Memcached | memcached | - | 11211/tcp | | memcached-mailcow | Memcached | memcached | - | 11211/tcp |
All containers share a network ${MAILCOW_NETWORK} (name can be changed, but remove all containers and rebuild them after changing). All containers share a network "mailcow-network" with the subnet 172.22.1.0/24 - if you want to change it, set it in the composer file.
IPs are dynamic and taken from subnet ${DOCKER_SUBNET}. IPs are dynamic except for PowerDNS resolver which has a static ip address 172.22.1.2.
FAQ: ### **FAQ**
- rspamd learns mail as spam or ham when you move a message in or out of the junk folder to any mailbox besides trash. - rspamd learns mail as spam or ham when you move a message in or out of the junk folder to any mailbox besides trash.
- rspamd auto-learns mail when a high or low score is detected (see https://rspamd.com/doc/configuration/statistic.html#autolearning) - rspamd auto-learns mail when a high or low score is detected (see https://rspamd.com/doc/configuration/statistic.html#autolearning)
@ -34,16 +34,15 @@ FAQ:
## Installation ## Installation
1. You need Docker. Most systems can install Docker by running `wget -qO- https://get.docker.com/ | sh` 1. You need Docker and Docker Compose. Most systems can install Docker by running `wget -qO- https://get.docker.com/ | sh` - see [this link](https://docs.docker.com/compose/install/) for installing Docker Compose.
2. Clone this repository and configure `mailcow.conf`, do not use special chars in passwords in this file (will be fixed soon). 2. Clone this repository and configure `mailcow.conf`, do not use special chars in passwords in this file (will be fixed soon).
It is almost always enough to just change the hostname.
3. Run `./build-all.sh` - select `Y` when asked to reset the admin password. 3. `docker-compose up -d` - leave the `-d` out for a wall of logs in case of debugging.
Done. Done.
You can now access https://${MAILCOW_HOSTNAME} with the default credentials `admin` + password `moohoo`. You can now access https://${MAILCOW_HOSTNAME} with the default credentials `admin` + password `moohoo`. The database will be initialized when you first visit the UI.
## Configuration after installation ## Configuration after installation
@ -102,7 +101,8 @@ docker restart nginx-mailcow
When renewing certificates, run the last two steps (link + restart) as post-hook in certbot. When renewing certificates, run the last two steps (link + restart) as post-hook in certbot.
## Special usage ## More useful commands and examples (todo: move to wiki soon)
### build-*.files ### build-*.files
(Re)build a container: (Re)build a container:
@ -123,49 +123,50 @@ You can use docker logs $name for almost all containers. Only rmilter does not l
Connect to MariaDB database: Connect to MariaDB database:
``` ```
./n-build-sql.sh --client source mailcow.conf
docker exec -it mariadb-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME}
``` ```
Init schema (will also be installed when running `./n-build-sql.sh` without parameters): Init schema (will be auto-installed by mailcow UI, but just in case...):
``` ```
./n-build-sql.sh --init-schema source mailcow.conf
docker exec -it mariadb-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} < data/web/inc/init.sql
``` ```
Reset mailcow admin to `admin:moohoo`: Reset mailcow admin to `admin:moohoo`:
``` ```
./n-build-sql.sh --reset-admin source mailcow.conf
docker exec -it mariadb-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DROP TABLE admin; DROP TABLE domain_admins"
# Open mailcow UI to auto-init the db
``` ```
Dump database to file backup_${DBNAME}_${DATE}.sql: Backup and restore database:
``` ```
./n-build-sql.sh --dump source mailcow.conf
``` # Create
DATE=$(date +"%Y%m%d_%H%M%S")
Restore database from a file: docker exec -it mariadb-mailcow /bin/bash mysqldump --default-character-set=utf8mb4 -u${DBUSER} -p${DBPASS} ${DBNAME} > backup_${DBNAME}_${DATE}.sql
``` # Restore
./n-build-sql.sh --restore filename docker exec -i mariadb-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} < ${1}
``` ```
### Redis ### Redis
Connect to redis database: Connect to redis key store:
``` ```
./n-build-redis.sh --client docker exec -it redis-mailcow /bin/bash -c "redis-cli"
``` ```
### Some examples ### Use rspamadm:
Use rspamadm:
``` ```
docker exec -it rspamd-mailcow rspamadm --help docker exec -it rspamd-mailcow rspamadm --help
``` ```
Use rspamc: ### Use rspamc:
``` ```
docker exec -it rspamd-mailcow rspamc --help docker exec -it rspamd-mailcow rspamc --help
``` ```
### Use doveadm:
Use doveadm:
``` ```
docker exec -it dovecot-mailcow doveadm docker exec -it dovecot-mailcow doveadm
``` ```

View File

@ -1,10 +0,0 @@
#!/bin/bash
/bin/bash port-check.sh
[[ $? != 0 ]] && exit 1
for build in $(ls *build*.sh | grep -v all); do
echo "Starting build file ${buildx} ..."
/bin/bash ${build}
done
/bin/bash fix-permissions.sh

View File

@ -1,7 +0,0 @@
#!/bin/bash
defaults write sogod SOGoUserSources '({type = sql;id = directory;viewURL = mysql://${DBUSER}:${DBPASS}@${DBHOST}:3306/${DBNAME}/sogo_view;canAuthenticate = YES;isAddressBook = YES;displayName = \"GAL\";MailFieldNames = (aliases, ad_aliases, senderacl);userPasswordAlgorithm = ssha256;})'
defaults write sogod SOGoProfileURL 'mysql://${DBUSER}:${DBPASS}@${DBHOST}:3306/${DBNAME}/sogo_user_profile'
defaults write sogod OCSFolderInfoURL 'mysql://${DBUSER}:${DBPASS}@${DBHOST}:3306/${DBNAME}/sogo_folder_info'
defaults write sogod OCSEMailAlarmsFolderURL 'mysql://${DBUSER}:${DBPASS}@${DBHOST}:3306/${DBNAME}/sogo_alarms_folder'
defaults write sogod OCSSessionsFolderURL 'mysql://${DBUSER}:${DBPASS}@${DBHOST}:3306/${DBNAME}/sogo_sessions_folder'

View File

@ -0,0 +1,2 @@
chown -R 5000:5000 ../vmail
chown -R 33:33 ../dkim

View File

@ -1,2 +0,0 @@
REPLACE INTO admin VALUES ('admin','{SSHA256}K8eVJ6YsZbQCfuJvSUbaQRLr0HPLz5rC9IAp0PAFl0tmNDBkMDc0NDAyOTAxN2Rk', 1, NOW(), NOW(), 1);
REPLACE INTO domain_admins (username, domain, created, active) VALUES ('admin', 'ALL', NOW(), '1');

View File

@ -30,6 +30,11 @@ server {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
} }
location ^~ /inc/init.sql {
deny all;
}
location ^~ /Microsoft-Server-ActiveSync { location ^~ /Microsoft-Server-ActiveSync {
proxy_pass http://sogo/SOGo/Microsoft-Server-ActiveSync; proxy_pass http://sogo/SOGo/Microsoft-Server-ActiveSync;
proxy_connect_timeout 1000; proxy_connect_timeout 1000;

View File

@ -32,6 +32,31 @@ function hasDomainAccess($username, $role, $domain) {
} }
return false; return false;
} }
function init_db_schema() {
global $pdo;
try {
$stmt = $pdo->prepare("SELECT `username` FROM `admin`");
$stmt->execute();
}
catch (Exception $e) {
$lines = file('/web/inc/init.sql');
$data = '';
foreach ($lines as $line) {
if (substr($line, 0, 2) == '--' || $line == '') {
continue;
}
$data .= $line;
if (substr(trim($line), -1, 1) == ';') {
$pdo->query($data);
$data = '';
}
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => 'Database initialization completed.'
);
}
}
function verify_ssha256($hash, $password) { function verify_ssha256($hash, $password) {
// Remove tag if any // Remove tag if any
$hash = ltrim($hash, '{SSHA256}'); $hash = ltrim($hash, '{SSHA256}');

View File

@ -245,3 +245,12 @@ CREATE TABLE IF NOT EXISTS sogo_user_profile (
c_settings text, c_settings text,
PRIMARY KEY (c_uid) PRIMARY KEY (c_uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
INSERT INTO admin (username, password, superadmin, created, modified, active)
SELECT 'admin', '{SSHA256}K8eVJ6YsZbQCfuJvSUbaQRLr0HPLz5rC9IAp0PAFl0tmNDBkMDc0NDAyOTAxN2Rk', 1, NOW(), NOW(), 1
WHERE NOT EXISTS (SELECT username FROM admin WHERE superadmin='1');
INSERT INTO domain_admins (username, domain, created, active)
SELECT 'admin', 'ALL', NOW(), 1
WHERE NOT EXISTS (SELECT username FROM domain_admins WHERE domain='ALL');

View File

@ -22,7 +22,6 @@ $opt = [
PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_EMULATE_PREPARES => false,
]; ];
$pdo = new PDO($dsn, $database_user, $database_pass, $opt); $pdo = new PDO($dsn, $database_user, $database_pass, $opt);
$_SESSION['mailcow_locale'] = strtolower(trim($DEFAULT_LANG)); $_SESSION['mailcow_locale'] = strtolower(trim($DEFAULT_LANG));
setcookie('language', $DEFAULT_LANG); setcookie('language', $DEFAULT_LANG);
if (isset($_COOKIE['language'])) { if (isset($_COOKIE['language'])) {
@ -69,3 +68,4 @@ require_once 'lang/lang.en.php';
include 'lang/lang.'.$_SESSION['mailcow_locale'].'.php'; include 'lang/lang.'.$_SESSION['mailcow_locale'].'.php';
require_once 'inc/functions.inc.php'; require_once 'inc/functions.inc.php';
require_once 'inc/triggers.inc.php'; require_once 'inc/triggers.inc.php';
init_db_schema();

View File

@ -1,5 +1,5 @@
<?php <?php
error_reporting(0); error_reporting(E_ALL);
/* /*
PLEASE USE THE FILE "vars.local.inc.php" TO OVERWRITE SETTINGS AND MAKE THEM PERSISTENT! PLEASE USE THE FILE "vars.local.inc.php" TO OVERWRITE SETTINGS AND MAKE THEM PERSISTENT!

187
docker-compose.yml 100644
View File

@ -0,0 +1,187 @@
version: '2'
services:
pdns-mailcow:
image: andryyy/mailcow-dockerized:pdns
volumes:
- ./data/conf/pdns/:/etc/powerdns/
restart: always
networks:
mailcow-network:
ipv4_address: 172.22.1.2
aliases:
- pdns
mariadb-mailcow:
image: mariadb:latest
depends_on:
- pdns-mailcow
volumes:
- ./data/db/mysql/:/var/lib/mysql/
- ./data/conf/mysql/:/etc/mysql/conf.d/:ro
environment:
- MYSQL_ROOT_PASSWORD=${DBROOT}
- MYSQL_DATABASE=${DBNAME}
- MYSQL_USER=${DBUSER}
- MYSQL_PASSWORD=${DBPASS}
restart: always
networks:
mailcow-network:
aliases:
- mysql
redis-mailcow:
image: redis
depends_on:
- pdns-mailcow
volumes:
- ./data/db/redis/:/data/
restart: always
networks:
mailcow-network:
aliases:
- redis
rspamd-mailcow:
image: andryyy/mailcow-dockerized:rspamd
depends_on:
- pdns-mailcow
volumes:
- ./data/conf/rspamd/override.d/:/etc/rspamd/override.d:ro
- ./data/conf/rspamd/local.d/:/etc/rspamd/local.d:ro
- ./data/conf/rspamd/lua/:/etc/rspamd/lua/:ro
- ./data/dkim/txt/:/etc/rspamd/dkim/txt/:ro
- ./data/dkim/keys/:/etc/rspamd/dkim/keys/:ro
restart: always
dns:
- 172.22.1.2
- 127.0.0.11
dns_search: mailcow-network
networks:
mailcow-network:
aliases:
- rspamd
php-fpm-mailcow:
image: andryyy/mailcow-dockerized:phpfpm
depends_on:
- pdns-mailcow
volumes:
- ./data/web:/web:ro
- ./data/conf/rspamd/dynmaps:/dynmaps:ro
- ./data/dkim/:/shared/dkim/
restart: always
networks:
mailcow-network:
aliases:
- phpfpm
sogo-mailcow:
image: andryyy/mailcow-dockerized:sogo
depends_on:
- pdns-mailcow
environment:
- DBNAME=${DBNAME}
- DBUSER=${DBUSER}
- DBPASS=${DBPASS}
volumes:
- ./data/conf/sogo/:/etc/sogo/
restart: always
networks:
mailcow-network:
aliases:
- sogo
rmilter-mailcow:
image: andryyy/mailcow-dockerized:rmilter
depends_on:
- pdns-mailcow
volumes:
- ./data/conf/rmilter/:/etc/rmilter.conf.d/:ro
restart: always
networks:
mailcow-network:
aliases:
- rmilter
dovecot-mailcow:
image: andryyy/mailcow-dockerized:dovecot
depends_on:
- pdns-mailcow
volumes:
- ./data/conf/dovecot:/etc/dovecot:ro
- ./data/vmail:/var/vmail
- ./data/assets/ssl:/etc/ssl/mail/:ro
ports:
- "${IMAP_PORT}:143"
- "${IMAPS_PORT}:993"
- "${POP_PORT}:110"
- "${POPS_PORT}:995"
- "${SIEVE_PORT}:4190"
restart: always
hostname: ${MAILCOW_HOSTNAME}
networks:
mailcow-network:
aliases:
- dovecot
postfix-mailcow:
image: andryyy/mailcow-dockerized:postfix
depends_on:
- pdns-mailcow
volumes:
- ./data/conf/postfix:/opt/postfix/conf:ro
- ./data/assets/ssl:/etc/ssl/mail/:ro
ports:
- "${SMTP_PORT}:25"
- "${SMTPS_PORT}:465"
- "${SUBMISSION_PORT}:587"
restart: always
hostname: ${MAILCOW_HOSTNAME}
dns:
- 172.22.1.2
- 127.0.0.11
dns_search: mailcow-network
networks:
mailcow-network:
aliases:
- postfix
memcached-mailcow:
image: memcached
depends_on:
- pdns-mailcow
restart: always
networks:
mailcow-network:
aliases:
- memcached
nginx-mailcow:
depends_on:
- mariadb-mailcow
- sogo-mailcow
- php-fpm-mailcow
image: nginx
volumes:
- ./data/web:/web:ro
- ./data/conf/rspamd/dynmaps:/dynmaps:ro
- ./data/assets/ssl/:/etc/ssl/mail/:ro
- ./data/conf/nginx/:/etc/nginx/conf.d/:ro
ports:
- "443:443"
restart: always
networks:
mailcow-network:
aliases:
- nginx
networks:
mailcow-network:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.22.1.0/24
gateway: 172.22.1.1

View File

@ -1,2 +0,0 @@
chown -R 5000:5000 data/vmail
chown -R 33:33 data/dkim

View File

@ -22,9 +22,3 @@ POP_PORT=110
POPS_PORT=995 POPS_PORT=995
SIEVE_PORT=4190 SIEVE_PORT=4190
# Networking
# You need to rebuild all containers after changing values.
# Remove old networks manually.
DOCKER_NETWORK="mailcow-network"
DOCKER_SUBNET="172.18.0.0/16"

View File

@ -1,20 +0,0 @@
#!/bin/bash
. mailcow.conf
if [[ -z $(which ss) ]]; then echo "Please install the ss util first."; exit 1; fi
for port in ${SMTP_PORT} ${SMTPS_PORT} ${SUBMISSION_PORT} ${IMAP_PORT} ${IMAPS_PORT} ${POP_PORT} ${POPS_PORT} ${SIEVE_PORT} 443; do
if [[ ! -z $(ss -tlnp "( sport = :$port )" 2> /dev/null | grep LISTEN | grep -vi docker) ]]; then
echo "Port $port is in use by another process."
err=1
fi
done
if [[ ${err} == "1" ]]; then
echo
echo "Exiting."
exit 1
fi
exit 0