-
-
Notifications
You must be signed in to change notification settings - Fork 690
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
Deploy a live instance of demos/apache-proxy #1522
Comments
Should just be a case of deploying this FROM python:3-alpine
RUN apk add --no-cache \
apache2 \
apache2-proxy \
bash
RUN pip install datasette
ENV TINI_VERSION v0.18.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static /tini
RUN chmod +x /tini
# Append this to the end of the default httpd.conf file
RUN echo $'ServerName localhost\n\
\n\
<Proxy *>\n\
Order deny,allow\n\
Allow from all\n\
</Proxy>\n\
\n\
ProxyPass /foo/bar/ http://localhost:9000/\n\
Header add X-Proxied-By "Apache2"' >> /etc/apache2/httpd.conf
RUN echo $'<a href="/foo/bar/">Datasette</a>' > /var/www/localhost/htdocs/index.html
WORKDIR /app
ADD https://latest.datasette.io/fixtures.db /app/fixtures.db
RUN echo $'#!/usr/bin/env bash\n\
set -e\n\
\n\
httpd -D FOREGROUND &\n\
datasette fixtures.db --setting base_url "/foo/bar/" -p 9000 &\n\
\n\
wait -n' > /app/start.sh
RUN chmod +x /app/start.sh
EXPOSE 80
ENTRYPOINT ["/tini", "--", "/app/start.sh"] I can follow this TIL: https://til.simonwillison.net/cloudrun/ship-dockerfile-to-cloud-run |
This is frustrating: I have the following Dockerfile: FROM python:3-alpine
RUN apk add --no-cache \
apache2 \
apache2-proxy \
bash
RUN pip install datasette
ENV TINI_VERSION v0.18.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static /tini
RUN chmod +x /tini
# Append this to the end of the default httpd.conf file
RUN echo $'ServerName localhost\n\
\n\
<Proxy *>\n\
Order deny,allow\n\
Allow from all\n\
</Proxy>\n\
\n\
ProxyPass /prefix/ http://localhost:8001/\n\
Header add X-Proxied-By "Apache2"' >> /etc/apache2/httpd.conf
RUN echo $'<a href="/prefix/">Datasette</a>' > /var/www/localhost/htdocs/index.html
WORKDIR /app
ADD https://latest.datasette.io/fixtures.db /app/fixtures.db
RUN echo $'#!/usr/bin/env bash\n\
set -e\n\
\n\
httpd -D FOREGROUND &\n\
datasette fixtures.db --setting base_url "/prefix/" -h 0.0.0.0 -p 8001 &\n\
\n\
wait -n' > /app/start.sh
RUN chmod +x /app/start.sh
EXPOSE 80
ENTRYPOINT ["/tini", "--", "/app/start.sh"] It works fine when I run it locally:
But when I deploy it to Cloud Run with the following script: #!/bin/bash
# https://til.simonwillison.net/cloudrun/ship-dockerfile-to-cloud-run
NAME="datasette-apache-proxy-demo"
PROJECT=$(gcloud config get-value project)
IMAGE="gcr.io/$PROJECT/$NAME"
gcloud builds submit --tag $IMAGE
gcloud run deploy \
--allow-unauthenticated \
--platform=managed \
--image $IMAGE $NAME \
--port 80 It serves the
Cloud Run logs: |
Oh weird, it started working: https://datasette-apache-proxy-demo-j7hipcg4aq-uc.a.run.app/prefix/fixtures/sortable |
Demo code is now at: https://github.com/simonw/datasette/tree/main/demos/apache-proxy |
I wan a GitHub Action which I can manually activate to deploy a new version of that demo... and I want it to bake in the latest release of Datasette so I can use it to demonstrate bug fixes. |
I want to be able to use build arguments to specify which commit version or branch of Datasette to deploy. This is proving hard to work out. I have this in my Dockerfile now:
Which works locally:
But I can't figure out the right incantation to pass to |
Do I have to use |
Wrote a TIL about |
That 503 error is really frustrating: I have a deploy running at https://apache-proxy-demo.datasette.io/prefix/ and after a fresh deploy it serves 503 errors for quite a while - then eventually starts working. |
https://apache-proxy-demo.datasette.io/prefix/fixtures/compound_three_primary_keys has broken suggested facet links - they go to |
Yup, that fixed it. |
I have a hunch that running |
I figured out a recipe to run FROM python:3-alpine
# openrc gives us rc-service
RUN apk add --no-cache \
openrc \
apache2 \
apache2-proxy \
bash
ARG DATASETTE_REF
RUN pip install https://github.com/simonw/datasette/archive/${DATASETTE_REF}.zip
# Append this to the end of the default httpd.conf file
RUN echo -e 'ServerName localhost\n\
\n\
<Proxy *>\n\
Order deny,allow\n\
Allow from all\n\
</Proxy>\n\
\n\
ProxyPreserveHost On\n\
ProxyPass /prefix/ http://127.0.0.1:8001/\n\
Header add X-Proxied-By "Apache2"' >> /etc/apache2/httpd.conf
RUN echo '<a href="/prefix/">Datasette</a>' > /var/www/localhost/htdocs/index.html
WORKDIR /app
ADD https://latest.datasette.io/fixtures.db /app/fixtures.db
EXPOSE 80
# RUN echo -e "#!/bin/bash\nopenrc default\nrc-service apache2 start;\ndatasette /app/fixtures.db --setting base_url '/prefix/' --version-note '${DATASETTE_REF}' -h 0.0.0.0 -p 8001" > /app/start.sh
RUN echo "#!/bin/bash" >> start.sh
RUN echo "openrc default" >> start.sh
RUN echo "rc-service apache2 start" >> start.sh
RUN echo "datasette /app/fixtures.db --setting base_url '/prefix/' --version-note '${DATASETTE_REF}' -h 0.0.0.0 -p 8001" >> /app/start.sh
RUN chmod +x /app/start.sh
CMD /app/start.sh I'm going to try this on Cloud Run and see if it fixes the 503s One annoying thing about this: Ctrl+C on my laptop no longer stops the container, I have to |
Deploy to Cloud Run appears to hang here:
Waiting for health check to begin makes it sound like the container didn't start properly. |
I'm going to try running Apache with |
Again, that approach worked on my laptop but when deployed to Cloud Run mostly gave me 503 errors for the I did this: RUN echo "#!/bin/bash" >> start.sh
# Start Datasette running in background with &
RUN echo "datasette /app/fixtures.db --setting base_url '/prefix/' --version-note '${DATASETTE_REF}' -h 0.0.0.0 -p 8001 &" >> /app/start.sh
RUN echo "httpd -D FOREGROUND" >> /app/start.sh
RUN chmod +x /app/start.sh
CMD /app/start.sh |
https://docs.docker.com/config/containers/multi-service_container/ suggests https://stackoverflow.com/a/49100302/6083 has a neat looking recipe for than in Alpine:
|
OK, that works on my laptop - and Ctrl+C quits it, which is nice:
Here's my new Dockerfile: FROM python:3-alpine
RUN apk add --no-cache \
apache2 \
apache2-proxy \
supervisor \
bash
ARG DATASETTE_REF
RUN pip install https://github.com/simonw/datasette/archive/${DATASETTE_REF}.zip
# Append this to the end of the default httpd.conf file
RUN echo -e 'ServerName localhost\n\
\n\
<Proxy *>\n\
Order deny,allow\n\
Allow from all\n\
</Proxy>\n\
\n\
ProxyPreserveHost On\n\
ProxyPass /prefix/ http://127.0.0.1:8001/\n\
Header add X-Proxied-By "Apache2"' >> /etc/apache2/httpd.conf
RUN echo '<a href="/prefix/">Datasette</a>' > /var/www/localhost/htdocs/index.html
WORKDIR /app
ADD https://latest.datasette.io/fixtures.db /app/fixtures.db
EXPOSE 80
RUN echo "[supervisord]" >> /app/supervisord.conf
RUN echo "nodaemon=true" >> /app/supervisord.conf
RUN echo "" >> /app/supervisord.conf
RUN echo "[program:httpd]" >> /app/supervisord.conf
RUN echo "command=httpd -D FOREGROUND" >> /app/supervisord.conf
RUN echo "" >> /app/supervisord.conf
RUN echo "[program:datasette]" >> /app/supervisord.conf
RUN echo "command=datasette /app/fixtures.db --setting base_url '/prefix/' --version-note '${DATASETTE_REF}' -h 0.0.0.0 -p 8001" >> /app/supervisord.conf
CMD ["/usr/bin/supervisord", "-c", "/app/supervisord.conf"] |
So frustrating, that's giving me the same problem after being deployed! 503 errors for the first while, then it starts working. |
Aha! This could be the clue I was looking for: https://www.reddit.com/r/googlecloud/comments/fmkx63/comment/fl5csty/?utm_source=reddit&utm_medium=web2x&context=3
Maybe the |
Based on https://medium.com/google-cloud/init-process-for-containers-d03a471fa0cc I might try s6. |
First I'm going to try using Debian Buster as the base image instead of Alpine. |
I managed to port the whole thing over to Debian - which took a lot of work because their packaged Apache 2 works very differently from the Alpine one. Once again... I got it working fine on my laptop, but the image deployed to Cloud Run throws 503 errors! FROM python:3.9.7-slim-bullseye
RUN apt-get update && \
apt-get install -y apache2 supervisor && \
apt clean && \
rm -rf /var/lib/apt && \
rm -rf /var/lib/dpkg/info/*
# Apache environment, copied from
# https://github.com/ijklim/laravel-benfords-law-app/blob/e9bf385dcaddb62ea466a7b245ab6e4ef708c313/docker/os/Dockerfile
ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_PID_FILE /var/run/apache2.pid
ENV APACHE_RUN_DIR /var/run/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2
ENV APACHE_LOG_DIR /var/log
RUN ln -sf /dev/stdout /var/log/apache2-access.log
RUN ln -sf /dev/stderr /var/log/apache2-error.log
RUN mkdir -p $APACHE_RUN_DIR $APACHE_LOCK_DIR
RUN a2enmod proxy
RUN a2enmod proxy_http
RUN a2enmod headers
ARG DATASETTE_REF
RUN pip install https://github.com/simonw/datasette/archive/${DATASETTE_REF}.zip
# Append this to the end of the default httpd.conf file
RUN echo '\n\
<Directory /app/html/>\n\
Options Indexes FollowSymLinks\n\
AllowOverride None\n\
Require all granted\n\
</Directory>\n\
\n\
<VirtualHost *:80>\n\
ServerName localhost\n\
DocumentRoot /app/html\n\
ProxyPreserveHost On\n\
ProxyPass /prefix/ http://127.0.0.1:8001/\n\
Header add X-Proxied-By "Apache2"\n\
</VirtualHost>\n\
' > /etc/apache2/sites-enabled/000-default.conf
WORKDIR /app
RUN mkdir -p /app/html
RUN echo '<a href="/prefix/">Datasette</a>' > /app/html/index.html
ADD https://latest.datasette.io/fixtures.db /app/fixtures.db
EXPOSE 80
RUN echo "[supervisord]" >> /app/supervisord.conf
RUN echo "nodaemon=true" >> /app/supervisord.conf
RUN echo "" >> /app/supervisord.conf
RUN echo "[program:apache2]" >> /app/supervisord.conf
RUN echo "command=apache2 -D FOREGROUND" >> /app/supervisord.conf
RUN echo "" >> /app/supervisord.conf
RUN echo "[program:datasette]" >> /app/supervisord.conf
RUN echo "command=datasette /app/fixtures.db --setting base_url '/prefix/' --version-note '${DATASETTE_REF}' -h 0.0.0.0 -p 8001" >> /app/supervisord.conf
CMD ["/usr/bin/supervisord", "-c", "/app/supervisord.conf"] |
I've now tried both Debian and Alpine, and I've tried both |
As a a sanity check, would it be worth looking at trying to push the multi-process container on another provider of a knative / cloud run / tekton ? I have a somewhat similar use case for a future proejct, so i'm been very grateful to you sharing all the progress in this issue. As I understand it, Scaleway also offer a very similar offering using what appear to be many similar components that might at least see if it's an issue with more than one knative based FaaS provider https://www.scaleway.com/en/serverless-containers/ |
I'm going to leave this issue open, tag it as "help wanted" and cross my fingers that someone with Cloud Run deep expertise takes an interest in figuring out what's going wrong here! |
That's a great idea. I'll try running on a non-Knative host too (probably Fly - though they actually run containers using Firecracker which ends up being completely different). Cloud Run are the only Knative host I've used, know of any others aside from Scaleway? They look like they're worth getting familiar with. |
I tried to deploy it to Fly - initially using Almost got it working, but it failed the health check:
|
Here's why it failed - the [[services]]
http_checks = []
internal_port = 8080
processes = ["app"]
protocol = "tcp"
script_checks = [] But I need https://floral-dust-4577.fly.dev/prefix/ - not seeing any 503 errors there. |
I'm going to go with Fly instead for this, especially as I can keep it within their free tier (and iI want to get more familiar with their platform). |
The demo is now live on https://datasette-apache-proxy-demo.fly.dev/prefix/ |
If you suspect that Cloud Run throttled CPU could be the cause, you can request to have CPU always allocated with It could also be the Cloud Run sandbox that somehow gets in the way here, in which case I recommend testing with the second generation execution environment: |
I tried deploying the most recent version of the Dockerfile in this thread (link to comment), and after trying a few different different combinations, I was only successful when I used Using this method, I got a very similar issue to you: The first time I'd load the site I'd get a 503. But after that first load, I didn't get the issue again. It would re-occur if the service started from cold boot. I suspect this is a race condition in the supervisord configuration. The errors I got were the same Looking at the order of logs getting back, the processes reported successfully completing loading after the first 503 was returned, so that makes me think race condition. I can replicate this locally, if I Unfortunately supervisor/supervisor issue 122 (not linking as to prevent cross-project link spam) seems to say that dependency chaining is a feature that's been asked for for a long time, but hasn't been implemented. You could try some suggestions in that thread. |
Originally posted by @simonw in #1521 (comment)
I started by following https://ahmet.im/blog/cloud-run-multiple-processes-easy-way/ - see example in https://github.com/ahmetb/multi-process-container-lazy-solution
The text was updated successfully, but these errors were encountered: