Browse Source

gitea build

feature/startup-from-labels
root 5 years ago
parent
commit
ef5b9ce59b
  1. 22
      bin/pdm-build
  2. 7
      bin/pdm-launch
  3. 0
      bin/shflags
  4. 4
      src/debian/Containerfile
  5. 94
      src/gitea/Containerfile
  6. 14
      src/gitea/Systemdfile
  7. 2
      src/gitea/bugfix/cronfix
  8. 69
      src/gitea/resources/app.ini.esh
  9. 2
      src/gitea/resources/bin/db-dump
  10. 3
      src/gitea/resources/bin/db-load
  11. 12
      src/gitea/resources/bin/db-make
  12. 366
      src/gitea/resources/bin/esh
  13. 41
      src/gitea/resources/bin/maint
  14. 5
      src/gitea/resources/crontab
  15. 33
      src/gitea/resources/gitea.service
  16. 1
      src/gitea/resources/pg_hba.conf
  17. 39
      src/nextcloud/Containerfile
  18. 2
      src/nextcloud/bugfix/cronfix
  19. 21
      src/nextcloud/resources/bin/maint
  20. 7
      src/nextcloud/resources/crontab

22
bin/pdm-build

@ -4,19 +4,17 @@
quit() {
if [[ $1 == 0 || $FLAGS_debug == $FLAGS_FALSE ]]; then
podman rm -i -f tmp-$epoch 2>&1 > /dev/null
podman rmi tmp:$epoch 2>&1 > /dev/null
fi
exit $1
}
libdir=/tank/local/podman/lib
today=$(date "+%Y-%m-%d-T%H%M")
epoch=$(date "+%s.%3N")
epoch=$(date +%s.%3N)
today=$(date +%Y-%m-%d-T%H%M)
# Handle flags
source $libdir/shflags
source shflags
DEFINE_boolean 'squash' false 'squash newly built layers into a single new layer' 's'
DEFINE_boolean 'debug' false "Don't delete temporary image/container on build fail" 'd'
DEFINE_boolean 'debug' false "Don't delete temporary container on build fail" 'd'
DEFINE_string 'tag' 'latest' 'Tag (other than date) to assign to the image' 't'
FLAGS_HELP="Usage: $0 [-s] [-d] [-t tag] [directory] [name]
@ -57,21 +55,21 @@ else
name=$(basename $(pwd))
fi
# build options
buildopts=""
if [[ $FLAGS_squash == $FLAGS_TRUE ]]; then
buildopts="--squash"
else
buildopts=""
buildopts="$buildopts --squash"
fi
# Main
# build image
echo "Building container ..."
podman build -f Containerfile -t tmp:$epoch $buildopts || quit $?
echo "Building image ..."
podman build -f Containerfile -t tmp $buildopts || quit $?
# start container
echo "Creating container ..."
podman create --name tmp-$epoch tmp:$epoch || quit $?
podman create --name tmp-$epoch tmp || quit $?
podman start tmp-$epoch || quit $?
# Systemdfile is for commands that need systemd to execute
echo "Running build steps that require systemd ..."

7
bin/pdm-launch

@ -1,12 +1,7 @@
#!/bin/bash
# potential flags: deploy config other than default, overwrite
# Variables
libdir=/tank/local/podman/lib
# Handle flags
source $libdir/shflags
source shflags
DEFINE_boolean 'overwrite' false 'Overwrite container if one with same name already exists.' 'o'
DEFINE_boolean 'config' false "Automatically configure container with deploy options stored in image metadata." 'c'
DEFINE_string 'deployopts' 'deployopts' 'Image metadata label from which to get the deploy options.' 'd'

0
lib/shflags → bin/shflags

4
src/debian/Containerfile

@ -2,6 +2,8 @@ FROM debian:stable
CMD [ "/sbin/init" ]
ENTRYPOINT [ "/sbin/init" ]
WORKDIR /root/
# We can't use timedatectl because systemd isn't available
# during the build process, so we have to set the timezone manually
ENV TZ=US/Central
@ -12,7 +14,7 @@ RUN rm /etc/localtime && \
# Install packages
RUN apt update -y
RUN apt upgrade -y
RUN apt install -y init sudo wget nano less man-db
RUN apt install -y init sudo wget nano less man-db unzip
RUN apt autoremove -y --purge
RUN apt clean -y

94
src/gitea/Containerfile

@ -0,0 +1,94 @@
###
### Build Variables
###
FROM localhost/debian:latest
# deploy options
# -p (port) and -v (volume) both go host:container
LABEL deployopts="\
-p 9081:80 \
-p 9022:22 \
-v /tank/files/git:/vol/git \
-v /tank/files/db/gitea:/vol/db"
# make sure mount directories exist
RUN mkdir -p /vol/git /vol/db
# version of postgres
ARG psqlv=11
# uid that the files owner user should have
ARG FILESUID=5000
# Container Variables
# database name and user
ENV DBUSER=gtadmin
ENV DBNAME=gitea
# put environment variables in /etc/environment so we can access them from cron scripts
RUN echo "DBUSER=$DBUSER" >> /etc/environment && \
echo "DBNAME=$DBNAME" >> /etc/environment
###
### General Setup
###
# install packages we want
RUN apt update -y && apt install -y postgresql postgresql-doc git
# create gitea user with file owner UID
RUN addgroup --gid $FILESUID gitea && \
adduser gitea --ingroup gitea --uid $FILESUID --disabled-password --gecos "Gitea Server" --shell /usr/sbin/nologin
# copy our custom scripts
COPY resources/bin/ /usr/local/bin/
###
### PostgreSQL ###
###
# configure PostgreSQL access
COPY --chown=postgres:postgres resources/pg_hba.conf /etc/postgresql/${psqlv}/main/pg_hba.conf
###
### Gitea
###
# dowload gitea
RUN wget https://dl.gitea.io/gitea/master/gitea-master-linux-amd64 && \
mv gitea-master-linux-amd64 /usr/local/bin/gitea && \
chmod +x /usr/local/bin/gitea
# make directories gitea needs
RUN mkdir -p /var/lib/gitea/ && \
cd /var/lib/gitea/ && \
mkdir custom data log && \
chown -R gitea:gitea /var/lib/gitea/ && \
chmod -R 750 /var/lib/gitea/
# copy gitea config template
COPY resources/app.ini.esh /etc/gitea/
# template config file
RUN cd /etc/gitea/ && \
esh app.ini.esh > app.ini && \
rm app.ini.esh && \
chmod -R +r /etc/gitea/
COPY resources/gitea.service /etc/systemd/system/
###
### Crontab
###
COPY resources/crontab /root/
RUN crontab -u gitea /root/crontab
###
### Systemdfile
###
COPY Systemdfile /root/
RUN chmod +x /root/Systemdfile
###
### Bugfix
###
# execute command to workaround bug in cron
COPY bugfix/cronfix /root/
RUN chmod +x /root/cronfix && /root/cronfix

14
src/gitea/Systemdfile

@ -0,0 +1,14 @@
#!/bin/bash
# fail if any command returns error
set -e
set -x
# wait 5 seconds to make sure all services have finished starting up
sleep 5
# make database for gitea
db-make
# enable and start gitea
systemctl enable gitea
systemctl start gitea

2
src/gitea/bugfix/cronfix

@ -0,0 +1,2 @@
#!/bin/sh
sed -i '/session required pam_loginuid.so/c\#session required pam_loginuid.so' /etc/pam.d/cron

69
src/gitea/resources/app.ini.esh

@ -0,0 +1,69 @@
APP_NAME = Gitea: Git with a cup of tea
RUN_USER = gitea
RUN_MODE = prod
[oauth2]
JWT_SECRET = <%= $(gitea generate secret JWT_SECRET) %>
[security]
INTERNAL_TOKEN = <%= $(gitea generate secret INTERNAL_TOKEN) %>
INSTALL_LOCK = true
SECRET_KEY = <%= $(gitea generate secret SECRET_KEY) %>
; disable password complexity checks
PASSWORD_COMPLEXITY = off
[database]
DB_TYPE = postgres
HOST = /var/run/postgresql
NAME = gitea
USER = gtadmin
PASSWD =
SSL_MODE = disable
CHARSET = utf8
PATH = /var/lib/gitea/data/gitea.db
[repository]
ROOT = /vol/git/repos
[server]
DOMAIN = medusa.alemor.org
ROOT_URL = http://medusa.casa.alemor.org/git/
HTTP_PORT = 80
START_SSH_SERVER = true
SSH_PORT = 9022
SSH_LISTEN_PORT = 22
LFS_START_SERVER = trxue
LFS_CONTENT_PATH = /vol/git/lfs
LFS_JWT_SECRET = <%= $(gitea generate secret JWT_SECRET) %>
OFFLINE_MODE = true
[mailer]
ENABLED = false
[service]
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL = false
DISABLE_REGISTRATION = true
ALLOW_ONLY_EXTERNAL_REGISTRATION = false
ENABLE_CAPTCHA = false
REQUIRE_SIGNIN_VIEW = false
DEFAULT_KEEP_EMAIL_PRIVATE = false
DEFAULT_ALLOW_CREATE_ORGANIZATION = false
DEFAULT_ENABLE_TIMETRACKING = true
NO_REPLY_ADDRESS = noreply.localhost
[picture]
DISABLE_GRAVATAR = true
ENABLE_FEDERATED_AVATAR = false
[openid]
ENABLE_OPENID_SIGNIN = true
ENABLE_OPENID_SIGNUP = false
[session]
PROVIDER = file
[log]
MODE = file
LEVEL = info
ROOT_PATH = /var/lib/gitea/log

2
src/gitea/resources/bin/db-dump

@ -0,0 +1,2 @@
#!/bin/bash
pg_dump -O -U $DBUSER -d $DBNAME -f $1

3
src/gitea/resources/bin/db-load

@ -0,0 +1,3 @@
#!/bin/bash
db-make
psql -U $DBUSER -d $DBNAME -f $1

12
src/gitea/resources/bin/db-make

@ -0,0 +1,12 @@
#!/bin/bash
cmd() {
sudo -u postgres psql -c "$1"
}
cd /var/lib/postgresql
cmd "DROP DATABASE IF EXISTS $DBNAME;"
cmd "DROP USER IF EXISTS $DBUSER;"
cmd "CREATE USER $DBUSER;"
cmd "CREATE DATABASE $DBNAME WITH TEMPLATE template0 ENCODING UTF8 LC_COLLATE 'C.UTF-8' LC_CTYPE 'C.UTF-8';"
cmd "GRANT ALL PRIVILEGES ON DATABASE $DBNAME TO $DBUSER;"

366
src/gitea/resources/bin/esh

@ -0,0 +1,366 @@
#!/bin/sh
# vim: set ts=4:
#---help---
# USAGE:
# esh [options] [--] <input> [<variable>...]
# esh <-h | -V>
#
# Process and evaluate an ESH template.
#
# ARGUMENTS:
# <input> Path of the template file or "-" to read from STDIN.
# <variable> Variable(s) specified as <name>=<value> to pass into the
# template (the have higher priority than environment
# variables).
#
# OPTIONS:
# -d Don't evaluate template, just dump a shell script.
# -o <file> Output file or "-" for STDOUT. Defaults to "-".
# -s <shell> Command name or path of the shell to use for template
# evaluation. It must not contain spaces.
# Defaults to "/bin/sh".
# -h Show this help message and exit.
# -V Print version and exit.
#
# ENVIRONMENT:
# ESH_AWK Command name of path of the awk program to use.
# It must not contain spaces. Defaults to "awk".
# ESH_MAX_DEPTH Maximum include depth. Defaults to 3.
# ESH_SHELL Same as -s.
#
# EXIT STATUS:
# 0 Clean exit, no error has encountered.
# 1 Generic error.
# 10 Invalid usage.
# 11 ESH syntax error.
# 12 Include error: file not found.
# 13 Include error: exceeded max include depth (ESH_MAX_DEPTH).
#
# Please report bugs at <https://github.com/jirutka/esh/issues>.
#---help---
set -eu
readonly PROGNAME='esh'
readonly VERSION='0.3.0'
readonly SCRIPTPATH="$0"
AWK_CONVERTER=$(cat <<'AWK'
function fail(code, msg) {
state = "ERROR"
# FIXME: /dev/stderr is not portable
printf("%s: %s\n", line_info(), msg) > "/dev/stderr"
exit code
}
function line_info() {
return FILENAME ? (filenames[depth] ":" linenos[depth]) : "(init)" # (init) if inside BEGIN
}
# IMPORTANT: This is the only function that should print a newline.
function puts(str) {
print(line_info()) > MAP_FILE
print(str)
}
function fputs(str) {
printf("%s", str)
}
function trim(str) {
gsub(/^[ \t\r\n]+|[ \t\r\n]+$/, "", str)
return str
}
function read(len, _str) {
if (len == "") {
_str = buff
buff = ""
} else if (len > 0) {
_str = substr(buff, 1, len)
buff = substr(buff, len + 1, length(buff))
}
return _str
}
function skip(len) {
buff = substr(buff, len + 1, length(buff))
}
function flush(len, _str) {
_str = read(len)
if (state == "TEXT") {
gsub("'", "'\\''", _str)
}
if (state != "COMMENT") {
fputs(_str)
}
}
function file_exists(filename, _junk) {
if ((getline _junk < filename) >= 0) {
close(filename)
return 1
}
return 0
}
function dirname(path) {
return sub(/\/[^\/]+\/*$/, "/", path) ? path : ""
}
function include(filename) {
if (index(filename, "/") != 1) { # if does not start with "/"
filename = dirname(filenames[depth]) filename
}
if (!file_exists(filename)) {
fail(12, "cannot include " filename ": not a file or not readable")
}
if (depth > MAX_DEPTH) {
fail(13, "cannot include " filename ": exceeded maximum depth of " MAX_DEPTH)
}
buffs[depth] = buff
states[depth] = state
filenames[depth + 1] = filename
depth++
init()
while ((getline buff < filename) > 0) {
if (print_nl && state != "COMMENT") {
puts("")
}
process_line()
}
end_text()
close(filename)
depth--
buff = buffs[depth]
state = states[depth]
}
function init() {
buff = ""
linenos[depth] = 0
print_nl = 0
start_text()
}
function start_text() {
puts("")
fputs("printf '%s' '")
state = "TEXT"
}
function end_text() {
if (state != "TEXT") { return }
puts("' #< " line_info())
state = "UNDEF"
}
function process_line() {
linenos[depth]++
while (buff != "") {
print_nl = 1
if (state == "TEXT" && match(buff, /<%/)) {
flush(RSTART - 1) # print buff before "<%"
skip(2) # skip "<%"
flag = substr(buff, 1, 1)
if (flag != "%") {
end_text()
}
if (flag == "%") { # <%%
skip(1)
fputs("<%")
} else if (flag == "=") { # <%=
skip(1)
fputs("__print ")
state = "TAG"
} else if (flag == "+") { # <%+
if (!match(buff, /[^%]%>/)) {
fail(11, "syntax error: <%+ must be closed on the same line")
}
filename = trim(substr(buff, 2, match(buff, /.-?%>/) - 1))
skip(RSTART)
include(filename)
state = "TAG"
} else if (flag == "#") { # <%#
state = "COMMENT"
} else {
state = "TAG"
}
} else if (state != "TEXT" && match(buff, /%>/)) {
flag = RSTART > 1 ? substr(buff, RSTART - 1, 1) : ""
if (flag == "%") { # %%>
flush(RSTART - 2)
skip(1)
flush(2)
} else if (flag == "-") { # -%>
flush(RSTART - 2)
skip(3)
print_nl = 0
} else { # %>
flush(RSTART - 1)
skip(2)
}
if (flag != "%") {
start_text()
}
} else {
flush()
}
}
}
BEGIN {
FS = ""
depth = 0
puts("#!" (SHELL ~ /\// ? SHELL : "/usr/bin/env " SHELL))
puts("set -eu")
puts("if ( set -o pipefail 2>/dev/null ); then set -o pipefail; fi")
puts("__print() { printf '%s' \"$*\"; }")
split(VARS, _lines, /\n/)
for (_i in _lines) {
puts(_lines[_i])
}
init()
}
{
if (NR == 1) {
filenames[0] = FILENAME # this var is not defined in BEGIN so we must do it here
}
buff = $0
process_line()
if (print_nl && state != "COMMENT") {
puts("")
}
}
END {
end_text()
}
AWK
)
AWK_ERR_FILTER=$(cat <<'AWK'
function line_info(lno, _line, _i) {
while ((getline _line < MAPFILE) > 0 && _i++ < lno) { }
close(MAPFILE)
return _line
}
{
if (match($0, "^" SRCFILE ":( line)? ?[0-9]+:") && match(substr($0, 1, RLENGTH), /[0-9]+:$/)) {
lno = substr($0, RSTART, RLENGTH - 1) + 0
msg = substr($0, RSTART + RLENGTH + 1) # v-- some shells duplicate filename
msg = index(msg, SRCFILE ":") == 1 ? substr(msg, length(SRCFILE) + 3) : msg
print(line_info(lno) ": " msg)
} else if ($0 != "") {
print($0)
}
}
AWK
)
readonly AWK_CONVERTER AWK_ERR_FILTER
print_help() {
sed -En '/^#---help---/,/^#---help---/p' "$SCRIPTPATH" | sed -E 's/^# ?//; 1d;$d;'
}
filter_shell_stderr() {
$ESH_AWK \
-v SRCFILE="$1" \
-v MAPFILE="$2" \
-- "$AWK_ERR_FILTER"
}
evaluate() {
local srcfile="$1"
local mapfile="$2"
# This FD redirection magic is for swapping stdout/stderr back and forth.
exec 3>&1
{ set +e; $ESH_SHELL "$srcfile" 2>&1 1>&3; echo $? >>"$mapfile"; } \
| filter_shell_stderr "$srcfile" "$mapfile" >&2
exec 3>&-
return $(tail -n 1 "$mapfile")
}
convert() {
local input="$1"
local vars="$2"
local map_file="${3:-"/dev/null"}"
$ESH_AWK \
-v MAX_DEPTH="$ESH_MAX_DEPTH" \
-v SHELL="$ESH_SHELL" \
-v MAP_FILE="$map_file" \
-v VARS="$vars" \
-- "$AWK_CONVERTER" "$input"
}
process() {
local input="$1"
local vars="$2"
local evaluate="${3:-yes}"
local ret=0 tmpfile mapfile
if [ "$evaluate" = yes ]; then
tmpfile=$(mktemp)
mapfile=$(mktemp)
convert "$input" "$vars" "$mapfile" > "$tmpfile" || ret=$?
test $ret -ne 0 || evaluate "$tmpfile" "$mapfile" || ret=$?
rm -f "$tmpfile" "$mapfile"
else
convert "$input" "$vars" || ret=$?
fi
return $ret
}
: ${ESH_AWK:="awk"}
: ${ESH_MAX_DEPTH:=3}
: ${ESH_SHELL:="/bin/sh"}
EVALUATE='yes'
OUTPUT=''
while getopts ':dho:s:V' OPT; do
case "$OPT" in
d) EVALUATE=no;;
h) print_help; exit 0;;
o) OUTPUT="$OPTARG";;
s) ESH_SHELL="$OPTARG";;
V) echo "$PROGNAME $VERSION"; exit 0;;
'?') echo "$PROGNAME: unknown option: -$OPTARG" >&2; exit 10;;
esac
done
shift $(( OPTIND - 1 ))
if [ $# -eq 0 ]; then
printf "$PROGNAME: %s\n\n" 'missing argument <input>' >&2
print_help >&2
exit 10
fi
INPUT="$1"; shift
[ "$INPUT" != '-' ] || INPUT=''
if [ "$INPUT" ] && ! [ -f "$INPUT" -a -r "$INPUT" ]; then
echo "$PROGNAME: can't read $INPUT: not a file or not readable" >&2; exit 10
fi
# Validate arguments.
for arg in "$@"; do
case "$arg" in
*=*) ;;
*) echo "$PROGNAME: illegal argument: $arg" >&2; exit 10;;
esac
done
# Format variables into shell variable assignments.
vars=''; for item in "$@"; do
vars="$vars\n${item%%=*}='$(
printf %s "${item#*=}" | $ESH_AWK "{ gsub(/'/, \"'\\\\\\\''\"); print }"
)'"
done
export ESH="$0"
if [ "${OUTPUT#-}" ]; then
tmpfile="$(mktemp)"
trap "rm -f '$tmpfile'" EXIT HUP INT TERM
process "$INPUT" "$vars" "$EVALUATE" > "$tmpfile"
mv "$tmpfile" "$OUTPUT"
else
process "$INPUT" "$vars" "$EVALUATE"
fi

41
src/gitea/resources/bin/maint

@ -0,0 +1,41 @@
#!/bin/bash
# load environment variables
source /etc/environment
hour=$(date +%H)
day=$(date +%d)
month=$(date +%m)
year=$(date +%Y)
dumpdir=/vol/db
errlog=error/$year-$month-$day-T$hour.log
mkdir -p $dumpdir/error
cd $dumpdir
if [[ $# -lt 2 ]]; then
echo "Error: called with missing hour and/or day parameter. Script exited without running." | tee $errlog
exit 1
fi
if [[ $hour == $1 ]]; then
nc-occ maintenance:mode --on
fi
db-dump $DBNAME-hourly-$hour.sql 2>> $errlog
if [[ $hour == $1 ]]; then
nc-occ maintenance:mode --off
mv $DBNAME-hourly-$hour.sql $DBNAME-daily-$day.sql 2>> $errlog
if [[ $day == $2 ]]; then
mv $DBNAME-daily-$day.sql $DBNAME-$year-$month-$day.sql 2>> $errlog
fi
fi
# If error log is size 0, erase it because I don't like seeing it
if [[ ! -s $errlog ]]; then
rm $errlog
rmdir --ignore-fail-on-non-empty error
fi

5
src/gitea/resources/crontab

@ -0,0 +1,5 @@
PATH=/usr/local/bin:/bin:/usr/bin
# m h dom mon dow command
# Dump database every hour
23 * * * * maint 01 01

33
src/gitea/resources/gitea.service

@ -0,0 +1,33 @@
[Unit]
Description=Gitea (Git with a cup of tea)
After=syslog.target
After=network.target
Requires=postgresql.service
[Service]
# Modify these two values and uncomment them if you have
# repos with lots of files and get an HTTP error 500 because
# of that
###
#LimitMEMLOCK=infinity
#LimitNOFILE=65535
RestartSec=2s
Type=simple
User=gitea
Group=gitea
WorkingDirectory=/var/lib/gitea/
# If using Unix socket: tells systemd to create the /run/gitea folder, which will contain the gitea.sock file
# (manually creating /run/gitea doesn't work, because it would not persist across reboots)
#RuntimeDirectory=gitea
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
Restart=always
Environment=USER=gitea HOME=/home/gitea GITEA_WORK_DIR=/var/lib/gitea
# If you want to bind Gitea to a port below 1024, uncomment
# the two values below, or use socket activation to pass Gitea its ports as above
###
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
###
[Install]
WantedBy=multi-user.target

1
src/gitea/resources/pg_hba.conf

@ -0,0 +1 @@
local all all trust

39
src/nextcloud/Containerfile

@ -5,36 +5,40 @@ FROM localhost/debian
# deploy options
# -p (port) and -v (volume) both go host:container
LABEL deployopts="-p 4380:80 \
LABEL deployopts="\
-p 9080:80 \
-v /tank/files/user/mar:/vol/files/mar/files \
-v /tank/files/db/nextcloud:/vol/db"
# make directories that we will be mounting into
# make sure mount directories exist
RUN mkdir -p /vol/files/mar/files /vol/db
# php and postgres versions. will depend on version of debian we are running
# Build Variables
# versions of php and postgres
ARG phpv=7.3
ARG psqlv=11
# uid that the files owner user should have
ARG FILESUID=5000
# database variables
# Environment Variables
# database name and user
ENV DBUSER=ncadmin
ENV DBNAME=nextcloud
# put environment variables in /etc/environment so we can access them from cron scripts
RUN echo "DBUSER=$DBUSER" >> /etc/environment && \
echo "DBNAME=$DBNAME" >> /etc/environment
###
### General Setup
###
# install packages we want
RUN apt update -y && apt install -y systemd sudo wget apache2 php-fpm \
php-gd php-zip php-pgsql php-curl php-mbstring php-intl php-imagick \
php-xml php-json redis php-redis postgresql postgresql-doc \
unzip php-ldap
# this is a bug workaround b/c testing is currently between versions of php. should be removed ideally
RUN update-alternatives --set php /usr/bin/php7.3
RUN apt update -y && apt install -y apache2 php-fpm php-gd php-zip \
php-pgsql php-curl php-mbstring php-intl php-imagick php-xml \
php-json redis php-redis postgresql postgresql-doc php-ldap
# change www-data's UID to the file owner UID
RUN usermod --uid 5000 www-data && \
groupmod --gid 5000 www-data && \
RUN usermod --uid $FILESUID www-data && \
groupmod --gid $FILESUID www-data && \
chown -R www-data:www-data /var/www /vol
# copy our custom scripts
@ -99,9 +103,8 @@ COPY --chown=www-data:www-data resources/my.config.php nextcloud/config/
### Crontab
###
COPY resources/crontab /root/
# the sed command is needed to workaround a bug in cron
RUN sed -i '/session required pam_loginuid.so/c\#session required pam_loginuid.so' /etc/pam.d/cron && \
crontab -u www-data /root/crontab
# crontab for www-data
RUN crontab -u www-data /root/crontab
###
### Systemdfile
@ -115,3 +118,7 @@ RUN chmod +x /root/Systemdfile
# push the fixed systemd file for redis
COPY bugfix/redis.service /etc/systemd/system/redis.service
# execute command to workaround bug in cron
COPY bugfix/cronfix /root/
RUN chmod +x /root/cronfix && /root/cronfix

2
src/nextcloud/bugfix/cronfix

@ -0,0 +1,2 @@
#!/bin/sh
sed -i '/session required pam_loginuid.so/c\#session required pam_loginuid.so' /etc/pam.d/cron

21
src/nextcloud/resources/bin/maint

@ -1,17 +1,21 @@
#!/bin/bash
# load environment variables
source /etc/environment
hour=$(date +%H)
day=$(date +%d)
month=$(date +%m)
year=$(date +%Y)
dumpdir=/vol/db
errlog=error/$year-$month-$day-T$hour.log
mkdir -p $dumpdir
mkdir -p $dumpdir/error
cd $dumpdir
if [[ $# -lt 2 ]]; then
echo "[$year-$month-$day] Error: called with missing hour and/or day parameter. Script exited without running." | tee error.log
echo "Error: called with missing hour and/or day parameter. Script exited without running." | tee $errlog
exit 1
fi
@ -19,18 +23,19 @@ if [[ $hour == $1 ]]; then
nc-occ maintenance:mode --on
fi
db-dump $DBNAME-hourly-$hour.sql 2>> error.log
db-dump $DBNAME-hourly-$hour.sql 2>> $errlog
if [[ $hour == $1 ]]; then
nc-occ maintenance:mode --off
mv $DBNAME-hourly-$hour.sql $DBNAME-daily-$day.sql 2>> error.log
mv $DBNAME-hourly-$hour.sql $DBNAME-daily-$day.sql 2>> $errlog
if [[ $day == $2 ]]; then
mv $DBNAME-daily-$day.sql $DBNAME-$year-$month-$day.sql 2>> error.log
mv $DBNAME-daily-$day.sql $DBNAME-$year-$month-$day.sql 2>> $errlog
fi
fi
# If error.log is size 0, erase it because I don't like seeing it
if [[ ! -s ./error.log ]]; then
rm error.log
# If error log is size 0, erase it because I don't like seeing it
if [[ ! -s $errlog ]]; then
rm $errlog
rmdir --ignore-fail-on-non-empty error
fi

7
src/nextcloud/resources/crontab

@ -1,8 +1,11 @@
PATH=/usr/local/bin:/bin:/usr/bin
# m h dom mon dow command
# Run Nextcloud cron tasks every 5 minutes
*/5 * * * * php -f /var/www/html/nextcloud/cron.php
# Dump database every hour
10 * * * * maint 01 01
# Scan for new files every 15 minutes
*/15 * * * * nc-occ files:scan --all
# Dump database every hour
23 * * * * maint 01 01

Loading…
Cancel
Save