From 9d7dae201a315f0a709a209054cc3eee165448ac Mon Sep 17 00:00:00 2001 From: Michael Matloka Date: Mon, 28 Sep 2020 20:50:38 +0200 Subject: [PATCH] Make production docker-compose.yml generated (#1704) * Make production docker-compose.yml generated * Move "version" to top * Update instructions * Leave a fallback docker-compose.yml * Fix grammar * Update instructions * Delete docker-compose.proxy.yml * Improve error handling * Update script * Update wording --- docker-compose-config.py | 79 ++++++++++++++++++++++++++++++++++++++++ docker-compose.proxy.yml | 29 --------------- docker-compose.yml | 27 +++++++------- requirements.txt | 1 + 4 files changed, 93 insertions(+), 43 deletions(-) create mode 100755 docker-compose-config.py delete mode 100644 docker-compose.proxy.yml diff --git a/docker-compose-config.py b/docker-compose-config.py new file mode 100755 index 00000000000..2a154c265ff --- /dev/null +++ b/docker-compose-config.py @@ -0,0 +1,79 @@ +import secrets +import string +from typing import Optional + +import yaml +from yaml.loader import FullLoader + +FILE_PATH = "docker-compose.yml" + + +def generate_secret_key() -> str: + """Securely generate random 50 ASCII letters and digits.""" + return "".join(secrets.choice(string.ascii_letters + string.digits) for _ in range(50)) + + +def read_config() -> dict: + with open(FILE_PATH, "r") as file: + config = yaml.load(file, Loader=FullLoader) + if not config: + raise ValueError("Current docker-compose.yml is malformed! Get a fresh one from the PostHog repository.") + return config + + +def save_config(config: dict, *, host_port: int, secret_key: str) -> None: + with open(FILE_PATH, "w") as file: + try: + config["services"]["web"]["ports"] = [f"{host_port}:8000"] + config["services"]["web"]["environment"]["SECRET_KEY"] = secret_key + except KeyError: + raise ValueError("Current docker-compose.yml is malformed! Get a fresh one from the PostHog repository.") + yaml.dump( + config, stream=file, indent=4, + ) + + +def input_host_port(n: int, default: int = 80) -> int: + print( + f"\n{n}. On which host port should the PostHog server be exposed? (default: {default})\n" + "Leave on default value if not using a reverse proxy such as nginx.\n" + "Otherwise select a higher-numbered port (like 8000)\n" + "and point your reverse proxy server to it.\n" + ) + while True: + try: + host_port_raw = input() + return int(host_port_raw) if host_port_raw else default + except ValueError: + print("Port must be a number! Please try again.\n") + + +def input_secret_key(n: int) -> str: + print( + f"\n{n}. Do you have a specific Django SECRET_KEY? (default: random)\n" + "Django uses the SECRET_KEY variable for e.g. encrypting sessions and tokens,\n" + "so it's important that it is secret and only yours.\n" + "If you don't have one already, skip this and let us generate you one.\n" + ) + return input() or "".join(secrets.choice(string.ascii_letters + string.digits) for _ in range(50)) + + +def main(): + host_port: Optional[int] = None + secret_key: Optional[str] = None + config: dict = read_config() + + print("Let's build the right production docker-compose.yml for your PostHog instance.") + + print("\nIf you're OK with a step's default value, you can skip by pressing Enter/Return.") + + host_port = input_host_port(1) + secret_key = input_secret_key(2) + + save_config(config, host_port=host_port, secret_key=secret_key) + + print("\nConfigured and saved docker-compose.yml. You can now use it in production.") + + +if __name__ == "__main__": + main() diff --git a/docker-compose.proxy.yml b/docker-compose.proxy.yml deleted file mode 100644 index fe07fd598ec..00000000000 --- a/docker-compose.proxy.yml +++ /dev/null @@ -1,29 +0,0 @@ -version: '3' - -services: - db: - image: postgres:alpine - container_name: posthog_db - environment: - POSTGRES_USER: posthog - POSTGRES_DB: posthog - POSTGRES_PASSWORD: posthog - redis: - image: 'redis:alpine' - container_name: posthog_redis - web: - image: posthog/posthog:latest - container_name: posthog_web - ports: - - '8000:8000' - environment: - IS_DOCKER: 'true' - DATABASE_URL: 'postgres://posthog:posthog@db:5432/posthog' - REDIS_URL: 'redis://redis:6379/' - SECRET_KEY: '' - depends_on: - - db - - redis - links: - - db:db - - redis:redis diff --git a/docker-compose.yml b/docker-compose.yml index 7bd34b5dd22..93f44566455 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,30 +1,29 @@ -version: '3' - services: db: - image: postgres:alpine container_name: posthog_db environment: - POSTGRES_USER: posthog POSTGRES_DB: posthog POSTGRES_PASSWORD: posthog + POSTGRES_USER: posthog + image: postgres:alpine redis: - image: 'redis:alpine' container_name: posthog_redis + image: redis:alpine web: - image: posthog/posthog:latest container_name: posthog_web - ports: - - '8000:8000' - - '80:8000' - environment: - IS_DOCKER: 'true' - DATABASE_URL: 'postgres://posthog:posthog@db:5432/posthog' - REDIS_URL: 'redis://redis:6379/' - SECRET_KEY: '' depends_on: - db - redis + environment: + DATABASE_URL: postgres://posthog:posthog@db:5432/posthog + IS_DOCKER: 'true' + REDIS_URL: redis://redis:6379/ + SECRET_KEY: + image: posthog/posthog:latest links: - db:db - redis:redis + ports: + - 8000:8000 + - 80:8000 +version: '3' diff --git a/requirements.txt b/requirements.txt index e2b1be49541..f1c6c366bc7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -82,3 +82,4 @@ wcwidth==0.1.9 Werkzeug==1.0.0 whitenoise==5.0.1 zipp==3.1.0 +pyyaml==5.3.1