2022-11-04 16:15:19 +02:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
2022-11-05 00:21:11 +02:00
|
|
|
set -euo pipefail
|
2022-11-04 16:15:19 +02:00
|
|
|
|
|
|
|
### CONFIG
|
|
|
|
|
|
|
|
DEV_NAME="${DEV_NAME:-mailu-dev}"
|
2022-11-05 00:21:11 +02:00
|
|
|
DEV_DB="${DEV_DB:-}"
|
2022-11-04 22:41:31 +02:00
|
|
|
DEV_PROFILER="${DEV_PROFILER:-false}"
|
|
|
|
DEV_LISTEN="${DEV_LISTEN:-127.0.0.1:8080}"
|
|
|
|
[[ "${DEV_LISTEN}" == *:* ]] || DEV_LISTEN="127.0.0.1:${DEV_LISTEN}"
|
2022-11-05 00:21:11 +02:00
|
|
|
DEV_ADMIN="${DEV_ADMIN:-admin@example.com}"
|
2022-11-07 17:35:01 +02:00
|
|
|
DEV_PASSWORD="${DEV_PASSWORD:-letmein}"
|
2022-12-29 16:36:07 +02:00
|
|
|
DEV_ARGS=( "$@" )
|
2022-11-04 16:15:19 +02:00
|
|
|
|
|
|
|
### MAIN
|
|
|
|
|
2022-11-05 00:21:11 +02:00
|
|
|
[[ -n "${DEV_DB}" ]] && {
|
|
|
|
[[ -f "${DEV_DB}" ]] || {
|
|
|
|
echo "Sorry, can't find DEV_DB: '${DEV_DB}'"
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
DEV_DB="$(realpath "${DEV_DB}")"
|
|
|
|
}
|
|
|
|
|
2022-11-04 19:29:45 +02:00
|
|
|
docker="$(command -v podman || command -v docker || echo false)"
|
|
|
|
[[ "${docker}" == "false" ]] && {
|
2022-11-05 00:21:11 +02:00
|
|
|
echo "Sorry, you'll need podman or docker to run this."
|
|
|
|
exit 1
|
2022-11-04 19:29:45 +02:00
|
|
|
}
|
|
|
|
|
2022-11-05 00:21:11 +02:00
|
|
|
tmp="$(mktemp -d)"
|
|
|
|
[[ -n "${tmp}" && -d "${tmp}" ]] || {
|
|
|
|
echo "Sorry, can't create temporary folder."
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
trap "rm -rf '${tmp}'" INT TERM EXIT
|
2022-11-04 16:15:19 +02:00
|
|
|
|
2022-11-05 00:21:11 +02:00
|
|
|
admin="$(realpath "$(pwd)/${0%/*}")"
|
|
|
|
base="${admin}/../base"
|
|
|
|
assets="${admin}/assets"
|
|
|
|
|
|
|
|
cd "${tmp}"
|
2022-11-04 16:15:19 +02:00
|
|
|
|
|
|
|
# base
|
2022-11-05 00:21:11 +02:00
|
|
|
cp "${base}"/requirements-* .
|
|
|
|
cp -r "${base}"/libs .
|
|
|
|
sed -E '/^#/d;s:^FROM system$:FROM system AS base:' "${base}/Dockerfile" >Dockerfile
|
2022-11-04 16:15:19 +02:00
|
|
|
|
|
|
|
# assets
|
2022-11-05 00:39:39 +02:00
|
|
|
cp "${assets}/package.json" .
|
2022-11-13 13:58:57 +02:00
|
|
|
cp -r "${assets}/assets" ./assets
|
2022-11-05 00:39:39 +02:00
|
|
|
awk '/new compress/{f=1}!f{print}/}),/{f=0}' <"${assets}/webpack.config.js" >webpack.config.js
|
2022-11-05 00:21:11 +02:00
|
|
|
sed -E '/^#/d;s:^(FROM [^ ]+$):\1 AS assets:' "${assets}/Dockerfile" >>Dockerfile
|
2022-11-04 16:15:19 +02:00
|
|
|
|
|
|
|
# admin
|
2022-11-05 00:21:11 +02:00
|
|
|
sed -E '/^#/d;/^(COPY|EXPOSE|HEALTHCHECK|VOLUME|CMD) /d; s:^(.* )[^ ]*pybabel[^\\]*(.*):\1true \2:' "${admin}/Dockerfile" >>Dockerfile
|
2022-11-04 19:29:45 +02:00
|
|
|
|
2022-11-05 00:21:11 +02:00
|
|
|
# development
|
|
|
|
cat >>Dockerfile <<EOF
|
2022-11-04 16:15:19 +02:00
|
|
|
COPY --from=assets /work/static/ ./static/
|
|
|
|
|
|
|
|
RUN set -euxo pipefail \
|
2022-11-05 00:21:11 +02:00
|
|
|
; mkdir /data \
|
2022-11-04 16:15:19 +02:00
|
|
|
; ln -s /app/audit.py / \
|
|
|
|
; ln -s /app/start.py /
|
|
|
|
|
2022-11-05 00:21:11 +02:00
|
|
|
ENV \
|
2022-11-13 13:58:57 +02:00
|
|
|
FLASK_DEBUG="true" \
|
2022-11-05 00:21:11 +02:00
|
|
|
MEMORY_SESSIONS="true" \
|
|
|
|
RATELIMIT_STORAGE_URL="memory://" \
|
|
|
|
SESSION_COOKIE_SECURE="false" \
|
|
|
|
\
|
|
|
|
DEBUG="true" \
|
|
|
|
DEBUG_PROFILER="${DEV_PROFILER}" \
|
|
|
|
DEBUG_ASSETS="/app/static" \
|
2022-11-14 18:38:10 +02:00
|
|
|
DEBUG_TB_INTERCEPT_REDIRECTS=False \
|
2022-11-05 00:21:11 +02:00
|
|
|
\
|
2022-12-08 13:46:31 +02:00
|
|
|
ADMIN_ADDRESS="127.0.0.1" \
|
|
|
|
FRONT_ADDRESS="127.0.0.1" \
|
2022-11-05 00:21:11 +02:00
|
|
|
SMTP_ADDRESS="127.0.0.1" \
|
2022-12-08 13:46:31 +02:00
|
|
|
IMAP_ADDRESS="127.0.0.1" \
|
2022-11-05 00:21:11 +02:00
|
|
|
REDIS_ADDRESS="127.0.0.1" \
|
2022-12-08 13:46:31 +02:00
|
|
|
ANTIVIRUS_ADDRESS="127.0.0.1" \
|
|
|
|
ANTISPAM_ADDRESS="127.0.0.1" \
|
|
|
|
WEBMAIL_ADDRESS="127.0.0.1" \
|
|
|
|
WEBDAV_ADDRESS="127.0.0.1"
|
2022-11-05 00:21:11 +02:00
|
|
|
|
2022-11-13 13:58:57 +02:00
|
|
|
CMD ["/bin/bash", "-c", "flask db upgrade &>/dev/null && flask mailu admin '${DEV_ADMIN/@*}' '${DEV_ADMIN#*@}' '${DEV_PASSWORD}' --mode ifmissing >/dev/null; flask --debug run --host=0.0.0.0 --port=8080"]
|
2022-11-04 16:15:19 +02:00
|
|
|
EOF
|
|
|
|
|
|
|
|
# build
|
2022-11-05 00:21:11 +02:00
|
|
|
chmod -R u+rwX,go+rX .
|
2022-12-29 16:36:07 +02:00
|
|
|
echo Running: "${docker/*\/}" build --tag "${DEV_NAME}:latest" "${DEV_ARGS[@]}" .
|
|
|
|
"${docker}" build --tag "${DEV_NAME}:latest" "${DEV_ARGS[@]}" .
|
2022-11-05 00:21:11 +02:00
|
|
|
|
|
|
|
# gather volumes to map into container
|
|
|
|
volumes=()
|
|
|
|
|
2022-11-05 00:51:32 +02:00
|
|
|
[[ -n "${DEV_DB}" ]] && volumes+=( --volume "${DEV_DB}:/data/main.db" )
|
2022-11-04 16:15:19 +02:00
|
|
|
|
|
|
|
for vol in audit.py start.py mailu/ migrations/; do
|
2022-11-05 00:21:11 +02:00
|
|
|
volumes+=( --volume "${admin}/${vol}:/app/${vol}" )
|
2022-11-04 16:15:19 +02:00
|
|
|
done
|
|
|
|
|
2022-11-05 00:39:39 +02:00
|
|
|
for file in "${assets}/assets"/*; do
|
|
|
|
[[ ! -f "${file}" || "${file}" == */vendor.js ]] && continue
|
2022-11-05 00:21:11 +02:00
|
|
|
volumes+=( --volume "${file}:/app/static/${file/*\//}" )
|
2022-11-04 16:15:19 +02:00
|
|
|
done
|
|
|
|
|
2022-11-05 00:21:11 +02:00
|
|
|
# show configuration
|
|
|
|
cat <<EOF
|
|
|
|
|
|
|
|
=============================================================================
|
2022-12-29 16:36:07 +02:00
|
|
|
|
2022-11-05 00:51:32 +02:00
|
|
|
The "${DEV_NAME}" container was built using this configuration:
|
|
|
|
|
2022-11-05 00:21:11 +02:00
|
|
|
DEV_NAME="${DEV_NAME}"
|
|
|
|
DEV_DB="${DEV_DB}"
|
|
|
|
DEV_PROFILER="${DEV_PROFILER}"
|
|
|
|
DEV_LISTEN="${DEV_LISTEN}"
|
|
|
|
DEV_ADMIN="${DEV_ADMIN}"
|
|
|
|
DEV_PASSWORD="${DEV_PASSWORD}"
|
2022-12-29 16:36:07 +02:00
|
|
|
DEV_ARGS=( ${DEV_ARGS[*]} )
|
2022-11-05 00:21:11 +02:00
|
|
|
|
2022-11-05 00:51:32 +02:00
|
|
|
=============================================================================
|
2022-12-29 16:36:07 +02:00
|
|
|
|
|
|
|
You can start the container later using this command:
|
2022-11-05 00:51:32 +02:00
|
|
|
|
|
|
|
${docker/*\/} run --rm -it --name "${DEV_NAME}" --publish ${DEV_LISTEN}:8080$(printf " %q" "${volumes[@]}") "${DEV_NAME}"
|
2022-12-29 16:36:07 +02:00
|
|
|
|
2022-11-05 00:51:32 +02:00
|
|
|
=============================================================================
|
|
|
|
|
2022-12-29 16:36:07 +02:00
|
|
|
Enter the running container using this command:
|
|
|
|
${docker/*\/} exec -it "${DEV_NAME}" /bin/bash
|
|
|
|
|
2022-11-05 00:21:11 +02:00
|
|
|
=============================================================================
|
2022-12-29 16:36:07 +02:00
|
|
|
|
|
|
|
To update requirements-prod.txt you can build (and test) using:
|
|
|
|
${docker/*\/} build --tag "${DEV_NAME}:latest" --build-arg MAILU_DEPS=dev .
|
|
|
|
|
|
|
|
And then fetch the new dependencies with:
|
|
|
|
${docker/*\/} exec "${DEV_NAME}" pip freeze >$(realpath "${base}")/requirements-new.txt
|
|
|
|
|
|
|
|
=============================================================================
|
|
|
|
|
2022-11-05 00:21:11 +02:00
|
|
|
The Mailu UI can be found here: http://${DEV_LISTEN}/sso/login
|
|
|
|
EOF
|
|
|
|
[[ -z "${DEV_DB}" ]] && echo "You can log in with user ${DEV_ADMIN} and password ${DEV_PASSWORD}"
|
|
|
|
cat <<EOF
|
2022-12-29 16:36:07 +02:00
|
|
|
|
2022-11-05 00:21:11 +02:00
|
|
|
=============================================================================
|
|
|
|
|
|
|
|
Starting mailu dev environment...
|
|
|
|
EOF
|
|
|
|
|
|
|
|
# run
|
|
|
|
"${docker}" run --rm -it --name "${DEV_NAME}" --publish "${DEV_LISTEN}:8080" "${volumes[@]}" "${DEV_NAME}"
|
2022-11-04 16:15:19 +02:00
|
|
|
|