diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3f664a1 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +.vscode/ +.git/ +.github/ +deployment/postgres/ diff --git a/.gitignore b/.gitignore index c19112f..78e5a29 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ __pycache__ .DS_Store .env.* db.sqlite3 +caddy.env diff --git a/DOCKER.md b/DOCKER.md new file mode 100644 index 0000000..bbdbfa3 --- /dev/null +++ b/DOCKER.md @@ -0,0 +1,77 @@ +# Docker + +There are 3 images that make up this project: + +- `frogress` - the app itself, based upon [python:3.10-slim](https://hub.docker.com/_/python) image. +- `caddy` - [caddy](https://hub.docker.com/_/caddy) running as a reverse proxy that also provides auto-https for production +- `postgres` - [postgresql](https://hub.docker.com/_/postgres) database + +## Production + +By default, `PRODUCTION=NO` is set in the `caddy.env` file which means the reverse proxy (Caddy) will listen on port 80/http. Changing this to `PRODUCTION=YES` will cause Caddy to listen on 443/https and will generate SSL certificates and attempt to confirm ownership of the domain (progress.deco.mp). + +Note: The production domain can be overridden by setting `DOMAIN_NAME=www.mydomainname.com` environment variable within the `caddy.env` + +## Persisted data + +The database data is persisted to `./deployment/postgres/data`, this can be changed within the `docker-compose.yaml` file. + +## Daemon + +To run the project in the background, add the `--daemon` argument to `docker-compose up`. + +## Monitoring + +Check what containers are running: +```sh +$ docker-compose ps + Name Command State Ports +---------------------------------------------------------------------------------------------------------------------------------------------- +frogress_caddy_1 /entrypoint.sh Up 2019/tcp, 0.0.0.0:443->443/tcp,:::443->443/tcp, 0.0.0.0:80->80/tcp,:::80->80/tcp +frogress_frogress_1 /entrypoint.sh Up 0.0.0.0:8000->8000/tcp,:::8000->8000/tcp +frogress_postgres_1 docker-entrypoint.sh postgres Up 0.0.0.0:5432->5432/tcp,:::5432->5432/tcp +``` + +Jump inside the main frogress container: +```sh +$ docker exec -ti frogress_frogress_1 bash +root@7a1645fece43:/frogress# +``` + +Follow logs for the main frogress container: +```sh +$ docker logs -f frogress_frogress_1 +Waiting for database to become available on postgres:5432... +Waiting for database to become available on postgres:5432... +Operations to perform: + Apply all migrations: admin, auth, contenttypes, frog_api, sessions +Running migrations: + Applying contenttypes.0001_initial... OK + Applying auth.0001_initial... OK + Applying admin.0001_initial... OK + Applying admin.0002_logentry_remove_auto_add... OK + Applying admin.0003_logentry_add_action_flag_choices... OK + Applying contenttypes.0002_remove_content_type_name... OK + Applying auth.0002_alter_permission_name_max_length... OK + Applying auth.0003_alter_user_email_max_length... OK + Applying auth.0004_alter_user_username_opts... OK + Applying auth.0005_alter_user_last_login_null... OK + Applying auth.0006_require_contenttypes_0002... OK + Applying auth.0007_alter_validators_add_error_messages... OK + Applying auth.0008_alter_user_username_max_length... OK + Applying auth.0009_alter_user_last_name_max_length... OK + Applying auth.0010_alter_group_name_max_length... OK + Applying auth.0011_update_proxy_permissions... OK + Applying auth.0012_alter_user_first_name_max_length... OK + Applying frog_api.0001_initial... OK + Applying frog_api.0002_remove_entry_version_category_entry_category... OK + Applying frog_api.0003_rename_decompiled_functions_entry_decompiled_chunks_and_more... OK + Applying frog_api.0004_alter_category_options_alter_entry_options_and_more... OK + Applying frog_api.0005_remove_entry_decompiled_bytes_and_more... OK + Applying frog_api.0006_alter_project_auth_key... OK + Applying frog_api.0007_alter_entry_timestamp... OK + Applying frog_api.0008_project_discord_project_repository_project_website... OK + Applying frog_api.0009_alter_project_discord_alter_project_repository_and_more... OK + Applying sessions.0001_initial... OK +Watching for file changes with StatReloader +``` diff --git a/README.md b/README.md index e072a26..addb820 100644 --- a/README.md +++ b/README.md @@ -8,4 +8,14 @@ For those interested in contributing to frogress's development, please see [CONT ## Usage The API will be hosted at https://progress.deco.mp. Usage guide coming soon. -TODO: add example curl commands as well as code snippets / CSV parser for existing format \ No newline at end of file +TODO: add example curl commands as well as code snippets / CSV parser for existing format + +## Docker + +This project can be deployed locally using [Docker Compose](https://docs.docker.com/compose/). + +```sh +docker-compose up --build +``` + +See [DOCKER.md](DOCKER.md) for more information. diff --git a/caddy.env b/caddy.env new file mode 100644 index 0000000..5597f4e --- /dev/null +++ b/caddy.env @@ -0,0 +1 @@ +PRODUCTION=NO diff --git a/deployment/caddy/Caddyfile b/deployment/caddy/Caddyfile new file mode 100644 index 0000000..bceab45 --- /dev/null +++ b/deployment/caddy/Caddyfile @@ -0,0 +1,3 @@ +__DOMAIN_NAME__ { + reverse_proxy __BACKEND_HOST__:__BACKEND_PORT__ +} diff --git a/deployment/caddy/Dockerfile b/deployment/caddy/Dockerfile new file mode 100644 index 0000000..7603cff --- /dev/null +++ b/deployment/caddy/Dockerfile @@ -0,0 +1,7 @@ +FROM caddy:2.5.2-alpine + +COPY deployment/caddy/Caddyfile /etc/caddy/ + +COPY deployment/caddy/entrypoint.sh /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/deployment/caddy/entrypoint.sh b/deployment/caddy/entrypoint.sh new file mode 100755 index 0000000..22f1dbb --- /dev/null +++ b/deployment/caddy/entrypoint.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env sh + +BE_HOST=${BACKEND_HOST:-frogress} +BE_PORT=${BACKEND_PORT:-8000} + +CADDY_DOMAIN=${DOMAIN_NAME:-progress.deco.mp} + +IS_PROD=${PRODUCTION:-YES} + +until nc -z ${BE_HOST} ${BE_PORT} > /dev/null; do + echo "Waiting for backend to become available on ${BE_HOST}:${BE_PORT}..." + sleep 1 +done + +if [[ "${IS_PROD}" == "YES" ]]; then + echo "Frogress API available at https://${CADDY_DOMAIN}" + sed -i "s/__DOMAIN_NAME__/${CADDY_DOMAIN}/g" /etc/caddy/Caddyfile +else + echo "Frogress API available at http://localhost:80" + sed -i "s/__DOMAIN_NAME__/:80/g" /etc/caddy/Caddyfile +fi + +sed -i "s/__BACKEND_HOST__/${BE_HOST}/g" /etc/caddy/Caddyfile +sed -i "s/__BACKEND_PORT__/${BE_PORT}/g" /etc/caddy/Caddyfile + +/usr/bin/caddy run --config /etc/caddy/Caddyfile --adapter caddyfile diff --git a/deployment/frogress/Dockerfile b/deployment/frogress/Dockerfile new file mode 100644 index 0000000..e42d03d --- /dev/null +++ b/deployment/frogress/Dockerfile @@ -0,0 +1,33 @@ +FROM python:3.10-slim + +RUN apt-get update && apt-get install -y curl netcat + +ARG POETRY_VERSION=1.1.15 +ENV POETRY_VERSION=${POETRY_VERSION} +RUN curl -sSL https://install.python-poetry.org | \ + POETRY_VERSION=${POETRY_VERSION} POETRY_HOME=/etc/poetry python - + +RUN echo 'export PATH="/etc/poetry/bin:$PATH"' > /root/.bashrc + +RUN mkdir /frogress + +COPY consumer_scripts /frogress/consumer_scripts +COPY frog_api /frogress/frog_api +COPY frogress /frogress/frogress + +COPY manage.py /frogress/ +COPY mypy.ini /frogress/ +COPY poetry.lock /frogress/ +COPY pyproject.toml /frogress/ + +WORKDIR /frogress + +ENV PATH="$PATH:/etc/poetry/bin" + +RUN poetry install + +COPY .env /frogress + +COPY ./deployment/frogress/entrypoint.sh /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/deployment/frogress/entrypoint.sh b/deployment/frogress/entrypoint.sh new file mode 100755 index 0000000..572d1e7 --- /dev/null +++ b/deployment/frogress/entrypoint.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +DB_HOST=${DATABASE_HOST:-postgres} +DB_PORT=${DATABASE_PORT:-5432} + +BE_HOST=${BACKEND_HOST:-frogress} +BE_PORT=${BACKEND_PORT:-8000} + +until nc -z ${DB_HOST} ${DB_PORT} > /dev/null; do + echo "Waiting for database to become available on ${DB_HOST}:${DB_PORT}..." + sleep 1 +done + +poetry run python manage.py migrate + +poetry run python manage.py runserver ${BE_HOST}:${BE_PORT} diff --git a/deployment/postgres/.gitignore b/deployment/postgres/.gitignore new file mode 100644 index 0000000..654617b --- /dev/null +++ b/deployment/postgres/.gitignore @@ -0,0 +1,2 @@ +**/* +!.gitignore diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..6fda91b --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,25 @@ +version: '2' +services: + postgres: + image: postgres:13-alpine + environment: + POSTGRES_USER: frogress + POSTGRES_PASSWORD: frogress + ports: + - "5432:5432" + volumes: + - ./deployment/postgres/data:/var/lib/postgresql/data + frogress: + build: + context: . + dockerfile: deployment/frogress/Dockerfile + ports: + - "8000:8000" + caddy: + env_file: caddy.env + build: + context: . + dockerfile: deployment/caddy/Dockerfile + ports: + - "80:80" + - "443:443"