generate_config.sh 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. #!/usr/bin/env bash
  2. set -o pipefail
  3. if [[ "$(uname -r)" =~ ^4\.15\.0-60 ]]; then
  4. echo "DO NOT RUN mailcow ON THIS UBUNTU KERNEL!";
  5. echo "Please update to 5.x or use another distribution."
  6. exit 1
  7. fi
  8. if [[ "$(uname -r)" =~ ^4\.4\. ]]; then
  9. if grep -q Ubuntu <<< $(uname -a); then
  10. echo "DO NOT RUN mailcow ON THIS UBUNTU KERNEL!";
  11. echo "Please update to linux-generic-hwe-16.04 by running \"apt-get install --install-recommends linux-generic-hwe-16.04\""
  12. exit 1
  13. fi
  14. fi
  15. if grep --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo "BusyBox grep detected, please install gnu grep, \"apk add --no-cache --upgrade grep\""; exit 1; fi
  16. # This will also cover sort
  17. if cp --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo "BusyBox cp detected, please install coreutils, \"apk add --no-cache --upgrade coreutils\""; exit 1; fi
  18. if sed --help 2>&1 | head -n 1 | grep -q -i "busybox"; then echo "BusyBox sed detected, please install gnu sed, \"apk add --no-cache --upgrade sed\""; exit 1; fi
  19. for bin in openssl curl docker git awk sha1sum; do
  20. if [[ -z $(which ${bin}) ]]; then echo "Cannot find ${bin}, exiting..."; exit 1; fi
  21. done
  22. if docker compose > /dev/null 2>&1; then
  23. if docker compose version --short | grep "^2." > /dev/null 2>&1; then
  24. COMPOSE_VERSION=native
  25. echo -e "\e[31mFound Docker Compose Plugin (native).\e[0m"
  26. echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable to native\e[0m"
  27. sleep 2
  28. echo -e "\e[33mNotice: You´ll have to update this Compose Version via your Package Manager manually!\e[0m"
  29. else
  30. echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m"
  31. echo -e "\e[31mPlease update/install it manually regarding to this doc site: https://mailcow.github.io/mailcow-dockerized-docs/i_u_m/i_u_m_install/\e[0m"
  32. exit 1
  33. fi
  34. elif docker-compose > /dev/null 2>&1; then
  35. if ! [[ $(alias docker-compose 2> /dev/null) ]] ; then
  36. if docker-compose version --short | grep "^2." > /dev/null 2>&1; then
  37. COMPOSE_VERSION=standalone
  38. echo -e "\e[31mFound Docker Compose Standalone.\e[0m"
  39. echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable to standalone\e[0m"
  40. sleep 2
  41. echo -e "\e[33mNotice: For an automatic update of docker-compose please use the update_compose.sh scripts located at the helper-scripts folder.\e[0m"
  42. else
  43. echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m"
  44. echo -e "\e[31mPlease update/install manually regarding to this doc site: https://mailcow.github.io/mailcow-dockerized-docs/i_u_m/i_u_m_install/\e[0m"
  45. exit 1
  46. fi
  47. fi
  48. else
  49. echo -e "\e[31mCannot find Docker Compose.\e[0m"
  50. echo -e "\e[31mPlease install it regarding to this doc site: https://mailcow.github.io/mailcow-dockerized-docs/i_u_m/i_u_m_install/\e[0m"
  51. exit 1
  52. fi
  53. ### If generate_config.sh is started with --dev or -d it will not check out nightly or master branch and will keep on the current branch
  54. if [[ ${1} == "--dev" || ${1} == "-d" ]]; then
  55. SKIP_BRANCH=y
  56. else
  57. SKIP_BRANCH=n
  58. fi
  59. if [ -f mailcow.conf ]; then
  60. read -r -p "A config file exists and will be overwritten, are you sure you want to continue? [y/N] " response
  61. case $response in
  62. [yY][eE][sS]|[yY])
  63. mv mailcow.conf mailcow.conf_backup
  64. chmod 600 mailcow.conf_backup
  65. ;;
  66. *)
  67. exit 1
  68. ;;
  69. esac
  70. fi
  71. echo "Press enter to confirm the detected value '[value]' where applicable or enter a custom value."
  72. while [ -z "${MAILCOW_HOSTNAME}" ]; do
  73. read -p "Mail server hostname (FQDN) - this is not your mail domain, but your mail servers hostname: " -e MAILCOW_HOSTNAME
  74. DOTS=${MAILCOW_HOSTNAME//[^.]};
  75. if [ ${#DOTS} -lt 2 ] && [ ! -z ${MAILCOW_HOSTNAME} ]; then
  76. echo "${MAILCOW_HOSTNAME} is not a FQDN"
  77. MAILCOW_HOSTNAME=
  78. fi
  79. done
  80. if [ -a /etc/timezone ]; then
  81. DETECTED_TZ=$(cat /etc/timezone)
  82. elif [ -a /etc/localtime ]; then
  83. DETECTED_TZ=$(readlink /etc/localtime|sed -n 's|^.*zoneinfo/||p')
  84. fi
  85. while [ -z "${MAILCOW_TZ}" ]; do
  86. if [ -z "${DETECTED_TZ}" ]; then
  87. read -p "Timezone: " -e MAILCOW_TZ
  88. else
  89. read -p "Timezone [${DETECTED_TZ}]: " -e MAILCOW_TZ
  90. [ -z "${MAILCOW_TZ}" ] && MAILCOW_TZ=${DETECTED_TZ}
  91. fi
  92. done
  93. MEM_TOTAL=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
  94. if [ ${MEM_TOTAL} -le "2621440" ]; then
  95. echo "Installed memory is <= 2.5 GiB. It is recommended to disable ClamAV to prevent out-of-memory situations."
  96. echo "ClamAV can be re-enabled by setting SKIP_CLAMD=n in mailcow.conf."
  97. read -r -p "Do you want to disable ClamAV now? [Y/n] " response
  98. case $response in
  99. [nN][oO]|[nN])
  100. SKIP_CLAMD=n
  101. ;;
  102. *)
  103. SKIP_CLAMD=y
  104. ;;
  105. esac
  106. else
  107. SKIP_CLAMD=n
  108. fi
  109. if [ ${MEM_TOTAL} -le "2097152" ]; then
  110. echo "Disabling Solr on low-memory system."
  111. SKIP_SOLR=y
  112. elif [ ${MEM_TOTAL} -le "3670016" ]; then
  113. echo "Installed memory is <= 3.5 GiB. It is recommended to disable Solr to prevent out-of-memory situations."
  114. echo "Solr is a prone to run OOM and should be monitored. The default Solr heap size is 1024 MiB and should be set in mailcow.conf according to your expected load."
  115. echo "Solr can be re-enabled by setting SKIP_SOLR=n in mailcow.conf but will refuse to start with less than 2 GB total memory."
  116. read -r -p "Do you want to disable Solr now? [Y/n] " response
  117. case $response in
  118. [nN][oO]|[nN])
  119. SKIP_SOLR=n
  120. ;;
  121. *)
  122. SKIP_SOLR=y
  123. ;;
  124. esac
  125. else
  126. SKIP_SOLR=n
  127. fi
  128. if [[ ${SKIP_BRANCH} != y ]]; then
  129. echo "Which branch of mailcow do you want to use?"
  130. echo ""
  131. echo "Available Branches:"
  132. echo "- master branch (stable updates) | default, recommended [1]"
  133. echo "- nightly branch (unstable updates, testing) | not-production ready [2]"
  134. sleep 1
  135. while [ -z "${MAILCOW_BRANCH}" ]; do
  136. read -r -p "Choose the Branch with it´s number [1/2] " branch
  137. case $branch in
  138. [2])
  139. MAILCOW_BRANCH="nightly"
  140. ;;
  141. *)
  142. MAILCOW_BRANCH="master"
  143. ;;
  144. esac
  145. done
  146. git fetch --all
  147. git checkout -f $git_branch
  148. elif [[ ${SKIP_BRANCH} == y ]]; then
  149. echo -e "\033[33mEnabled Dev Mode.\033[0m"
  150. echo -e "\033[33mNot checking out a different branch!\033[0m"
  151. MAILCOW_BRANCH=$(git rev-parse --short $(git rev-parse @{upstream}))
  152. else
  153. echo -e "\033[31mCould not determine branch input..."
  154. echo -e "\033[31mExiting."
  155. exit 1
  156. fi
  157. if [ ! -z "${MAILCOW_BRANCH}" ]; then
  158. git_branch=${MAILCOW_BRANCH}
  159. fi
  160. [ ! -f ./data/conf/rspamd/override.d/worker-controller-password.inc ] && echo '# Placeholder' > ./data/conf/rspamd/override.d/worker-controller-password.inc
  161. cat << EOF > mailcow.conf
  162. # ------------------------------
  163. # mailcow web ui configuration
  164. # ------------------------------
  165. # example.org is _not_ a valid hostname, use a fqdn here.
  166. # Default admin user is "admin"
  167. # Default password is "moohoo"
  168. MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
  169. # Password hash algorithm
  170. # Only certain password hash algorithm are supported. For a fully list of supported schemes,
  171. # see https://mailcow.github.io/mailcow-dockerized-docs/models/model-passwd/
  172. MAILCOW_PASS_SCHEME=BLF-CRYPT
  173. # ------------------------------
  174. # SQL database configuration
  175. # ------------------------------
  176. DBNAME=mailcow
  177. DBUSER=mailcow
  178. # Please use long, random alphanumeric strings (A-Za-z0-9)
  179. DBPASS=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 28)
  180. DBROOT=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 28)
  181. # ------------------------------
  182. # HTTP/S Bindings
  183. # ------------------------------
  184. # You should use HTTPS, but in case of SSL offloaded reverse proxies:
  185. # Might be important: This will also change the binding within the container.
  186. # If you use a proxy within Docker, point it to the ports you set below.
  187. # Do _not_ use IP:PORT in HTTP(S)_BIND or HTTP(S)_PORT
  188. # IMPORTANT: Do not use port 8081, 9081 or 65510!
  189. # Example: HTTP_BIND=1.2.3.4
  190. # For IPv4 leave it as it is: HTTP_BIND= & HTTPS_PORT=
  191. # For IPv6 see https://mailcow.github.io/mailcow-dockerized-docs/post_installation/firststeps-ip_bindings/
  192. HTTP_PORT=80
  193. HTTP_BIND=
  194. HTTPS_PORT=443
  195. HTTPS_BIND=
  196. # ------------------------------
  197. # Other bindings
  198. # ------------------------------
  199. # You should leave that alone
  200. # Format: 11.22.33.44:25 or 12.34.56.78:465 etc.
  201. SMTP_PORT=25
  202. SMTPS_PORT=465
  203. SUBMISSION_PORT=587
  204. IMAP_PORT=143
  205. IMAPS_PORT=993
  206. POP_PORT=110
  207. POPS_PORT=995
  208. SIEVE_PORT=4190
  209. DOVEADM_PORT=127.0.0.1:19991
  210. SQL_PORT=127.0.0.1:13306
  211. SOLR_PORT=127.0.0.1:18983
  212. REDIS_PORT=127.0.0.1:7654
  213. # Your timezone
  214. # See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones for a list of timezones
  215. # Use the row named 'TZ database name' + pay attention for 'Notes' row
  216. TZ=${MAILCOW_TZ}
  217. # Fixed project name
  218. # Please use lowercase letters only
  219. COMPOSE_PROJECT_NAME=mailcowdockerized
  220. # Used Docker Compose version
  221. # Switch here between native (compose plugin) and standalone
  222. # For more informations take a look at the mailcow docs regarding the configuration options.
  223. # Normally this should be untouched but if you decided to use either of those you can switch it manually here.
  224. # Please be aware that at least one of those variants should be installed on your machine or mailcow will fail.
  225. DOCKER_COMPOSE_VERSION=${COMPOSE_VERSION}
  226. # Set this to "allow" to enable the anyone pseudo user. Disabled by default.
  227. # When enabled, ACL can be created, that apply to "All authenticated users"
  228. # This should probably only be activated on mail hosts, that are used exclusivly by one organisation.
  229. # Otherwise a user might share data with too many other users.
  230. ACL_ANYONE=disallow
  231. # Garbage collector cleanup
  232. # Deleted domains and mailboxes are moved to /var/vmail/_garbage/timestamp_sanitizedstring
  233. # How long should objects remain in the garbage until they are being deleted? (value in minutes)
  234. # Check interval is hourly
  235. MAILDIR_GC_TIME=7200
  236. # Additional SAN for the certificate
  237. #
  238. # You can use wildcard records to create specific names for every domain you add to mailcow.
  239. # Example: Add domains "example.com" and "example.net" to mailcow, change ADDITIONAL_SAN to a value like:
  240. #ADDITIONAL_SAN=imap.*,smtp.*
  241. # This will expand the certificate to "imap.example.com", "smtp.example.com", "imap.example.net", "smtp.example.net"
  242. # plus every domain you add in the future.
  243. #
  244. # You can also just add static names...
  245. #ADDITIONAL_SAN=srv1.example.net
  246. # ...or combine wildcard and static names:
  247. #ADDITIONAL_SAN=imap.*,srv1.example.com
  248. #
  249. ADDITIONAL_SAN=
  250. # Additional server names for mailcow UI
  251. #
  252. # Specify alternative addresses for the mailcow UI to respond to
  253. # This is useful when you set mail.* as ADDITIONAL_SAN and want to make sure mail.maildomain.com will always point to the mailcow UI.
  254. # If the server name does not match a known site, Nginx decides by best-guess and may redirect users to the wrong web root.
  255. # You can understand this as server_name directive in Nginx.
  256. # Comma separated list without spaces! Example: ADDITIONAL_SERVER_NAMES=a.b.c,d.e.f
  257. ADDITIONAL_SERVER_NAMES=
  258. # Skip running ACME (acme-mailcow, Let's Encrypt certs) - y/n
  259. SKIP_LETS_ENCRYPT=n
  260. # Create seperate certificates for all domains - y/n
  261. # this will allow adding more than 100 domains, but some email clients will not be able to connect with alternative hostnames
  262. # see https://wiki.dovecot.org/SSL/SNIClientSupport
  263. ENABLE_SSL_SNI=n
  264. # Skip IPv4 check in ACME container - y/n
  265. SKIP_IP_CHECK=n
  266. # Skip HTTP verification in ACME container - y/n
  267. SKIP_HTTP_VERIFICATION=n
  268. # Skip ClamAV (clamd-mailcow) anti-virus (Rspamd will auto-detect a missing ClamAV container) - y/n
  269. SKIP_CLAMD=${SKIP_CLAMD}
  270. # Skip SOGo: Will disable SOGo integration and therefore webmail, DAV protocols and ActiveSync support (experimental, unsupported, not fully implemented) - y/n
  271. SKIP_SOGO=n
  272. # Skip Solr on low-memory systems or if you do not want to store a readable index of your mails in solr-vol-1.
  273. SKIP_SOLR=${SKIP_SOLR}
  274. # Solr heap size in MB, there is no recommendation, please see Solr docs.
  275. # Solr is a prone to run OOM and should be monitored. Unmonitored Solr setups are not recommended.
  276. SOLR_HEAP=1024
  277. # Allow admins to log into SOGo as email user (without any password)
  278. ALLOW_ADMIN_EMAIL_LOGIN=n
  279. # Enable watchdog (watchdog-mailcow) to restart unhealthy containers
  280. USE_WATCHDOG=y
  281. # Send watchdog notifications by mail (sent from watchdog@MAILCOW_HOSTNAME)
  282. # CAUTION:
  283. # 1. You should use external recipients
  284. # 2. Mails are sent unsigned (no DKIM)
  285. # 3. If you use DMARC, create a separate DMARC policy ("v=DMARC1; p=none;" in _dmarc.MAILCOW_HOSTNAME)
  286. # Multiple rcpts allowed, NO quotation marks, NO spaces
  287. #WATCHDOG_NOTIFY_EMAIL=a@example.com,b@example.com,c@example.com
  288. #WATCHDOG_NOTIFY_EMAIL=
  289. # Notify about banned IP (includes whois lookup)
  290. WATCHDOG_NOTIFY_BAN=n
  291. # Subject for watchdog mails. Defaults to "Watchdog ALERT" followed by the error message.
  292. #WATCHDOG_SUBJECT=
  293. # Checks if mailcow is an open relay. Requires a SAL. More checks will follow.
  294. # https://www.servercow.de/mailcow?lang=en
  295. # https://www.servercow.de/mailcow?lang=de
  296. # No data is collected. Opt-in and anonymous.
  297. # Will only work with unmodified mailcow setups.
  298. WATCHDOG_EXTERNAL_CHECKS=n
  299. # Enable watchdog verbose logging
  300. WATCHDOG_VERBOSE=n
  301. # Max log lines per service to keep in Redis logs
  302. LOG_LINES=9999
  303. # Internal IPv4 /24 subnet, format n.n.n (expands to n.n.n.0/24)
  304. # Use private IPv4 addresses only, see https://en.wikipedia.org/wiki/Private_network#Private_IPv4_addresses
  305. IPV4_NETWORK=172.22.1
  306. # Internal IPv6 subnet in fc00::/7
  307. # Use private IPv6 addresses only, see https://en.wikipedia.org/wiki/Private_network#Private_IPv6_addresses
  308. IPV6_NETWORK=fd4d:6169:6c63:6f77::/64
  309. # Use this IPv4 for outgoing connections (SNAT)
  310. #SNAT_TO_SOURCE=
  311. # Use this IPv6 for outgoing connections (SNAT)
  312. #SNAT6_TO_SOURCE=
  313. # Create or override an API key for the web UI
  314. # You _must_ define API_ALLOW_FROM, which is a comma separated list of IPs
  315. # An API key defined as API_KEY has read-write access
  316. # An API key defined as API_KEY_READ_ONLY has read-only access
  317. # Allowed chars for API_KEY and API_KEY_READ_ONLY: a-z, A-Z, 0-9, -
  318. # You can define API_KEY and/or API_KEY_READ_ONLY
  319. #API_KEY=
  320. #API_KEY_READ_ONLY=
  321. #API_ALLOW_FROM=172.22.1.1,127.0.0.1
  322. # mail_home is ~/Maildir
  323. MAILDIR_SUB=Maildir
  324. # SOGo session timeout in minutes
  325. SOGO_EXPIRE_SESSION=480
  326. # DOVECOT_MASTER_USER and DOVECOT_MASTER_PASS must both be provided. No special chars.
  327. # Empty by default to auto-generate master user and password on start.
  328. # User expands to DOVECOT_MASTER_USER@mailcow.local
  329. # LEAVE EMPTY IF UNSURE
  330. DOVECOT_MASTER_USER=
  331. # LEAVE EMPTY IF UNSURE
  332. DOVECOT_MASTER_PASS=
  333. # Let's Encrypt registration contact information
  334. # Optional: Leave empty for none
  335. # This value is only used on first order!
  336. # Setting it at a later point will require the following steps:
  337. # https://mailcow.github.io/mailcow-dockerized-docs/troubleshooting/debug-reset_tls/
  338. ACME_CONTACT=
  339. # WebAuthn device manufacturer verification
  340. # After setting WEBAUTHN_ONLY_TRUSTED_VENDORS=y only devices from trusted manufacturers are allowed
  341. # root certificates can be placed for validation under mailcow-dockerized/data/web/inc/lib/WebAuthn/rootCertificates
  342. WEBAUTHN_ONLY_TRUSTED_VENDORS=n
  343. EOF
  344. mkdir -p data/assets/ssl
  345. chmod 600 mailcow.conf
  346. # copy but don't overwrite existing certificate
  347. echo "Generating snake-oil certificate..."
  348. # Making Willich more popular
  349. openssl req -x509 -newkey rsa:4096 -keyout data/assets/ssl-example/key.pem -out data/assets/ssl-example/cert.pem -days 365 -subj "/C=DE/ST=NRW/L=Willich/O=mailcow/OU=mailcow/CN=${MAILCOW_HOSTNAME}" -sha256 -nodes
  350. echo "Copying snake-oil certificate..."
  351. cp -n -d data/assets/ssl-example/*.pem data/assets/ssl/
  352. # Set app_info.inc.php
  353. case ${git_branch} in
  354. master)
  355. mailcow_git_version=$(git describe --tags `git rev-list --tags --max-count=1`)
  356. ;;
  357. nightly)
  358. mailcow_git_version=$(git rev-parse --short $(git rev-parse @{upstream}))
  359. mailcow_last_git_version=""
  360. ;;
  361. *)
  362. mailcow_git_version=$(git rev-parse --short HEAD)
  363. mailcow_last_git_version=""
  364. ;;
  365. esac
  366. # if [ ${git_branch} == "master" ]; then
  367. # mailcow_git_version=$(git describe --tags `git rev-list --tags --max-count=1`)
  368. # elif [ ${git_branch} == "nightly" ]; then
  369. # mailcow_git_version=$(git rev-parse --short $(git rev-parse @{upstream}))
  370. # mailcow_last_git_version=""
  371. # else
  372. # mailcow_git_version=$(git rev-parse --short HEAD)
  373. # mailcow_last_git_version=""
  374. # fi
  375. if [[ $SKIP_BRANCH != "y" ]]; then
  376. mailcow_git_commit=$(git rev-parse origin/${git_branch})
  377. mailcow_git_commit_date=$(git log -1 --format=%ci @{upstream} )
  378. else
  379. mailcow_git_commit=$(git rev-parse ${git_branch})
  380. mailcow_git_commit_date=$(git log -1 --format=%ci @{upstream} )
  381. git_branch=$(git rev-parse --abbrev-ref HEAD)
  382. fi
  383. if [ $? -eq 0 ]; then
  384. echo '<?php' > data/web/inc/app_info.inc.php
  385. echo ' $MAILCOW_GIT_VERSION="'$mailcow_git_version'";' >> data/web/inc/app_info.inc.php
  386. echo ' $MAILCOW_LAST_GIT_VERSION="";' >> data/web/inc/app_info.inc.php
  387. echo ' $MAILCOW_GIT_OWNER="mailcow";' >> data/web/inc/app_info.inc.php
  388. echo ' $MAILCOW_GIT_REPO="mailcow-dockerized";' >> data/web/inc/app_info.inc.php
  389. echo ' $MAILCOW_GIT_URL="https://github.com/mailcow/mailcow-dockerized";' >> data/web/inc/app_info.inc.php
  390. echo ' $MAILCOW_GIT_COMMIT="'$mailcow_git_commit'";' >> data/web/inc/app_info.inc.php
  391. echo ' $MAILCOW_GIT_COMMIT_DATE="'$mailcow_git_commit_date'";' >> data/web/inc/app_info.inc.php
  392. echo ' $MAILCOW_BRANCH="'$git_branch'";' >> data/web/inc/app_info.inc.php
  393. echo ' $MAILCOW_UPDATEDAT='$(date +%s)';' >> data/web/inc/app_info.inc.php
  394. echo '?>' >> data/web/inc/app_info.inc.php
  395. else
  396. echo '<?php' > data/web/inc/app_info.inc.php
  397. echo ' $MAILCOW_GIT_VERSION="'$mailcow_git_version'";' >> data/web/inc/app_info.inc.php
  398. echo ' $MAILCOW_LAST_GIT_VERSION="";' >> data/web/inc/app_info.inc.php
  399. echo ' $MAILCOW_GIT_OWNER="mailcow";' >> data/web/inc/app_info.inc.php
  400. echo ' $MAILCOW_GIT_REPO="mailcow-dockerized";' >> data/web/inc/app_info.inc.php
  401. echo ' $MAILCOW_GIT_URL="https://github.com/mailcow/mailcow-dockerized";' >> data/web/inc/app_info.inc.php
  402. echo ' $MAILCOW_GIT_COMMIT="";' >> data/web/inc/app_info.inc.php
  403. echo ' $MAILCOW_GIT_COMMIT_DATE="";' >> data/web/inc/app_info.inc.php
  404. echo ' $MAILCOW_BRANCH="'$git_branch'";' >> data/web/inc/app_info.inc.php
  405. echo ' $MAILCOW_UPDATEDAT='$(date +%s)';' >> data/web/inc/app_info.inc.php
  406. echo '?>' >> data/web/inc/app_info.inc.php
  407. echo -e "\e[33mCannot determine current git repository version...\e[0m"
  408. fi