{"html_url": "https://github.com/simonw/datasette/issues/1521#issuecomment-974433520", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1521", "id": 974433520, "node_id": "IC_kwDOBm6k_c46FKzw", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T20:32:29Z", "updated_at": "2021-11-19T20:32:29Z", "author_association": "OWNER", "body": "This configuration works great.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058815557, "label": "Docker configuration for exercising Datasette behind Apache mod_proxy"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1521#issuecomment-974388295", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1521", "id": 974388295, "node_id": "IC_kwDOBm6k_c46E_xH", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T20:00:06Z", "updated_at": "2021-11-19T20:00:06Z", "author_association": "OWNER", "body": "And this is the version that proxies to a `base_url` of `/foo/bar/`:\r\n\r\n```Dockerfile\r\nFROM python:3-alpine\r\n\r\nRUN apk add --no-cache \\\r\n\tapache2 \\\r\n\tapache2-proxy \\\r\n\tbash\r\n\r\nRUN pip install datasette\r\n\r\nENV TINI_VERSION v0.18.0\r\nADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static /tini\r\nRUN chmod +x /tini\r\n\r\n# Append this to the end of the default httpd.conf file\r\nRUN echo $'ServerName localhost\\n\\\r\n\\n\\\r\n\\n\\\r\n Order deny,allow\\n\\\r\n Allow from all\\n\\\r\n\\n\\\r\n\\n\\\r\nProxyPass /foo/bar/ http://localhost:9000/\\n\\\r\nHeader add X-Proxied-By \"Apache2\"' >> /etc/apache2/httpd.conf\r\n\r\nRUN echo $'Datasette' > /var/www/localhost/htdocs/index.html\r\n\r\nWORKDIR /app\r\n\r\nADD https://latest.datasette.io/fixtures.db /app/fixtures.db\r\n\r\nRUN echo $'#!/usr/bin/env bash\\n\\\r\nset -e\\n\\\r\n\\n\\\r\nhttpd -D FOREGROUND &\\n\\\r\ndatasette fixtures.db --setting base_url \"/foo/bar/\" -p 9000 &\\n\\\r\n\\n\\\r\nwait -n' > /app/start.sh\r\n\r\nRUN chmod +x /app/start.sh\r\n\r\nEXPOSE 80\r\nENTRYPOINT [\"/tini\", \"--\", \"/app/start.sh\"]\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058815557, "label": "Docker configuration for exercising Datasette behind Apache mod_proxy"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1521#issuecomment-974380798", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1521", "id": 974380798, "node_id": "IC_kwDOBm6k_c46E97-", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T19:54:26Z", "updated_at": "2021-11-19T19:54:26Z", "author_association": "OWNER", "body": "Got it working! Here's a `Dockerfile` which runs completely stand-alone (thanks to using the `echo $'` trick to write out the config files it needs) and successfully serves Datasette behind Apache and `mod_proxy`:\r\n\r\n```Dockerfile\r\nFROM python:3-alpine\r\n\r\nRUN apk add --no-cache \\\r\n\tapache2 \\\r\n\tapache2-proxy \\\r\n\tbash\r\n\r\nRUN pip install datasette\r\n\r\nENV TINI_VERSION v0.18.0\r\nADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static /tini\r\nRUN chmod +x /tini\r\n\r\n# Append this to the end of the default httpd.conf file\r\nRUN echo $'ServerName localhost\\n\\\r\n\\n\\\r\n\\n\\\r\n Order deny,allow\\n\\\r\n Allow from all\\n\\\r\n\\n\\\r\n\\n\\\r\nProxyPass / http://localhost:9000/\\n\\\r\nProxyPassReverse / http://localhost:9000/\\n\\\r\nHeader add X-Proxied-By \"Apache2\"' >> /etc/apache2/httpd.conf\r\n\r\nWORKDIR /app\r\n\r\nRUN echo $'#!/usr/bin/env bash\\n\\\r\nset -e\\n\\\r\n\\n\\\r\nhttpd -D FOREGROUND &\\n\\\r\ndatasette -p 9000 &\\n\\\r\n\\n\\\r\nwait -n' > /app/start.sh\r\n\r\nRUN chmod +x /app/start.sh\r\n\r\nEXPOSE 80\r\nENTRYPOINT [\"/tini\", \"--\", \"/app/start.sh\"]\r\n```\r\n\r\nRun it like this:\r\n\r\n```\r\ndocker build -t datasette-apache2-proxy . \r\ndocker run -p 5000:80 --rm datasette-apache2-proxy\r\n```\r\nThen run this to confirm:\r\n```\r\n~ % curl -i 'http://localhost:5000/-/versions.json'\r\nHTTP/1.1 200 OK\r\nDate: Fri, 19 Nov 2021 19:54:05 GMT\r\nServer: uvicorn\r\ncontent-type: application/json; charset=utf-8\r\nX-Proxied-By: Apache2\r\nTransfer-Encoding: chunked\r\n\r\n{\"python\": {\"version\": \"3.10.0\", \"full\": \"3.10.0 (default, Nov 13 2021, 03:23:03) [GCC 10.3.1 20210424]\"}, \"datasette\": {\"version\": \"0.59.2\"}, \"asgi\": \"3.0\", \"uvicorn\": \"0.15.0\", \"sqlite\": {\"version\": \"3.35.5\", \"fts_versions\": [\"FTS5\", \"FTS4\", \"FTS3\"], \"extensions\": {\"json1\": null}, \"compile_options\": [\"COMPILER=gcc-10.3.1 20210424\", \"ENABLE_COLUMN_METADATA\", \"ENABLE_DBSTAT_VTAB\", \"ENABLE_FTS3\", \"ENABLE_FTS3_PARENTHESIS\", \"ENABLE_FTS4\", \"ENABLE_FTS5\", \"ENABLE_GEOPOLY\", \"ENABLE_JSON1\", \"ENABLE_MATH_FUNCTIONS\", \"ENABLE_RTREE\", \"ENABLE_UNLOCK_NOTIFY\", \"MAX_VARIABLE_NUMBER=250000\", \"SECURE_DELETE\", \"THREADSAFE=1\", \"USE_URI\"]}}\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058815557, "label": "Docker configuration for exercising Datasette behind Apache mod_proxy"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1521#issuecomment-974371116", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1521", "id": 974371116, "node_id": "IC_kwDOBm6k_c46E7ks", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T19:45:47Z", "updated_at": "2021-11-19T19:45:47Z", "author_association": "OWNER", "body": "https://github.com/krallin/tini says:\r\n\r\n> *NOTE: If you are using Docker 1.13 or greater, Tini is included in Docker itself. This includes all versions of Docker CE. To enable Tini, just [pass the `--init` flag to `docker run`](https://docs.docker.com/engine/reference/commandline/run/).*", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058815557, "label": "Docker configuration for exercising Datasette behind Apache mod_proxy"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1521#issuecomment-974336020", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1521", "id": 974336020, "node_id": "IC_kwDOBm6k_c46EzAU", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T19:10:48Z", "updated_at": "2021-11-19T19:10:48Z", "author_association": "OWNER", "body": "There's a promising looking minimal Apache 2 proxy config here: https://stackoverflow.com/questions/26474476/minimal-configuration-for-apache-reverse-proxy-in-docker-container\r\n\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058815557, "label": "Docker configuration for exercising Datasette behind Apache mod_proxy"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1521#issuecomment-974334278", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1521", "id": 974334278, "node_id": "IC_kwDOBm6k_c46EylG", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T19:08:09Z", "updated_at": "2021-11-19T19:08:09Z", "author_association": "OWNER", "body": "Stripping comments using this StackOverflow recipe: https://unix.stackexchange.com/a/157619\r\n\r\n docker run -it --entrypoint sh alpine-apache2-sh \\\r\n -c \"cat /etc/apache2/httpd.conf\" | sed '/^[[:blank:]]*#/d;s/#.*//'\r\n\r\nResult is here: https://gist.github.com/simonw/0a05090df5fcff8e8b3334621fa17976", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058815557, "label": "Docker configuration for exercising Datasette behind Apache mod_proxy"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1521#issuecomment-974332787", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1521", "id": 974332787, "node_id": "IC_kwDOBm6k_c46EyNz", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T19:05:52Z", "updated_at": "2021-11-19T19:05:52Z", "author_association": "OWNER", "body": "Made myself this Dockerfile to let me explore a bit:\r\n```Dockerfile\r\nFROM python:3-alpine\r\n\r\nRUN apk add --no-cache \\\r\n\tapache2\r\n\r\nCMD [\"sh\"]\r\n```\r\nThen:\r\n```\r\n% docker run alpine-apache2-sh\r\n% docker run -it alpine-apache2-sh\r\n/ # ls /etc/apache2/httpd.conf\r\n/etc/apache2/httpd.conf\r\n/ # cat /etc/apache2/httpd.conf\r\n#\r\n# This is the main Apache HTTP server configuration file. It contains the\r\n# configuration directives that give the server its instructions.\r\n...\r\n```\r\nCopying that into a GIST like so:\r\n```\r\ndocker run -it --entrypoint sh alpine-apache2-sh -c \"cat /etc/apache2/httpd.conf\" | pbcopy\r\n```\r\nGist here: https://gist.github.com/simonw/5ea0db6049192cb9f761fbd6beb3a84a", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058815557, "label": "Docker configuration for exercising Datasette behind Apache mod_proxy"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1521#issuecomment-974327812", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1521", "id": 974327812, "node_id": "IC_kwDOBm6k_c46ExAE", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T18:58:49Z", "updated_at": "2021-11-19T18:59:55Z", "author_association": "OWNER", "body": "From this example: https://github.com/tigelane/dockerfiles/blob/06cff2ac8cdc920ebd64f50965115eaa3d0afb84/Alpine-Apache2/Dockerfile#L25-L31 it looks like running `apk add apache2` installs a config file at `/etc/apache2/httpd.conf` - so one approach is to then modify that file.\r\n\r\n```\r\n# APACHE - Alpine\r\n#################\r\nRUN apk --update add apache2 php5-apache2 && \\\r\n #apk add openrc --no-cache && \\\r\n rm -rf /var/cache/apk/* && \\\r\n sed -i 's/#ServerName www.example.com:80/ServerName localhost/' /etc/apache2/httpd.conf && \\\r\n mkdir -p /run/apache2/\r\n\r\n# Upload our files from folder \"dist\".\r\nCOPY dist /var/www/localhost/htdocs\r\n\r\n# Manually set up the apache environment variables\r\nENV APACHE_RUN_USER www-data\r\nENV APACHE_RUN_GROUP www-data\r\nENV APACHE_LOG_DIR /var/log/apache2\r\nENV APACHE_LOCK_DIR /var/lock/apache2\r\nENV APACHE_PID_FILE /var/run/apache2.pid\r\n\r\n# Execute apache2 on run\r\n########################\r\nEXPOSE 80\r\nENTRYPOINT [\"httpd\"]\r\nCMD [\"-D\", \"FOREGROUND\"]\r\n```\r\n\r\nI think I'll create my own separate copy and modify that.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058815557, "label": "Docker configuration for exercising Datasette behind Apache mod_proxy"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1521#issuecomment-974321391", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1521", "id": 974321391, "node_id": "IC_kwDOBm6k_c46Evbv", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T18:49:15Z", "updated_at": "2021-11-19T18:57:18Z", "author_association": "OWNER", "body": "This pattern looks like it can help: https://ahmet.im/blog/cloud-run-multiple-processes-easy-way/ - see example in https://github.com/ahmetb/multi-process-container-lazy-solution\r\n\r\nI got that demo working locally like this:\r\n\r\n```bash\r\ncd /tmp\r\ngit clone https://github.com/ahmetb/multi-process-container-lazy-solution\r\ncd multi-process-container-lazy-solution\r\ndocker build -t multi-process-container-lazy-solution .\r\ndocker run -p 5000:8080 --rm multi-process-container-lazy-solution\r\n```\r\n\r\nI want to use `apache2` rather than `nginx` though. I found a few relevant examples of Apache in Alpine:\r\n\r\n- https://github.com/Hacking-Lab/alpine-apache2-reverse-proxy/blob/master/Dockerfile\r\n- https://www.sentiatechblog.com/running-apache-in-a-docker-container\r\n- https://github.com/search?l=Dockerfile&q=alpine+apache2&type=code\r\n\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058815557, "label": "Docker configuration for exercising Datasette behind Apache mod_proxy"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1521#issuecomment-974322178", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1521", "id": 974322178, "node_id": "IC_kwDOBm6k_c46EvoC", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T18:50:22Z", "updated_at": "2021-11-19T18:50:22Z", "author_association": "OWNER", "body": "I'll get this working on my laptop first, but then I want to get it up and running on Cloud Run - maybe with a GitHub Actions workflow in this repo that re-deploys it on manual execution.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058815557, "label": "Docker configuration for exercising Datasette behind Apache mod_proxy"}, "performed_via_github_app": null}