diff --git a/Dockerfile b/Dockerfile index e2a7fd0..71cf0fd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,11 +8,27 @@ RUN apt-get update && \ apt-get install -y software-properties-common && \ add-apt-repository -y ppa:deadsnakes/ppa && \ apt-get update && \ - apt-get install -y --no-install-recommends python3.11 python3.11-venv python3-pip vim git && \ + apt-get install -y --no-install-recommends python3.11 python3.11-venv python3-pip vim git curl && \ update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1 && \ apt-get -y clean && \ rm -rf /var/lib/apt/lists/* +# Download and install FRP client into /usr/local/bin. +RUN set -ex; \ + ARCH=$(uname -m); \ + if [ "$ARCH" = "aarch64" ]; then \ + FRP_URL="https://raw.githubusercontent.com/nextcloud/HaRP/main/exapps_dev/frp_0.61.1_linux_arm64.tar.gz"; \ + else \ + FRP_URL="https://raw.githubusercontent.com/nextcloud/HaRP/main/exapps_dev/frp_0.61.1_linux_amd64.tar.gz"; \ + fi; \ + echo "Downloading FRP client from $FRP_URL"; \ + curl -L "$FRP_URL" -o /tmp/frp.tar.gz; \ + tar -C /tmp -xzf /tmp/frp.tar.gz; \ + mv /tmp/frp_0.61.1_linux_* /tmp/frp; \ + cp /tmp/frp/frpc /usr/local/bin/frpc; \ + chmod +x /usr/local/bin/frpc; \ + rm -rf /tmp/frp /tmp/frp.tar.gz + # Set working directory WORKDIR /app @@ -26,6 +42,9 @@ ENV NVIDIA_VISIBLE_DEVICES all ENV NVIDIA_DRIVER_CAPABILITIES compute ENV DEBIAN_FRONTEND dialog +COPY healthcheck.sh / +COPY --chmod=775 start.sh / + # Copy application files ADD cs[s] /app/css ADD im[g] /app/img @@ -35,6 +54,7 @@ ADD li[b] /app/lib ADD config.json /app/config.json ADD languages.json /app/languages.json -ENTRYPOINT ["python3", "lib/main.py"] +ENTRYPOINT ["/start.sh", "python3", "lib/main.py"] +HEALTHCHECK --interval=2s --timeout=2s --retries=300 CMD /healthcheck.sh LABEL org.opencontainers.image.source="https://github.com/nextcloud/translate2" diff --git a/healthcheck.sh b/healthcheck.sh new file mode 100755 index 0000000..e841729 --- /dev/null +++ b/healthcheck.sh @@ -0,0 +1,10 @@ +#! /bin/bash +# SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors +# SPDX-License-Identifier: AGPL-3.0-or-later +if [ -f /frpc.toml ] && [ -n "$HP_SHARED_KEY" ]; then + if pgrep -x "frpc" > /dev/null; then + exit 0 + else + exit 1 + fi +fi diff --git a/requirements.in.txt b/requirements.in.txt index 3a9ffc2..24d099b 100644 --- a/requirements.in.txt +++ b/requirements.in.txt @@ -1,5 +1,5 @@ fastapi ctranslate2 huggingface_hub -nc_py_api[app]>=0.16.0 +nc_py_api[app]>=0.20.0 sentencepiece diff --git a/requirements.txt b/requirements.txt index 3bc19ea..02ef0b1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,7 @@ httptools==0.6.1 httpx==0.27.0 huggingface-hub==0.24.6 idna==3.7 -nc-py-api==0.16.0 +nc-py-api==0.20.0 numpy==2.1.0 packaging==24.1 pydantic==2.8.2 diff --git a/start.sh b/start.sh new file mode 100644 index 0000000..82eaeb3 --- /dev/null +++ b/start.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors +# SPDX-License-Identifier: AGPL-3.0-or-later + +set -e + +# Only create a config file if HP_SHARED_KEY is set. +if [ -n "$HP_SHARED_KEY" ]; then + echo "HP_SHARED_KEY is set, creating /frpc.toml configuration file..." + if [ -d "/certs/frp" ]; then + echo "Found /certs/frp directory. Creating configuration with TLS certificates." + cat < /frpc.toml +serverAddr = "$HP_FRP_ADDRESS" +serverPort = $HP_FRP_PORT +loginFailExit = false + +transport.tls.enable = true +transport.tls.certFile = "/certs/frp/client.crt" +transport.tls.keyFile = "/certs/frp/client.key" +transport.tls.trustedCaFile = "/certs/frp/ca.crt" +transport.tls.serverName = "harp.nc" + +metadatas.token = "$HP_SHARED_KEY" + +[[proxies]] +remotePort = $APP_PORT +type = "tcp" +name = "$APP_ID" +[proxies.plugin] +type = "unix_domain_socket" +unixPath = "/tmp/exapp.sock" +EOF + else + echo "Directory /certs/frp not found. Creating configuration without TLS certificates." + cat < /frpc.toml +serverAddr = "$HP_FRP_ADDRESS" +serverPort = $HP_FRP_PORT +loginFailExit = false + +transport.tls.enable = false + +metadatas.token = "$HP_SHARED_KEY" + +[[proxies]] +remotePort = $APP_PORT +type = "tcp" +name = "$APP_ID" +[proxies.plugin] +type = "unix_domain_socket" +unixPath = "/tmp/exapp.sock" +EOF + fi +else + echo "HP_SHARED_KEY is not set. Skipping FRP configuration." +fi + +# If we have a configuration file and the shared key is present, start the FRP client +if [ -f /frpc.toml ] && [ -n "$HP_SHARED_KEY" ]; then + echo "Starting frpc in the background..." + frpc -c /frpc.toml & +fi + +# Start the main application (launch cmd for ExApp is an argument for this script) +echo "Starting application: $@" +exec "$@"