diff --git a/ansible/files/adminapi.sudoers.conf b/ansible/files/adminapi.sudoers.conf index fa7dae900..56278c7bf 100644 --- a/ansible/files/adminapi.sudoers.conf +++ b/ansible/files/adminapi.sudoers.conf @@ -1,3 +1,4 @@ +Cmnd_Alias KONG = /bin/systemctl start envoy.service, /bin/systemctl stop envoy.service, /bin/systemctl restart envoy.service, /bin/systemctl disable envoy.service, /bin/systemctl enable envoy.service, /bin/systemctl reload envoy.service Cmnd_Alias KONG = /bin/systemctl start kong.service, /bin/systemctl stop kong.service, /bin/systemctl restart kong.service, /bin/systemctl disable kong.service, /bin/systemctl enable kong.service, /bin/systemctl reload kong.service Cmnd_Alias POSTGREST = /bin/systemctl start postgrest.service, /bin/systemctl stop postgrest.service, /bin/systemctl restart postgrest.service, /bin/systemctl disable postgrest.service, /bin/systemctl enable postgrest.service Cmnd_Alias GOTRUE = /bin/systemctl start gotrue.service, /bin/systemctl stop gotrue.service, /bin/systemctl restart gotrue.service, /bin/systemctl disable gotrue.service, /bin/systemctl enable gotrue.service diff --git a/ansible/files/envoy.service b/ansible/files/envoy.service new file mode 100644 index 000000000..d38ffc916 --- /dev/null +++ b/ansible/files/envoy.service @@ -0,0 +1,24 @@ +[Unit] +Description=Envoy +After=postgrest.service gotrue.service adminapi.service +Wants=postgrest.service gotrue.service adminapi.service +Conflicts=kong.service + +[Service] +Type=simple +ExecStart=/opt/envoy-hot-restarter.py /opt/start-envoy.sh +ExecReload=/bin/kill -HUP $MAINPID +ExecStop=/bin/kill -TERM $MAINPID +User=envoy +Slice=services.slice +Restart=always +RestartSec=3 +LimitNOFILE=100000 + +# The envoy user is unpriviledged and thus not permited to bind on ports < 1024 +# Via systemd we grant the process a set of priviledges to bind to 80/443 +# See http://archive.vn/36zJU +AmbientCapabilities=CAP_NET_BIND_SERVICE + +[Install] +WantedBy=multi-user.target diff --git a/ansible/files/envoy_config/basic_auth.lua b/ansible/files/envoy_config/basic_auth.lua new file mode 100644 index 000000000..c1bf98f94 --- /dev/null +++ b/ansible/files/envoy_config/basic_auth.lua @@ -0,0 +1,12 @@ +function envoy_on_request(request_handle) + local authorization = request_handle:headers():get("authorization") + + if authorization and authorization:find("^[Bb][Aa][Ss][Ii][Cc] " .. request_handle:metadata():get("credentials")) then + return + end + + request_handle:respond({ + [":status"] = "401", + ["WWW-Authenticate"] = "Basic realm=\"Unknown\"" + }, "Unauthorized") +end diff --git a/ansible/files/envoy_config/cds.yaml b/ansible/files/envoy_config/cds.yaml new file mode 100644 index 000000000..7b9038235 --- /dev/null +++ b/ansible/files/envoy_config/cds.yaml @@ -0,0 +1,51 @@ +resources: + - '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster + name: admin-api + load_assignment: + cluster_name: admin-api + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 8085 + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + - '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster + name: gotrue + load_assignment: + cluster_name: gotrue + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 9999 + - '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster + name: postgrest + load_assignment: + cluster_name: postgrest + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 3000 + - '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster + name: postgrest-admin + load_assignment: + cluster_name: postgrest-admin + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 3001 + diff --git a/ansible/files/envoy_config/envoy.yaml b/ansible/files/envoy_config/envoy.yaml new file mode 100644 index 000000000..cbef636a1 --- /dev/null +++ b/ansible/files/envoy_config/envoy.yaml @@ -0,0 +1,23 @@ +dynamic_resources: + cds_config: + path_config_source: + path: /etc/envoy/cds.yaml + resource_api_version: V3 + lds_config: + path_config_source: + path: /etc/envoy/lds.yaml + resource_api_version: V3 +node: + cluster: cluster_0 + id: node_0 +overload_manager: + resource_monitors: + - name: envoy.resource_monitors.global_downstream_max_connections + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 500000 +stats_config: + stats_matcher: + reject_all: true + diff --git a/ansible/files/envoy_config/lds.yaml b/ansible/files/envoy_config/lds.yaml new file mode 100644 index 000000000..a012877e0 --- /dev/null +++ b/ansible/files/envoy_config/lds.yaml @@ -0,0 +1,265 @@ +resources: + - '@type': type.googleapis.com/envoy.config.listener.v3.Listener + name: http_listener + address: + socket_address: + address: 0.0.0.0 + port_value: 80 + filter_chains: + - filters: &ref_1 + - name: envoy.filters.network.http_connection_manager + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + generate_request_id: false + http_filters: + - name: envoy.filters.http.cors + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors + - name: envoy.filters.http.rbac + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC + rules: + action: DENY + policies: + api_key_missing: + permissions: + - any: true + principals: + - not_id: + or_ids: + ids: + - header: + name: apikey + present_match: true + - header: + name: ':path' + string_match: + contains: apikey= + api_key_not_valid: + permissions: + - any: true + principals: + - not_id: + or_ids: + ids: + - header: + name: apikey + string_match: + exact: anon_key + - header: + name: apikey + string_match: + exact: service_key + - header: + name: apikey + string_match: + exact: supabase_admin_key + - header: + name: ':path' + string_match: + contains: apikey=anon_key + - header: + name: ':path' + string_match: + contains: apikey=service_key + - header: + name: ':path' + string_match: + contains: apikey=supabase_admin_key + - name: envoy.filters.http.lua + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + source_codes: + basic_auth: + filename: /etc/envoy/basic_auth.lua + remove_apikey_query_parameter: + filename: /etc/envoy/remove_apikey_query_parameter.lua + - name: envoy.filters.http.router + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + dynamic_stats: false + local_reply_config: + mappers: + - filter: + and_filter: + filters: + - status_code_filter: + comparison: + value: + default_value: 403 + runtime_key: unused + - header_filter: + header: + name: ':path' + string_match: + prefix: /metrics/aggregated + invert_match: true + status_code: 401 + body_format_override: + json_format: + message: >- + `apikey` request header or query parameter is either + missing or invalid. Double check your Supabase `anon` + or `service_role` API key. + hint: '%RESPONSE_CODE_DETAILS%' + json_format_options: + sort_properties: false + route_config: + name: route_config_0 + virtual_hosts: + - name: virtual_host_0 + domains: + - '*' + typed_per_filter_config: + envoy.filters.http.cors: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.cors.v3.CorsPolicy + allow_origin_string_match: + - safe_regex: + regex: \* + allow_methods: GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS,TRACE,CONNECT + allow_headers: apikey,authorization,x-client-info + max_age: '3600' + routes: + - match: + safe_regex: + regex: >- + /auth/v1/(verify|callback|authorize|sso/saml/(acs|metadata|slo)) + route: + cluster: gotrue + regex_rewrite: + pattern: + regex: ^/auth/v1 + substitution: '' + retry_policy: + num_retries: 3 + retry_on: 5xx + typed_per_filter_config: + envoy.filters.http.rbac: &ref_0 + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute + - match: + prefix: /auth/v1/ + route: + cluster: gotrue + prefix_rewrite: / + - match: + prefix: /rest/v1/ + query_parameters: + - name: apikey + present_match: true + request_headers_to_remove: + - apikey + route: + cluster: postgrest + prefix_rewrite: / + typed_per_filter_config: + envoy.filters.http.lua: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + name: remove_apikey_query_parameter + - match: + prefix: /rest/v1/ + request_headers_to_remove: + - apikey + route: + cluster: postgrest + prefix_rewrite: / + - match: + prefix: /rest-admin/v1/ + query_parameters: + - name: apikey + present_match: true + request_headers_to_remove: + - apikey + route: + cluster: postgrest-admin + prefix_rewrite: / + typed_per_filter_config: + envoy.filters.http.lua: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + name: remove_apikey_query_parameter + - match: + prefix: /rest-admin/v1/ + request_headers_to_remove: + - apikey + route: + cluster: postgrest-admin + prefix_rewrite: / + - match: + path: /graphql/v1 + request_headers_to_add: + header: + key: Content-Profile + value: graphql_public + route: + cluster: postgrest + prefix_rewrite: /rpc/graphql + - match: + prefix: /admin/v1/ + route: + cluster: admin-api + prefix_rewrite: / + - match: + prefix: /customer/v1/privileged/ + route: + cluster: admin-api + prefix_rewrite: /privileged/ + typed_per_filter_config: + envoy.filters.http.lua: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + name: basic_auth + envoy.filters.http.rbac: *ref_0 + metadata: + filter_metadata: + envoy.filters.http.lua: + credentials: c2VydmljZV9yb2xlOnNlcnZpY2Vfa2V5 + - match: + prefix: /metrics/aggregated + route: + cluster: admin-api + prefix_rewrite: /supabase-internal/metrics + typed_per_filter_config: + envoy.filters.http.rbac: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute + rbac: + rules: + action: DENY + policies: + not_private_ip: + permissions: + - any: true + principals: + - not_id: + direct_remote_ip: + address_prefix: 10.0.0.0 + prefix_len: 8 + stat_prefix: ingress_http + - '@type': type.googleapis.com/envoy.config.listener.v3.Listener + name: https_listener + address: + socket_address: + address: 0.0.0.0 + port_value: 443 + filter_chains: + - filters: *ref_1 + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext + common_tls_context: + tls_certificates: + - certificate_chain: + filename: /etc/envoy/fullChain.pem + private_key: + filename: /etc/envoy/privKey.pem + diff --git a/ansible/files/envoy_config/remove_apikey_query_parameter.lua b/ansible/files/envoy_config/remove_apikey_query_parameter.lua new file mode 100644 index 000000000..059e7c83f --- /dev/null +++ b/ansible/files/envoy_config/remove_apikey_query_parameter.lua @@ -0,0 +1,5 @@ +function envoy_on_request(request_handle) + local path = request_handle:headers():get(":path") + + request_handle:headers():replace(":path", path:gsub("([&?])apikey=[^&]+&?", "%1"):gsub("&$", "")) +end diff --git a/ansible/files/kong_config/kong.service.j2 b/ansible/files/kong_config/kong.service.j2 index 6df4b55c6..5da813ac1 100644 --- a/ansible/files/kong_config/kong.service.j2 +++ b/ansible/files/kong_config/kong.service.j2 @@ -2,6 +2,7 @@ Description=Kong server After=postgrest.service gotrue.service adminapi.service Wants=postgrest.service gotrue.service adminapi.service +Conflicts=envoy.service [Service] Type=forking diff --git a/ansible/files/start_envoy.sh b/ansible/files/start_envoy.sh new file mode 100644 index 000000000..1ea07f915 --- /dev/null +++ b/ansible/files/start_envoy.sh @@ -0,0 +1,2 @@ +#!/bin/bash +exec /opt/envoy --config-path /etc/envoy/envoy.yaml --restart-epoch "$RESTART_EPOCH" diff --git a/ansible/playbook.yml b/ansible/playbook.yml index ececf09b9..5aef718f0 100644 --- a/ansible/playbook.yml +++ b/ansible/playbook.yml @@ -51,6 +51,11 @@ - install-postgrest - install-supabase-internal + - name: Install Envoy + import_tasks: tasks/setup-envoy.yml + tags: + - install-supabase-internal + - name: Install Kong import_tasks: tasks/setup-kong.yml tags: diff --git a/ansible/tasks/internal/admin-api.yml b/ansible/tasks/internal/admin-api.yml index fe40d6f46..4cb4cc6e6 100644 --- a/ansible/tasks/internal/admin-api.yml +++ b/ansible/tasks/internal/admin-api.yml @@ -1,7 +1,7 @@ - name: adminapi - system user user: name: adminapi - groups: root,admin,kong,pgbouncer,postgres,postgrest,systemd-journal,wal-g + groups: root,admin,envoy,kong,pgbouncer,postgres,postgrest,systemd-journal,wal-g append: yes - name: Move shell scripts to /root dir diff --git a/ansible/tasks/setup-envoy.yml b/ansible/tasks/setup-envoy.yml new file mode 100644 index 000000000..e62daa1a8 --- /dev/null +++ b/ansible/tasks/setup-envoy.yml @@ -0,0 +1,55 @@ +- name: Envoy - system user + ansible.builtin.user: + name: envoy + +- name: Envoy - download binary + ansible.builtin.get_url: + checksum: "{{ envoy_release_checksum }}" + dest: /opt/envoy + mode: u+x + owner: envoy + # yamllint disable-line rule:line-length + url: "https://github.com/envoyproxy/envoy/releases/download/v{{ envoy_release }}/envoy-{{ envoy_release }}-linux-aarch_64" + +- name: Envoy - download hot restarter script + ansible.builtin.get_url: + checksum: "{{ envoy_hot_restarter_release_checksum }}" + dest: /opt/envoy-hot-restarter.py + mode: u+x + owner: envoy + # yamllint disable-line rule:line-length + url: https://raw.githubusercontent.com/envoyproxy/envoy/v{{ envoy_release }}/restarter/hot-restarter.py + +- name: Envoy - bump up ulimit + community.general.pam_limits: + domain: envoy + limit_item: nofile + limit_type: soft + value: 4096 + +- name: Envoy - create service file + ansible.builtin.copy: + dest: /opt/start_envoy.sh + mode: u+x + owner: envoy + src: files/start_envoy.sh + +- name: Envoy - create configuration files + ansible.builtin.copy: + dest: /etc/envoy/ + mode: u=rw,g=rw,o=r + owner: envoy + src: files/envoy_config/ + +- name: Envoy - create service file + ansible.builtin.copy: + dest: /etc/systemd/system/envoy.service + mode: u=rw,g=r,o=r + src: files/envoy.service + +- name: Envoy - disable service + ansible.builtin.systemd: + daemon_reload: true + enabled: false + name: envoy + state: stopped diff --git a/ansible/vars.yml b/ansible/vars.yml index 9cb35e859..85f15e1bf 100644 --- a/ansible/vars.yml +++ b/ansible/vars.yml @@ -24,6 +24,10 @@ golang_version_checksum: arm64: sha256:99de2fe112a52ab748fb175edea64b313a0c8d51d6157dba683a6be163fd5eab amd64: sha256:74b9640724fd4e6bb0ed2a1bc44ae813a03f1e72a4c76253e2d5c015494430ba +envoy_release: 1.28.0 +envoy_release_checksum: sha1:b0a06e9cfb170f1993f369beaa5aa9d7ec679ce5 +envoy_hot_restarter_release_checksum: sha1:6d43b89d266fb2427a4b51756b649883b0617eda + kong_release_target: focal # if it works, it works kong_deb: kong_2.8.1_arm64.deb kong_deb_checksum: sha1:2086f6ccf8454fe64435252fea4d29d736d7ec61 diff --git a/common.vars.pkr.hcl b/common.vars.pkr.hcl index c1d683dae..d1dfe37a7 100644 --- a/common.vars.pkr.hcl +++ b/common.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.1.0.136" +postgres-version = "15.1.0.137" diff --git a/docker/all-in-one/Dockerfile b/docker/all-in-one/Dockerfile index 0e36d81b9..cc9a7fdda 100644 --- a/docker/all-in-one/Dockerfile +++ b/docker/all-in-one/Dockerfile @@ -8,6 +8,7 @@ ARG adminapi_release=0.48.0 ARG adminmgr_release=0.9.0 ARG vector_release=0.22.3 ARG postgres_exporter_release=0.9.0 +ARG envoy_release=1.28.0 FROM supabase/postgres:${postgres_version} as base ARG TARGETARCH @@ -60,12 +61,17 @@ FROM postgrest/postgrest:v${postgrest_release} as pgrst #################### FROM supabase/gotrue:v${gotrue_release} as gotrue +#################### +# Install Envoy +#################### +FROM envoyproxy/envoy:v${envoy_release} as envoy + #################### # Install Kong #################### FROM base as kong ARG kong_release -ADD "https://download.konghq.com/gateway-2.x-ubuntu-focal/pool/all/k/kong/kong_${kong_release}_${TARGETARCH}.deb" \ +ADD "https://packages.konghq.com/public/gateway-28/deb/ubuntu/pool/focal/main/k/ko/kong_${kong_release}/kong_${kong_release}_${TARGETARCH}.deb" \ /tmp/kong.deb #################### @@ -146,6 +152,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ COPY --from=pgrst /bin/postgrest /dist/ COPY --from=gotrue /usr/local/bin/gotrue /dist/ COPY --from=gotrue /usr/local/etc/gotrue /opt/gotrue/ +COPY --from=envoy /usr/local/bin/envoy /dist/ COPY --from=adminapi /tmp/supabase-admin-api /dist/ COPY --chown=root:root --from=adminmgr /tmp/admin-mgr /dist/ COPY --from=exporter /tmp/postgres_exporter /opt/postgres_exporter/ @@ -158,7 +165,7 @@ RUN ln -s /data/opt/supabase-admin-api /opt/supabase-admin-api \ && ln -s /data/opt/admin-mgr /usr/bin/admin-mgr # Scripts for adminapi -COPY ansible/files/admin_api_scripts /root +COPY ansible/files/admin_api_scripts /root COPY --chown=adminapi:adminapi docker/all-in-one/etc/adminapi /etc/adminapi COPY docker/all-in-one/etc/sudoers.d /etc/sudoers.d/ @@ -191,6 +198,9 @@ COPY --chown=postgrest:postgrest docker/all-in-one/etc/postgrest/generated.conf # Customizations for gotrue COPY docker/all-in-one/etc/gotrue.env /etc/gotrue.env +# Customizations for envoy +COPY --chown=envoy:envoy ansible/files/envoy_config/ /etc/envoy/ + # Customizations for kong COPY docker/all-in-one/etc/kong/kong.conf /etc/kong/kong.conf COPY docker/all-in-one/etc/kong/kong.yml /etc/kong/kong.yml @@ -214,9 +224,15 @@ ENV GOTRUE_SITE_URL=http://localhost:${PGRST_SERVER_PORT} ENV GOTRUE_API_PORT=9999 EXPOSE ${GOTRUE_API_PORT} +ENV ENVOY_HTTP_PORT=8000 +ENV ENVOY_HTTPS_PORT=8443 + ENV KONG_HTTP_PORT=8000 ENV KONG_HTTPS_PORT=8443 -EXPOSE ${KONG_HTTP_PORT} ${KONG_HTTPS_PORT} + +ENV HTTP_PORT=${ENVOY_HTTP_PORT:-KONG_HTTP_PORT} +ENV HTTP_PORT=${ENVOY_HTTPS_PORT:-KONG_HTTPS_PORT} +EXPOSE ${HTTP_PORT} ${HTTPS_PORT} ENV ADMIN_API_CERT_DIR=/etc/ssl/adminapi ENV ADMIN_API_PORT=8085 @@ -233,9 +249,10 @@ ENV VECTOR_API_PORT=9001 # Create system users RUN useradd --create-home --shell /bin/bash postgrest && \ useradd --create-home --shell /bin/bash gotrue && \ + useradd --create-home --shell /bin/bash envoy && \ useradd --create-home --shell /bin/bash pgbouncer -G postgres,ssl-cert && \ # root,admin,kong,pgbouncer,postgres,postgrest,systemd-journal,wal-g - useradd --create-home --shell /bin/bash adminapi -G root,kong,pgbouncer,postgres,postgrest,wal-g && \ + useradd --create-home --shell /bin/bash adminapi -G root,envoy,kong,pgbouncer,postgres,postgrest,wal-g && \ usermod --append --shell /bin/bash -G postgres vector RUN mkdir -p /etc/wal-g && \ chown -R adminapi:adminapi /etc/wal-g && \ diff --git a/docker/all-in-one/entrypoint.sh b/docker/all-in-one/entrypoint.sh index f857577db..86bcec548 100755 --- a/docker/all-in-one/entrypoint.sh +++ b/docker/all-in-one/entrypoint.sh @@ -155,7 +155,7 @@ function report_health { } function start_supervisor { - # Start health reporting + # Start health reporting report_health & # Start supervisord @@ -241,6 +241,11 @@ if [ "${AUTOSHUTDOWN_ENABLED:-}" == "true" ]; then sed -i "s/autostart=.*/autostart=true/" /etc/supervisor/db-only/supa-shutdown.conf fi +if [ "${ENVOY_ENABLED:-}" == "true" ]; then + sed -i "s/autostart=.*/autostart=true/" /etc/supervisor/services/envoy.conf + sed -i "s/autostart=.*/autostart=false/" /etc/supervisor/services/kong.conf +fi + if [ "${FAIL2BAN_DISABLED:-}" == "true" ]; then sed -i "s/autostart=.*/autostart=false/" /etc/supervisor/services/fail2ban.conf sed -i "s/autorestart=.*/autorestart=false/" /etc/supervisor/services/fail2ban.conf diff --git a/docker/all-in-one/etc/supervisor/services/envoy.conf b/docker/all-in-one/etc/supervisor/services/envoy.conf new file mode 100644 index 000000000..89231cc32 --- /dev/null +++ b/docker/all-in-one/etc/supervisor/services/envoy.conf @@ -0,0 +1,8 @@ +[program:envoy] +command=/opt/envoy --config-path /etc/envoy/envoy.yaml +user=envoy +autorestart=false +autostart=false +stdout_logfile=/var/log/services/envoy.log +redirect_stderr=true +stdout_logfile_maxbytes=10MB diff --git a/docker/all-in-one/init/configure-envoy.sh b/docker/all-in-one/init/configure-envoy.sh new file mode 100755 index 000000000..05d6084a9 --- /dev/null +++ b/docker/all-in-one/init/configure-envoy.sh @@ -0,0 +1,43 @@ +#!/bin/bash +set -eou pipefail + +ENVOY_LDS_CONF=/etc/envoy/lds.yaml +touch /var/log/services/envoy.log + +/usr/local/bin/configure-shim.sh /dist/envoy /opt/envoy + +if [ "$DATA_VOLUME_MOUNTPOINT" ]; then + ENVOY_CUSTOM_DIR="${DATA_VOLUME_MOUNTPOINT}/etc/envoy" + mkdir -p "$ENVOY_CUSTOM_DIR" + if [ ! -f "$CONFIGURED_FLAG_PATH" ]; then + echo "Copying existing custom envoy config from /etc/envoy/ to ${ENVOY_CUSTOM_DIR}" + cp -R "/etc/envoy/." "${ENVOY_CUSTOM_DIR}/" + fi + + rm -rf "/etc/envoy" + ln -s "$ENVOY_CUSTOM_DIR" "/etc/envoy" + chown -R adminapi:adminapi "/etc/envoy" + + chown -R adminapi:adminapi "$ENVOY_CUSTOM_DIR" + chmod g+rx "$ENVOY_CUSTOM_DIR" +fi + +if [ -f "${INIT_PAYLOAD_PATH:-}" ]; then + echo "init envoy payload" + tar -xzvf "$INIT_PAYLOAD_PATH" -C / ./etc/envoy/ + chown -R adminapi:adminapi /etc/envoy +fi + +# Inject project specific configuration +sed -i -e "s|anon_key|$ANON_KEY|g" \ + -e "s|service_key|$SERVICE_ROLE_KEY|g" \ + -e "s|supabase_admin_key|$ADMIN_API_KEY|g" \ + "$ENVOY_LDS_CONF" + +# Update Envoy ports +sed -i "s|:80 |:$ENVOY_HTTP_PORT |g" "$ENVOY_LDS_CONF" +sed -i "s|:443 |:$ENVOY_HTTPS_PORT |g" "$ENVOY_LDS_CONF" +sed -i "s|:3000 |:$PGRST_SERVER_PORT |g" "$ENVOY_LDS_CONF" +sed -i "s|:3001 |:$PGRST_ADMIN_SERVER_PORT |g" "$ENVOY_LDS_CONF" +sed -i "s|:8085 |:$ADMIN_API_PORT |g" "$ENVOY_LDS_CONF" +sed -i "s|:9999 |:$GOTRUE_API_PORT |g" "$ENVOY_LDS_CONF"