feat(traefik): basic traefik setup

This commit is contained in:
Dan Anglin 2022-04-18 20:45:56 +01:00
parent 2d718c401c
commit 27605518e8
Signed by: dananglin
GPG key ID: 0C1D44CFBEE68638
9 changed files with 353 additions and 0 deletions

View file

@ -0,0 +1,55 @@
---
version: "3.8"
networks:
forge:
name: "forge-flow"
ipam:
driver: "default"
config:
- subnet: "${NETWORK_FORGE_FLOW_SUBNET}"
volumes:
traefik-shared:
name: "traefik-config-shared-volume"
services:
traefik:
container_name: "traefik-flow"
build:
args:
TRAEFIK_VERSION: "${TRAEFIK_VERSION}"
context: "./traefik"
networks:
forge:
ipv4_address: "${TRAEFIK_CONTAINER_IPV4_ADDRESS}"
ports:
- target: 80
published: 80
protocol: "tcp"
mode: "host"
- target: 443
published: 443
protocol: "tcp"
mode: "host"
- target: 22
published: ${TRAEFIK_EXTERNAL_SSH_PORT}
protocol: "tcp"
mode: "host"
restart: "always"
volumes:
- type: "volume"
source: "traefik-shared"
target: "${TRAEFIK_SHARED_MOUNT_POINT}"
- type: "bind"
source: "/etc/timezone"
target: "/etc/timezone"
read_only: true
- type: "bind"
source: "/etc/localtime"
target: "/etc/localtime"
read_only: true
# For TLS certificate
#- type: "bind"
# source: ""
# target: ""

103
files/scripts/bootstrap.sh Normal file
View file

@ -0,0 +1,103 @@
#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
function usage() {
echo "usage: $0 [options]"
echo "Bootstraps the flow instance"
echo ""
echo "-h,--help: print this help message"
echo "--network-forge-flow-subnet: The subnet for the forge flow docker network. (default: 172.20.0.0/24)"
echo "--traefik-container-ipv4-address: The IPv4 address of the traefik container. (default: 172.20.0.2)"
echo "--traefik-check-new-version: Set to true to enable automatic checks for new Traefik versions. (default: true)"
echo "--traefik-domain: The root domain of the traefik. (default: localhost)"
echo "--traefik-external-ssh-port: The external SSH port to expose for Gitea. (default: 22)"
}
while [[ $# -gt 0 ]]; do
arg="$1"
case $arg in
-h|--help)
usage
exit 0
;;
--network-forge-flow-subnet)
NETWORK_FORGE_FLOW_SUBNET=$2
shift
shift
;;
--traefik-container-ipv4-address)
TRAEFIK_CONTAINER_IPV4_ADDRESS=$2
shift
shift
;;
--traefik-check-new-version)
TRAEFIK_CHECK_NEW_VERSION=$2
shift
shift
;;
--traefik-domain)
TRAEFIK_DOMAIN=$2
shift
shift
;;
--traefik-external-ssh-port)
TRAEFIK_EXTERNAL_SSH_PORT=$2
shift
shift
;;
--traefik-log-level)
TRAEFIK_LOG_LEVEL=$2
shift
shift
;;
--traefik-send-anonymous-usage)
TRAEFIK_SEND_ANONYMOUS_USAGE=$2
shift
shift
;;
--traefik-version)
TRAEFIK_VERSION=$2
shift
shift
;;
*)
# unknown argument
shift
;;
esac
done
source /etc/flow/setup/env
DOCKER_ROOT="/home/${FLOW_USERNAME}/Docker/flow"
export NETWORK_FORGE_FLOW_SUBNET="${NETWORK_FORGE_FLOW_SUBNET:-172.20.0.0/24}"
export TRAEFIK_DOCKER_DIR="${DOCKER_ROOT}/traefik"
export TRAEFIK_CHECK_NEW_VERSION="${TRAEFIK_CHECK_NEW_VERSION:-true}"
export TRAEFIK_DOMAIN="${TRAEFIK_DOMAIN:-localhost}"
export TRAEFIK_EXTERNAL_SSH_PORT="${TRAEFIK_EXTERNAL_SSH_PORT:-22}"
export TRAEFIK_LOG_LEVEL="${TRAEFIK_LOG_LEVEL:-info}"
export TRAEFIK_SEND_ANONYMOUS_USAGE="${TRAEFIK_SEND_ANONYMOUS_USAGE:-false}"
export TRAEFIK_VERSION="${TRAEFIK_VERSION:-latest}"
export TRAEFIK_CONTAINER_IPV4_ADDRESS="${TRAEFIK_CONTAINER_IPV4_ADDRESS:-172.20.0.2}"
export TRAEFIK_SHARED_MOUNT_POINT="/flow/shared/traefik"
mkdir -p "${DOCKER_ROOT}"
envsubst < "${ROOT_SETUP_DIRECTORY}/template/compose/docker-compose.yaml" > "${DOCKER_ROOT}/docker-compose.yaml"
# Traefik setup section
mkdir -p "${TRAEFIK_DOCKER_DIR}"
cp "${ROOT_SETUP_DIRECTORY}/template/traefik/Dockerfile" "${TRAEFIK_DOCKER_DIR}/Dockerfile"
for i in $(find "${ROOT_SETUP_DIRECTORY}/template/traefik" -type f -mindepth 1 -not -name *Dockerfile); do
file=$(basename ${i})
envsubst < "${ROOT_SETUP_DIRECTORY}/template/traefik/${file}" > "${TRAEFIK_DOCKER_DIR}/${file}"
done
chown -R ${FLOW_USERNAME}:${FLOW_USERNAME} /home/${FLOW_USERNAME}/Docker
chmod -R a-rwx,u+rwX /home/${FLOW_USERNAME}/Docker
rc-service docker start

15
files/traefik/Dockerfile Normal file
View file

@ -0,0 +1,15 @@
ARG TRAEFIK_VERSION
FROM traefik:${TRAEFIK_VERSION}
ADD traefik.yaml /flow/traefik/
ADD entrypoint.sh /
ADD dynamic_dashboard.yaml /tmp/
RUN chmod +x /entrypoint.sh
EXPOSE 22 80 443
CMD ["--configfile=/flow/traefik/traefik.yaml"]

View file

@ -0,0 +1,9 @@
---
http:
routers:
dashboard:
entryPoints:
- "https"
rule: "Host(`${TRAEFIK_DOMAIN}`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
service: "api@internal"
tls: {}

View file

@ -0,0 +1,28 @@
#!/bin/sh
set -e
# Create the dynamic config directory in the shared volume.
mkdir -p ${TRAEFIK_SHARED_MOUNT_POINT}/dynamic
chgrp ${FLOW_GID} ${TRAEFIK_SHARED_MOUNT_POINT}/dynamic
chmod a-rwx,u+rwx,g+rwx ${TRAEFIK_SHARED_MOUNT_POINT}/dynamic
# Move the dashboard config to the new directory.
if [ -f /tmp/dynamic_dashboard.yaml ]; then
mv /tmp/dynamic_dashboard.yaml ${TRAEFIK_SHARED_MOUNT_POINT}/dynamic/dynamic_dashboard.yaml
fi
# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
set -- traefik "$@"
fi
# if our command is a valid Traefik subcommand, let's invoke it through Traefik instead
# (this allows for "docker run traefik version", etc)
if traefik "$1" --help >/dev/null 2>&1
then
set -- traefik "$@"
else
echo "= '$1' is not a Traefik command: assuming shell execution." 1>&2
fi
exec "$@"

View file

@ -0,0 +1,27 @@
---
global:
checkNewVersion: ${TRAEFIK_CHECK_NEW_VERSION}
sendAnonymousUsage: ${TRAEFIK_SEND_ANONYMOUS_USAGE}
api:
insecure: false
dashboard: true
debug: false
entryPoints:
http:
address: "${TRAEFIK_CONTAINER_IP}:80"
http:
redirections:
entryPoint:
to: "https"
scheme: "https"
permanent: true
https:
address: "${TRAEFIK_CONTAINER_IP}:443"
ssh:
address: "${TRAEFIK_CONTAINER_IP}:22"
providers:
file:
watch: true
directory: "${TRAEFIK_SHARED_MOUNT_POINT}/dynamic"
log:
level: "${TRAEFIK_LOG_LEVEL}"

58
images/lxd/image.pkr.json Normal file
View file

@ -0,0 +1,58 @@
{
"source": {
"lxd": {
"flow_infra": {
"container_name": "${var.lxd_container_name}",
"image": "${var.lxd_base_image}",
"publish_properties": {
"description": "LXD image for Flow Infra Dev"
},
"virtual_machine": false
}
}
},
"build": {
"source": {
"lxd.flow_infra": {
"name": "flow-infra",
"output_image": "${var.lxd_output_image_name}"
}
},
"provisioner": {
"shell": {
"inline": ["apk add bash"]
}
},
"provisioner": {
"shell": {
"environment_vars": [
"FLOW_USERNAME=${var.flow_username}",
"FLOW_GID=${var.flow_gid}",
"FLOW_UID=${var.flow_uid}",
"ROOT_SETUP_DIRECTORY=${var.root_setup_directory}"
],
"script": "${path.root}/../../provisioners/shell/setup.sh"
}
},
"provisioner": {
"file": {
"sources": [
"${path.root}/../../files/traefik/Dockerfile",
"${path.root}/../../files/traefik/dynamic_dashboard.yaml",
"${path.root}/../../files/traefik/entrypoint.sh",
"${path.root}/../../files/traefik/traefik.yaml"
],
"destination": "${var.root_setup_directory}/template/traefik/"
},
"file": {
"source": "${path.root}/../../files/compose/docker-compose.yaml",
"destination": "${var.root_setup_directory}/template/compose/"
},
"file": {
"source": "${path.root}/../../files/scripts/bootstrap.sh",
"destination": "${var.root_setup_directory}/bootstrap.sh"
}
}
}
}

View file

@ -0,0 +1,13 @@
{
"variables": {
"lxd_base_image": "images:alpine/3.15",
"lxd_container_name": "flow-infra-lxd-packer-builder",
"lxd_output_image_name": "flow-infra",
"flow_username": "flow",
"flow_gid": 22379,
"flow_uid": 22379,
"root_setup_directory": "/etc/flow/setup"
}
}

View file

@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -euo pipefail
DOCKER_COMPOSE_VERSION="v2.2.3"
DOCKER_COMPOSE_SOURCE="https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-linux-x86_64"
DOCKER_COMPOSE_DESTINATION="/home/${FLOW_USERNAME}/.docker/cli-plugins/docker-compose"
# Upgrade system and install required packages
apk update
apk upgrade
apk add curl \
docker \
gettext \
shadow \
tzdata
groupadd -g "${FLOW_GID}" "${FLOW_USERNAME}"
useradd -s /bin/bash -g "${FLOW_GID}" -u "${FLOW_UID}" -m -G docker "${FLOW_USERNAME}"
# Set the timezone and local time
mkdir -p /etc/zoneinfo/Europe
chmod -R 0755 /etc/zoneinfo
cp /usr/share/zoneinfo/Europe/London /etc/zoneinfo/Europe/
ln -fs /etc/zoneinfo/Europe/London /etc/localtime
echo "Europe/London" > /etc/timezone
apk del tzdata
mkdir -p \
"/home/${FLOW_USERNAME}/.docker/cli-plugins" \
"${ROOT_SETUP_DIRECTORY}/template/compose" \
"${ROOT_SETUP_DIRECTORY}/template/traefik" \
"${ROOT_SETUP_DIRECTORY}/template/gitea"
curl -SL "${DOCKER_COMPOSE_SOURCE}" -o "${DOCKER_COMPOSE_DESTINATION}"
chown "${FLOW_USERNAME}":"${FLOW_USERNAME}" "${DOCKER_COMPOSE_DESTINATION}"
chmod u+x "${DOCKER_COMPOSE_DESTINATION}"
cat <<EOF > ${ROOT_SETUP_DIRECTORY}/env
export FLOW_USERNAME=${FLOW_USERNAME}
export FLOW_GID=${FLOW_GID}
export ROOT_SETUP_DIRECTORY=${ROOT_SETUP_DIRECTORY}
EOF