Commit d4489b98 authored by T. Andrew Manning's avatar T. Andrew Manning
Browse files

Update Hubzilla and Traefik deployments

Update Hubzilla to latest sources, using parameterized docker-compose
files and environment variables to customize deployment. Update Traefik
to v2.
parent 64efffc9
docker-compose.yml
traefik.toml
hub.conf
FROM debian
ENV DEBIAN_FRONTEND noninteractive
ARG DOMAIN
ARG SMTP_EMAIL
ARG SMTP_SERVER
ARG SMTP_PORT
ARG SMTP_USER
ARG SMTP_PASS
ARG ADMIN_EMAIL
# Install packages
RUN apt-get update && apt-get install -y apache2 openssl php php-cli php-mysql php-curl php-fpm php-gd php-json php-xml php-zip php-mbstring software-properties-common git ssmtp mysql-client
# Remove APT files
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Generate self-signed SSL certificate
RUN openssl req -x509 -nodes -subj "/C=US/ST=Oregon/L=Portland/O=organization/OU=Org/CN=$DOMAIN" -newkey rsa:4096 -keyout /etc/ssl/private/$DOMAIN.key -out /etc/ssl/certs/$DOMAIN.crt -days 365
# Install and activate the apache config file
COPY src/container_apache.conf /etc/apache2/sites-available/$DOMAIN.conf
RUN sed -i "s/{{DOMAIN}}/$DOMAIN/g" /etc/apache2/sites-available/$DOMAIN.conf
RUN a2dissite 000-default default-ssl
RUN a2ensite $DOMAIN.conf
RUN a2enmod ssl rewrite
# Construct the hub web root from the official git repositories
RUN rm -r /var/www/html/
RUN git clone https://framagit.org/hubzilla/core.git /var/www/html/
RUN cd /var/www/html/ && util/add_addon_repo https://framagit.org/hubzilla/addons.git official
RUN mkdir -p "/var/www/html/store/[data]/smarty3" && \
chown -R www-data:www-data /var/www/html/
# Configure sSMTP for hub activity notification email delivery
COPY src/ssmtp.conf /etc/ssmtp/ssmtp.conf
COPY src/revaliases /etc/ssmtp/revaliases
RUN sed -i "s/{{SMTP_EMAIL}}/$SMTP_EMAIL/g" /etc/ssmtp/ssmtp.conf && \
sed -i "s/{{SMTP_SERVER}}/$SMTP_SERVER/g" /etc/ssmtp/ssmtp.conf && \
sed -i "s/{{SMTP_PORT}}/$SMTP_PORT/g" /etc/ssmtp/ssmtp.conf && \
sed -i "s/{{SMTP_PASS}}/$SMTP_PASS/g" /etc/ssmtp/ssmtp.conf && \
sed -i "s/{{SMTP_USER}}/$SMTP_USER/g" /etc/ssmtp/ssmtp.conf
RUN sed -i "s/{{SMTP_EMAIL}}/$SMTP_EMAIL/g" /etc/ssmtp/revaliases
RUN sed -i 's#\;sendmail_path =#sendmail_path = /usr/sbin/ssmtp -t#g' /etc/php/7.0/apache2/php.ini
# Generate the basic hub config file
COPY src/.htconfig.php /var/www/html/.htconfig.php
RUN LOCATION_HASH=$(cat /dev/urandom | tr -dc 'a-f0-9' | fold -w 64 | head -n 1) && \
sed -i "s/{{DOMAIN}}/$DOMAIN/g" /var/www/html/.htconfig.php && \
sed -i "s/{{LOCATION_HASH}}/$LOCATION_HASH/g" /var/www/html/.htconfig.php && \
sed -i "s/{{ADMIN_EMAIL}}/$ADMIN_EMAIL/g" /var/www/html/.htconfig.php
# TODO: Implement the cron job
#RUN echo "*/15 * * * * cd /var/www/html; /usr/bin/php Zotlabs/Daemon/Master.php Cron" | crontab -u www-data -
# Run the startup script when the container is launched
COPY src/start.sh /start.sh
CMD /bin/bash /start.sh
# Deploy Hubzilla with Docker
Deploy Hubzilla and Traefik using Docker Compose
=================================================
## Overview
Overview
-----------------------------------------------
Docker makes deploying a [Hubzilla](http://hubzilla.org) server, or "hub", as simple as it gets. Three Docker containers are created using the docker-compose system. One container runs [Traefik](http://traefik.io), which acts as a reverse proxy and an automatic installer for your hub's [LetsEncrypt](http://letsencrypt.org) SSL certificate. Another container runs the MySQL database. The third container runs the webserver and the Hubzilla instance.
Docker makes deploying a [Hubzilla](http://hubzilla.org) server, or "hub", as simple as it gets. Three Docker containers are created using the docker-compose system. One container runs [Traefik](http://traefik.io), which acts as a reverse proxy and an automatic installer for your hub's [LetsEncrypt](http://letsencrypt.org) SSL certificate.
## Requirements
The Hubzilla instance consists of a webserver running the Hubzilla source code and a container running the MySQL database.
All you need is a Linux host machine with [docker-compose](https://docs.docker.com/compose/) installed. It is recommended to run Docker as a non-root user, who is added to the `docker` group.
Requirements
-----------------------------------------------
## Instructions
You need a Linux host machine with [docker-compose](https://docs.docker.com/compose/) installed. It is recommended to run Docker as a non-root user, who is added to the `docker` group.
1. Clone this repository to a folder such as `/opt/hubzilla-docker/`.
Installation
-----------------------------------------------
1. Copy `hub.template.conf` to `hub.conf`.
```
cp conf/hub.template.conf conf/hub.conf
vi conf/hub.conf
```
Add the information about your SMTP server as well as the hub domain (`hub.example.com`) and the email address you want to use for the hub administrator account to `hub.conf`. The hub admin email will also be the email address used for the LetsEncrypt registration.
1. Clone this repo to some directory path we will reference as `$REPO`.
1. Copy `$REPO/hubzilla/sample.env` to `$REPO/hubzilla/.env` and customize for your server configuration.
1. Modify the `$REPO/traefik/traefik.yaml` config file with your own email address and any other customizations you wish to make.
1. Launch Traefik:
```
cd $REPO/traefik
docker-compose up -d
```
1. Launch Hubzilla:
```
cd $REPO/hubzilla
docker-compose up -d
```
1. In the same folder execute the `bootstrap.sh` script, which applies your information to construct the `docker-compose.yml` file and launches the `docker-compose up` command that build and runs the containers:
```
bash bootstrap.sh
```
In a few minutes your hub should be online with a valid TLS cert from LetsEncrypt.
1. Open `https://hub.example.com/register` in a browser and register the hub admin account using the same email you entered in `hub.conf`. Email verification is disabled at this stage for convenience, so you should immediately be redirected to the new channel page, where you can create your first channel.
Notes
-----------------------------------------------
* The self-signed TLS certificate generated in the Dockefile is only needed because Hubzilla will throw an error if it detects that it is running on HTTP, because there is no way to make it aware that it is behind a reverse-proxy like Traefik that is providing the TLS termination.
\ No newline at end of file
#!/usr/bin/env bash
source conf/hub.conf
cp src/docker-compose.template.yml docker-compose.yml
cp src/traefik.template.toml traefik.toml
sed -i "s/{{SMTP_EMAIL}}/$SMTP_EMAIL/g" docker-compose.yml
sed -i "s/{{SMTP_SERVER}}/$SMTP_SERVER/g" docker-compose.yml
sed -i "s/{{SMTP_PORT}}/$SMTP_PORT/g" docker-compose.yml
sed -i "s/{{SMTP_PASS}}/$SMTP_PASS/g" docker-compose.yml
sed -i "s/{{SMTP_USER}}/$SMTP_USER/g" docker-compose.yml
sed -i "s/{{HUB_DOMAIN}}/$HUB_DOMAIN/g" docker-compose.yml
sed -i "s/{{HUB_ADMIN_EMAIL}}/$HUB_ADMIN_EMAIL/g" docker-compose.yml
sed -i "s/{{HUB_DOMAIN}}/$HUB_DOMAIN/g" traefik.toml
sed -i "s/{{HUB_ADMIN_EMAIL}}/$HUB_ADMIN_EMAIL/g" traefik.toml
docker-compose up -d
SMTP_EMAIL=""
SMTP_SERVER=""
SMTP_PORT=587
SMTP_USER=""
SMTP_PASS=""
HUB_DOMAIN=""
HUB_ADMIN_EMAIL=""
FROM debian:buster
# Install packages
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
apt-get install -y \
software-properties-common \
apache2 \
openssl \
mariadb-client \
libapache2-mod-php \
php \
php-mysql \
php-cli \
php-curl \
php-fpm \
php-gd \
php-json \
php-xml \
php-zip \
php-mbstring \
msmtp \
git \
&& \
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \
php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" && \
php composer-setup.php --version=2.0.9 --install-dir=/usr/local/bin --filename=composer && \
php -r "unlink('composer-setup.php');"
RUN sed -i 's/AllowOverride None/AllowOverride All/g' /etc/apache2/apache2.conf
COPY src/ /opt/
RUN chmod -R a+r /opt/ && \
chmod +x /opt/start.sh
CMD ["/bin/bash", "-c", "/opt/start.sh"]
version: '3'
networks:
traefik_proxy:
external: true
internal:
external: false
services:
db:
image: mariadb:10
env_file: .env
networks:
- internal
restart: unless-stopped
volumes:
- ${VOLUME_PATH_DB}:/var/lib/mysql
www:
image: hubzilla:latest
build:
context: .
env_file: .env
restart: unless-stopped
volumes:
- ${VOLUME_PATH_WWW}:/var/www/html
- ${VOLUME_PATH_DB}:/var/lib/mysql
depends_on:
- db
networks:
- traefik_proxy
- internal
ports:
- 80
labels:
- "traefik.enable=true"
- "traefik.http.routers.hubzilla.rule=Host(`${DOMAIN}`)"
- "traefik.http.routers.hubzilla.entrypoints=web,websecure"
- "traefik.http.routers.hubzilla.tls.certresolver=leresolver"
- "traefik.docker.network=traefik_proxy"
\ No newline at end of file
# Server configuration
DOMAIN=yourdomain.example.com
SITE_NAME=Hubzilla
TIMEZONE=America/Chicago
# Volumes
# Specify the paths for the two persistent volumes that
# will be created for the server data and MySQL database files.
VOLUME_PATH_WWW=./data/www
VOLUME_PATH_DB=./data/db
# Database
# The MySQL username, database and passwords entered here are
# arbitrary and are used to create the database upon initialization.
MYSQL_DATABASE=hubzilla
MYSQL_USER=hubzilla
MYSQL_PASSWORD=p@55w0rd
MYSQL_ROOT_PASSWORD=p@55w0rdp@55w0rd
# Email configuration
ADMIN_EMAIL=admin@example.com
SMTP_EMAIL=admin@example.com
SMTP_SERVER=smtp.elasticemail.com
SMTP_PORT=2525
SMTP_USER=admin@example.com
SMTP_PASS=p@55w0rd
# Source repositories
SOURCE_URL_CORE=https://codeberg.org/hubzilla/hubzilla.git
SOURCE_URL_ADDONS=https://codeberg.org/hubzilla/hubzilla-addons.git
\ No newline at end of file
......@@ -5,9 +5,9 @@
$db_host = 'db';
$db_port = '0';
$db_user = 'hubzilla';
$db_pass = 'hubzilla';
$db_data = 'hubzilla';
$db_user = '{{MYSQL_USER}}';
$db_pass = '{{MYSQL_PASSWORD}}';
$db_data = '{{MYSQL_DATABASE}}';
$db_type = '0'; // an integer. 0 or unset for mysql, 1 for postgres
/*
......@@ -22,16 +22,17 @@ $db_type = '0'; // an integer. 0 or unset for mysql, 1 for postgres
*
*/
define('NOMADIC',1);
// Choose a legal default timezone. If you are unsure, use "America/Los_Angeles".
// It can be changed later and only applies to timestamps for anonymous viewers.
App::$config['system']['timezone'] = 'America/New_York';
App::$config['system']['timezone'] = '{{TIMEZONE}}';
// What is your site url? DO NOT ADD A TRAILING SLASH!
App::$config['system']['baseurl'] = 'https://{{DOMAIN}}';
App::$config['system']['sitename'] = "Hubzilla";
App::$config['system']['sitename'] = "{{SITE_NAME}}";
App::$config['system']['location_hash'] = '{{LOCATION_HASH}}';
// These lines set additional security headers to be sent with all responses
......@@ -109,3 +110,4 @@ App::$config['system']['theme'] = 'redbasic';
//ini_set('error_log','php.out');
//ini_set('log_errors','1');
//ini_set('display_errors', '0');
......@@ -18,3 +18,4 @@ SSLCertificateFile /etc/ssl/certs/{{DOMAIN}}.crt
SSLCertificateKeyFile /etc/ssl/private/{{DOMAIN}}.key
</VirtualHost>
account default
host {{SMTP_SERVER}}
port {{SMTP_PORT}}
tls on
tls_starttls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
tls_certcheck on
auth on
user {{SMTP_USER}}
password {{SMTP_PASS}}
from {{SMTP_EMAIL}}
logfile /var/log/msmtp.log
\ No newline at end of file
#!/bin/bash -e
if [[ -f /etc/ssl/certs/$DOMAIN.crt ]]; then
echo "Self-signed SSL certificate already generated."
else
echo "Generating self-signed SSL certificate..."
# Generate self-signed SSL certificate
openssl req -x509 -nodes -subj "/C=US/ST=Oregon/L=Portland/O=organization/OU=Org/CN=$DOMAIN" -newkey rsa:4096 -keyout /etc/ssl/private/$DOMAIN.key -out /etc/ssl/certs/$DOMAIN.crt -days 365
# Install and activate the apache config file
cp /opt/container_apache.conf /etc/apache2/sites-available/$DOMAIN.conf
sed -i "s/{{DOMAIN}}/$DOMAIN/g" /etc/apache2/sites-available/$DOMAIN.conf
a2dissite 000-default default-ssl
a2ensite $DOMAIN.conf
a2enmod ssl rewrite
fi
if [[ -f /etc/msmtprc ]]; then
echo "Email already configured."
else
echo "Configuring mSMTP email configuration..."
# Configure mSMTP for hub activity notification email delivery
cp /opt/msmtprc /etc/msmtprc
# cp /opt/revaliases /etc/ssmtp/revaliases
sed -i "s/{{SMTP_EMAIL}}/$SMTP_EMAIL/g" /etc/msmtprc && \
sed -i "s/{{SMTP_SERVER}}/$SMTP_SERVER/g" /etc/msmtprc && \
sed -i "s/{{SMTP_PORT}}/$SMTP_PORT/g" /etc/msmtprc && \
sed -i "s/{{SMTP_PASS}}/$SMTP_PASS/g" /etc/msmtprc && \
sed -i "s/{{SMTP_USER}}/$SMTP_USER/g" /etc/msmtprc
# sed -i "s/{{SMTP_EMAIL}}/$SMTP_EMAIL/g" /etc/ssmtp/revaliases
ls -la /etc/php/7.3/*
sed -i 's#\;sendmail_path =#sendmail_path = /usr/sbin/msmtp -t#g' /etc/php/7.3/apache2/php.ini
fi
if [[ -f /var/www/html/.htconfig.php ]]; then
echo "Hubzilla already installed"
else
echo "Installing Hubzilla..."
# Construct the hub web root from the official git repositories
git clone $SOURCE_URL_CORE /var/www/html/
cd /var/www/html/ && util/add_addon_repo $SOURCE_URL_ADDONS official
mkdir -p "/var/www/html/store/[data]/smarty3" && \
chown -R www-data:www-data /var/www/html/
# Generate the basic hub config file
cp /opt/.htconfig.php /var/www/html/.htconfig.php
LOCATION_HASH=$(cat /dev/urandom | tr -dc 'a-f0-9' | fold -w 64 | head -n 1) && \
sed -i "s/{{DOMAIN}}/$DOMAIN/g" /var/www/html/.htconfig.php && \
sed -i "s/{{SITE_NAME}}/$SITE_NAME/g" /var/www/html/.htconfig.php && \
sed -i "s#{{TIMEZONE}}#$TIMEZONE#g" /var/www/html/.htconfig.php && \
sed -i "s/{{LOCATION_HASH}}/$LOCATION_HASH/g" /var/www/html/.htconfig.php && \
sed -i "s/{{ADMIN_EMAIL}}/$ADMIN_EMAIL/g" /var/www/html/.htconfig.php
sed -i "s/{{MYSQL_USER}}/$MYSQL_USER/g" /var/www/html/.htconfig.php
sed -i "s/{{MYSQL_PASSWORD}}/$MYSQL_PASSWORD/g" /var/www/html/.htconfig.php
sed -i "s/{{MYSQL_DATABASE}}/$MYSQL_DATABASE/g" /var/www/html/.htconfig.php
fi
if [[ -f /var/lib/mysql/hubzilla/account.frm ]]; then
echo "Database already installed."
else
echo "Installing database..."
# Initialize the database tables
mysql \
--host="db" \
--user="${MYSQL_USER}" \
--password="${MYSQL_PASSWORD}" \
--database="${MYSQL_DATABASE}" \
< /var/www/html/install/schema_mysql.sql
fi
cd /var/www/html
util/udall
/usr/sbin/apache2ctl -D FOREGROUND
version: '2'
volumes:
db:
hubzilla:
networks:
web:
external: true
internal:
external: false
services:
traefik:
image: traefik:latest
restart: always
ports:
- 80:80
- 443:443
networks:
- web
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /opt/traefik/traefik.toml:/traefik.toml
- /opt/traefik/acme.json:/acme.json
container_name: traefik
db:
container_name: hubzilladb
environment:
MYSQL_ROOT_PASSWORD: "password"
MYSQL_DATABASE: "hubzilla"
MYSQL_USER: "hubzilla"
MYSQL_PASSWORD: "hubzilla"
image: mariadb
restart: always
volumes:
- db:/var/lib/mysql
networks:
- internal
app:
container_name: hubzilla
build:
context: .
dockerfile: Dockerfile
args:
DOMAIN: "{{HUB_DOMAIN}}"
SMTP_EMAIL: "{{SMTP_EMAIL}}"
SMTP_SERVER: "{{SMTP_SERVER}}"
SMTP_PORT: {{SMTP_PORT}}
SMTP_USER: "{{SMTP_USER}}"
SMTP_PASS: "{{SMTP_PASS}}"
ADMIN_EMAIL: "{{HUB_ADMIN_EMAIL}}"
image: hubzilla
restart: always
networks:
- web
- internal
volumes:
- hubzilla:/var/www/html
expose:
- "443"
depends_on:
- db
links:
- db
labels:
- "traefik.docker.network=web"
- "traefik.enable=true"
- "traefik.backend=app"
- "traefik.frontend.rule=Host:{{HUB_DOMAIN}}"
- "traefik.port=443"
- "traefik.protocol=https"
www-data:{{SMTP_EMAIL}}
Root={{SMTP_EMAIL}}
AuthUser={{SMTP_USER}}
AuthPass={{SMTP_PASS}}
Mailhub={{SMTP_SERVER}}:{{SMTP_PORT}}
FromLineOverride=YES
UseSTARTTLS=YES
UseTLS=YES
#!/usr/bin/env bash
if ls -l /var/lib/mysql/hubzilla/account.frm 2> /dev/null > /dev/null
then
echo "Database already installed."
else
echo "Installing database..."
# The pause for five seconds give the database container time to start. Database
# connection errors can occur if there is no delay.
sleep 5
# Initialize the database tables
mysql -h db -uhubzilla -phubzilla hubzilla < /var/www/html/install/schema_mysql.sql
fi
/usr/sbin/apache2ctl -D FOREGROUND
debug = false
logLevel = "ERROR"
defaultEntryPoints = ["https","http"]
InsecureSkipVerify = true
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[retry]
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "{{HUB_DOMAIN}}"
watch = true
exposedByDefault = false
[acme]
email = "{{HUB_ADMIN_EMAIL}}"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
[acme.httpChallenge]
entryPoint = "http"
version: '3'
networks:
traefik_proxy:
external: true
services:
traefik:
image: traefik:v2.2
container_name: "traefik"
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- .:/etc/traefik
networks:
- traefik_proxy
\ No newline at end of file
log:
level: "DEBUG"
log:
filePath: "/etc/traefik/traefik.log"
providers:
docker:
exposedByDefault: false
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
http:
tls:
certResolver: leresolver
certificatesResolvers:
leresolver:
acme:
email: you@example.com
storage: "/etc/traefik/acme.json"
httpChallenge:
entryPoint: web
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment