Skip to content
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

Add dev docker-compose file to manage supporting services #525

Merged
merged 7 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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: 11 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.PHONY: dev
dev:
docker compose --profile central -f docker-compose.yml -f docker-compose.dev.yml up -d

.PHONY: upgrade-successful
upgrade-successful:
docker compose exec postgres14 touch /var/lib/odk/postgresql/14/.postgres14-upgrade-successful

.PHONY: stop
stop:
docker compose stop
alxndrsn marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ In addition to the Backend and the Frontend, Central deploys services:
* Central relies on [pyxform-http](https://github.com/getodk/pyxform-http) for converting Forms from XLSForm. It generally shouldn't be needed in development but can be run locally.
* Central relies on [Enketo](https://github.com/enketo/enketo-express) for Web Form functionality. Enketo can be run locally and configured to work with Frontend and Backend in development by following [these instructions](https://github.com/getodk/central-frontend/blob/master/docs/enketo.md).

If you want to work on Central codebase and don't want to setup dependent services like Postgresql, Enketo, etc manually then you can run `make dev`, which will start those services as Docker containers. If you are setting up development environment for the first time, please run `make upgrade-successful` to skip the Postgresql upgrade.
alxndrsn marked this conversation as resolved.
Show resolved Hide resolved

Operations
----------

Expand Down
51 changes: 51 additions & 0 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Assumption: This file will be merged by `docker compose`
#
# What it does:
# Sets profiles for each service depending on whether that
# service is required for development of that particular application
# For Central be/fe development, we need postgres14, pyxform, enketo, redis_main
# For Enketo development, we need postgres14, service, nginx, redis_main
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove stale comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

# 'none' profile is set for services that are not need for either
#
# depends_on of some services are reset using !reset custom yml tag
# nb: can't replace depends_on so we have removed all the values, ok for dev
services:
postgres14:
profiles:
- central
network_mode: host
postgres:
profiles:
- none
mail:
profiles:
- none
service:
profiles:
- none
nginx:
profiles:
- none
pyxform:
profiles:
- central
# changing port here - can't use `ports` mapping with host networking
command: ["gunicorn", "--bind", "0.0.0.0:5001", "--workers", "5", "--timeout", "600", "--max-requests", "1", "--max-requests-jitter", "3", "main:app()"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a significant deviation from the parent docker-compose.yml. Is this running pyxform from source?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is just overriding the port in the command of the pyxform-http docker file: https://github.com/getodk/pyxform-http/blob/master/Dockerfile

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the standard command be used, and this container's port 80 be exposed locally on port 5001? That would seem to simplify this section, and also protect against future divergence.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't expose ports when using host networking mode. And host networking is required so that Enketo can communicate with Central via http://localhost:8989, which is running on the host.

I know we can use host.docker.internal to access services running on the host from the bridge container but configuration in Enketo and Central doesn't really support that. For example, Central uses env.domain to generate URLs in OpenRosa manifest, whose value is http://localhost:8989 in local environment.

I had tried modifying /etc/hosts file in the Enketo container to map localhost to the IP assigned by docker to the host.docker.internal but Enketo using discontinued/deprecated request.js doesn't respects values in host file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using discontinued/deprecated request.js doesn't respects values in host file.

Have you got a source for this? I couldn't find anything obvious in the request issue tracker.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way requestjs resolves domain name has to do with it:

request/request#2491

Note: above issue closed due to staleness

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having trouble reproducing this issue. Is it possible this has been resolved by enketo's move to @cypress/request (introduced by 37b8f8b2f0b057e7adaa2da472f88ab8a5e460e0 in April 2024)?

Copy link
Contributor Author

@sadiqkhoja sadiqkhoja Dec 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to map localhost to the IP Address of host-gateway in Enketo container, that didn't work. Localhost was still resolving to 127.0.0.1.

So I ended up adding a custom domain in my local hosts file and changing default.env.domain to that host in the backend repository and now everything works. I have to access central via that custom host instead of localhost, which is fine. I have updated the instructions in readme file as well.

network_mode: host
secrets:
profiles:
- none
enketo:
profiles:
- central
depends_on: !reset []
environment:
- ENV=DEV
network_mode: host
enketo_redis_main:
profiles:
- central
network_mode: host
enketo_redis_cache:
profiles:
- none
9 changes: 9 additions & 0 deletions files/enketo/start-enketo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@
CONFIG_PATH=${ENKETO_SRC_DIR}/config/config.json
echo "generating enketo configuration..."

if [ "$ENV" = "DEV" ]; then
sed -i -e 's/enketo_redis_main/localhost/g' \
-e 's/enketo_redis_cache/localhost/g' \
-e 's/6380/6379/g' \
-e 's/${SECRET}/s0m3v3rys3cr3tk3y/g' \
-e 's/${LESS_SECRET}/this $3cr3t key is crackable/g' \
-e 's/${API_KEY}/enketorules/g' "$CONFIG_PATH.template"
alxndrsn marked this conversation as resolved.
Show resolved Hide resolved
fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change to reduce the number of redis containers required? If so, is the increased complexity in these scripts and the deviation from the standard docker-compose.yml worth the savings?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. Originally I wanted this PR to facilitate Enketo development as well and Enketo suggests to run only one redis in development for the easiness. I have now removed the port substitution from this command and starting two redis instances.

I still need to substitute enketo_redis_main and enketo_redis_cache with localhost because of host network mode.

Copy link
Contributor

@alxndrsn alxndrsn Dec 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still need to substitute enketo_redis_main and enketo_redis_cache with localhost because of host network mode.

Similar to pyxform config above, it would be great if there was a way to achieve this without having to modify files/enketo/start-enketo.sh and make fragile changes with sed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed.


BASE_URL=$( [ "${HTTPS_PORT}" = 443 ] && echo https://"${DOMAIN}" || echo https://"${DOMAIN}":"${HTTPS_PORT}" ) \
SECRET=$(cat /etc/secrets/enketo-secret) \
LESS_SECRET=$(cat /etc/secrets/enketo-less-secret) \
Expand Down
2 changes: 1 addition & 1 deletion files/postgres14/start-postgres.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash -eu
set -o pipefail

flag_upgradeCompletedOk="$PGDATA/../.postgres14-upgrade-successful"
flag_upgradeCompletedOk=$(readlink -f -m "$PGDATA/../.postgres14-upgrade-successful")
alxndrsn marked this conversation as resolved.
Show resolved Hide resolved

logPrefix="$(basename "$0")"
log() {
Expand Down