Skip to content

Use the flexible runtime for the webapp #4226

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ github_action_go_setup:
fi
# NOTE: We prune before generate, because node_modules are embedded into the
# binary (and part of the build).
go_build: git mockgen github_action_go_setup
make webapp_node_modules_prod
go_build: git mockgen github_action_go_setup webapp_node_modules_prod
go generate ./...
# Check all packages without producing any output.
go build -v ./...
Expand All @@ -77,7 +76,7 @@ go_lint: golint go_test_tag_lint
golangci_lint: golangci-lint github_action_go_setup
golangci-lint cache clean
golangci-lint run ./api/...

go_test_tag_lint:
@ # Printing a list of test files without +build tag, asserting empty...
@TAGLESS=$$(grep -PL '\/\/(\s?\+build|go:build) !?(small|medium|large|cloud)' $(GO_TEST_FILES)); \
Expand Down Expand Up @@ -204,10 +203,12 @@ package_service: var-APP_PATH
# Trim the potential "app.staging.yaml" suffix.
if [[ "$(APP_PATH)" == "api/query/cache/service"* ]]; then \
APP_PATH="api/query/cache/service"; \
elif [[ "$(APP_PATH)" == "webapp/web"* ]]; then \
APP_PATH="webapp/web"; \
else \
APP_PATH="$(APP_PATH)"; \
fi ; \
if [[ "$${APP_PATH}" == "api/query/cache/service" ]]; then \
if [[ "$${APP_PATH}" == "api/query/cache/service" || "$${APP_PATH}" == "webapp/web" ]]; then \
TMP_DIR=$$(mktemp -d); \
rm -rf $(WPTD_PATH)$${APP_PATH}/wpt.fyi; \
cp -r $(WPTD_PATH)* $${TMP_DIR}/; \
Expand Down Expand Up @@ -292,6 +293,7 @@ deploy_staging: deployment_state var-BRANCH_NAME
util/deploy.sh -q -b $(BRANCH_NAME) $(APP_PATH); \
fi
rm -rf $(WPTD_PATH)api/query/cache/service/wpt.fyi
rm -rf $(WPTD_PATH)webapp/web/wpt.fyi

cleanup_staging_versions: gcloud_login
$(WPTD_PATH)/util/cleanup-versions.sh
Expand All @@ -300,6 +302,7 @@ deploy_production: deployment_state
gcloud config set project wptdashboard
util/deploy.sh -r $(APP_PATH)
rm -rf $(WPTD_PATH)api/query/cache/service/wpt.fyi
rm -rf $(WPTD_PATH)webapp/web/wpt.fyi

webapp_node_modules_all: node
cd webapp; npm install
Expand Down
2 changes: 1 addition & 1 deletion api/query/cache/service/.gcloudignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Files matching the following rules won't be uploaded to AppEngine (webapp).
# Files matching the following rules won't be uploaded to AppEngine (searchcache).
# The syntax is the same as `.gitignore`; we do not use `.gitignore` directly
# because we need to update some generated files.

Expand Down
6 changes: 4 additions & 2 deletions api/query/cache/service/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ RUN apt-get update
RUN apt-get install -qy --no-install-suggests git
WORKDIR /go/src/wpt.fyi

COPY wpt.fyi .
# Default to the existing path when running inside the development docker container.
ARG LOCAL_SRC=wpt.fyi
COPY $LOCAL_SRC .
RUN CGO_ENABLED=0 /usr/local/go/bin/go build -o ../../bin/app ./api/query/cache/service

# Application image.
FROM gcr.io/distroless/static-debian11
FROM gcr.io/distroless/static-debian12

COPY --from=builder /go/bin/app /usr/local/bin/app

Expand Down
3 changes: 1 addition & 2 deletions docs/app-engine.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ each of which has an `app.yaml` file in its directory and in some cases an
3. **searchcache**: `/api/query/cache/service/`, an in-memory cache and query
executor for [structured searches](../api/query/README.md).

The `default` service is a standard App Engine service while the other two are
Flex.
All services are App Engine Flex services.

## Deploy the app

Expand Down
33 changes: 0 additions & 33 deletions webapp/web/.gcloudignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,5 @@
# The syntax is the same as `.gitignore`; we do not use `.gitignore` directly
# because we need to update some generated files.

# Tests
*_test.go
/webapp/static/wptd-metrics/
/webapp/static/24278ab617/
/webdriver/
test/

# Configurations
.eslintrc.json
package-lock.json
package.json
renovate.json
wct.conf.json

# Misc
.git/
.github/
.lighthouseci/
.vscode/
/docs/
/git/
CODE_OF_CONDUCT.md
CONTRIBUTING.md
ISSUE_TEMPLATE.md
ISSUE_TEMPLATE/
PULL_REQUEST_TEMPLATE.md
README.md

# Google Cloud secret
client-secret.json

# Other services
/api/query/cache/service/
/results-processor/
/util/
34 changes: 34 additions & 0 deletions webapp/web/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Production deployment spec for the webapp.

FROM golang:1.22.11-bookworm as builder

RUN apt-get update
RUN apt-get install -qy --no-install-suggests git sudo
WORKDIR /go/src/wpt.fyi

# Default to the existing path when running inside the development docker container.
ARG LOCAL_SRC=wpt.fyi
COPY $LOCAL_SRC .
RUN CGO_ENABLED=0 make go_build

# Application image.
FROM nginx:1.26.3-alpine3.20

# Copy your application binary
COPY --from=builder /go/src/wpt.fyi/web /usr/local/bin/app

# Copy static assets
COPY --from=builder /go/src/wpt.fyi/webapp/dynamic-components /usr/share/nginx/html/dynamic-components/
COPY --from=builder /go/src/wpt.fyi/webapp/components /usr/share/nginx/html/components/
COPY --from=builder /go/src/wpt.fyi/webapp/static /usr/share/nginx/html/static/
COPY --from=builder /go/src/wpt.fyi/webapp/templates /usr/share/nginx/html/templates/
COPY --from=builder /go/src/wpt.fyi/webapp/views /usr/share/nginx/html/views/
RUN chmod -R a+r /usr/share/nginx/html

# Copy the Nginx configuration (see below)
COPY nginx.conf /etc/nginx/nginx.conf

# create log dir configured in nginx.conf
RUN mkdir -p /var/log/app_engine

CMD ["/bin/sh", "-c", "nginx -g 'daemon off;' & PORT=8081 /usr/local/bin/app"]
6 changes: 5 additions & 1 deletion webapp/web/app.staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

runtime: go122
runtime: custom
env: flex
instance_class: F4_1G

inbound_services:
- warmup

default_expiration: "1d"

# TODO: can we remove this now that service 'default' is not App Engine
# Standard? Same change for app.yaml and the VPC mention in app-engine.md.
vpc_access_connector:
name: projects/wptdashboard-staging/locations/us-east4/connectors/appengine-connector

env_variables:
REDISHOST: "10.171.142.203"
REDISPORT: "6379"

# TODO: Remove these handlers and align with app.yaml once #4231 is completed.
# Also refer to dispatch.yaml for higher-priority routing rules.
handlers:
# Special dynamic components:
Expand Down
39 changes: 2 additions & 37 deletions webapp/web/app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

runtime: go122
runtime: custom
env: flex
instance_class: F4_1G

inbound_services:
Expand All @@ -17,39 +18,3 @@ env_variables:
REDISHOST: "10.171.142.203"
REDISPORT: "6379"

# Also refer to dispatch.yaml for higher-priority routing rules.
handlers:
# Special dynamic components:
- url: /dynamic-components/wpt-env-flags.js
script: auto
secure: always
- url: /node_modules/.*
script: auto
secure: always
# Static files:
- url: /static
static_dir: webapp/static
secure: always
- url: /favicon.ico
static_files: webapp/static/favicon.ico
upload: webapp/static/favicon.ico
secure: always
- url: /robots.txt
static_files: webapp/static/robots.txt
upload: webapp/static/robots.txt
secure: always
# Static files that change often (i.e. our own code).
- url: /components
static_dir: webapp/components
expiration: 10m
secure: always
- url: /views
static_dir: webapp/views
expiration: 10m
secure: always


# Everything else (templates & APIs):
- url: /.*
script: auto
secure: always
76 changes: 76 additions & 0 deletions webapp/web/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
events {
worker_connections 768;
}

http {
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;

# Logs will appear on the Google Developer's Console when logged to this
# directory.
access_log /var/log/app_engine/app.log;
error_log /var/log/app_engine/app.log;

gzip on;
gzip_disable "msie6";

server {
# Google App Engine expects the runtime to serve HTTP traffic from
# port 8080.
listen 8080;
# Special dynamic components:
location /dynamic-components/wpt-env-flags.js {
proxy_pass http://127.0.0.1:8081/dynamic-components/wpt-env-flags.js;
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;
}

location /node_modules/ {
proxy_pass http://127.0.0.1:8081/node_modules/;
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;
}

# Static files:
location /static {
root /usr/share/nginx/html;
}

location /favicon.ico {
root /usr/share/nginx/html;
}

location /robots.txt {
root /usr/share/nginx/html;
}

# Static files that change often:
location /components {
root /usr/share/nginx/html;
expires 10m;
}

location /views {
root /usr/share/nginx/html;
expires 10m;
}

# Everything else (templates & APIs):
location / {
proxy_pass http://127.0.0.1:8081;
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;
}
}
}