diff --git a/frontend/Dockerfile b/frontend/Dockerfile deleted file mode 100644 index 4b6542201..000000000 --- a/frontend/Dockerfile +++ /dev/null @@ -1,72 +0,0 @@ -# syntax=docker/dockerfile:1 -# ┬─┐┬ ┐o┬ ┬─┐ -# │─││ │││ │ │ -# ┘─┘┘─┘┘┘─┘┘─┘ - -FROM --platform=$BUILDPLATFORM node:20.11.0-alpine AS builder - -WORKDIR /build - -ARG USE_RELEASE=false -ARG RELEASE_VERSION=unstable -ENV PNPM_CACHE_FOLDER .cache/pnpm/ -ENV PUPPETEER_SKIP_DOWNLOAD true - -COPY package.json ./ -COPY pnpm-lock.yaml ./ -COPY patches ./patches/ - -RUN if [ "$USE_RELEASE" != true ]; then \ - # https://pnpm.io/installation#using-corepack - corepack enable && \ - pnpm install; \ - fi - -COPY . ./ - -RUN if [ "$USE_RELEASE" != true ]; then \ - apk add --no-cache --virtual .build-deps git jq && \ - git describe --tags --always --abbrev=10 | sed 's/-/+/; s/^v//; s/-g/-/' | \ - xargs -0 -I{} jq -Mcnr --arg version {} '{VERSION:$version}' | \ - apk del .build-deps; \ - fi - -RUN if [ "$USE_RELEASE" = true ]; then \ - wget "https://dl.vikunja.io/frontend/vikunja-frontend-${RELEASE_VERSION}.zip" -O frontend-release.zip && \ - unzip frontend-release.zip -d dist/; \ - else \ - # we don't use corepack prepare here by intend since - # we have renovate to keep our dependencies up to date - # Build the frontend - pnpm run build; \ - fi - -# ┌┐┐┌─┐o┌┐┐┐ │ -# ││││ ┬││││┌┼┘ -# ┘└┘┘─┘┘┘└┘┘ └ - -FROM nginx:stable-alpine AS runner -WORKDIR /usr/share/nginx/html -LABEL maintainer="maintainers@vikunja.io" - -ENV VIKUNJA_HTTP_PORT 80 -ENV VIKUNJA_HTTP2_PORT 81 -ENV VIKUNJA_LOG_FORMAT main -ENV VIKUNJA_API_URL /api/v1 -ENV VIKUNJA_SENTRY_ENABLED false -ENV VIKUNJA_SENTRY_DSN https://85694a2d757547cbbc90cd4b55c5a18d@o1047380.ingest.sentry.io/6024480 -ENV VIKUNJA_PROJECT_INFINITE_NESTING_ENABLED false -ENV VIKUNJA_ALLOW_ICON_CHANGES true -ENV VIKUNJA_CUSTOM_LOGO_URL "''" - -COPY docker/injector.sh /docker-entrypoint.d/50-injector.sh -COPY docker/ipv6-disable.sh /docker-entrypoint.d/60-ipv6-disable.sh -COPY docker/nginx.conf /etc/nginx/nginx.conf -COPY docker/templates/. /etc/nginx/templates/ -# copy compiled files from stage 1 -COPY --from=builder /build/dist ./ -# manage permissions -RUN chmod 0755 /docker-entrypoint.d/*.sh /etc/nginx/templates && \ - chmod -R 0644 /etc/nginx/nginx.conf && \ - chown -R nginx:nginx ./ /etc/nginx/conf.d /etc/nginx/templates && \ - rm -f /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh diff --git a/frontend/docker/injector.sh b/frontend/docker/injector.sh deleted file mode 100755 index 244e211dd..000000000 --- a/frontend/docker/injector.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env sh -set -e - -echo "info: API URL is $VIKUNJA_API_URL" -echo "info: Sentry enabled: $VIKUNJA_SENTRY_ENABLED" - -# Escape the variable to prevent sed from complaining -VIKUNJA_API_URL="$(echo "$VIKUNJA_API_URL" | sed -r 's/([:;])/\\\1/g')" -VIKUNJA_SENTRY_DSN="$(echo "$VIKUNJA_SENTRY_DSN" | sed -r 's/([:;])/\\\1/g')" - -sed -ri "s:^(\s*window.API_URL\s*=)\s*.+:\1 '${VIKUNJA_API_URL}':g" /usr/share/nginx/html/index.html -sed -ri "s:^(\s*window.SENTRY_ENABLED\s*=)\s*.+:\1 ${VIKUNJA_SENTRY_ENABLED}:g" /usr/share/nginx/html/index.html -sed -ri "s:^(\s*window.SENTRY_DSN\s*=)\s*.+:\1 '${VIKUNJA_SENTRY_DSN}':g" /usr/share/nginx/html/index.html -sed -ri "s:^(\s*window.PROJECT_INFINITE_NESTING_ENABLED\s*=)\s*.+:\1 '${VIKUNJA_PROJECT_INFINITE_NESTING_ENABLED}':g" /usr/share/nginx/html/index.html -sed -ri "s:^(\s*window.ALLOW_ICON_CHANGES\s*=)\s*.+:\1 ${VIKUNJA_ALLOW_ICON_CHANGES}:g" /usr/share/nginx/html/index.html -sed -ri "s:^(\s*window.CUSTOM_LOGO_URL\s*=)\s*.+:\1 ${VIKUNJA_CUSTOM_LOGO_URL}:g" /usr/share/nginx/html/index.html - -date -uIseconds | xargs echo 'info: started at' diff --git a/frontend/docker/ipv6-disable.sh b/frontend/docker/ipv6-disable.sh deleted file mode 100755 index 5d0d00f46..000000000 --- a/frontend/docker/ipv6-disable.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env sh -set -e - -if [ ! -f "/proc/net/if_inet6" ]; then - echo "info: IPv6 is not available! Removing IPv6 listen configuration" - find /etc/nginx/conf.d -name '*.conf' -type f | \ - while IFS= read -r CONFIG; do - sed -r '/^\s*listen\s*\[::\]:.+$/d' "$CONFIG" > "$CONFIG.temp" - if ! diff -U 5 "$CONFIG" "$CONFIG.temp" > "$CONFIG.diff"; then - echo "info: Removing IPv6 lines from $CONFIG" | \ - cat - "$CONFIG.diff" - echo "# IPv6 is disabled because /proc/net/if_inet6 was not found" | \ - cat - "$CONFIG.temp" > "$CONFIG" - else - echo "info: Skipping $CONFIG because it does not have IPv6 listen" - fi - rm -f "$CONFIG.temp" "$CONFIG.diff" - done -fi diff --git a/frontend/docker/nginx.conf b/frontend/docker/nginx.conf deleted file mode 100644 index 892cd3e76..000000000 --- a/frontend/docker/nginx.conf +++ /dev/null @@ -1,111 +0,0 @@ -# Generated by nginxconfig.io -# https://www.digitalocean.com/community/tools/nginx?domains.0.server.domain=localhost&domains.0.server.documentRoot=%2Fusr%2Fshare%2Fnginx%2Fhtml&domains.0.server.cdnSubdomain=true&domains.0.https.https=false&domains.0.php.php=false&domains.0.routing.index=index.html&domains.0.routing.fallbackHtml=true&domains.0.routing.fallbackPhp=false&global.performance.assetsExpiration=1d&global.performance.mediaExpiration=1d&global.performance.svgExpiration=1d&global.performance.fontsExpiration=1d&global.logging.accessLog=%2Fdev%2Fstdout&global.logging.errorLog=%2Fdev%2Fstderr%20warn&global.logging.logNotFound=true&global.nginx.user=nginx&global.nginx.pid=%2Fvar%2Frun%2Fnginx.pid&global.nginx.clientMaxBodySize=50&global.docker.dockerfile=true&global.tools.modularizedStructure=false&global.tools.symlinkVhost=false -# and then edited manually ;) - -pid /tmp/nginx.pid; -worker_processes auto; - -events { - multi_accept on; - worker_connections 1024; -} - -http { - charset utf-8; - sendfile on; - tcp_nopush on; - tcp_nodelay on; - server_tokens off; - types_hash_max_size 2048; - types_hash_bucket_size 64; - - # rootless - client_body_temp_path /tmp/client_temp; - proxy_temp_path /tmp/proxy_temp_path; - fastcgi_temp_path /tmp/fastcgi_temp; - uwsgi_temp_path /tmp/uwsgi_temp; - scgi_temp_path /tmp/scgi_temp; - - # MIME - include mime.types; - default_type application/octet-stream; - types { - application/manifest+json webmanifest; - } - - # Logging - log_format json escape=json - '{' - '"bytes_sent": "$bytes_sent",' - '"http_user_agent": "$http_user_agent",' - '"nginx_version": "$nginx_version",' - '"query_string": "$query_string",' - '"realip_remote_addr": "$realip_remote_addr",' - '"remote_addr": "$remote_addr",' - '"remote_user": "$remote_user",' - '"request_length": "$request_length",' - '"request_method": "$request_method",' - '"request_time": "$request_time",' - '"server_addr": "$server_addr",' - '"server_port": "$server_port",' - '"server_protocol": "$server_protocol",' - '"status": "$status",' - '"time_local": "$time_local",' - '"uri": "$uri"' - '}'; - - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - - access_log /dev/stdout main; - error_log /dev/stderr warn; - - keepalive_timeout 65; - - # compression - gzip on; - gzip_vary on; - gzip_proxied any; - gzip_comp_level 6; - gzip_buffers 16 8k; - gzip_http_version 1.1; - gzip_min_length 256; - gzip_types - text/plain - text/css - application/json - application/x-javascript - application/javascript - text/xml - application/xml - application/xml+rss - text/javascript - application/vnd.ms-fontobject - application/x-font-ttf - font/opentype - image/svg+xml - image/x-icon - audio/wav; - - map_hash_max_size 128; - map_hash_bucket_size 128; - - map $sent_http_content_type $expires { - default off; - text/css max; - application/javascript max; - text/javascript max; - application/vnd.ms-fontobject max; - application/x-font-ttf max; - font/opentype max; - font/woff2 max; - image/svg+xml max; - image/x-icon max; - audio/wav max; - ~images/ max; - ~font/ max; - } - - include /etc/nginx/conf.d/*.conf; -} diff --git a/frontend/docker/templates/default.conf.template b/frontend/docker/templates/default.conf.template deleted file mode 100644 index 250b8b2fa..000000000 --- a/frontend/docker/templates/default.conf.template +++ /dev/null @@ -1,85 +0,0 @@ -server { - listen ${VIKUNJA_HTTP_PORT}; - listen [::]:${VIKUNJA_HTTP_PORT}; - ## Needed when behind HAProxy with SSL termination + HTTP/2 support - listen ${VIKUNJA_HTTP2_PORT} default_server http2 proxy_protocol; - listen [::]:${VIKUNJA_HTTP2_PORT} default_server http2 proxy_protocol; - - server_name _; - expires $expires; - root /usr/share/nginx/html; - access_log /dev/stdout ${VIKUNJA_LOG_FORMAT}; - # security headers - add_header X-XSS-Protection "1; mode=block" always; - add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "no-referrer-when-downgrade" always; - add_header Content-Security-Policy "default-src 'self' http: https: ws: wss: data: blob: 'unsafe-inline'; frame-ancestors 'self';" always; - add_header Permissions-Policy "interest-cohort=()" always; - - # . files - location ~ /\.(?!well-known) { - deny all; - } - - # assume that everything else is handled by the application router, by injecting the index.html. - location / { - autoindex off; - expires off; - add_header Cache-Control "public, max-age=0, s-maxage=0, must-revalidate" always; - try_files $uri /index.html =404; - } - - # Disable caching for sw - location = /sw.js { - autoindex off; - expires off; - add_header Cache-Control "public, max-age=0, s-maxage=0, must-revalidate" always; - } - - # Disable caching for webmanifest - location = /manifest.webmanifest { - autoindex off; - expires off; - add_header Cache-Control "public, max-age=0, s-maxage=0, must-revalidate" always; - } - - # favicon.ico - location = /favicon.ico { - log_not_found off; - access_log off; - } - - # robots.txt - location = /robots.txt { - log_not_found off; - access_log off; - expires -1; # no-cache - } - - location = /ready { - return 200 ""; - access_log off; - expires -1; # no-cache - } - - # all assets contain hash in filename, cache forever - location ^~ /assets/ { - add_header Cache-Control "public, max-age=31536000, s-maxage=31536000, immutable"; - try_files $uri =404; - } - - # all workbox scripts are compiled with hash in filename, cache forever3 - location ^~ /workbox- { - add_header Cache-Control "public, max-age=31536000, s-maxage=31536000, immutable"; - try_files $uri =404; - } - - # assets, media - location ~* .(txt|webmanifest|css|js|mjs|map|svg|jpg|jpeg|png|ico|ttf|woff|woff2|wav)$ { - try_files $uri $uri/ =404; - } - - error_page 500 502 503 504 /50x.html; - location = /50x.html { } - -}