「🏗️」 wip: Removed ftp server and started borgbackup container
This commit is contained in:
119
srcs/cmd/borg-backup/entrypoint/entrypoint.go
Normal file
119
srcs/cmd/borg-backup/entrypoint/entrypoint.go
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"bufio"
|
||||||
|
|
||||||
|
"git.keyzox.me/42_adjoly/inception/internal/cmd"
|
||||||
|
"git.keyzox.me/42_adjoly/inception/internal/env"
|
||||||
|
_log "git.keyzox.me/42_adjoly/inception/internal/log"
|
||||||
|
"git.keyzox.me/42_adjoly/inception/internal/pass"
|
||||||
|
)
|
||||||
|
|
||||||
|
func overrideCronFile(filePath string, jobs []string) error {
|
||||||
|
file, err := os.Create(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
writer := bufio.NewWriter(file)
|
||||||
|
for _, job := range jobs {
|
||||||
|
_, err := writer.WriteString(job + "\n")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return writer.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
func isBorgInit(repo string) (bool, error) {
|
||||||
|
cmd := exec.Command("borg", "info", repo)
|
||||||
|
|
||||||
|
err := cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
if exitError, ok := err.(*exec.ExitError); ok {
|
||||||
|
if exitError.ExitCode() == 2 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
args := os.Args
|
||||||
|
|
||||||
|
src := env.EnvCheck("BORG_SRC", "/source")
|
||||||
|
if _, err := os.ReadDir(src); err != nil {
|
||||||
|
_log.Log("error", src+" does not exist can't perform backup")
|
||||||
|
}
|
||||||
|
|
||||||
|
repo := env.EnvCheck("BORG_REPO", "/backup")
|
||||||
|
if _, err := os.ReadDir(src); err != nil {
|
||||||
|
_log.Log("error", repo+" does not exist can't perform backup")
|
||||||
|
}
|
||||||
|
is, err := isBorgInit(repo)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
} else if is == true {
|
||||||
|
_log.Log("note", "Repo already initialize, skipping...")
|
||||||
|
} else {
|
||||||
|
_log.Log("note", "Initializing repo...")
|
||||||
|
|
||||||
|
passphrase := env.FileEnv("BORG_PASSPHRASE", "")
|
||||||
|
if passphrase == "" {
|
||||||
|
_log.Log("error", "No passphrase specified, exiting...")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = cmd.ExecCmd([]string{"borg", "init", "--encryption=" + passphrase, repo})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interval := env.EnvCheck("CRON_INTERVAL", "0 0 * * *")
|
||||||
|
cronFilePath := "/etc/crontabs/root"
|
||||||
|
newJobs := []string{
|
||||||
|
"# Borg Backup Cron Job",
|
||||||
|
interval + " root run-parts /docker-backup.d >> /var/log/cron.log 2>&1",
|
||||||
|
}
|
||||||
|
err = overrideCronFile(cronFilePath, newJobs)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error overriding cron file: %v\n", err)
|
||||||
|
} else {
|
||||||
|
fmt.Println("Cron file overridden successfully.")
|
||||||
|
}
|
||||||
|
|
||||||
|
dir, err := os.ReadDir("/docker-entrypoint.d")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
_log.Log("note", "Running entrypoint scripts")
|
||||||
|
for _, v := range dir {
|
||||||
|
os.Chmod("/docker-entrypoint.d/"+v.Name(), 0755)
|
||||||
|
cmd := exec.Command("/docker-entrypoint.d/" + v.Name())
|
||||||
|
cmd.Env = os.Environ()
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
cmd.Stdin = os.Stdin
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
fmt.Printf("Error running script(%s): %v\n", v.Name(), err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command(args[1], args[2:]...)
|
||||||
|
cmd.Env = os.Environ()
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
cmd.Stdin = os.Stdin
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
fmt.Printf("Error running BORGBACKUP: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
@ -1,81 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"os/exec"
|
|
||||||
|
|
||||||
"git.keyzox.me/42_adjoly/inception/internal/cmd"
|
|
||||||
"git.keyzox.me/42_adjoly/inception/internal/env"
|
|
||||||
_log "git.keyzox.me/42_adjoly/inception/internal/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func configFtp() {
|
|
||||||
_log.Log("note", "Configuring VSFTPD...")
|
|
||||||
ftpUser := env.FileEnv("FTP_USER", "ftp")
|
|
||||||
ftpPass := env.FileEnv("FTP_PASS", "ftppass")
|
|
||||||
cmd.ExecCmd([]string{"adduser", ftpUser, "--disabled-password"})
|
|
||||||
|
|
||||||
var stdin bytes.Buffer
|
|
||||||
stdin.WriteString(fmt.Sprintf("%s:%s", ftpUser, ftpPass))
|
|
||||||
|
|
||||||
cmd := exec.Command("/usr/sbin/chpasswd")
|
|
||||||
cmd.Stdin = &stdin
|
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = os.Create("/etc/vsftpd.check")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("could not create check file :O")
|
|
||||||
}
|
|
||||||
os.WriteFile("/etc/vsftpd/vsftpd.userlist", []byte(ftpUser), 0766)
|
|
||||||
|
|
||||||
_log.Log("note", "VSFTPD configured ;D")
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
args := os.Args
|
|
||||||
|
|
||||||
if args[1] == "vsftpd" {
|
|
||||||
_log.Log("note", "Entrypoint script for VSFTPD Server started")
|
|
||||||
|
|
||||||
_, err := os.ReadFile("/etc/vsftpd.check")
|
|
||||||
if err != nil {
|
|
||||||
configFtp()
|
|
||||||
} else {
|
|
||||||
_log.Log("note", "VSFTPD already configured, skipping...")
|
|
||||||
}
|
|
||||||
|
|
||||||
dir, err := os.ReadDir("/docker-entrypoint.d")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
_log.Log("note", "Running entrypoint scripts")
|
|
||||||
for _, v := range dir {
|
|
||||||
os.Chmod("/docker-entrypoint.d/"+v.Name(), 0755)
|
|
||||||
cmd := exec.Command("/docker-entrypoint.d/" + v.Name())
|
|
||||||
cmd.Env = os.Environ()
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
cmd.Stdin = os.Stdin
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
fmt.Printf("Error running script(%s): %v\n", v.Name(), err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cmd := exec.Command(args[1], args[2:]...)
|
|
||||||
cmd.Env = os.Environ()
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
cmd.Stdin = os.Stdin
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
fmt.Printf("Error running VSFTPD: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
@ -83,24 +83,6 @@ services:
|
|||||||
- wp-db:/var/lib/mysql
|
- wp-db:/var/lib/mysql
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
ftp:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: docker/bonus/vsftpd/Dockerfile
|
|
||||||
ports:
|
|
||||||
- 2100:2100
|
|
||||||
- 30000-30100:30000-30100
|
|
||||||
volumes:
|
|
||||||
- wp-site:/var/ftp
|
|
||||||
environment:
|
|
||||||
- FTP_USER=kanel
|
|
||||||
- FTP_PASS=legoat
|
|
||||||
depends_on:
|
|
||||||
nginx:
|
|
||||||
condition: service_started
|
|
||||||
wordpress-php:
|
|
||||||
condition: service_healthy
|
|
||||||
|
|
||||||
static-site:
|
static-site:
|
||||||
build: docker/bonus/static-site
|
build: docker/bonus/static-site
|
||||||
ports:
|
ports:
|
||||||
@ -111,4 +93,32 @@ services:
|
|||||||
- TZ=Europe/Paris
|
- TZ=Europe/Paris
|
||||||
- NGINX_SSL_KEY_FILE=/etc/nginx/ssl/kanel-wp.key
|
- NGINX_SSL_KEY_FILE=/etc/nginx/ssl/kanel-wp.key
|
||||||
- NGINX_SSL_CERT_FILE=/etc/nginx/ssl/kanel-wp.crt
|
- NGINX_SSL_CERT_FILE=/etc/nginx/ssl/kanel-wp.crt
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
backup:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: docker/bonus/borg-backup/Dockerfile
|
||||||
|
networks:
|
||||||
|
- inception
|
||||||
|
environment:
|
||||||
|
- TZ=Europe/Paris # handled by tzdata
|
||||||
|
- CRON_INTERVAL=0 0 * * * # handled by entrypoint
|
||||||
|
- BORG_PASSPHRASE=Hanky-Kangaroo-Thinning5-Statute-Mascot-Islamist
|
||||||
|
- BORG_REPO=/backup
|
||||||
|
- BORG_SRC=/source
|
||||||
|
- BORG_COMPRESS=zstd
|
||||||
|
- BORG_PRUNE_KEEP_DAILY=3
|
||||||
|
- BORG_PRUNE_KEEP_WEEKLY=2
|
||||||
|
- BORG_PRUNE_KEEP_MONTHLY=1
|
||||||
|
#- BORG_EXCLUDE_PATTERNS=/var/www/cache # just an exemple to remove after
|
||||||
|
- BORG_LOG_LEVEL=info
|
||||||
|
- BORG_CHECK_LAST=3
|
||||||
|
- BORG_CHECK_DATA=1
|
||||||
|
depends_on:
|
||||||
|
nginx:
|
||||||
|
condition: service_healthy
|
||||||
|
volumes:
|
||||||
|
- wp-db:/source/db
|
||||||
|
- wp-site:/source/wordpress
|
||||||
|
restart: unless-stopped
|
||||||
|
33
srcs/docker/bonus/borg-backup/Dockerfile
Normal file
33
srcs/docker/bonus/borg-backup/Dockerfile
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
FROM scratch AS builder
|
||||||
|
ADD alpine-minirootfs-3.21.2-x86_64.tar.gz /
|
||||||
|
|
||||||
|
WORKDIR /build
|
||||||
|
|
||||||
|
COPY go.sum /build/go.sum
|
||||||
|
COPY go.mod /build/go.mod
|
||||||
|
COPY cmd /build/cmd
|
||||||
|
COPY internal /build/internal
|
||||||
|
|
||||||
|
RUN cd /build \
|
||||||
|
&& go build git.keyzox.me/42_adjoly/inception/cmd/borg-backup/entrypoint
|
||||||
|
|
||||||
|
FROM scratch
|
||||||
|
ADD alpine-minirootfs-3.21.2-x86_64.tar.gz /
|
||||||
|
|
||||||
|
RUN mkdir -p /backup \
|
||||||
|
&& mkdir -p /source \
|
||||||
|
&& mkdir /docker-entrypoint.d \
|
||||||
|
&& mkdir /docker-backup.d
|
||||||
|
|
||||||
|
RUN apk add --no-cache borgbackup tzdata \
|
||||||
|
&& rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
|
COPY --from=builder /build/entrypoint /docker-entrypoint
|
||||||
|
COPY docker/bonus/borg-backup/default-bak.sh /docker-backup.d
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/docker-entrypoint" ]
|
||||||
|
WORKDIR /
|
||||||
|
|
||||||
|
STOPSIGNAL SIGQUIT
|
||||||
|
|
||||||
|
CMD [ "crond", "-l", "${CRON_LOGLEVEL:-8}", "-f" ]
|
45
srcs/docker/bonus/borg-backup/default-bak.sh
Normal file
45
srcs/docker/bonus/borg-backup/default-bak.sh
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Define variables from environment
|
||||||
|
REPO=${BORG_REPO}
|
||||||
|
PASSPHRASE=${BORG_PASSPHRASE}
|
||||||
|
SOURCE=${BORG_SOURCE}
|
||||||
|
COMPRESSION=${BORG_COMPRESS:-zstd}
|
||||||
|
PRUNE_KEEP_DAILY=${BORG_PRUNE_KEEP_DAILY:-7}
|
||||||
|
PRUNE_KEEP_WEEKLY=${BORG_PRUNE_KEEP_WEEKLY:-4}
|
||||||
|
PRUNE_KEEP_MONTHLY=${BORG_PRUNE_KEEP_MONTHLY:-6}
|
||||||
|
EXCLUDE_PATTERNS=${BORG_EXCLUDE_PATTERNS:-}
|
||||||
|
CHECK_LAST=${BORG_CHECK_LAST}
|
||||||
|
|
||||||
|
BAK_ARGS=--compression $COMPRESSION
|
||||||
|
|
||||||
|
if [[ -z "$PASSPHRASE" ]]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$EXCLUDE_PATTERNS" ]]; then
|
||||||
|
BAK_ARGS+=--exclude $EXCLUDE_PATTERNS
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Borg backup command
|
||||||
|
borg create --stats $BAK_ARGS \
|
||||||
|
$REPO::$(hostname)-$(date +%Y-%m-%d) $SOURCE
|
||||||
|
|
||||||
|
# Borg prune command
|
||||||
|
|
||||||
|
echo "Creating backup..."
|
||||||
|
borg prune --list $REPO --keep-daily=$PRUNE_KEEP_DAILY --keep-weekly=$PRUNE_KEEP_WEEKLY --keep-monthly=$PRUNE_KEEP_MONTHLY
|
||||||
|
|
||||||
|
# Borg check command
|
||||||
|
CHECK_ARGS=""
|
||||||
|
|
||||||
|
if [[ -n "$CHECK_LAST" ]]; then
|
||||||
|
CHECK_ARGS+=--last $CHECK_LAST
|
||||||
|
fi
|
||||||
|
if [[ -n "$CHECK_DATA" ]]; then
|
||||||
|
CHECK_ARGS+=--verify-data
|
||||||
|
fi
|
||||||
|
|
||||||
|
borg check $CHECK_ARGS $REPO
|
@ -1,39 +0,0 @@
|
|||||||
FROM scratch as builder
|
|
||||||
ADD docker/alpine/alpine-minirootfs-3.21.2-x86_64.tar.gz /
|
|
||||||
|
|
||||||
RUN apk add --no-cache go
|
|
||||||
|
|
||||||
WORKDIR /build
|
|
||||||
|
|
||||||
COPY go.mod /build/go.mod
|
|
||||||
COPY cmd /build/cmd
|
|
||||||
COPY internal /build/internal
|
|
||||||
|
|
||||||
RUN cd /build \
|
|
||||||
&& go build git.keyzox.me/42_adjoly/inception/cmd/vsftpd/entrypoint
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
ADD docker/alpine/alpine-minirootfs-3.21.2-x86_64.tar.gz /
|
|
||||||
|
|
||||||
LABEL maintainer="KeyZox"
|
|
||||||
LABEL version="0.1"
|
|
||||||
|
|
||||||
COPY --from=builder /build/entrypoint /docker-entrypoint
|
|
||||||
COPY docker/bonus/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf
|
|
||||||
|
|
||||||
RUN apk add vsftpd \
|
|
||||||
&& mkdir -p /var/ftp \
|
|
||||||
&& mkdir -p /docker-entrypoint.d
|
|
||||||
|
|
||||||
VOLUME /var/ftp
|
|
||||||
|
|
||||||
|
|
||||||
ENTRYPOINT [ "/docker-entrypoint" ]
|
|
||||||
WORKDIR /etc/vsftpd
|
|
||||||
|
|
||||||
EXPOSE 21
|
|
||||||
EXPOSE 30000-30100
|
|
||||||
|
|
||||||
STOPSIGNAL SIGQUIT
|
|
||||||
|
|
||||||
CMD [ "vsftpd", "/etc/vsftpd/vsftpd.conf" ]
|
|
@ -1,25 +0,0 @@
|
|||||||
anonymous_enable=NO
|
|
||||||
local_enable=YES
|
|
||||||
write_enable=YES
|
|
||||||
dirmessage_enable=YES
|
|
||||||
xferlog_enable=YES
|
|
||||||
|
|
||||||
ftpd_banner=Welcome to your WordPress FTP server.
|
|
||||||
|
|
||||||
chroot_local_user=YES
|
|
||||||
allow_writeable_chroot=YES
|
|
||||||
user_sub_token=$USER
|
|
||||||
local_root=/var/ftp
|
|
||||||
|
|
||||||
listen=YES
|
|
||||||
listen_port=2100
|
|
||||||
listen_address=0.0.0.0
|
|
||||||
seccomp_sandbox=NO
|
|
||||||
|
|
||||||
pasv_enable=YES
|
|
||||||
pasv_min_port=30000
|
|
||||||
pasv_max_port=30100
|
|
||||||
|
|
||||||
userlist_enable=YES
|
|
||||||
userlist_file=/etc/vsftpd/vsftpd.userlist
|
|
||||||
userlist_deny=NO
|
|
@ -25,16 +25,9 @@ RUN addgroup mysql \
|
|||||||
COPY --from=builder /build/entrypoint /docker-entrypoint
|
COPY --from=builder /build/entrypoint /docker-entrypoint
|
||||||
COPY --from=builder /build/healthcheck /docker-healthcheck
|
COPY --from=builder /build/healthcheck /docker-healthcheck
|
||||||
|
|
||||||
RUN mkdir /build
|
RUN apk add --no-cache mariadb tzdata mariadb-client \
|
||||||
|
|
||||||
COPY go.mod /build/go.mod
|
|
||||||
COPY cmd /build/cmd
|
|
||||||
COPY internal /build/internal
|
|
||||||
|
|
||||||
RUN apk add --no-cache go mariadb tzdata mariadb-client \
|
|
||||||
&& chmod +x /docker-healthcheck \
|
&& chmod +x /docker-healthcheck \
|
||||||
&& chmod +x /docker-entrypoint \
|
&& chmod +x /docker-entrypoint \
|
||||||
&& apk del go \
|
|
||||||
&& mkdir -p /etc/mysql/conf.d /etc/mysql/mariadb.conf.d/ /run/mariadb /run/mysqld \
|
&& mkdir -p /etc/mysql/conf.d /etc/mysql/mariadb.conf.d/ /run/mariadb /run/mysqld \
|
||||||
&& chmod ugo+rwx,o+t /run/mariadb \
|
&& chmod ugo+rwx,o+t /run/mariadb \
|
||||||
&& chown -R mysql:mysql /var/lib/mysql /run/mariadb /run/mysqld \
|
&& chown -R mysql:mysql /var/lib/mysql /run/mariadb /run/mysqld \
|
||||||
|
@ -7,13 +7,11 @@ import (
|
|||||||
_log "git.keyzox.me/42_adjoly/inception/internal/log"
|
_log "git.keyzox.me/42_adjoly/inception/internal/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExecCmd(cmdStr []string) {
|
func ExecCmd(cmdStr []string) error {
|
||||||
cmd := exec.Command(cmdStr[0], cmdStr...)
|
cmd := exec.Command(cmdStr[0], cmdStr...)
|
||||||
cmd.Env = os.Environ()
|
cmd.Env = os.Environ()
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
cmd.Stdin = os.Stdin
|
cmd.Stdin = os.Stdin
|
||||||
if err := cmd.Run(); err != nil {
|
return cmd.Run()
|
||||||
_log.Log("error", "Could not execute : " + cmdStr[0])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user