diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dcf8d41 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +### JetBrains template +.idea/ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..e7c015e --- /dev/null +++ b/.travis.yml @@ -0,0 +1,43 @@ +# Define build stages +stages: + - Tests + - SDLC Tasks + - Build and Publish + +# Use minimal image +language: minimal + +jobs: + include: + - stage: Tests + name: Shellcheck + env: + - SHELLCHECK_OPTS="-e SC1008 -e SC2154" + script: + - shellcheck $(find . -type f -name '*.sh') + - name: Dockerfile linter + script: + - docker run --rm -v $PWD:/root/ projectatomic/dockerfile-lint dockerfile_lint -f ./Dockerfile + - stage: "SDLC Tasks" + name: Tag & iteration update + sudo: required + script: + - bash bin/travis-ci/check_tag.sh + - stage: Build and Publish + name: Docker image + env: + - secure: gtTzu+h5OXZJmsNTf1HilJqcjqiFgrcepTSh2vwzQ/WEv0ccRI2qz+aWxob9YH05/u23slHyJycQ1mxZzeZF2qWjuDZvQK2jMmZ+dDjW6i5KUsqeWJALVAZNVxJ49cMC91LvkHDFZEj2qEXw69ATrJ3dcs715fmYw3FunSgGvfwcmpR1XjznLEa8A2Zp2byVeMkf2YHp/GB0HqidAl7SvBmEuPpiDG/SuoX4oEoctgZDRNp473LskrdF6aj1JnVhUV3wb7iQCHnLyvW0ssaA73p2O4nw3OcMM+RMTFoPwJw2Oy5Rw8bjFy64gH0i/tiZw7v/Jmo9tVMh63TzPHwBvjg85gWgleYOwLbaJZ1SaT4QbDN4dgwlCPtfboZQBWtOuZzdeCahyRU/Fx1z0mZLWd5vpIXEQwFQw2UsFOA9CUfjAB0bzUGzw6Fiezgdtj21purLepNr1NwYYA8eOU3g19/2EWo8AqDQbPxkFGYKlqUyDC6+gJU06GuHhTmAT6kUcp18mz/vSIdY2kkyOvDKgwcTpPC2RKmfa3HrYFT3srR3meeu8afweJZ+IiDAN1cFrdrKEB/9V6OGy69JlHzjLXjLxXS5qEJAqt2FJcqPeb0ckfGDrfiaSS7EzdjvghkT6fojwN+T6sk+9kOD6zspQWtJKrzJNCI4q3T4oFaQZgQ= + - secure: m366bb6pMii/kTSNKzJ9VwVW3sNijYFACMZ5vtear0zXhwjOAsGm32q+Hk7K41FutvIPFEHNNSLuddtPsliNlFH9LaODYQzd2VOJs4vEC6wRNqUWJkXmSztRFshnBGPBSzfQokHxk84pl0Z4lHkBwJBsvXLktoEFCY4NbbphX0o06vuAGDsxipnVG9Ngqx1yArIQrnSxOnzd6tO1QYlHavi4KYfVKxvx6dQJ+9DNZVSlaN7V0RAyEKyO4+HLvWf6QN1MynGV93ObzGnDEeZBjD8CaxoblTuUi2rg4aTHBkyA6t/vRle1HD5byRZ3p5cIz5diTr2VwF5bf6Wvt9xpWdyVCa4YMA3THLJMa+tH6KTbE+wo1b0UzCsjwoCoYHEzO3jznsWhgeNEEAZMppE9QQKzfdgR0Pl1VZ/NpOAHdtelgXPTO+7lhYp3T+GsZFurSrDt8OnUhe1rXxMBlRRmI47jK2pZDhOC5JnnI7ZnQOjDsllN8XTyFA/2FCB7yyrdSoPjeWBKr75GQ/kncZHYi+D3lm7oDyFUqxiJHiQJQfuCnN7DAR8as3zwsWJ21+Ey8fFVsbM1wI0agp2qPm/xRIeFZKmhSNfiUopSwI0F6ceR/E/VWa6agFPUgImqzSWc95cpJjTGaZnIQJqZnupjBNZn7QELjU5noTPQWIkjpDM= + - secure: kNyXuhAM13YxKLTik9AHkHxvy/flJVm4jV09eAQoLjV11Jo1/KuHpsO1xpCkAz6/pmmNoccBOK8/4K/sJkiJMgtV+lxcQNFw76CC3bmhSzRiIc2WST8dZMWrJl3qcf1Mv4KRAWSklS+smodhTDegSEsCZlEHdZiePrIXG+4Yhq7AnLe3I/0CGdNLppEf0Rduyx1O0pt9yJp8fZJfhZMNQ/ea37ef+cO5XWO5UwcpgB5IJqTf2/80iiwHDiJ8D6QOnmUlRRYAYFZEGFxt25YA53LR1FBjW7OWSKlFat4L2ewek8d0jfULcSY6ohviHDn+XWV2J2FAw82BD6BE5QFkGSJrt8VEtE0JeoZX+r466v653cM++53E/eRa5StU8SasUByn6wuaNk0J7zGLi87aSEXyDocz8dxA0FGnXiqHQM/FVxLuv1XCD53BWRmexstPqOB+UQpHmLka76khfT48W7Ay9pqgRQymYEqnzBu2WYleBjDxWIaohjiqpvD+JmEqLYMzwZe8w+/UIB0FXp6iSnw93TotT9P24oi2OfnDPlu8DcVlTzqh32i22iQWMEvd03dKaHyDyLt3I2hRJ8ojsMlSI2a07vgI0SsuMXnTBJ+Pb9/KzYVJGrpMfTZWsXdYeHFx6C4CcAFQAL4M/dWw6McNQWxi6Li4swK6LzUaDPU= + sudo: required + services: + - docker + script: + - bash bin/travis-ci/docker_upgrade.sh + - bash bin/travis-ci/docker_build.sh + deploy: + skip_cleanup: true + provider: script + script: bash bin/travis-ci/docker_publish.sh + on: + tags: true diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..6e78c73 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,30 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [v0.1.4] - 2019-06-27 +### Changed +- Merging to master + +## [v0.1.3] - 2018-11-07 +### Added +- Deployment step in CI +- CONTRIBUTION.md + +### Changed +- Clean up CI configuration +- Update scripts + - tag checking + - docker publish + +## [v0.1.2] - 2018-10-25 +### Added +- TLS support +- SASL Auth support + +## [v0.1.1] - 2018-09-24 +### Added +- Project `CHANGELOG.md`, `README.md`, and `LICENSE` +- Initial commit of Docker, build, and configuration diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..1f2d739 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,28 @@ +# Contributing to `postfix-docker` + +## Tags +### Summary +* Tag `develop` after merging feature branches +* Tag `master` after merging `develop` +* Tag creation generate DEB package and pushes container to registry + * See `.travis.yml` and `bin/travis-ci/*.sh` for details + +### Procedure +1. Push changes to appropriate branch (See [Pull Requests](#pull-requests)) + * In addition to any code changes, add a new entry in `CHANGELOG.md` with version bump and update `BUILD_VERSION` in `.env` to match +2. Create PR +3. Verify that all status checks pass +4. Merge PR once approved +5. Create a tag on the appropriate branch + +## Pull Requests + +### Feature Pull Requests +* Base: `develop` +* Increment PATCH version (e.g. `v0.1.12` -> `v0.1.13`) +* Tag `master` after merging PR + +### `master` Pull Requests +* Base: `master` +* Increment MINOR version (e.g. `v0.1.12` -> `v0.2.0`) +* Tag `master` after merging PR diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..915674f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,24 @@ +FROM ubuntu:bionic + +LABEL name="postfix" +LABEL version="latest" + +# Disable frontend dialogs +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get update \ + && apt-get install --yes \ + ca-certificates \ + postfix \ + rsyslog \ + supervisor \ + && apt-get --purge -y autoremove \ + && apt-get --yes clean \ + && rm -rf /etc/apt/sources.list.d/temp.list /var/lib/apt/lists/* + +COPY ./supervisor.conf /etc/supervisor/conf.d/postfix.conf + +COPY ./bin/postfix_init.sh /postfix_init.sh +RUN chmod u+x /postfix_init.sh + +CMD ["/usr/bin/python", "/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"] diff --git a/README.md b/README.md index 01e1d0c..b11f1ee 100644 --- a/README.md +++ b/README.md @@ -1 +1,19 @@ -# postfix-docker \ No newline at end of file +# postfix-docker + +This repo deploys and configures `postfix` inside a Docker container. + +## Configuration + +See `./bin/postfix_init.sh` for configuration parameters that are available via environment variables. + +## Features + +* Supervisor to manaage `postfix`, `rsyslog`, and log output to `stdout` +* Logging support is added with `rsyslog` +* TLS Support + * Set `POSTFIX_TLS` to `true` + * Default: unset/disabled +* SASL Support + * Set `POSTFIX_SASL_AUTH` to `:` + * Requires `POSTFIX_RELAYHOST` and `POSTFIX_TLS` + * Default: unset/disabled diff --git a/bin/postfix_init.sh b/bin/postfix_init.sh new file mode 100644 index 0000000..5302cb3 --- /dev/null +++ b/bin/postfix_init.sh @@ -0,0 +1,73 @@ +#!/bin/bash +# +# Copyright (c) 2018 SD Elements Inc. +# +# All Rights Reserved. +# +# NOTICE: All information contained herein is, and remains +# the property of SD Elements Incorporated and its suppliers, +# if any. The intellectual and technical concepts contained +# herein are proprietary to SD Elements Incorporated +# and its suppliers and may be covered by U.S., Canadian and other Patents, +# patents in process, and are protected by trade secret or copyright law. +# Dissemination of this information or reproduction of this material +# is strictly forbidden unless prior written permission is obtained +# from SD Elements Inc.. +# Version + +set -eo pipefail + +echo "Configuring postfix with any environment variables that are set" + +if [[ -n "${POSTFIX_MYNETWORKS}" ]]; then + echo "Setting custom 'mynetworks' to '${POSTFIX_MYNETWORKS}'" + postconf mynetworks="${POSTFIX_MYNETWORKS}" +else + echo "Revert 'mynetworks' to default" + postconf mynetworks="127.0.0.1/32 172.0.0.0/8" +fi + +if [[ -n "${POSTFIX_RELAYHOST}" ]]; then + echo "Setting custom 'relayhost' to '${POSTFIX_RELAYHOST}'" + postconf relayhost="[${POSTFIX_RELAYHOST}]:${POSTFIX_RELAYHOST_PORT}" +else + echo "Revert 'relayhost' to default (unset)" + postconf -# relayhost +fi + +echo "Disable chroot for the smtp service" +postconf -F smtp/inet/chroot=n +postconf -F smtp/unix/chroot=n + +if [[ "${POSTFIX_TLS}" = "true" ]]; then + echo "Configuring TLS" + postconf smtp_tls_CAfile="/etc/ssl/certs/ca-certificates.crt" + postconf smtp_tls_security_level="encrypt" + postconf smtp_use_tls="yes" +fi + +echo "Configuring SASL Auth" +if [[ -n "${POSTFIX_SASL_AUTH}" ]]; then + if [[ -z "${POSTFIX_RELAYHOST}" || -z "${POSTFIX_TLS}" ]]; then + echo "Please set 'POSTFIX_RELAYHOST' AND 'POSTFIX_TLS' before attempting to enable SSL auth." + exit 1 + fi + + postconf smtp_sasl_auth_enable="yes" + postconf smtp_sasl_password_maps="hash:/etc/postfix/sasl_passwd" + postconf smtp_sasl_security_options="noanonymous" + postconf smtp_tls_note_starttls_offer="yes" + + # generate the SASL password map + echo "${POSTFIX_RELAYHOST} ${POSTFIX_SASL_AUTH}" > /etc/postfix/sasl_passwd + + # generate a .db file and clean it up + postmap hash:/etc/postfix/sasl_passwd && rm /etc/postfix/sasl_passwd + + # set permissions + chmod 600 /etc/postfix/sasl_passwd.db +fi + + +echo "Starting postfix in the foreground" +postfix start-fg diff --git a/bin/travis-ci/check_tag.sh b/bin/travis-ci/check_tag.sh new file mode 100644 index 0000000..d22c5d2 --- /dev/null +++ b/bin/travis-ci/check_tag.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# +# Copyright (c) 2018 SD Elements Inc. +# +# All Rights Reserved. +# +# NOTICE: All information contained herein is, and remains +# the property of SD Elements Incorporated and its suppliers, +# if any. The intellectual and technical concepts contained +# herein are proprietary to SD Elements Incorporated +# and its suppliers and may be covered by U.S., Canadian and other Patents, +# patents in process, and are protected by trade secret or copyright law. +# Dissemination of this information or reproduction of this material +# is strictly forbidden unless prior written permission is obtained +# from SD Elements Inc.. +# Version + +set -eo pipefail + +echo "Installing shtdlib" +shtdlib_local_path="/usr/local/bin/shtdlib.sh" +sudo curl -s -L -o "${shtdlib_local_path}" https://github.com/sdelements/shtdlib/raw/master/shtdlib.sh +sudo chmod 775 "${shtdlib_local_path}" +# shellcheck disable=SC1091,SC1090 +source "${shtdlib_local_path}" +color_echo green "shtdlib.sh installed successfully" + +version_pattern='v\d+\.\d+\.\d+(?:qa)?' +version_pattern_line="^${version_pattern}$" + +# Get the latest tag from GitHub +latest_tag="$(git fetch -t && git tag -l | sort --version-sort | tail -n1)" +color_echo green "Latest Git tag from repo: '${latest_tag}'" + +# Get the latest tag from the CHANGELOG +changelog_ver="$(grep -oP "\[${version_pattern}\]" CHANGELOG.md | tr -d '[]' | sort --version-sort -r | head -n1)" +color_echo green "CHANGELOG version: '${changelog_ver}'" + +# Validate version strings +echo "${latest_tag}" | grep -qP "${version_pattern_line}" || ( color_echo red "Invalid tag from repo: '${latest_tag}'" && exit 1 ) +echo "${changelog_ver}" | grep -qP "${version_pattern_line}" || ( color_echo red "Invalid tag from CHANGELOG: '${changelog_ver}'" && exit 1 ) + +# Check if a tag triggered the build +if [[ -z "${TRAVIS_TAG}" ]]; then + # Ensure tags in CHANGELOG and iteration are greater than highest repo tag + if [ "${latest_tag}" = "${changelog_ver}" ] \ + || ! compare_versions "${latest_tag}" "${changelog_ver}"; then + color_echo red "Error: Incorrect version update. CHANGELOG.md (${changelog_ver}) not updated" + exit 1 + else + color_echo green "Version bumps PASS!" + fi +else + color_echo green "Newly created tag: '${TRAVIS_TAG}'" + # Validate version strings + echo "${TRAVIS_TAG}" | grep -qP "${version_pattern_line}" || ( color_echo red "Invalid tag name created: '${TRAVIS_TAG}'" && exit 1 ) + + # Ensure all the tags match up + if [ ! "${TRAVIS_TAG}" = "${changelog_ver}" ]; then + color_echo red "Error: tag version (${TRAVIS_TAG}) should match CHANGELOG.md (${changelog_ver})" + exit 1 + else + color_echo green "Version bumps PASS!" + fi +fi diff --git a/bin/travis-ci/docker_build.sh b/bin/travis-ci/docker_build.sh new file mode 100644 index 0000000..7b8483c --- /dev/null +++ b/bin/travis-ci/docker_build.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# +# Copyright (c) 2018 SD Elements Inc. +# +# All Rights Reserved. +# +# NOTICE: All information contained herein is, and remains +# the property of SD Elements Incorporated and its suppliers, +# if any. The intellectual and technical concepts contained +# herein are proprietary to SD Elements Incorporated +# and its suppliers and may be covered by U.S., Canadian and other Patents, +# patents in process, and are protected by trade secret or copyright law. +# Dissemination of this information or reproduction of this material +# is strictly forbidden unless prior written permission is obtained +# from SD Elements Inc.. +# Version + +set -eo pipefail + +# Build image +docker build --no-cache --tag "${DOCKER_REGISTRY_URL}/postfix" . +docker images diff --git a/bin/travis-ci/docker_publish.sh b/bin/travis-ci/docker_publish.sh new file mode 100644 index 0000000..9cbc1e3 --- /dev/null +++ b/bin/travis-ci/docker_publish.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# +# Copyright (c) 2018 SD Elements Inc. +# +# All Rights Reserved. +# +# NOTICE: All information contained herein is, and remains +# the property of SD Elements Incorporated and its suppliers, +# if any. The intellectual and technical concepts contained +# herein are proprietary to SD Elements Incorporated +# and its suppliers and may be covered by U.S., Canadian and other Patents, +# patents in process, and are protected by trade secret or copyright law. +# Dissemination of this information or reproduction of this material +# is strictly forbidden unless prior written permission is obtained +# from SD Elements Inc.. +# Version + +set -eo pipefail + +# Log into our Docker registry +echo "${DOCKER_REGISTRY_PASSWORD}" | docker login -u "${DOCKER_REGISTRY_USER}" --password-stdin "${DOCKER_REGISTRY_URL}" + +echo "Tagging container" +docker tag "${DOCKER_REGISTRY_URL}/postfix:latest" "${DOCKER_REGISTRY_URL}/postfix:${TRAVIS_TAG}" + +# Push images +docker push "${DOCKER_REGISTRY_URL}/postfix:latest" +docker push "${DOCKER_REGISTRY_URL}/postfix:${TRAVIS_TAG}" +docker images diff --git a/bin/travis-ci/docker_upgrade.sh b/bin/travis-ci/docker_upgrade.sh new file mode 100644 index 0000000..fa9c1e7 --- /dev/null +++ b/bin/travis-ci/docker_upgrade.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# +# Copyright (c) 2018 SD Elements Inc. +# +# All Rights Reserved. +# +# NOTICE: All information contained herein is, and remains +# the property of SD Elements Incorporated and its suppliers, +# if any. The intellectual and technical concepts contained +# herein are proprietary to SD Elements Incorporated +# and its suppliers and may be covered by U.S., Canadian and other Patents, +# patents in process, and are protected by trade secret or copyright law. +# Dissemination of this information or reproduction of this material +# is strictly forbidden unless prior written permission is obtained +# from SD Elements Inc.. +# Version + +set -eo pipefail + +# Update docker +sudo apt-get update +sudo apt-get --yes install docker-ce + +# Update docker-compose +sudo rm /usr/local/bin/docker-compose +sudo curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose +sudo chmod +x /usr/local/bin/docker-compose + +# Verify +docker version && docker-compose --version diff --git a/supervisor.conf b/supervisor.conf new file mode 100644 index 0000000..4e97f70 --- /dev/null +++ b/supervisor.conf @@ -0,0 +1,13 @@ +[supervisord] +nodaemon=true + +[program:postfix] +command=/postfix_init.sh + +[program:rsyslog] +command=/usr/sbin/rsyslogd -n + +[program:readlog] +command=/usr/bin/tail -F /var/log/mail.log +stdout_logfile=/dev/fd/1 +stdout_logfile_maxbytes=0