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 initial docker build and documentation #926

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

jwbensley
Copy link

As discussed, this PR adds an initial docker implementation and documentation.

I don't really know IRRd at all so you might need to rework this somehow but this is working as I had hoped.

Build the container:

$ docker compose -f docker/docker-compose.yaml build
[+] Building 58.8s (17/21)                                                                                                                                                                          docker:default
[+] Building 110.1s (22/22) FINISHED                                                                                                                                                                docker:default
 => [irrd internal] load build definition from Dockerfile                                                                                                                                                     0.0s
 => => transferring dockerfile: 1.51kB                                                                                                                                                                        0.0s
 => [irrd internal] load metadata for docker.io/library/ubuntu:22.04                                                                                                                                          0.9s
 => [irrd internal] load .dockerignore                                                                                                                                                                        0.0s
 => => transferring context: 2B                                                                                                                                                                               0.0s
 => [irrd  1/17] FROM docker.io/library/ubuntu:22.04@sha256:77906da86b60585ce12215807090eb327e7386c8fafb5402369e421f44eff17e                                                                                  0.0s
 => [irrd internal] load build context                                                                                                                                                                        0.0s
 => => transferring context: 36B                                                                                                                                                                              0.0s
 => CACHED [irrd  2/17] RUN DEBIAN_FRONTEND=noninteractive apt-get update                                                                                                                                     0.0s
 => [irrd  3/17] RUN DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y ca-certificates build-essential python3-dev pipx wget gpg git                                                 22.4s 
 => [irrd  4/17] RUN mkdir "/opt/irrd_data/"                                                                                                                                                                  0.3s 
 => [irrd  5/17] RUN wget -nc -O "/opt/irrd_data//ripe.db.as-set.gz" https://ftp.ripe.net/ripe/dbase/split/ripe.db.as-set.gz                                                                                  1.4s 
 => [irrd  6/17] RUN wget -nc -O "/opt/irrd_data//ripe.db.aut-num.gz" https://ftp.ripe.net/ripe/dbase/split/ripe.db.aut-num.gz                                                                                2.0s 
 => [irrd  7/17] RUN wget -nc -O "/opt/irrd_data//ripe.db.route-set.gz" https://ftp.ripe.net/ripe/dbase/split/ripe.db.route-set.gz                                                                            0.7s 
 => [irrd  8/17] RUN wget -nc -O "/opt/irrd_data//ripe.db.route.gz" https://ftp.ripe.net/ripe/dbase/split/ripe.db.route.gz                                                                                    2.5s 
 => [irrd  9/17] RUN wget -nc -O "/opt/irrd_data//ripe.db.route6.gz" https://ftp.ripe.net/ripe/dbase/split/ripe.db.route6.gz                                                                                  1.2s 
 => [irrd 10/17] RUN wget -nc -O "/opt/irrd_data//RIPE.CURRENTSERIAL" https://ftp.ripe.net/ripe/dbase/RIPE.CURRENTSERIAL                                                                                      0.5s 
 => [irrd 11/17] RUN wget -nc -O "/opt/irrd_data//radb.db.gz" ftp://ftp.radb.net/radb/dbase/radb.db.gz                                                                                                       10.3s 
 => [irrd 12/17] RUN wget -nc -O "/opt/irrd_data//RADB.CURRENTSERIAL" ftp://ftp.radb.net/radb/dbase/RADB.CURRENTSERIAL                                                                                        2.3s 
 => [irrd 13/17] RUN pipx ensurepath                                                                                                                                                                          0.6s 
 => [irrd 14/17] RUN pipx install poetry                                                                                                                                                                     13.8s 
 => [irrd 15/17] COPY ./pyproject.toml /irrd/pyproject.toml                                                                                                                                                   0.1s 
 => [irrd 16/17] RUN cd /irrd/ && /root/.local/bin/poetry config virtualenvs.create false && /root/.local/bin/poetry install -vv --no-interaction --with=dev,docs                                            49.4s 
 => [irrd 17/17] RUN useradd irrd                                                                                                                                                                             0.2s 
 => [irrd] exporting to image                                                                                                                                                                                 1.5s 
 => => exporting layers                                                                                                                                                                                       1.5s  => => writing image sha256:7c9f076735ce37af05aa70e7f272bfe6d0fcc71ded22558a691f730c7949beb7                                                                                                                  0.0s 
 => => naming to docker.io/library/docker-irrd                                                                                                                                                                0.0s 

Start the containers:

$ docker compose -f docker/docker-compose.yaml up -d
[+] Running 4/5
 ⠇ Network docker_default              Created                                                                                                                                                                0.8s 
 ✔ Container docker-postgresql-1       Started                                                                                                                                                                0.5s 
 ✔ Container docker-redis-1            Started                                                                                                                                                                0.5s 
 ✔ Container docker-test-postgresql-1  Started                                                                                                                                                                0.3s 
 ✔ Container docker-irrd-1             Started                                                                                                                                                                0.7s 

(Wait for initial data import to complete by checking status HTTP endpoint....)

Check data is available via WHOIS and GraphQL:

$ curl 'http://localhost:8080/graphql/' \
-X POST \
-H 'Accept: application/json, multipart/mixed' \
-H 'content-type: application/json' \
--data-raw '{"query":"query{\n recursiveSetMembers(setNames:[\"AS-VOSTRON\"]) {\n  \tmembers\n\t}\n}"}'

{"data":{"recursiveSetMembers":[{"members":["AS16568","AS41695","AS54748"]}]},"extensions":{"execution":0.009879501001705648}}

$ whois -h localhost -p 8043 AS-VOSTRON | grep member
members:        AS41695
members:        AS16568
members:        AS54748

Run pytest inside docker (everything passes):

$ docker compose -f docker/docker-compose.yaml exec irrd bash
root@d2657fba3e20:/# cd /opt/irrd/
root@d2657fba3e20:/opt/irrd# export IRRD_DATABASE_URL=postgresql://host.docker.internal:5433/irrd_test
root@d2657fba3e20:/opt/irrd# export IRRD_REDIS_URL=redis://host.docker.internal/3
root@d2657fba3e20:/opt/irrd# pytest irrd/
=============================================================================================== test session starts ===============================================================================================
platform linux -- Python 3.10.12, pytest-7.4.4, pluggy-1.4.0
rootdir: /opt/irrd
configfile: pyproject.toml
plugins: smtpdfix-0.5.1, cov-4.1.0, asyncio-0.20.3, freezegun-0.4.2, Faker-24.4.0, anyio-4.3.0
asyncio: mode=auto
collected 768 items                                                                                                                                                                                               

irrd/conf/test_conf.py ...........                                                                                                                                                                          [  1%]
irrd/mirroring/nrtm4/tests/test_jsonseq.py ..                                                                                                                                                               [  1%]
irrd/mirroring/nrtm4/tests/test_nrtm4_client.py ................                                                                                                                                            [  3%]
irrd/mirroring/nrtm4/tests/test_nrtm4_server.py ..                                                                                                                                                          [  4%]
irrd/mirroring/nrtm4/tests/test_nrtm4_types.py ..............                                                                                                                                               [  5%]
irrd/mirroring/tests/test_jobs.py ...                                                                                                                                                                       [  6%]
irrd/mirroring/tests/test_mirror_runners_export.py ....                                                                                                                                                     [  6%]
irrd/mirroring/tests/test_mirror_runners_import.py .........................                                                                                                                                [ 10%]
irrd/mirroring/tests/test_nrtm_generator.py .................                                                                                                                                               [ 12%]
irrd/mirroring/tests/test_nrtm_operation.py ..........                                                                                                                                                      [ 13%]
irrd/mirroring/tests/test_parsers.py ................                                                                                                                                                       [ 15%]
irrd/mirroring/tests/test_retrieval.py .                                                                                                                                                                    [ 15%]
irrd/mirroring/tests/test_scheduler.py ...........                                                                                                                                                          [ 17%]
irrd/routepref/tests/test_routepref.py ...                                                                                                                                                                  [ 17%]
irrd/rpki/tests/test_importer.py ....                                                                                                                                                                       [ 18%]
irrd/rpki/tests/test_notifications.py ...                                                                                                                                                                   [ 18%]
irrd/rpki/tests/test_validators.py .....                                                                                                                                                                    [ 19%]
irrd/rpsl/tests/test_fields.py ..................                                                                                                                                                           [ 21%]
irrd/rpsl/tests/test_rpsl_objects.py ..............................................................                                                                                                         [ 29%]
irrd/scopefilter/tests/test_scopefilter.py ....                                                                                                                                                             [ 30%]
irrd/scripts/tests/test_expire_journal.py .....                                                                                                                                                             [ 30%]
irrd/scripts/tests/test_irr_rpsl_submit.py .......................................................                                                                                                          [ 37%]
irrd/scripts/tests/test_irrd_control.py ....................                                                                                                                                                [ 40%]
irrd/scripts/tests/test_load_database.py ...                                                                                                                                                                [ 40%]
irrd/scripts/tests/test_load_pgp_keys.py .                                                                                                                                                                  [ 41%]
irrd/scripts/tests/test_mirror_force_reload.py .                                                                                                                                                            [ 41%]
irrd/scripts/tests/test_rpsl_read.py .                                                                                                                                                                      [ 41%]
irrd/scripts/tests/test_set_last_modified_auth.py .                                                                                                                                                         [ 41%]
irrd/scripts/tests/test_submit_email.py ..                                                                                                                                                                  [ 41%]
irrd/scripts/tests/test_submit_update.py .                                                                                                                                                                  [ 41%]
irrd/scripts/tests/test_update_database.py ...                                                                                                                                                              [ 42%]
irrd/server/test_access_check.py ....                                                                                                                                                                       [ 42%]
irrd/server/graphql/tests/test_extensions.py ..                                                                                                                                                             [ 42%]
irrd/server/graphql/tests/test_resolvers.py .............                                                                                                                                                   [ 44%]
irrd/server/graphql/tests/test_schema_generator.py .                                                                                                                                                        [ 44%]
irrd/server/http/tests/test_endpoints.py .........                                                                                                                                                          [ 45%]
irrd/server/http/tests/test_event_stream.py ........                                                                                                                                                        [ 47%]
irrd/server/http/tests/test_metrics_generator.py .                                                                                                                                                          [ 47%]
irrd/server/http/tests/test_status_generator.py .                                                                                                                                                           [ 47%]
irrd/server/tests/test_query_resolver.py .......................                                                                                                                                            [ 50%]
irrd/server/whois/tests/test_query_parser.py ............................................                                                                                                                   [ 55%]
irrd/server/whois/tests/test_query_response.py ..                                                                                                                                                           [ 56%]
irrd/server/whois/tests/test_server.py .......                                                                                                                                                              [ 57%]
irrd/storage/tests/test_database.py ...................                                                                                                                                                     [ 59%]
irrd/storage/tests/test_event_stream.py .                                                                                                                                                                   [ 59%]
irrd/storage/tests/test_preload.py .....                                                                                                                                                                    [ 60%]
irrd/updates/tests/test_email.py ......                                                                                                                                                                     [ 61%]
irrd/updates/tests/test_handler.py .........                                                                                                                                                                [ 62%]
irrd/updates/tests/test_parser.py ...............................................                                                                                                                           [ 68%]
irrd/updates/tests/test_suspension.py ..                                                                                                                                                                    [ 68%]
irrd/updates/tests/test_validators.py ..........................                                                                                                                                            [ 72%]
irrd/utils/tests/test_crypto.py .                                                                                                                                                                           [ 72%]
irrd/utils/tests/test_email.py ..............                                                                                                                                                               [ 74%]
irrd/utils/tests/test_misc.py .                                                                                                                                                                             [ 74%]
irrd/utils/tests/test_pgp.py ....                                                                                                                                                                           [ 74%]
irrd/utils/tests/test_process_support.py ...                                                                                                                                                                [ 75%]
irrd/utils/tests/test_text.py .....                                                                                                                                                                         [ 75%]
irrd/utils/tests/test_validators.py ...                                                                                                                                                                     [ 76%]
irrd/utils/tests/test_whois_client.py ..............                                                                                                                                                        [ 77%]
irrd/webui/tests/test_auth_endpoints.py .......................................                                                                                                                             [ 83%]
irrd/webui/tests/test_auth_endpoints_mfa.py ....................................                                                                                                                            [ 87%]
irrd/webui/tests/test_endpoints.py ..........................................                                                                                                                               [ 93%]
irrd/webui/tests/test_endpoints_mntners.py ...................................................                                                                                                              [ 99%]
irrd/webui/tests/test_helpers.py .                                                                                                                                                                          [100%]

================================================================================================ warnings summary =================================================================================================
../../usr/local/lib/python3.10/dist-packages/pydantic_core/core_schema.py:3979
../../usr/local/lib/python3.10/dist-packages/pydantic_core/core_schema.py:3979
  /usr/local/lib/python3.10/dist-packages/pydantic_core/core_schema.py:3979: DeprecationWarning: `FieldValidationInfo` is deprecated, use `ValidationInfo` instead.
    warnings.warn(msg, DeprecationWarning, stacklevel=1)

../../usr/local/lib/python3.10/dist-packages/starlette/routing.py:640
  /usr/local/lib/python3.10/dist-packages/starlette/routing.py:640: DeprecationWarning: The on_startup and on_shutdown parameters are deprecated, and they will be removed on version 1.0. Use the lifespan parameter instead. See more about it on https://www.starlette.io/lifespan/.
    warnings.warn(

../../usr/local/lib/python3.10/dist-packages/pytest_freezegun.py:17: 1536 warnings
irrd/mirroring/nrtm4/tests/test_nrtm4_types.py: 16 warnings
irrd/scripts/tests/test_expire_journal.py: 2 warnings
irrd/server/http/tests/test_event_stream.py: 4 warnings
  /usr/local/lib/python3.10/dist-packages/pytest_freezegun.py:17: DeprecationWarning: distutils Version classes are deprecated. Use packaging.version instead.
    if LooseVersion(pytest.__version__) < LooseVersion('3.6.0'):

irrd/server/http/tests/test_endpoints.py::TestObjectSubmissionEndpoint::test_endpoint
irrd/server/http/tests/test_endpoints.py::TestObjectSubmissionEndpoint::test_endpoint
irrd/server/http/tests/test_endpoints.py::TestSuspensionSubmissionEndpoint::test_endpoint
irrd/webui/tests/test_auth_endpoints_mfa.py::TestWebAuthnAuthenticate::test_valid_authenticate
irrd/webui/tests/test_auth_endpoints_mfa.py::TestWebAuthnAuthenticate::test_invalid_authenticate
  /usr/local/lib/python3.10/dist-packages/httpx/_content.py:204: DeprecationWarning: Use 'content=<...>' to upload raw bytes/text content.
    warnings.warn(message, DeprecationWarning)

irrd/server/http/tests/test_event_stream.py::TestEventStreamEndpoint::test_endpoint
irrd/server/http/tests/test_event_stream.py::TestEventStreamEndpoint::test_endpoint
irrd/server/http/tests/test_event_stream.py::TestEventStreamEndpoint::test_endpoint
  /usr/local/lib/python3.10/dist-packages/pydantic/main.py:1089: PydanticDeprecatedSince20: The `parse_raw` method is deprecated; if your data is JSON use `model_validate_json`, otherwise load the data then use `model_validate` instead. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.6/migration/
    warnings.warn(

irrd/server/http/tests/test_event_stream.py::TestEventStreamEndpoint::test_endpoint
irrd/server/http/tests/test_event_stream.py::TestEventStreamEndpoint::test_endpoint
irrd/server/http/tests/test_event_stream.py::TestEventStreamEndpoint::test_endpoint
  /usr/local/lib/python3.10/dist-packages/pydantic/main.py:1097: PydanticDeprecatedSince20: `load_str_bytes` is deprecated. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.6/migration/
    obj = parse.load_str_bytes(

irrd/webui/tests/test_auth_endpoints.py: 29 warnings
irrd/webui/tests/test_auth_endpoints_mfa.py: 37 warnings
irrd/webui/tests/test_endpoints.py: 32 warnings
irrd/webui/tests/test_endpoints_mntners.py: 35 warnings
  /usr/local/lib/python3.10/dist-packages/starlette/templating.py:178: DeprecationWarning: The `name` is not the first parameter anymore. The first parameter should be the `Request` instance.
  Replace `TemplateResponse(name, {"request": request})` by `TemplateResponse(request, name)`.
    warnings.warn(

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
================================================================================== 768 passed, 1705 warnings in 82.20s (0:01:22) ==================================================================================

@jwbensley
Copy link
Author

Not sure if you want me to keep adding words to docs/spelling_wordlist.txt until it passes or not?

@mxsasha
Copy link
Collaborator

mxsasha commented Apr 8, 2024

This is a good start! Some thoughts:

  • I don't think we should distribute RIPE db by default. The default image should probably not have any sources configured. There should definitely not be db dumps in the docker base image.
  • I'd prefer another workaround for the git status rather than hardcoding a path in the compose file. Why would we even care in the image? Don't see a reason to run git there. Or perhaps .git should be excluded.
  • Any reason to label the volumes with :z? They aren't shared right?
  • This makes me want a two layer irrd.yaml config file: in a docker instance, operators should never meddle with the listening host. And if they use the compose file, probably not database_url. But surely they would want to set the source settings. Or maybe something templated, so that the image can be used in different compose configs rather than the included one. And how to handle reloads well? Kind of a useful feature that we have now. I'm not sure about the best approach.

@mxsasha
Copy link
Collaborator

mxsasha commented Apr 9, 2024

I'm also wondering if original client IPs are still visible to IRRD with this network setup?

If all this creates complexity beyond your available time/interest/skill, I can probably also pick this up myself :)

@jwbensley
Copy link
Author

jwbensley commented Sep 11, 2024

I have tried to address you concerns:

  • I don't think we should distribute RIPE db by default. The default image should probably not have any sources configured. There should definitely not be db dumps in the docker base image.

Yeah makes sense, my original PR was coming from a dev perspective (more on this later). I have removed the IRR data and put it in a script so that devs can import data only if they want to, for testing. I've also added it to the documentation.

  • I'd prefer another workaround for the git status rather than hardcoding a path in the compose file. Why would we even care in the image? Don't see a reason to run git there. Or perhaps .git should be excluded.

The git thing was coming from running Sphinx tests inside docker. Because the .git/ sub-folder is mounted by docker-compose Sphinx checks if the owner of the folder is correctly set (it's not, because docker runs as root). It's not possible to not mount the .git/ sub-folder. I also tried to make the .git/ sub-folder empty but Sphinx then complains there is a .git/ folder which is not a real repo. To resolve this I updated the documentation, you still need to run the command, but only if you want to run the Sphinx tests, and at run time, not build time, so it's not baked into the container.

  • Any reason to label the volumes with :z? They aren't shared right?

Just internal practice I copy-pastered. Fixed now.

  • This makes me want a two layer irrd.yaml config file: in a docker instance, operators should never meddle with the listening host. And if they use the compose file, probably not database_url. But surely they would want to set the source settings. Or maybe something templated, so that the image can be used in different compose configs rather than the included one. And how to handle reloads well? Kind of a useful feature that we have now. I'm not sure about the best approach.

Hold that thought...

I'm also wondering if original client IPs are still visible to IRRD with this network setup?

Yes original client IPs are visible, but this comment, and the one above, and also you first comment I quoted above, all make me think we have different goals with "dockerising" IRRd.

My aim with this PR is to get IRRd and all it's Python dependencies, and application dependencies (Postgres and Redis), all running in containers for easy development work (and that also requires some real data, hence the import data script).

Right now the barrier to entry to doing dev work on IRRd is quite high because I need to basically deploy a new virtual machine and do a full OS install, then install Postgres and Redis, then I can build IRRd, then config IRR DB sources and wait for the data import.

What I have tried to achieve with this PR is to dockerise IRRd for dev work. You comments make me think you want to dockerise it for production operation. That's fine but IMO it's a different process. I see getting IRRd into docker for dev work as step 1, and getting it into docker for deployment as step 2.

Just my two pence; internally we create Dockerfile's and docker-compose files for all apps:

  • docker compose is used to build and run apps on a developer's machine
  • in production we use docker compose to build and put the image into a private image store, and then use k8's manifests to pull the images from our image store and deploy to our k8s clusters. If you want to do that with IRRd too, my two pence is to split the work up into separate steps.

Update: I see there is another Docker PR open. That PR pulls the latest "release" of IRRd and dockerises that. This PR I have raised uses the local codebase. These are different approaches, my is aimed at dev work, that other PR is aimed at running in production. This is further to my point, I would split the two things up because they are not the same.

Update 2: I forgot to mention what's changed in the latest version of the PR, apart from addressing your concerns:

  • I have tried to removed all hard coded paths, they are in ENV vars so they can be overridden
  • I added a .env file so that you don't have to specify the path to the docker-compose file
  • I bumped Postgres to v15 and Redis to v7 because these are the latest versions supported by IRRd
  • The PR is based on the latest commit in main
  • The Python dependency docutils wasn't pinned and the latest release is b0rked, so I pinned it

Pytest is fully passing inside docker:

================================================================================== 768 passed, 1761 warnings in 85.12s (0:01:25) ==================================================================================

Sphinx test is fully passing inside docker (there are a bunch of words no in the dictionary which I didn't add, which it complains about though):

Warning, treated as error:
Found 63 misspelled words

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants