mirror of
https://github.com/lleene/dockerconfig.git
synced 2025-01-23 05:12:20 +01:00
Merge from roundcube setup.
This commit is contained in:
commit
5f65170a3e
12
.env.example
Normal file
12
.env.example
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# SET HOST NAME
|
||||||
|
NGINX_HOST=""
|
||||||
|
|
||||||
|
# GOOGLE DNS API TOKEN
|
||||||
|
GDNS_USERNAME=""
|
||||||
|
GDNS_PASSWORD=""
|
||||||
|
|
||||||
|
# COMMON DB PASSWORD
|
||||||
|
SQL_PSWD=""
|
||||||
|
|
||||||
|
# SENDGRID Relay API Key
|
||||||
|
SENDGRID_APIKEY=""
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -23,3 +23,5 @@ bundles/
|
|||||||
vendor/pkg/
|
vendor/pkg/
|
||||||
pyenv
|
pyenv
|
||||||
Vagrantfile
|
Vagrantfile
|
||||||
|
gitea
|
||||||
|
pgsql
|
||||||
|
6
TODO.md
Normal file
6
TODO.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
# Startup after docker compose
|
||||||
|
|
||||||
|
- Create admin email account
|
||||||
|
- Update dkim and DNS records
|
||||||
|
|
94
config/gitea.ini
Normal file
94
config/gitea.ini
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
APP_NAME = Gitea: Git with a cup of tea
|
||||||
|
RUN_MODE = prod
|
||||||
|
RUN_USER = git
|
||||||
|
|
||||||
|
[repository]
|
||||||
|
ROOT = /data/git/repositories
|
||||||
|
|
||||||
|
[repository.local]
|
||||||
|
LOCAL_COPY_PATH = /data/gitea/tmp/local-repo
|
||||||
|
|
||||||
|
[repository.upload]
|
||||||
|
TEMP_PATH = /data/gitea/uploads
|
||||||
|
|
||||||
|
[server]
|
||||||
|
APP_DATA_PATH = /data/gitea
|
||||||
|
DOMAIN = localhost
|
||||||
|
SSH_DOMAIN = localhost
|
||||||
|
HTTP_PORT = 3000
|
||||||
|
ROOT_URL = http://localhost:3000/
|
||||||
|
DISABLE_SSH = false
|
||||||
|
SSH_PORT = 22
|
||||||
|
SSH_LISTEN_PORT = 22
|
||||||
|
LFS_START_SERVER = true
|
||||||
|
LFS_JWT_SECRET = 13R03sc6ZlnDkBFwKup2PoeT3eOggjn2oEmkOSjkQsE
|
||||||
|
OFFLINE_MODE = false
|
||||||
|
|
||||||
|
[database]
|
||||||
|
PATH = /data/gitea/gitea.db
|
||||||
|
DB_TYPE = postgres
|
||||||
|
HOST = database:5432
|
||||||
|
NAME = gitea
|
||||||
|
USER = gitea
|
||||||
|
PASSWD = "hear397sew"
|
||||||
|
LOG_SQL = false
|
||||||
|
SCHEMA =
|
||||||
|
SSL_MODE = disable
|
||||||
|
CHARSET = utf8
|
||||||
|
|
||||||
|
[indexer]
|
||||||
|
ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve
|
||||||
|
|
||||||
|
[session]
|
||||||
|
PROVIDER_CONFIG = /data/gitea/sessions
|
||||||
|
PROVIDER = file
|
||||||
|
|
||||||
|
[picture]
|
||||||
|
AVATAR_UPLOAD_PATH = /data/gitea/avatars
|
||||||
|
REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars
|
||||||
|
ENABLE_FEDERATED_AVATAR = false
|
||||||
|
|
||||||
|
[attachment]
|
||||||
|
PATH = /data/gitea/attachments
|
||||||
|
|
||||||
|
[log]
|
||||||
|
MODE = console
|
||||||
|
LEVEL = info
|
||||||
|
ROUTER = console
|
||||||
|
ROOT_PATH = /data/gitea/log
|
||||||
|
|
||||||
|
[security]
|
||||||
|
INSTALL_LOCK = true
|
||||||
|
SECRET_KEY =
|
||||||
|
REVERSE_PROXY_LIMIT = 1
|
||||||
|
REVERSE_PROXY_TRUSTED_PROXIES = *
|
||||||
|
INTERNAL_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE2NjcxMjI4NDN9.2POH2B9XRVJQx5Ixymbz1iNT7D8OOPiaJNnk1ELTM8s
|
||||||
|
PASSWORD_HASH_ALGO = pbkdf2
|
||||||
|
|
||||||
|
[service]
|
||||||
|
DISABLE_REGISTRATION = false
|
||||||
|
REQUIRE_SIGNIN_VIEW = false
|
||||||
|
REGISTER_EMAIL_CONFIRM = false
|
||||||
|
ENABLE_NOTIFY_MAIL = false
|
||||||
|
ALLOW_ONLY_EXTERNAL_REGISTRATION = false
|
||||||
|
ENABLE_CAPTCHA = false
|
||||||
|
DEFAULT_KEEP_EMAIL_PRIVATE = false
|
||||||
|
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
|
||||||
|
DEFAULT_ENABLE_TIMETRACKING = true
|
||||||
|
NO_REPLY_ADDRESS = noreply.localhost
|
||||||
|
|
||||||
|
[lfs]
|
||||||
|
PATH = /data/git/lfs
|
||||||
|
|
||||||
|
[mailer]
|
||||||
|
ENABLED = false
|
||||||
|
|
||||||
|
[openid]
|
||||||
|
ENABLE_OPENID_SIGNIN = true
|
||||||
|
ENABLE_OPENID_SIGNUP = true
|
||||||
|
|
||||||
|
[repository.pull-request]
|
||||||
|
DEFAULT_MERGE_STYLE = merge
|
||||||
|
|
||||||
|
[repository.signing]
|
||||||
|
DEFAULT_TRUST_MODEL = committer
|
30
config/hugo/Dockerfile
Normal file
30
config/hugo/Dockerfile
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
FROM alpine
|
||||||
|
|
||||||
|
LABEL description="Hugo static build process."
|
||||||
|
LABEL maintainer="Lieuwe Leene <lieuwe@leene.dev>"
|
||||||
|
|
||||||
|
ARG HUGO_BASE="localhost"
|
||||||
|
ARG SSL_ALGO=secp521r1
|
||||||
|
|
||||||
|
RUN wget -O - "https://github.com/gohugoio/hugo/releases/download/$(wget -O - https://api.github.com/repos/gohugoio/hugo/releases/latest | grep -om 1 "/v[0-9.]*/hugo_[0-9.]*_Linux-64bit.tar.gz")" | tar -xz -C /tmp \
|
||||||
|
&& mkdir -p /usr/local/sbin \
|
||||||
|
&& mv /tmp/hugo /usr/local/sbin/hugo \
|
||||||
|
&& rm -rf /tmp/${HUGO_ID}_linux_amd64 \
|
||||||
|
&& rm -rf /tmp/LICENSE.md \
|
||||||
|
&& rm -rf /tmp/README.md
|
||||||
|
|
||||||
|
RUN apk add --update git asciidoctor libc6-compat libstdc++ \
|
||||||
|
&& apk upgrade \
|
||||||
|
&& apk add --no-cache ca-certificates \
|
||||||
|
&& git clone https://github.com/lleene/hugo-site.git /src \
|
||||||
|
&& git clone https://github.com/lleene/hermit.git /src/themes/hermit \
|
||||||
|
&& /usr/local/sbin/hugo -b ${BASE_URL}/ -s /src -d /public --minify
|
||||||
|
|
||||||
|
RUN apk update && \
|
||||||
|
apk add --no-cache openssl && \
|
||||||
|
rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
|
RUN mkdir -p /etc/letsencrypt/live
|
||||||
|
|
||||||
|
RUN openssl ecparam -name ${SSL_ALGO} -genkey | openssl pkey -out /etc/letsencrypt/live/ecprivkey.pem && \
|
||||||
|
openssl pkey -in /etc/letsencrypt/live/ecprivkey.pem -pubout -out /etc/letsencrypt/live/ecpubkey.pem
|
13
config/hugo/configure
vendored
Normal file
13
config/hugo/configure
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
server {
|
||||||
|
listen ${VIRTUAL_PORT};
|
||||||
|
listen [::]:${VIRTUAL_PORT};
|
||||||
|
server_name ${VIRTUAL_HOST};
|
||||||
|
location / {
|
||||||
|
root /var/www/html;
|
||||||
|
index index.html index.htm;
|
||||||
|
}
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
}
|
||||||
|
}
|
7
config/mail/10-custom.conf
Normal file
7
config/mail/10-custom.conf
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Enables mail_crypt for all services (imap, pop3, etc)
|
||||||
|
mail_plugins = $mail_plugins mail_crypt
|
||||||
|
plugin {
|
||||||
|
mail_crypt_global_private_key = </etc/letsencrypt/live/ecprivkey.pem
|
||||||
|
mail_crypt_global_public_key = </etc/letsencrypt/live/ecpubkey.pem
|
||||||
|
mail_crypt_save_version = 2
|
||||||
|
}
|
19
config/mail/config.php
Normal file
19
config/mail/config.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
$config['imap_host'] = 'tls://mailserver:143';
|
||||||
|
$config['smtp_host'] = 'tls://mailserver:587';
|
||||||
|
|
||||||
|
$config['imap_conn_options'] = array(
|
||||||
|
'ssl' => array(
|
||||||
|
'verify_peer' => false,
|
||||||
|
'verify_peer_name' => false,
|
||||||
|
'allow_self_signed' => true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$config['smtp_conn_options'] = array(
|
||||||
|
'ssl' => array(
|
||||||
|
'verify_peer' => false,
|
||||||
|
'verify_peer_name' => false,
|
||||||
|
'allow_self_signed' => true,
|
||||||
|
),
|
||||||
|
);
|
17
config/nginx/header_default
Normal file
17
config/nginx/header_default
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
## Start of configuration add by letsencrypt container
|
||||||
|
location ^~ /.well-known/acme-challenge/ {
|
||||||
|
auth_basic off;
|
||||||
|
auth_request off;
|
||||||
|
allow all;
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
try_files $uri =404;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
## End of configuration add by letsencrypt container
|
||||||
|
add_header Referrer-Policy "no-referrer" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-Download-Options "noopen" always;
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Permitted-Cross-Domain-Policies "none" always;
|
||||||
|
add_header X-Robots-Tag "none" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
26
config/nginx/inbox_location
Normal file
26
config/nginx/inbox_location
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
root /var/www/roundcube;
|
||||||
|
index index.php index.html index.htm;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.php?q=$uri&$args;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ \.php$ {
|
||||||
|
try_files $uri =404;
|
||||||
|
fastcgi_keep_conn on;
|
||||||
|
fastcgi_split_path_info ^(.+\.php)(.*)$;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
fastcgi_pass inbox.zathura.leene.dev;
|
||||||
|
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
include fastcgi_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ ^/(README|INSTALL|LICENSE|CHANGELOG|UPGRADING)$ {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ ^/(bin|SQL)/ {
|
||||||
|
deny all;
|
||||||
|
}
|
94
config/nginx/nextcloud_location
Normal file
94
config/nginx/nextcloud_location
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
root /var/www/nextcloud;
|
||||||
|
index index.php index.html index.htm;
|
||||||
|
|
||||||
|
# set max upload size
|
||||||
|
client_max_body_size 512M;
|
||||||
|
fastcgi_buffers 64 4K;
|
||||||
|
|
||||||
|
# Enable gzip but do not remove ETag headers
|
||||||
|
gzip on;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_comp_level 4;
|
||||||
|
gzip_min_length 256;
|
||||||
|
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
|
||||||
|
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
|
||||||
|
|
||||||
|
location = /robots.txt {
|
||||||
|
allow all;
|
||||||
|
log_not_found off;
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /.well-known/carddav {
|
||||||
|
return 301 $scheme://$host:$server_port/remote.php/dav;
|
||||||
|
}
|
||||||
|
location = /.well-known/caldav {
|
||||||
|
return 301 $scheme://$host:$server_port/remote.php/dav;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
rewrite ^ /index.php;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy)\.php(?:$|\/) {
|
||||||
|
fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
|
||||||
|
set $path_info $fastcgi_path_info;
|
||||||
|
try_files $fastcgi_script_name =404;
|
||||||
|
include fastcgi_params;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
fastcgi_param PATH_INFO $path_info;
|
||||||
|
fastcgi_param HTTPS on;
|
||||||
|
# Avoid sending the security headers twice
|
||||||
|
fastcgi_param modHeadersAvailable true;
|
||||||
|
# Enable pretty urls
|
||||||
|
fastcgi_param front_controller_active true;
|
||||||
|
fastcgi_pass nextcloud.zathura.leene.dev;
|
||||||
|
fastcgi_intercept_errors on;
|
||||||
|
fastcgi_request_buffering off;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
|
||||||
|
try_files $uri/ =404;
|
||||||
|
index index.php;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Adding the cache control header for js, css and map files
|
||||||
|
# Make sure it is BELOW the PHP block
|
||||||
|
location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
|
||||||
|
try_files $uri /index.php$request_uri;
|
||||||
|
add_header Cache-Control "public, max-age=15778463";
|
||||||
|
# Add headers to serve security related headers (It is intended to
|
||||||
|
# have those duplicated to the ones above)
|
||||||
|
# Before enabling Strict-Transport-Security headers please read into
|
||||||
|
# this topic first.
|
||||||
|
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
|
||||||
|
#
|
||||||
|
# WARNING: Only add the preload option once you read about
|
||||||
|
# the consequences in https://hstspreload.org/. This option
|
||||||
|
# will add the domain to a hardcoded list that is shipped
|
||||||
|
# in all major browsers and getting removed from this list
|
||||||
|
# could take several months.
|
||||||
|
add_header Referrer-Policy "no-referrer" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-Download-Options "noopen" always;
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Permitted-Cross-Domain-Policies "none" always;
|
||||||
|
add_header X-Robots-Tag "none" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
|
||||||
|
# Optional: Don't log access to assets
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$ {
|
||||||
|
try_files $uri /index.php$request_uri;
|
||||||
|
# Optional: Don't log access to other assets
|
||||||
|
access_log off;
|
||||||
|
}
|
23
config/pg-init-scripts/init_db.sh
Normal file
23
config/pg-init-scripts/init_db.sh
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -u
|
||||||
|
|
||||||
|
function create_user_and_database() {
|
||||||
|
local database=$1
|
||||||
|
echo "Creating user and database '$database'"
|
||||||
|
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
|
||||||
|
CREATE USER $database;
|
||||||
|
CREATE DATABASE $database WITH OWNER $database TEMPLATE template0 ENCODING UTF8 LC_COLLATE 'en_US.UTF-8' LC_CTYPE 'en_US.UTF-8';
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE $database TO $database;
|
||||||
|
ALTER ROLE $database WITH LOGIN PASSWORD '$POSTGRES_PASSWORD';
|
||||||
|
EOSQL
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then
|
||||||
|
echo "Creating databases: $POSTGRES_MULTIPLE_DATABASES"
|
||||||
|
for db in $(echo "$POSTGRES_MULTIPLE_DATABASES" | tr ',' ' '); do
|
||||||
|
create_user_and_database "$db"
|
||||||
|
done
|
||||||
|
echo "Multiple databases created"
|
||||||
|
fi
|
@ -5,25 +5,228 @@ networks:
|
|||||||
driver: bridge
|
driver: bridge
|
||||||
enable_ipv6: false
|
enable_ipv6: false
|
||||||
|
|
||||||
|
|
||||||
x-mail: &defaults
|
x-mail: &defaults
|
||||||
|
restart: always
|
||||||
env_file: local.env
|
env_file: local.env
|
||||||
networks:
|
networks:
|
||||||
- internalnet
|
- internalnet
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
hugo-html:
|
||||||
|
networks:
|
||||||
|
- internalnet
|
||||||
|
container_name: hugo-html
|
||||||
|
build:
|
||||||
|
context: ./config/hugo
|
||||||
|
args:
|
||||||
|
HUGO_BASE: lieuwe.${NGINX_HOST}
|
||||||
|
volumes:
|
||||||
|
- hugo_data:/public:z
|
||||||
|
- nginx_certs:/etc/letsencrypt/live:z
|
||||||
|
|
||||||
hugo-site:
|
hugo-site:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
container_name: hugo-site
|
container_name: hugo-site
|
||||||
build: ./config/hugo
|
|
||||||
image: nginx:alpine
|
image: nginx:alpine
|
||||||
environment:
|
environment:
|
||||||
- VIRTUAL_HOST=lieuwe.${NGINX_HOST}
|
|
||||||
- VIRTUAL_PORT=6262
|
- VIRTUAL_PORT=6262
|
||||||
- VIRTUAL_PROTO=http
|
- VIRTUAL_PROTO=http
|
||||||
|
- VIRTUAL_HOST=lieuwe.${NGINX_HOST}
|
||||||
- LETSENCRYPT_HOST=lieuwe.${NGINX_HOST}
|
- LETSENCRYPT_HOST=lieuwe.${NGINX_HOST}
|
||||||
volumes:
|
volumes:
|
||||||
|
- hugo_data:/var/www/html:ro,z
|
||||||
- ./config/hugo/configure:/etc/nginx/templates/default.conf.template:ro,z
|
- ./config/hugo/configure:/etc/nginx/templates/default.conf.template:ro,z
|
||||||
restart: always
|
ports:
|
||||||
|
- "6262:6262"
|
||||||
|
|
||||||
|
pgsqlserver:
|
||||||
|
<<: *defaults
|
||||||
|
container_name: pgsqlserver
|
||||||
|
image: postgres:15
|
||||||
|
environment:
|
||||||
|
- POSTGRES_MULTIPLE_DATABASES=gitea, roundcube, nextcloud
|
||||||
|
- POSTGRES_PASSWORD=${SQL_PSWD}
|
||||||
|
volumes:
|
||||||
|
- sql_data:/var/lib/postgresql/data/:z
|
||||||
|
- ./config/pg-init-scripts:/docker-entrypoint-initdb.d:ro,z
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
|
||||||
|
nextcloud:
|
||||||
|
<<: *defaults
|
||||||
|
image: nextcloud:fpm
|
||||||
|
container_name: nextcloud
|
||||||
|
environment:
|
||||||
|
- VIRTUAL_HOST=nextcloud.${NGINX_HOST}
|
||||||
|
- VIRTUAL_PORT=9000
|
||||||
|
- LETSENCRYPT_HOST=nextcloud.${NGINX_HOST}
|
||||||
|
- POSTGRES_HOST=pgsqlserver
|
||||||
|
- POSTGRES_PORT=5432
|
||||||
|
- POSTGRES_DB=nextcloud
|
||||||
|
- POSTGRES_USER=nextcloud
|
||||||
|
- POSTGRES_PASSWORD=${SQL_PSWD}
|
||||||
|
- NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.${NGINX_HOST}
|
||||||
|
- NEXTCLOUD_ADMIN_USER=penny
|
||||||
|
- NEXTCLOUD_ADMIN_PASSWORD=${SQL_PSWD}
|
||||||
|
- SMTP_HOST=mailserver
|
||||||
|
- SMTP_SECURE=tls
|
||||||
|
- SMTP_NAME=admin@${NGINX_HOST}
|
||||||
|
- SMTP_PASSWORD=${SQL_PSWD}
|
||||||
|
depends_on:
|
||||||
|
- pgsqlserver
|
||||||
|
links:
|
||||||
|
- pgsqlserver
|
||||||
expose:
|
expose:
|
||||||
- "6262"
|
- "9000"
|
||||||
|
volumes:
|
||||||
|
- nextcloud_data:/var/www/html:z
|
||||||
|
- nextcloud_data:/var/www/nextcloud:z
|
||||||
|
|
||||||
|
gitea:
|
||||||
|
<<: *defaults
|
||||||
|
container_name: gitea
|
||||||
|
image: gitea/gitea
|
||||||
|
environment:
|
||||||
|
- VIRTUAL_HOST=git.${NGINX_HOST}
|
||||||
|
- VIRTUAL_PORT=3000
|
||||||
|
- LETSENCRYPT_HOST=git.${NGINX_HOST}
|
||||||
|
volumes:
|
||||||
|
- gitea_data:/data:z
|
||||||
|
expose:
|
||||||
|
- "3000"
|
||||||
|
ports:
|
||||||
|
- "222:22"
|
||||||
|
depends_on:
|
||||||
|
- pgsqlserver
|
||||||
|
links:
|
||||||
|
- pgsqlserver
|
||||||
|
|
||||||
|
roundcubemail:
|
||||||
|
<<: *defaults
|
||||||
|
image: roundcube/roundcubemail:latest-fpm
|
||||||
|
container_name: roundcubemail
|
||||||
|
environment:
|
||||||
|
- VIRTUAL_HOST=inbox.${NGINX_HOST}
|
||||||
|
- VIRTUAL_PORT=9000
|
||||||
|
- LETSENCRYPT_HOST=inbox.${NGINX_HOST}
|
||||||
|
- ROUNDCUBEMAIL_DB_HOST=pgsqlserver
|
||||||
|
- ROUNDCUBEMAIL_DEFAULT_HOST=tls://${NGINX_HOST}
|
||||||
|
- ROUNDCUBEMAIL_SMTP_SERVER=tls://${NGINX_HOST}
|
||||||
|
- ROUNDCUBEMAIL_DB_PASSWORD=${SQL_PSWD}
|
||||||
|
depends_on:
|
||||||
|
- pgsqlserver
|
||||||
|
links:
|
||||||
|
- pgsqlserver
|
||||||
|
expose:
|
||||||
|
- "9000"
|
||||||
|
volumes:
|
||||||
|
- mail_html:/var/www/html:z
|
||||||
|
- mail_html:/var/www/roundcube:z
|
||||||
|
- ./config/mail/config.php:/var/roundcube/config/${NGINX_HOST}.php:ro,z
|
||||||
|
|
||||||
|
mailserver:
|
||||||
|
<<: *defaults
|
||||||
|
image: mailserver/docker-mailserver:latest
|
||||||
|
container_name: mailserver
|
||||||
|
hostname: inbox
|
||||||
|
domainname: ${NGINX_HOST}
|
||||||
|
environment:
|
||||||
|
- POSTMASTER_ADDRESS=admin@${NGINX_HOST}
|
||||||
|
- RELAY_PASSWORD=${SENDGRID_APIKEY}
|
||||||
|
ports:
|
||||||
|
- "25:25"
|
||||||
|
- "143:143"
|
||||||
|
- "587:587"
|
||||||
|
- "993:993"
|
||||||
|
volumes:
|
||||||
|
- nginx_certs:/etc/letsencrypt/live:ro,z
|
||||||
|
- mail_data:/var/mail/:z
|
||||||
|
- mail_state:/var/mail-state/:z
|
||||||
|
- mail_config:/tmp/docker-mailserver/:z
|
||||||
|
cap_add:
|
||||||
|
- NET_ADMIN
|
||||||
|
depends_on:
|
||||||
|
- ddnsgd
|
||||||
|
|
||||||
|
reverse-proxy:
|
||||||
|
<<: *defaults
|
||||||
|
image: nginxproxy/nginx-proxy
|
||||||
|
container_name: nginx-proxy
|
||||||
|
environment:
|
||||||
|
- DEFAULT_EMAIL=admin@${NGINX_HOST}
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
volumes:
|
||||||
|
- nginx_html:/usr/share/nginx/html:z
|
||||||
|
- nginx_conf:/etc/nginx/conf.d/:z
|
||||||
|
- nginx_dhparam:/etc/nginx/dhparam:z
|
||||||
|
- nginx_certs:/etc/nginx/certs/:z
|
||||||
|
- nginx_vhost:/etc/nginx/vhost.d/:z
|
||||||
|
- mail_html:/var/www/roundcube:z
|
||||||
|
- nextcloud_data:/var/www/nextcloud:z
|
||||||
|
- ./config/nginx/inbox_location:/etc/nginx/vhost.d/inbox.${NGINX_HOST}_location:ro,z
|
||||||
|
- ./config/nginx/nextcloud_location:/etc/nginx/vhost.d/nextcloud.${NGINX_HOST}_location:ro,z
|
||||||
|
- ./config/nginx/header_default:/etc/nginx/vhost.d/default:z
|
||||||
|
- /var/run/docker.sock:/tmp/docker.sock:ro,z
|
||||||
|
depends_on:
|
||||||
|
- ddnsgd
|
||||||
|
|
||||||
|
acme-companion:
|
||||||
|
<<: *defaults
|
||||||
|
image: nginxproxy/acme-companion
|
||||||
|
container_name: nginx-proxy-acme
|
||||||
|
volumes_from:
|
||||||
|
- reverse-proxy
|
||||||
|
volumes:
|
||||||
|
- acme-state:/etc/acme.sh
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock:ro,z
|
||||||
|
depends_on:
|
||||||
|
- ddnsgd
|
||||||
|
|
||||||
|
ddnsgd:
|
||||||
|
<<: *defaults
|
||||||
|
container_name: "ddnsgd"
|
||||||
|
image: "ghcr.io/dominickbrasileiro/ddnsgd"
|
||||||
|
environment:
|
||||||
|
- HOSTNAME=${NGINX_HOST}
|
||||||
|
- USERNAME=${GDNS_USERNAME}
|
||||||
|
- PASSWORD=${GDNS_PASSWORD}
|
||||||
|
|
||||||
|
autodiscover:
|
||||||
|
<<: *defaults
|
||||||
|
image: monogramm/autodiscover-email-settings:latest
|
||||||
|
container_name: autodiscover
|
||||||
|
environment:
|
||||||
|
- VIRTUAL_HOST=autodiscover.${NGINX_HOST},autoconfig.${NGINX_HOST}
|
||||||
|
- VIRTUAL_PORT=8000
|
||||||
|
- LETSENCRYPT_HOST=autodiscover.${NGINX_HOST},autoconfig.${NGINX_HOST}
|
||||||
|
- DOMAIN=${NGINX_HOST}
|
||||||
|
- IMAP_HOST=mail.${NGINX_HOST}
|
||||||
|
- IMAP_PORT=993
|
||||||
|
- IMAP_SOCKET=SSL
|
||||||
|
- POP_HOST=mail.${NGINX_HOST}
|
||||||
|
- POP_PORT=995
|
||||||
|
- POP_SOCKET=SSL
|
||||||
|
- SMTP_HOST=mail.${NGINX_HOST}
|
||||||
|
- SMTP_PORT=587
|
||||||
|
- SMTP_SOCKET=STARTTLS
|
||||||
|
expose:
|
||||||
|
- "8000"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
acme-state:
|
||||||
|
gitea_data:
|
||||||
|
hugo_data:
|
||||||
|
nextcloud_data:
|
||||||
|
nginx_certs:
|
||||||
|
nginx_dhparam:
|
||||||
|
nginx_html:
|
||||||
|
nginx_conf:
|
||||||
|
nginx_vhost:
|
||||||
|
mail_data:
|
||||||
|
mail_config:
|
||||||
|
mail_state:
|
||||||
|
mail_html:
|
||||||
|
sql_data:
|
||||||
|
44
local.env
Normal file
44
local.env
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
## Docker Env
|
||||||
|
PERMIT_DOCKER=network
|
||||||
|
|
||||||
|
## Google Dynamic DNS
|
||||||
|
INTERVAL=900
|
||||||
|
|
||||||
|
## Mail Server Env
|
||||||
|
POSTFIX_INET_PROTOCOLS=ipv4
|
||||||
|
TZ=Europe/Berlin
|
||||||
|
ENABLE_SPAMASSASSIN=1
|
||||||
|
SPAMASSASSIN_SPAM_TO_INBOX=1
|
||||||
|
ENABLE_CLAMAV=1
|
||||||
|
ENABLE_FAIL2BAN=1
|
||||||
|
ENABLE_POSTGREY=1
|
||||||
|
ENABLE_SASLAUTHD=0
|
||||||
|
ONE_DIR=1
|
||||||
|
TLS_LEVEL=modern
|
||||||
|
ENABLE_UPDATE_CHECK=1
|
||||||
|
SSL_TYPE=letsencrypt
|
||||||
|
SPOOF_PROTECTION=1
|
||||||
|
ENABLE_POP3=1
|
||||||
|
POSTSCREEN_ACTION=ignore
|
||||||
|
ENABLE_DNSBL=0
|
||||||
|
ENABLE_QUOTAS=0
|
||||||
|
|
||||||
|
RELAY_HOST=smtp.sendgrid.net
|
||||||
|
RELAY_PORT=587
|
||||||
|
RELAY_USER=apikey
|
||||||
|
|
||||||
|
|
||||||
|
## SQL Server Env
|
||||||
|
POSTGRES_USER="pgadmin"
|
||||||
|
POSTGRES_INITDB_ARGS="--auth-host=scram-sha-256 --auth-local=scram-sha-256"
|
||||||
|
|
||||||
|
## Round Cube Env
|
||||||
|
ROUNDCUBEMAIL_DB_TYPE=pgsql
|
||||||
|
ROUNDCUBEMAIL_DB_NAME=roundcube
|
||||||
|
ROUNDCUBEMAIL_DB_USER=roundcube
|
||||||
|
ROUNDCUBEMAIL_SKIN=elastic
|
||||||
|
ROUNDCUBEMAIL_ASPELL_DICTS=en
|
||||||
|
|
||||||
|
## NGINX Reverse Proxy
|
||||||
|
NGINX_PROXY_CONTAINER=nginx-proxy
|
||||||
|
LETSENCRYPT_RESTART_CONTAINER=true
|
223
setup.sh
Normal file
223
setup.sh
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# version v1.0.0
|
||||||
|
# executed manually / via Make
|
||||||
|
# task wrapper for various setup scripts
|
||||||
|
|
||||||
|
CONFIG_PATH=
|
||||||
|
CONTAINER_NAME=
|
||||||
|
CRI=
|
||||||
|
DEFAULT_CONFIG_PATH=
|
||||||
|
DESIRED_CONFIG_PATH=
|
||||||
|
DIR=$(pwd)
|
||||||
|
DMS_CONFIG='/tmp/docker-mailserver'
|
||||||
|
IMAGE_NAME=
|
||||||
|
DEFAULT_IMAGE_NAME='docker.io/mailserver/docker-mailserver:latest'
|
||||||
|
INFO=
|
||||||
|
PODMAN_ROOTLESS=false
|
||||||
|
USE_SELINUX=
|
||||||
|
USE_TTY=
|
||||||
|
VOLUME=
|
||||||
|
|
||||||
|
WHITE=$(echo -ne '\e[37m')
|
||||||
|
ORANGE=$(echo -ne '\e[38;5;214m')
|
||||||
|
LBLUE=$(echo -ne '\e[94m')
|
||||||
|
RESET=$(echo -ne '\e[0m')
|
||||||
|
|
||||||
|
set -euEo pipefail
|
||||||
|
shopt -s inherit_errexit 2>/dev/null || true
|
||||||
|
|
||||||
|
function _show_local_usage
|
||||||
|
{
|
||||||
|
# shellcheck disable=SC2059
|
||||||
|
printf '%s' "${ORANGE}OPTIONS${RESET}
|
||||||
|
${LBLUE}Config path, container or image adjustments${RESET}
|
||||||
|
-i IMAGE_NAME
|
||||||
|
Provides the name of the 'docker-mailserver' image. The default value is
|
||||||
|
'${WHITE}${DEFAULT_IMAGE_NAME}${RESET}'
|
||||||
|
|
||||||
|
-c CONTAINER_NAME
|
||||||
|
Provides the name of the running container.
|
||||||
|
|
||||||
|
-p PATH
|
||||||
|
Provides the local path of the config folder to the temporary container instance.
|
||||||
|
Does not work if an existing a 'docker-mailserver' container is already running.
|
||||||
|
|
||||||
|
${LBLUE}SELinux${RESET}
|
||||||
|
-z
|
||||||
|
Allows container access to the bind mount content that is shared among
|
||||||
|
multiple containers on a SELinux-enabled host.
|
||||||
|
|
||||||
|
-Z
|
||||||
|
Allows container access to the bind mount content that is private and
|
||||||
|
unshared with other containers on a SELinux-enabled host.
|
||||||
|
|
||||||
|
${LBLUE}Podman${RESET}
|
||||||
|
-R
|
||||||
|
Accept running in Podman rootless mode. Ignored when using Docker / Docker Compose.
|
||||||
|
|
||||||
|
"
|
||||||
|
|
||||||
|
[[ ${1:-} == 'no-exit' ]] && return 0
|
||||||
|
|
||||||
|
# shellcheck disable=SC2059
|
||||||
|
printf '%s' "${ORANGE}EXIT STATUS${RESET}
|
||||||
|
Exit status is 0 if the command was successful. If there was an unexpected error, an error
|
||||||
|
message is shown describing the error. In case of an error, the script will exit with exit
|
||||||
|
status 1.
|
||||||
|
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _get_absolute_script_directory
|
||||||
|
{
|
||||||
|
if dirname "$(readlink -f "${0}")" &>/dev/null
|
||||||
|
then
|
||||||
|
DIR=$(dirname "$(readlink -f "${0}")")
|
||||||
|
elif realpath -e -L "${0}" &>/dev/null
|
||||||
|
then
|
||||||
|
DIR=$(realpath -e -L "${0}")
|
||||||
|
DIR="${DIR%/setup.sh}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function _set_default_config_path
|
||||||
|
{
|
||||||
|
if [[ -d "${DIR}/config" ]]
|
||||||
|
then
|
||||||
|
# legacy path (pre v10.2.0)
|
||||||
|
DEFAULT_CONFIG_PATH="${DIR}/config"
|
||||||
|
else
|
||||||
|
DEFAULT_CONFIG_PATH="${DIR}/docker-data/dms/config"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function _handle_config_path
|
||||||
|
{
|
||||||
|
if [[ -z ${DESIRED_CONFIG_PATH} ]]
|
||||||
|
then
|
||||||
|
# no desired config path
|
||||||
|
if [[ -n ${CONTAINER_NAME} ]]
|
||||||
|
then
|
||||||
|
VOLUME=$(${CRI} inspect "${CONTAINER_NAME}" \
|
||||||
|
--format="{{range .Mounts}}{{ println .Source .Destination}}{{end}}" | \
|
||||||
|
grep "${DMS_CONFIG}$" 2>/dev/null || :)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n ${VOLUME} ]]
|
||||||
|
then
|
||||||
|
CONFIG_PATH=$(echo "${VOLUME}" | awk '{print $1}')
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z ${CONFIG_PATH} ]]
|
||||||
|
then
|
||||||
|
CONFIG_PATH=${DEFAULT_CONFIG_PATH}
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
CONFIG_PATH=${DESIRED_CONFIG_PATH}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function _run_in_new_container
|
||||||
|
{
|
||||||
|
# start temporary container with specified image
|
||||||
|
if ! ${CRI} history -q "${IMAGE_NAME}" &>/dev/null
|
||||||
|
then
|
||||||
|
echo "Image '${IMAGE_NAME}' not found. Pulling ..."
|
||||||
|
${CRI} pull "${IMAGE_NAME}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
${CRI} run --rm "${USE_TTY}" \
|
||||||
|
-v "${CONFIG_PATH}:${DMS_CONFIG}${USE_SELINUX}" \
|
||||||
|
"${IMAGE_NAME}" "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _main
|
||||||
|
{
|
||||||
|
_get_absolute_script_directory
|
||||||
|
_set_default_config_path
|
||||||
|
|
||||||
|
local OPTIND
|
||||||
|
while getopts ":c:i:p:zZR" OPT
|
||||||
|
do
|
||||||
|
case ${OPT} in
|
||||||
|
( i ) IMAGE_NAME="${OPTARG}" ;;
|
||||||
|
( z | Z ) USE_SELINUX=":${OPT}" ;;
|
||||||
|
( c ) CONTAINER_NAME="${OPTARG}" ;;
|
||||||
|
( R ) PODMAN_ROOTLESS=true ;;
|
||||||
|
( p )
|
||||||
|
case "${OPTARG}" in
|
||||||
|
( /* ) DESIRED_CONFIG_PATH="${OPTARG}" ;;
|
||||||
|
( * ) DESIRED_CONFIG_PATH="${DIR}/${OPTARG}" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ ! -d ${DESIRED_CONFIG_PATH} ]]
|
||||||
|
then
|
||||||
|
echo "Specified directory '${DESIRED_CONFIG_PATH}' doesn't exist" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
( * )
|
||||||
|
echo "Invalid option: '-${OPTARG}'" >&2
|
||||||
|
echo -e "Use './setup.sh help' to get a complete overview.\n" >&2
|
||||||
|
_show_local_usage 'no-exit'
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $(( OPTIND - 1 ))
|
||||||
|
|
||||||
|
if command -v docker &>/dev/null
|
||||||
|
then
|
||||||
|
CRI=docker
|
||||||
|
elif command -v podman &>/dev/null
|
||||||
|
then
|
||||||
|
CRI=podman
|
||||||
|
if ! ${PODMAN_ROOTLESS} && [[ ${EUID} -ne 0 ]]
|
||||||
|
then
|
||||||
|
read -r -p "You are running Podman in rootless mode. Continue? [Y/n] "
|
||||||
|
[[ -n ${REPLY} ]] && [[ ${REPLY} =~ (n|N) ]] && exit 0
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo 'No supported Container Runtime Interface detected.'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
INFO=$(${CRI} ps --no-trunc --format "{{.Image}};{{.Names}}" --filter \
|
||||||
|
label=org.opencontainers.image.title="docker-mailserver" | tail -1)
|
||||||
|
|
||||||
|
[[ -z ${CONTAINER_NAME} ]] && CONTAINER_NAME=${INFO#*;}
|
||||||
|
[[ -z ${IMAGE_NAME} ]] && IMAGE_NAME=${INFO%;*}
|
||||||
|
if [[ -z ${IMAGE_NAME} ]]
|
||||||
|
then
|
||||||
|
IMAGE_NAME=${NAME:-${DEFAULT_IMAGE_NAME}}
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -t 0
|
||||||
|
then
|
||||||
|
USE_TTY="-it"
|
||||||
|
else
|
||||||
|
# GitHub Actions will fail (or really anything else
|
||||||
|
# lacking an interactive tty) if we don't set a
|
||||||
|
# value here; "-t" alone works for these cases.
|
||||||
|
USE_TTY="-t"
|
||||||
|
fi
|
||||||
|
|
||||||
|
_handle_config_path
|
||||||
|
|
||||||
|
if [[ -n ${CONTAINER_NAME} ]]
|
||||||
|
then
|
||||||
|
${CRI} exec "${USE_TTY}" "${CONTAINER_NAME}" setup "${@}"
|
||||||
|
else
|
||||||
|
_run_in_new_container setup "${@}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ ${1:-} == 'help' ]] && _show_local_usage
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
[[ -z ${1:-} ]] && set 'help'
|
||||||
|
_main "${@}"
|
Loading…
x
Reference in New Issue
Block a user