Compare commits

..

3 Commits

Author SHA1 Message Date
Erik Huelsmann
f9fa5f04c7 Adjust for new reverse proxy setup
Some checks are pending
Docker Image cleanup / cleanup (push) Waiting to run
2025-08-09 14:51:12 +02:00
Erik Huelsmann
62e773da73
Nginx reverse proxy combined with Starman server in one image (#46)
* feat: provide image with nginx

* Re-use parent container configuration and startup scripts

* Rewrite proxy Dockerfile:

* ARCH used to be hard-coded; is now set according to the architecture being built
* Build from the associated LedgerSMB base image (not from 'lsmb-split')
* More deletion of non-required files (/usr/share/doc/*)
* Fewer layers by combining RUN commands

* Use 'server-start' script generated by the installer instead of repeating ourselves

* Don't expose the status module

It won't be accessible anyway: the localhost address is the one inside the container...

* Ensure relative redirects

When the container port :80 is exposed as :8080 on the host,
nginx redirects to http://localhost:80/login.pl with a relative
path, instead of http://localhost:8080/login.pl; the container
isn't bound to :80, so that request fails...

* Rename proxy layer image

* Adjust 'build' script to publish base and regular images

---------

Co-authored-by: Walid Mujahid <walidmujahid@gmail.com>
2025-08-09 14:34:32 +02:00
Erik Huelsmann
acb9ad1bda Add build script to be called by ledgersmb-release-tools/publish 2025-08-09 14:09:56 +02:00
15 changed files with 166 additions and 98 deletions

View File

@ -53,7 +53,7 @@ do recommend not exposing this port publicly, because
2. We strongly recommend TLS encryption of all application traffic
While the exposed port can be used for quick evaluation, it's recommended
to add the TLS layer by applying Nginx or Apache as reverse proxy.
to add TLS for production situations.
Enabling optional functionalities such as outgoing e-mail and printing
could require additional setup of a mail service or CUPS printer service.
@ -259,50 +259,6 @@ files named `ledgersmb.1XX.yaml` in the same folder. E.g.:
keys](https://github.com/ledgersmb/LedgerSMB/blob/master/doc/conf/ledgersmb.yaml)
is available in the LedgerSMB repository.
## Docker Compose with reverse proxy
The `docker-compose-reverseproxy.yml` file shows a docker-compose setup
which adds an Nginx reverse proxy configuration on top of the base
`docker-compose.yml` configuration file. If the content of this repository
is cloned into the current directory (`git clone https://github.com/ledgersmb/ledgersmb-docker.git ; cd ledgersmb-docker`), it can be used as:
```plain
$ docker-compose \
-f docker-compose.yml \
-f docker-compose-reverseproxy.yml \
up -d
```
This setup can be used in combination with an image which runs the
Certbot certificate renewal process *and* Nginx to do TLS termination. The
default reverse proxy is mostly an example; it publishes on
[http://localhost:8080/](http://localhost:8080/).
An example of such an image can be found at
[https://github.com/jonasalfredsson/docker-nginx-certbot](https://github.com/jonasalfredsson/docker-nginx-certbot),
which is published on Docker Hub as
[jonasal/nginx-certbot](https://hub.docker.com/r/jonasal/nginx-certbot).
**Upgrade note** When upgrading this setup, please remove the volume ending
in `_lsmbdata` before starting the upgraded containers. Without that, the
webcontent won't be upgraded! E.g.:
```plain
$ docker-compose \
-f docker-compose.yml \
-f docker-compose-reverseproxy.yml \
rm -s -f -v && \
docker volume rm ledgersmb-docker_lsmbdata && \
docker-compose \
-f docker-compose.yml \
-f docker-compose-reverseproxy.yml \
pull && \
docker-compose \
-f docker-compose.yml \
-f docker-compose-reverseproxy.yml \
up -d
```
# Troubleshooting/Developing
Currently the LedgerSMB installation is in /srv/ledgersmb

View File

@ -39,6 +39,7 @@ RUN set -x ; \
cd /srv && \
curl -s -o ledgersmb-installer -L https://get.ledgersmb.org/ledgersmb-installer && \
ARTIFACT_LOCATION="$ARTIFACT_PATH" perl ledgersmb-installer install --yes --log-level=trace $LSMB_VERSION && \
mv /srv/ledgersmb/server-start /usr/local/bin/run.sh && \
rm -rf ~/.cpanm/ /var/lib/apt/lists/* /usr/share/man/*
WORKDIR /srv/ledgersmb
@ -66,7 +67,6 @@ ENV DEFAULT_DB=lsmb
COPY start.sh /usr/local/bin/start.sh
COPY config.sh /usr/local/bin/config.sh
COPY run.sh /usr/local/bin/run.sh
RUN chmod +x /usr/local/bin/start.sh /usr/local/bin/config.sh /usr/local/bin/run.sh && \
mkdir -p /var/www && \

24
build Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
set -euxo pipefail
${DOCKER:-docker} buildx build \
--progress plain \
--platform ${PLATFORM:-linux/amd64,linux/arm64,linux/arm/v7} \
--build-arg "ARTIFACT_PATH=$ARTIFACT_PATH" \
-t ledgersmb/ledgersmb:$BRANCH-base \
-t ledgersmb/ledgersmb:$VERSION-base \
-t ghcr.io/ledgersmb/ledgersmb:$BRANCH-base \
-t ghcr.io/ledgersmb/ledgersmb:$VERSION-base \
${SET_LATEST_TAG:+ -t ledgersmb/ledgersmb:latest-base -t ghcr.io/ledgersmb/ledgersmb:latest-base} \
--push base/
${DOCKER:-docker} buildx build \
--progress plain \
--platform ${PLATFORM:-linux/amd64,linux/arm64,linux/arm/v7} \
-t ledgersmb/ledgersmb:$BRANCH \
-t ledgersmb/ledgersmb:$VERSION \
-t ghcr.io/ledgersmb/ledgersmb:$BRANCH \
-t ghcr.io/ledgersmb/ledgersmb:$VERSION \
${SET_LATEST_TAG:+ -t ledgersmb/ledgersmb:latest -t ghcr.io/ledgersmb/ledgersmb:latest} \
--push proxy/

View File

@ -1,36 +0,0 @@
# Use this docker-compose file as:
#
# docker-compose -f docker-compose.yml -f docker-compose-reverseproxy.yml up -d
#
#
# This command creates one
# compose 'project' consisting of three containers
#
# 1. The PostgreSQL data container
# 2. The LedgerSMB application container
# 3. The Nginx reverse proxy container
#
# In addition to publishing LedgerSMB on port 5762 on localhost,
# this project also publishes Nginx's reverse proxied content on
# port 8080 on localhost
version: "3.2"
services:
proxy:
depends_on:
- lsmb
image: nginx:1-alpine
volumes:
- "lsmbdata:/srv/ledgersmb"
- "./nginx.conf:/etc/nginx/nginx.conf"
ports:
- "8080:8080"
# Comment the line below to stop the container from restarting on boot
# unless it was manually stopped
restart: unless-stopped
lsmb:
volumes:
- "lsmbdata:/srv/ledgersmb"
volumes:
lsmbdata:

View File

@ -8,7 +8,7 @@
# so no special care needs to be taken on
# container upgrades. With PostgreSQL, data is
# persisted across upgrades by the use of a
# special 'dbdata' volume
# special 'pgdata' volume
version: "3.2"
services:
@ -31,7 +31,7 @@ services:
lsmb:
depends_on:
- postgres
image: ghcr.io/ledgersmb/ledgersmb:1.12
image: ghcr.io/ledgersmb/ledgersmb:1.13
# In order to store the configuration outside the image, allowing it to
# be edited between container restarts, uncomment the section below and
# change the 'source' to the directory where you want the configuration
@ -48,13 +48,15 @@ services:
networks:
- internal
- default
# Comment the 'ports' section to disable mapping the LedgerSMB container port (5762)
# to the host's port of the same number. Mapping "5762:5762" makes LedgerSMB
# available on http://<host-dns-or-ip>:5762/
# Comment the 'ports' section to disable mapping the LedgerSMB container
# ports (80 and 5762) to host ports of the same number. The mapping below
# makes LedgerSMB available on http://localhost/ on the host.
#
# SECURITY NOTE: Leave this uncommented for evaluation purposes only!
# In production, be sure to use SSL/TLS (such as by reverse proxying) to protect
# user's passwords and other sensitive data
ports:
- "80:80"
- "5762:5762"
environment:
# The LSMB_WORKERS environment variable lets you select the number
@ -87,7 +89,7 @@ services:
# unless it was manually stopped
restart: unless-stopped
# having the dbdata volume is required to persist our
# having the pgdata volume is required to persist our
# data between PostgreSQL container updates; without
# that, the data is contained in the same volume as
# the rest of the image and on update/upgrade, the

47
proxy/Dockerfile Normal file
View File

@ -0,0 +1,47 @@
# Install LedgerSMB version
ARG LSMB_VERSION=1.13.0-beta1
# Install s6-overlay
ARG S6_OVERLAY_VERSION=3.2.0.2
FROM ledgersmb/ledgersmb:$LSMB_VERSION
# Repeat args if we still want to use them
ARG LSMB_VERSION
ARG S6_OVERLAY_VERSION
# Install nginx and other dependencies
USER root
RUN set -x && \
DEBIAN_FRONTEND=noninteractive apt-get update -y && \
DEBIAN_FRONTEND=noninteractive apt-get dist-upgrade -y && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends nginx wget xz-utils && \
mkdir -p /var/lib/nginx/body /var/cache/nginx && \
DEBIAN_FRONTEND=noninteractive apt-get autoremove -q -y && \
DEBIAN_FRONTEND=noninteractive apt-get clean -q && \
ARCH="$(case "$(dpkg --print-architecture)" in armv7*) echo "armhf" ;; arm64) echo "aarch64" ;; amd64) echo "x86_64" ;; *) exit 1 ;; esac)" && \
wget -O /tmp/s6-overlay-noarch.tar.xz https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz && \
wget -O /tmp/s6-overlay-noarch.tar.xz.sha256 https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz.sha256 && \
wget -O /tmp/s6-overlay-${ARCH}.tar.xz https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-${ARCH}.tar.xz && \
wget -O /tmp/s6-overlay-${ARCH}.tar.xz.sha256 https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-${ARCH}.tar.xz.sha256 && \
wget -O /tmp/s6-overlay-symlinks-noarch.tar.xz https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-symlinks-noarch.tar.xz && \
wget -O /tmp/s6-overlay-symlinks-noarch.tar.xz.sha256 https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-symlinks-noarch.tar.xz.sha256 && \
cd /tmp && \
sha256sum -c *.sha256 && \
tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz && \
tar -C / -Jxpf /tmp/s6-overlay-${ARCH}.tar.xz && \
tar -C / -Jxpf /tmp/s6-overlay-symlinks-noarch.tar.xz && \
rm -rf ~/.cpanm/ /var/lib/apt/lists/* /usr/share/man/* /usr/share/doc/* /tmp/s6-overlay-*.tar.xz*
COPY nginx.conf /etc/nginx/nginx.conf
# Configure nginx and starman with s6
COPY services/starman/run /etc/services.d/starman/run
COPY services/nginx/run /etc/services.d/nginx/run
COPY scripts/ledgersmb_config /etc/s6-overlay/s6-rc.d/ledgersmb_config
RUN chmod +x /etc/services.d/starman/run /etc/services.d/nginx/run /etc/s6-overlay/s6-rc.d/ledgersmb_config/up && \
touch /etc/s6-overlay/s6-rc.d/user/contents.d/ledgersmb_config
EXPOSE 80
ENTRYPOINT ["/init"]

74
proxy/nginx.conf Normal file
View File

@ -0,0 +1,74 @@
# This is a full (minimal) nginx configuration file
error_log /dev/stderr info;
pid /tmp/nginx.pid;
worker_processes 1;
user www-data;
events {
worker_connections 1024;
}
http {
client_body_temp_path /tmp/client_body;
proxy_temp_path /tmp/proxy_temp;
fastcgi_temp_path /tmp/fastcgi_temp;
scgi_temp_path /tmp/scgi_temp;
uwsgi_temp_path /tmp/uwsgi_temp;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /dev/stdout;
error_log /dev/stderr info;
gzip off;
gzip_static on;
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /srv/ledgersmb/UI;
access_log /dev/stdout;
error_log /dev/stderr info;
# Configuration files don't exist
location ^~ \.conf$ {
return 404;
}
# 'Hidden' files don't exist
location ~ /\. {
return 404;
}
location = / {
return 301 login.pl;
}
# JS & CSS
location ~* \.(js|css)$ {
add_header Pragma "public";
add_header Cache-Control "public, must-revalidate, proxy-revalidate"; # Production
expires 7d; # Indicate that the resource can be cached for 1 week # Production
try_files $uri =404;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 300;
proxy_pass http://127.0.0.1:5762;
}
}
}

View File

@ -0,0 +1 @@
oneshot

View File

@ -0,0 +1,3 @@
foreground { echo "Running config..." }
/usr/local/bin/config.sh

3
proxy/services/nginx/run Normal file
View File

@ -0,0 +1,3 @@
#!/usr/bin/with-contenv /bin/bash
exec nginx -g "daemon off;"

View File

@ -0,0 +1,3 @@
#!/usr/bin/with-contenv /bin/bash
s6-setuidgid www-data /usr/local/bin/run.sh

9
run.sh
View File

@ -1,9 +0,0 @@
#!/bin/bash
cd /srv/ledgersmb
# ':5762:' suppresses an uninitialized variable warning in starman
# the last colon means "don't connect using tls"; without it, there's a warning
exec starman --listen 0.0.0.0:5762 --workers ${LSMB_WORKERS:-5} \
-I lib -I old/lib \
--preload-app bin/ledgersmb-server.psgi