Remove old file
parent
2aca3e0d30
commit
9e8a003508
|
@ -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
|
|
@ -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
|
|
@ -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
|
104
003-build-sql.sh
104
003-build-sql.sh
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
55
README.md
55
README.md
|
@ -21,10 +21,10 @@ All configurations were written with security in mind.
|
|||
| redis-mailcow | Redis | redis | - | 6379/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).
|
||||
IPs are dynamic and taken from subnet ${DOCKER_SUBNET}.
|
||||
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 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 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
|
||||
|
||||
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).
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
|
@ -102,7 +101,8 @@ docker restart nginx-mailcow
|
|||
|
||||
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
|
||||
|
||||
(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:
|
||||
```
|
||||
./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`:
|
||||
```
|
||||
./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
|
||||
```
|
||||
|
||||
Restore database from a file:
|
||||
```
|
||||
./n-build-sql.sh --restore filename
|
||||
source mailcow.conf
|
||||
# Create
|
||||
DATE=$(date +"%Y%m%d_%H%M%S")
|
||||
docker exec -it mariadb-mailcow /bin/bash mysqldump --default-character-set=utf8mb4 -u${DBUSER} -p${DBPASS} ${DBNAME} > backup_${DBNAME}_${DATE}.sql
|
||||
# Restore
|
||||
docker exec -i mariadb-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} < ${1}
|
||||
```
|
||||
|
||||
### 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
|
||||
```
|
||||
|
||||
Use rspamc:
|
||||
### Use rspamc:
|
||||
```
|
||||
docker exec -it rspamd-mailcow rspamc --help
|
||||
```
|
||||
|
||||
Use doveadm:
|
||||
### Use doveadm:
|
||||
```
|
||||
docker exec -it dovecot-mailcow doveadm
|
||||
```
|
||||
|
|
10
build-all.sh
10
build-all.sh
|
@ -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
|
|
@ -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'
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
chown -R 5000:5000 ../vmail
|
||||
chown -R 33:33 ../dkim
|
|
@ -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');
|
|
@ -30,6 +30,11 @@ server {
|
|||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
location ^~ /inc/init.sql {
|
||||
deny all;
|
||||
}
|
||||
|
||||
|
||||
location ^~ /Microsoft-Server-ActiveSync {
|
||||
proxy_pass http://sogo/SOGo/Microsoft-Server-ActiveSync;
|
||||
proxy_connect_timeout 1000;
|
||||
|
|
|
@ -32,6 +32,31 @@ function hasDomainAccess($username, $role, $domain) {
|
|||
}
|
||||
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) {
|
||||
// Remove tag if any
|
||||
$hash = ltrim($hash, '{SSHA256}');
|
||||
|
|
|
@ -245,3 +245,12 @@ CREATE TABLE IF NOT EXISTS sogo_user_profile (
|
|||
c_settings text,
|
||||
PRIMARY KEY (c_uid)
|
||||
) 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');
|
||||
|
|
@ -22,7 +22,6 @@ $opt = [
|
|||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
];
|
||||
$pdo = new PDO($dsn, $database_user, $database_pass, $opt);
|
||||
|
||||
$_SESSION['mailcow_locale'] = strtolower(trim($DEFAULT_LANG));
|
||||
setcookie('language', $DEFAULT_LANG);
|
||||
if (isset($_COOKIE['language'])) {
|
||||
|
@ -69,3 +68,4 @@ require_once 'lang/lang.en.php';
|
|||
include 'lang/lang.'.$_SESSION['mailcow_locale'].'.php';
|
||||
require_once 'inc/functions.inc.php';
|
||||
require_once 'inc/triggers.inc.php';
|
||||
init_db_schema();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
error_reporting(0);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
/*
|
||||
PLEASE USE THE FILE "vars.local.inc.php" TO OVERWRITE SETTINGS AND MAKE THEM PERSISTENT!
|
||||
|
|
|
@ -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
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
chown -R 5000:5000 data/vmail
|
||||
chown -R 33:33 data/dkim
|
|
@ -22,9 +22,3 @@ POP_PORT=110
|
|||
POPS_PORT=995
|
||||
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"
|
||||
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue