initial docker commit

This commit is contained in:
Xander Luedtke 2023-01-03 18:22:36 -07:00
parent 09bb1d4636
commit 252deefdcd
7 changed files with 459 additions and 0 deletions

8
docker/.env Normal file
View File

@ -0,0 +1,8 @@
# Set container timezone
TZ=America/Edmonton
# Used within the docker-compose.yml template to provide easy configuration for your domain.
ROOT_DOMAIN=itflow.org
# Generate a random password using `docker run php:8.0-apache openssl rand -base64 32`
ITFLOW_DB_PASS=thisisnotsecure

75
docker/Dockerfile Normal file
View File

@ -0,0 +1,75 @@
FROM ubuntu:22.04
LABEL dockerfile.version="v1.1" dockerfile.release-date="2023-01-03"
# Set up ENVs that will be utilized in compose file.
ENV TZ Etc/UTC
ENV ITFLOW_NAME ITFlow
ENV ITFLOW_URL demo.itflow.org
ENV ITFLOW_PORT 8080
ENV ITFLOW_REPO github.com/itflow-org/itflow
# apache2 log levels: emerg, alert, crit, error, warn, notice, info, debug
ENV ITFLOW_LOG_LEVEL warn
ENV ITFLOW_DB_HOST itflow-db
ENV ITFLOW_DB_PASS null
# Set timezone from TZ ENV
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# PREREQS: php php-intl php-mysqli php-imap php-curl libapache2-mod-php mariadb-server git -y
# Upgrade, then install prereqs.
RUN apt-get update && apt-get upgrade -y && apt-get clean
# ITFlow Requirements
RUN apt-get install -y \
git\
apache2\
php
# Ubuntu quality of life installs
RUN apt-get install -y \
vim\
cron\
dnsutils\
iputils-ping
# Install & enable php extensions
RUN apt-get install -y \
php-intl\
php-mysqli\
php-curl\
php-imap
RUN apt-get install -y \
libapache2-mod-php\
libapache2-mod-md
# Enable md apache mod
RUN a2enmod md
# Set the work dir to the git repo.
WORKDIR /var/www/html
# Entrypoint
# On every run of the docker file, perform an entrypoint that verifies the container is good to go.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/apache2/access.log && ln -sf /dev/stderr /var/log/apache2/error.log
ENTRYPOINT [ "entrypoint.sh" ]
# Expose the apache port
EXPOSE $ITFLOW_PORT
# Start the httpd service and have logs appear in stdout
CMD [ "apache2ctl", "-D", "FOREGROUND" ]

53
docker/README.md Normal file
View File

@ -0,0 +1,53 @@
# About this Image
> This is an unofficial image of [ITFlow](https://github.com/itflow-org/itflow) @ https://itflow.org.
> Maintained by [@lued](https://github.com/lued/itflow/tree/docker)
# Usage
## ITFlow Only (no Reverse Proxy)
1. Copy [docker-compose.yml](https://raw.githubusercontent.com/lued/itflow/docker/docker/docker-compose.yml) to a directory.
2. Within docker-compose.yml, adjust the ```environment:``` variables such as ITFLOW_NAME, ITFLOW_URL and ITFLOW_REPO (to your own MSPs fork).
3. Copy the [.env](https://raw.githubusercontent.com/lued/itflow/docker/docker/.env) file to the same directory.
> Enter your timezone, root domain and database password within this file. You can avoid this step entirely by adding the information to your docker-compose.yml file directly instead. Or being safe, by using docker secrets.
4. Run ```docker compose up -d```
5. Go to your domain. You should be redirected to setup.php. Enter server information correlated to your set up .env and docker-compose.yml files.
> Defaults: Username: itflow, Password: $ITFLOW_DB_PASS from .env, Database: itflow, Server: itflow-db
## Complete [Traefik](https://doc.traefik.io/traefik/getting-started/quick-start/) Solution (Reverse Proxy)
1. Copy the traefik [docker-compose.yml](https://raw.githubusercontent.com/lued/itflow/docker/docker/traefik-complete/docker-compose.yml) to a directory.
2. Within docker-compose.yml, adjust the ```environment:``` variables such as ITFLOW_NAME, ITFLOW_URL and ITFLOW_REPO (to your own MSPs fork).
3. Copy the [.env](https://raw.githubusercontent.com/lued/itflow/docker/docker/traefik-complete/.env) file to the same directory.
> Enter your docker path (/srv/docker, ., etc), cloudflare info, timezone, root domain and database password within this file.
4. Create your A records for your host.
5. Run ```docker compose up -d```
6. Verify you are getting certificates through LetsEncrypt. You will have two public URLs, traefik.$ROOT_DOMAIN and $ITFLOW_URL.
7. Go to your domain. You should be redirected to setup.php. Enter server information correlated to .env and docker-compose.yml
> Defaults: Username: itflow, Password: $ITFLOW_DB_PASS from .env, Database: itflow, Server: itflow-db
## Environment Variables
```
ENV TZ Etc/UTC
ENV ITFLOW_NAME ITFlow
ENV ITFLOW_REPO github.com/itflow-org/itflow
ENV ITFLOW_URL demo.itflow.org
ENV ITFLOW_PORT 8080
# apache2 log levels: emerg, alert, crit, error, warn, notice, info, debug
ENV ITFLOW_LOG_LEVEL warn
ENV ITFLOW_DB_HOST itflow-db
ENV ITFLOW_DB_PASS null
```
### In Beta
* I highly recommend putting your solution behind [Authelia](https://www.authelia.com/). If requested, I can supply more information on this topic.
* This project is still in early beta and is considered a **work in progress**. Many changes are being performed and may cause breakage upon updates.
* Currently, we strongly recommend against storing confidential information in ITFlow; ITFlow has not undergone a third-party security assessment.
* We are hoping to have a stable 1.0 release early this year.

59
docker/docker-compose.yml Normal file
View File

@ -0,0 +1,59 @@
version: "3.9"
########################### NETWORKS
networks:
wan:
name: wan
driver: bridge
itflow-db:
name: itflow-db
external: false
########################### VOLUMES
volumes:
itflow-db:
########################### ITFLOW
services:
itflow:
hostname: itflow
container_name: itflow
# Comment out build for docker.io image
image: lued/itflow
# build: .
restart: unless-stopped
depends_on:
- itflow-db
networks:
- wan
- itflow-db
ports:
- "80:8080"
environment:
- TZ=$TZ
- ITFLOW_NAME=ITFlow
- ITFLOW_URL=it.$ROOT_DOMAIN
- ITFLOW_PORT=8080
- ITFLOW_REPO=github.com/itflow-org/itflow
- ITFLOW_LOG_LEVEL=info
- ITFLOW_DB_HOST=itflow-db
- ITFLOW_DB_PASS=$ITFLOW_DB_PASS
volumes:
- ./itflow/:/var/www/html
itflow-db:
hostname: itflow-db
container_name: itflow-db
image: mariadb:10.6.11
restart: always
networks:
- itflow-db
environment:
- MARIADB_RANDOM_ROOT_PASSWORD=true
- MARIADB_DATABASE=itflow
- MARIADB_USER=itflow
- MARIADB_PASSWORD=$ITFLOW_DB_PASS
volumes:
- itflow-db:/var/lib/mysql/

57
docker/entrypoint.sh Normal file
View File

@ -0,0 +1,57 @@
#!/bin/bash
# Update the apache2 sites-available
echo "<Directory '/var/www/html'>
Order allow,deny
Allow from all
Require all granted
</Directory>
<VirtualHost *:$ITFLOW_PORT>
ServerName $ITFLOW_URL
DocumentRoot /var/www/html/
LogLevel $ITFLOW_LOG_LEVEL
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
</VirtualHost>" > /etc/apache2/sites-available/000-default.conf
sed -i "s/^Listen.*/Listen $ITFLOW_PORT/g" /etc/apache2/ports.conf
# if itflow is not downloaded, perform the download after the volume mounting process within dockerfile is complete.
if [[ -f /var/www/html/index.php ]]; then
cd /var/www/html
git fetch
else
git clone https://$ITFLOW_REPO /var/www/html
fi
git config --global --add safe.directory /var/www/html
# Verify permissions of itflow git repository
chown -R www-data:www-data /var/www/html
# This updates the config.php file once initialization through setup.php has completed
if [[ -f /var/www/html/config.php ]]; then
# Company Name
sed -i "s/\$config_app_name.*';/\$config_app_name = '$ITFLOW_NAME';/g" /var/www/html/config.php
# MariaDB Host
sed -i "s/\$dbhost.*';/\$dbhost = '$ITFLOW_DB_HOST';/g" /var/www/html/config.php
# Database Password
sed -i "s/\$dbpassword.*';/\$dbpassword = '$ITFLOW_DB_PASS';/g" /var/www/html/config.php
# Base URL
sed -i "s/\$config_base_url.*';/\$config_base_url = '$ITFLOW_URL';/g" /var/www/html/config.php
find /var/www/html -type d -exec chmod 775 {} \;
find /var/www/html -type f -exec chmod 664 {} \;
chmod 640 /var/www/html/config.php
else
chmod -R 777 /var/www/html
fi
# Enable the apache2 sites-available
service apache2 reload
service apache2 stop
# Execute the command in the dockerfile's CMD
exec "$@"

View File

@ -0,0 +1,18 @@
# Where you want your itflow git clone files to be stored on your host. For windows, let DOCKERDIR=.
DOCKERDIR=/srv/containers
# Cloudflare API information for traefik LetsEncrypt deployment
CLOUDFLARE_API_KEY=
CLOUDFLARE_EMAIL=
# Set container timezone
TZ=America/Edmonton
# Used within the docker-compose.yml template to provide easy configuration for your domain.
ROOT_DOMAIN=itflow.org
ITFLOW_URL=demo.$ROOT_DOMAIN
# Generate a random password using `docker run php:8.0-apache openssl rand -base64 32`
ITFLOW_DB_PASS=thisisnotsecure

View File

@ -0,0 +1,189 @@
version: "3.9"
########################### NETWORKS
networks:
wan:
name: wan
driver: bridge
dockersocket:
name: dockersocket
itflow-db:
name: itflow-db
external: false
########################### VOLUMES
volumes:
traefik-acme:
itflow-db:
########################### DOCKER / TRAEFIK
services:
traefik: # Reverse Proxy & Router
image: traefik
hostname: traefik
container_name: traefik
restart: unless-stopped
command:
- --global.sendAnonymousUsage=false
- --entryPoints.web.address=:80
- --entryPoints.websecure.address=:443
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
# Allow these IPs to set the X-Forwarded-* headers - Cloudflare IPs: https://www.cloudflare.com/ips/
- --entrypoints.websecure.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/12,172.64.0.0/13,131.0.72.0/22
- --api=true
- --log=true
- --log.level=DEBUG # DEBUG, INFO, WARN, ERROR, FATAL, PANIC
- --providers.docker
- --providers.docker.endpoint=tcp://docker_proxy:2375 #unix:///var/run/docker.sock
- --providers.docker.defaultrule=Host(`{{ index .Labels "com.docker.compose.service" }}`)
- --providers.docker.exposedByDefault=false
- --providers.docker.network=wan
- --providers.docker.swarmMode=false
# Test acme resolution through LetsEncrypt's acme-staging-v02 URL to avoid blacklisting your IP.
# When ready, uncomment the line below and comment out the "acme-staging-v02" URL and uncomment the "acme-v02" URL.
#- --certificatesResolvers.dns-cloudflare.acme.caServer=https://acme-v02.api.letsencrypt.org/directory
- --certificatesResolvers.dns-cloudflare.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory
- --certificatesResolvers.dns-cloudflare.acme.email=$CLOUDFLARE_EMAIL
- --certificatesResolvers.dns-cloudflare.acme.storage=/acme/acme.json
- --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.provider=cloudflare
- --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.resolvers=1.1.1.1:53,1.0.0.1:53
- --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.delayBeforeCheck=90
- --providers.file.directory=/dynamic-conf # Load dynamic configuration from one or more .toml or .yml files in a directory.
- --providers.file.watch=true # Only works on top level files in the rules folder
networks:
- wan
- dockersocket
security_opt:
- no-new-privileges:true
ports:
- 80:80
- 443:443
volumes:
- traefik-acme:/acme
- ${DOCKERDIR}/traefik:/dynamic-conf
environment:
- CF_API_EMAIL=$CLOUDFLARE_EMAIL
- CF_API_KEY=$CLOUDFLARE_API_KEY
- TZ=$TZ
labels:
- "traefik.enable=true"
# Middleware Rules
# # Basic Authentication - https://doc.traefik.io/traefik/middlewares/http/basicauth/
# - "traefik.http.middlewares.basic-auth.basicAuth.realm=Traefik Basic Authentication"
# - "traefik.http.middlewares.basic-auth.basicAuth.users=admin:$$2y$$05$$so1Qmqxf8H6iA19nmqQX1usVZblGrKBM9w3SDEqS1WmEiYUqF3mT2"
# # Rate Limit
- "traefik.http.middlewares.rate-limit.rateLimit.average=100"
- "traefik.http.middlewares.rate-limit.rateLimit.burst=50" # # Secure Headers
- "traefik.http.middlewares.secure-headers.headers.framedeny=false"
- "traefik.http.middlewares.secure-headers.headers.stsincludesubdomains=true"
- "traefik.http.middlewares.secure-headers.headers.stspreload=true"
- "traefik.http.middlewares.secure-headers.headers.forceSTSHeader=true"
- "traefik.http.middlewares.secure-headers.headers.contentTypeNosniff=true"
- "traefik.http.middlewares.secure-headers.headers.stsseconds=63072000"
- "traefik.http.middlewares.secure-headers.headers.browserXssFilter=true"
- "traefik.http.middlewares.secure-headers.headers.contenttypenosniff=true"
- "traefik.http.middlewares.secure-headers.headers.accesscontrolallowmethods=GET,POST,PUT,OPTIONS"
- "traefik.http.middlewares.secure-headers.headers.accesscontrolmaxage=100"
- "traefik.http.middlewares.secure-headers.headers.addvaryheader=true"
#- "traefik.http.middlewares.secure-headers.headers.contentsecuritypolicy=script-src 'self'"
- "traefik.http.middlewares.secure-headers.headers.referrerpolicy=origin-when-cross-origin"
#- "traefik.http.middlewares.secure-headers.headers.customResponseHeaders=none,noarchive,nosnippet,notranslate,noimageindex"
- "traefik.http.middlewares.secure-headers.headers.hostsProxyHeaders=X-Forwarded-Host"
# Middleware Chains
- "traefik.http.middlewares.chain-no-auth.chain.middlewares=rate-limit,secure-headers"
#- "traefik.http.middlewares.chain-basic-auth.chain.middlewares=rate-limit,secure-headers,basic-auth"
# Services - API
- "traefik.http.routers.traefik-rtr.service=api@internal"
# HTTP Routers
- "traefik.http.routers.traefik-rtr.entrypoints=websecure"
- "traefik.http.routers.traefik-rtr.rule=Host(`traefik.$ROOT_DOMAIN`)"
- "traefik.http.routers.traefik-rtr.tls=true"
# Setting TLS to $DOMAIN#
- "traefik.http.routers.traefik-rtr.tls.certResolver=dns-cloudflare"
- "traefik.http.routers.traefik-rtr.tls.domains[0].main=$ROOT_DOMAIN"
- "traefik.http.routers.traefik-rtr.tls.domains[0].sans=*.$ROOT_DOMAIN"
watchtower:
image: containrrr/watchtower
hostname: watchtower
container_name: watchtower
restart: unless-stopped
networks:
- dockersocket
environment:
DOCKER_HOST: tcp://docker_proxy:2375
docker_proxy:
image: tecnativa/docker-socket-proxy
hostname: docker_proxy
container_name: docker_proxy
restart: unless-stopped
networks:
- dockersocket
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
CONTAINERS: 1
NETWORKS: 1
SERVICES: 1
INFO: 1
IMAGES: 1
VOLUMES: 1
POST: 1
########################### ITFLOW
itflow:
hostname: itflow
container_name: itflow
image: lued/itflow
# build: ../.
restart: unless-stopped
depends_on:
- itflow-db
networks:
- wan
- itflow-db
environment:
- TZ=$TZ
- ITFLOW_NAME=ITFlow
- ITFLOW_URL=$ITFLOW_URL
- ITFLOW_PORT=8080
- ITFLOW_REPO=github.com/itflow-org/itflow
- ITFLOW_LOG_LEVEL=info
- ITFLOW_DB_HOST=itflow-db
- ITFLOW_DB_PASS=$ITFLOW_DB_PASS
volumes:
- ${DOCKERDIR}/itflow/:/var/www/html
labels:
- "traefik.enable=true"
## HTTP Routers
- "traefik.http.routers.itflow-rtr.entrypoints=websecure"
- "traefik.http.routers.itflow-rtr.tls=true"
- "traefik.http.routers.itflow-rtr.rule=Host(`$ITFLOW_URL`)"
## Middlewares
- "traefik.http.routers.itflow-rtr.middlewares=chain-no-auth@docker"
## HTTP Services
- "traefik.http.routers.itflow-rtr.service=itflow-svc"
- "traefik.http.services.itflow-svc.loadbalancer.server.port=8080"
itflow-db:
hostname: itflow-db
container_name: itflow-db
image: mariadb:10.6.11
restart: always
networks:
- itflow-db
environment:
- TZ=$TZ
- MARIADB_RANDOM_ROOT_PASSWORD=true
- MARIADB_DATABASE=itflow
- MARIADB_USER=itflow
- MARIADB_PASSWORD=$ITFLOW_DB_PASS
volumes:
- itflow-db:/var/lib/mysql/