Skip to content

Commit

Permalink
Merge pull request #623 from bluecherrydvr/ci_actions
Browse files Browse the repository at this point in the history
Setup CI builds and push to docker hub
  • Loading branch information
curtishall authored Nov 24, 2023
2 parents 65c40e7 + 677c6ba commit 57376b4
Show file tree
Hide file tree
Showing 10 changed files with 507 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: 2
updates:
- package-ecosystem: docker
directory: "/"
schedule:
interval: daily
time: "11:00"
open-pull-requests-limit: 10
89 changes: 89 additions & 0 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: Publish Docker image
on:
push:
branches: [ "dev", "master" ]
pull_request:
branches: [ "dev", "master" ]
# Publish `v1.2.3` tags as releases.
tags:
- v*

# Run tests for any PRs.
# pull_request:

# steps:
# - uses: actions/checkout@v2
# Setup mysqlserver.
# See also https://docs.docker.com/docker-hub/builds/automated-testing/
jobs:
mysql57:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Shutdown existing MySQL
run: sudo service mysql stop


push_to_registries:
#- name: Push Docker image to multiple registries
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- name: Set up MySQL
uses: cweinberger/github-actions-mysql@main
with:
version: 5.7
hostPort: 3306
containerPort: 3306
rootPassword: root
user: TestUser
password: TestPassword
database: TestDatabase
characterSet: utf8mb4
collation: utf8mb4_general_ci
sqlMode: NO_ENGINE_SUBSTITUTION

- name: Print running docker containers
run: docker ps
- name: Check out the repo
uses: actions/checkout@v3
- name: Get branch name
run: echo "BRANCH=${GITHUB_REF##*/}" >> $GITHUB_ENV
- name: Identify git repo path
run: ls $GITHUB_WORKSPACE && ls -l /home/runner/work/
- name: Wait for mysql
run: sleep 15
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Log in to Docker Hub
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
# username: curtishall
# password: ${{ secrets.DOCKER_PASSWORD }}
# - name: Extract metadata (tags, labels) for Docker
# id: meta
# uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
# with:
# images: bluecherrydvr/bluecherry

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: bluecherrydvr/bluecherry

- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
#working-directory: server/
context: "{{defaultContext}}:actions"
# username: curtishall
# password: ${{ secrets.DOCKER_PASSWORD }}
# file: ./server/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
216 changes: 216 additions & 0 deletions actions/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
# set a base image with environment to build from
FROM ubuntu:20.04 AS baseos

ARG BLUECHERRY_GIT_BRANCH_TAG=master

# ---------------------------------------------------------------------------
# Build the base OS with some development libs and tools
FROM baseos AS os_dev_environment
ENV DEBIAN_FRONTEND=noninteractive
WORKDIR /root

RUN apt-get update

RUN apt-get install --no-install-recommends -y \
git sudo openssl ca-certificates wget gnupg gnupg2 gnupg1 \
ssl-cert nmap curl sysstat iproute2 \
autoconf automake libtool build-essential gcc g++ \
debhelper ccache bison flex texinfo yasm cmake

RUN apt-get install --no-install-recommends -y \
libbsd-dev libopencv-dev libudev-dev libva-dev \
linux-image-generic linux-headers-generic \
libmysqlclient-dev rsyslog

# ---------------------------------------------------------------------------
FROM os_dev_environment as bluecherry_base_environment
ENV DEBIAN_FRONTEND=noninteractive
WORKDIR /root

# RUN git clone --recurse-submodules --progress --depth 1 \
RUN git clone --recurse-submodules --progress http://github.com/bluecherrydvr/bluecherry-apps.git \
&& cd bluecherry-apps \
&& git checkout $BLUECHERRY_GIT_BRANCH_TAG \
&& sed -i 's/#define PRODUCT_VERSION "3.1.0-rc9"/#define PRODUCT_VERSION "3.1.0-rc9-docker"/' server/v3license_processor.h


RUN apt-get --no-install-recommends -y install \
libbsd0 libc6 libgcc1 libssl1.1 libstdc++6 libudev1 \
zlib1g ucf mkvtoolnix v4l-utils vainfo i965-va-driver

RUN apt-get --no-install-recommends -y install \
php-mail php-mail-mime php-net-smtp php-gd php-curl \
php-mysql php-sqlite3 \
apache2 libapache2-mod-php mysql-client sqlite3

# ---------------------------------------------------------------------------
# Build the bluecherry app and dependencies. This is done in a separate
# image because there are many ways it can fail and then we save time
# by being able to reuse prior containers leading up to this build.
FROM bluecherry_base_environment as bluecherry_build
ENV DEBIAN_FRONTEND=noninteractive
WORKDIR /root

COPY depends/onvif_tool bluecherry-apps/utils/onvif_tool

RUN cd bluecherry-apps \
&& ./scripts/build_pkg_native.sh


# ---------------------------------------------------------------------------
FROM bluecherry_build as bluecherry_build_cleaned
ENV DEBIAN_FRONTEND=noninteractive
WORKDIR /root

RUN rm -rf /usr/src/linux-headers-*

RUN rm -rf .ccache \
&& rm -rf bluecherry-apps/.git \
&& rm -rf bluecherry-apps/misc/libav \
&& rm -rf bluecherry-apps/misc/libconfig \
&& rm -rf bluecherry-apps/misc/pugixml


# ---------------------------------------------------------------------------
# Install the bluecherry app and dependencies
FROM baseos as bluecherry_install
ENV DEBIAN_FRONTEND=noninteractive
WORKDIR /root

COPY --from=bluecherry_build_cleaned \
/root/bluecherry-apps/releases/bluecherry_*.deb \
/root/bluecherry-apps/releases/

RUN ls -l /root/bluecherry-apps/releases/

# This step is needed if/when building a new bluecherry docker container
# that will connect to an existing bluecherry database. In this case, the
# bluecherry installer will see the existing database, and it needs the
# /etc/bluecherry.conf file to tell it that it is okay to connect to (and
# modify) that database
#
#COPY bluecherry.conf /etc/bluecherry.conf

ARG MYSQL_ADMIN_LOGIN=root
ARG MYSQL_ADMIN_PASSWORD=root

# Specific database credentials used by bluecherry server
ARG BLUECHERRY_DB_USER=bluecherry
ARG BLUECHERRY_DB_HOST=172.17.0.1
ARG BLUECHERRY_DB_PASSWORD=bluecherry
ARG BLUECHERRY_DB_NAME=bluecherry
ARG BLUECHERRY_DB_ACCESS_HOST=%

# User and Group info used for running bluecherry server processes
ARG BLUECHERRY_LINUX_GROUP_NAME=bluecherry
ARG BLUECHERRY_LINUX_GROUP_ID=1000
ARG BLUECHERRY_LINUX_USER_NAME=bluecherry
ARG BLUECHERRY_LINUX_USER_ID=1000

RUN apt-get update \
&& apt-get install -y \
rsyslog nmap curl sysstat iproute2 \
openssl ca-certificates ssl-cert gnupg gnupg2 gnupg1 sudo mysql-client python3-pip wget curl nano cron

RUN { \
echo "[client]"; \
echo "user=$MYSQL_ADMIN_LOGIN"; \
echo "password=$MYSQL_ADMIN_PASSWORD"; \
echo "[mysql]"; \
echo "user=$MYSQL_ADMIN_LOGIN"; \
echo "password=$MYSQL_ADMIN_PASSWORD"; \
echo "[mysqldump]"; \
echo "user=$MYSQL_ADMIN_LOGIN"; \
echo "password=$MYSQL_ADMIN_PASSWORD"; \
echo "[mysqldiff]"; \
echo "user=$MYSQL_ADMIN_LOGIN"; \
echo "password=$MYSQL_ADMIN_PASSWORD"; \
} > /root/.my.cnf

# NOTE: The line "export host=$BLUECHERRY_DB_HOST" ... This is required
# due to a weird global check of this env var by the "check_mysql_admin"
# function in /usr/share/bluecherry/bc_db_tool.sh ... which doesn't accept
# the db host as an argument like most of the other functions in that file.
# --- The Specific problem line is:
# if ! echo "show databases" | mysql_wrapper -h"${host}" -u"$MYSQL_ADMIN_LOGIN" &>/dev/null
#
RUN { \
echo bluecherry bluecherry/mysql_admin_login string $MYSQL_ADMIN_LOGIN; \
echo bluecherry bluecherry/mysql_admin_password password $MYSQL_ADMIN_PASSWORD; \
echo bluecherry bluecherry/db_host string $BLUECHERRY_DB_HOST; \
echo bluecherry bluecherry/db_userhost string $BLUECHERRY_DB_ACCESS_HOST; \
echo bluecherry bluecherry/db_name string $BLUECHERRY_DB_NAME; \
echo bluecherry bluecherry/db_user string $BLUECHERRY_DB_USER; \
echo bluecherry bluecherry/db_password password $BLUECHERRY_DB_PASSWORD; \
} | debconf-set-selections \
&& export host=$BLUECHERRY_DB_HOST \
&& apt install -y --no-install-recommends ./bluecherry-apps/releases/bluecherry_*.deb

# Cleanup tasks
RUN apt-get clean \
# && rm -f bluecherry-apps/releases/bluecherry_*.deb \
&& rm -rf /var/lib/apt/lists/*

# Remove these files -- we needed them to build the docker image, since the
# bluecherry installer scripts interact with the database. However, once the
# image is created, we expect it to receive all of the settings/credentials
# from environment variables passed in by docker or docker-compose.
RUN rm -f /root/.my.cnf \
&& rm -f /etc/bluecherry.conf

# When running rsyslog in a container, we need to disable imklog
# since the in-container process won't be allowed access to it.
RUN sed -i '/imklog/s/^/#/' /etc/rsyslog.conf

RUN /usr/sbin/groupadd -rf \
--gid=$BLUECHERRY_LINUX_GROUP_ID \
$BLUECHERRY_LINUX_GROUP_NAME \
&& /usr/sbin/useradd -rm \
--comment "Bluecherry DVR" \
--home-dir=/var/lib/bluecherry \
--gid=$BLUECHERRY_LINUX_GROUP_NAME \
--groups=audio,video \
--uid=$BLUECHERRY_LINUX_USER_ID \
$BLUECHERRY_LINUX_USER_NAME \
|| echo "bluecherry user already exists"

RUN mkdir /recordings \
&& chown bluecherry:bluecherry /recordings

EXPOSE 7001/tcp 7002/tcp

# This is the main script that runs as process ID 1 in the docker container
COPY entrypoint.sh /entrypoint.sh

# These scripts are wrappers used to manage the bluecherry database. They are
# necessary because the bluecherry installer usually sets up the database, but
# with a pre-built docker image the installer isn't run (so these actions have
# to be done manually as needed from the docker container... example usage
# from the docker host looks like:
#
# --- CREATE: sudo docker-compose run bluecherry bc-database-create
# --- UPGRADE: sudo docker-compose run bluecherry bc-database-upgrade
COPY bc-database-create.sh /bin/bc-database-create
COPY bc-database-upgrade.sh /bin/bc-database-upgrade

# This copies in a modified rsyslog config, which tells rsyslog to route
# bluecherry logs to both /var/log/bluecherry.log (within the container) and
# also to the STDOUT of container process with PID 1, which then allows the
# logs to be received by the docker engine (and read via `docker logs` , etc.)
COPY bc-rsyslog.conf /etc/rsyslog.d/10-bluecherry.conf

# Make the previously copied scripts executable
RUN chmod +x /entrypoint.sh \
&& chmod +x /bin/bc-database-create \
&& chmod +x /bin/bc-database-upgrade

# Delete the default nginx config, we don't need it.
RUN rm /etc/nginx/sites-enabled/default

RUN chown bluecherry.bluecherry -R /var/lib/bluecherry
#CMD rm -f /var/run/rsyslogd.pid
#CMD ["/usr/sbin/rsyslogd", "-n", "-f", "/etc/rsyslog.conf"]
#CMD service rsyslog start
CMD /usr/sbin/php-fpm7.4 -D
CMD ["/usr/sbin/nginx", "-g", "daemon off;"]
CMD "/entrypoint.sh"
15 changes: 15 additions & 0 deletions actions/bc-database-create.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

set -e

# Create a new bluecherry server database, following the same procedure used
# by bluecherry's "official" script from bluecherry-apps:misc/postinstall.sh
# but using environment variables as injected from docker or docker-compose.

/usr/share/bluecherry/bc_db_tool.sh new_db \
"$MYSQL_ADMIN_LOGIN" "$MYSQL_ADMIN_PASSWORD" \
"$BLUECHERRY_DB_NAME" "$BLUECHERRY_DB_USER" "$BLUECHERRY_DB_PASSWORD" \
"$BLUECHERRY_DB_HOST" "$BLUECHERRY_USERHOST" \
|| exit 1

exit 0
36 changes: 36 additions & 0 deletions actions/bc-database-upgrade.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/bin/bash

set -e

if ! echo 'exit' | mysql -h "$BLUECHERRY_DB_HOST" -D"$BLUECHERRY_DB_NAME" \
-u"$BLUECHERRY_DB_USER" -p"$BLUECHERRY_DB_PASSWORD"
then
echo "Can't connect mysql with credentials in /etc/bluecherry.conf"
echo "Please remove config or fix config"
exit 1
fi

DB_BACKUP_GZ_FILE=$(mktemp ~bluecherry/bc_db_backup.XXXXXXXXXX.sql.gz)
echo "Going to updgrade Bluecherry DB. Taking a backup into $DB_BACKUP_GZ_FILE just in case" >&2

# Backup the DB
mysqldump -h "$BLUECHERRY_DB_HOST" "$BLUECHERRY_DB_NAME" -u"$BLUECHERRY_DB_USER" \
-p"$BLUECHERRY_DB_PASSWORD" | gzip -c > $DB_BACKUP_GZ_FILE

if ! /usr/share/bluecherry/bc_db_tool.sh upgrade_db \
"$BLUECHERRY_DB_NAME" "$BLUECHERRY_DB_USER" \
"$BLUECHERRY_DB_PASSWORD" "$BLUECHERRY_DB_HOST"
then
echo Failed upgrade database, restoring backup
restore_mysql_backup "$BLUECHERRY_DB_NAME" "$BLUECHERRY_DB_USER" \
"$BLUECHERRY_DB_PASSWORD" "$BLUECHERRY_DB_HOST"
exit 1
fi

# database successfully upgraded
if [[ -f "$DB_BACKUP_GZ_FILE" ]]
then
rm -f "$DB_BACKUP_GZ_FILE"
fi

exit 0
9 changes: 9 additions & 0 deletions actions/bc-rsyslog.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Save all messages from the bluecherry apps to this log file

$FileGroup bluecherry

:programname,isequal,"bc-server" -/var/log/bluecherry.log
:programname,isequal,"bc-server" -/proc/self/fd/1
:programname,isequal,"bc-server" ~

$FileGroup adm
1 change: 1 addition & 0 deletions actions/depends/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
## This is a binary file built for Ubuntu 20.04.
Binary file added actions/depends/onvif_tool
Binary file not shown.
Loading

0 comments on commit 57376b4

Please sign in to comment.