From 97ab65ac552649b7d91535d4878caddb791c79e9 Mon Sep 17 00:00:00 2001 From: kiraum Date: Sun, 12 May 2024 21:21:32 +0200 Subject: [PATCH] chore: Adding Docker compose example/documentation --- .gitignore | 2 + docs/admins/deployment.rst | 27 +++++ irrd/docker/Dockerfile | 28 +++++ irrd/docker/docker-compose.yml | 48 ++++++++ irrd/docker/init.sh | 11 ++ irrd/docker/irrd.yaml | 213 +++++++++++++++++++++++++++++++++ 6 files changed, 329 insertions(+) create mode 100644 irrd/docker/Dockerfile create mode 100644 irrd/docker/docker-compose.yml create mode 100755 irrd/docker/init.sh create mode 100755 irrd/docker/irrd.yaml diff --git a/.gitignore b/.gitignore index d61380a7c..6581904da 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ syntax: glob __pycache__ _build twisted/plugins/dropin.cache + +irrd/docker/data diff --git a/docs/admins/deployment.rst b/docs/admins/deployment.rst index ad400b712..ef8b9c227 100644 --- a/docs/admins/deployment.rst +++ b/docs/admins/deployment.rst @@ -412,3 +412,30 @@ and :doc:`any relevant notifications are also sent `. .. note:: As a separate script, `irrd_submit_email` **always acts on the current configuration file** - not on the configuration that IRRd started with. + +Docker / Docker Compose + +If you need to quickly deploy a new IRRd instance, you can utilise the provided Docker file and Docker Compose configuration. + +Steps to set up the container infrastructure:: + + => Clone the repository + git clone git@github.com:irrdnet/irrd.git` + => Navigate to the Docker directory: + cd irrd/docker + => Launch the environment: + docker-compose -f docker-up -d + +You get the following services running:: + + % docker ps + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + 9d357d719f43 docker-irrd "/app/irrd/init.sh" About a minute ago Up 16 seconds (healthy) 0.0.0.0:8043->8043/tcp, 0.0.0.0:8080->8080/tcp irrd + 178603c6442f postgres "docker-entrypoint.s…" About a minute ago Up About a minute (healthy) 5432/tcp postgres_irrd + 416ebb4c0f4b redis "docker-entrypoint.s…" About a minute ago Up About a minute (healthy) 6379/tcp redis_irrd + +.. note:: + * Ensure to select the appropriate IRRd version in the Docker file; + * Always modify the default credentials in the `docker-compose.yml`/`irrd.yaml` file; + * Update the `irrd.yaml` configuration to suit your specific needs; + * IRRd web interface available at http://localhost:8080/. diff --git a/irrd/docker/Dockerfile b/irrd/docker/Dockerfile new file mode 100644 index 000000000..812303cdb --- /dev/null +++ b/irrd/docker/Dockerfile @@ -0,0 +1,28 @@ +# description="IRRd4 Docker Image" +# +# Dockerfile for the IRRd4 application. +# +# This Dockerfile sets up a Python 3.12.3 environment and installs the necessary dependencies for running the IRRd4 application. It copies an init script to the container, updates the package lists, installs build tools and other required packages, installs the IRRd4 package, and sets up the necessary directories and permissions. +# +# The resulting Docker image can be used to run the IRRd4 application in a containerized environment. + +FROM python:3.12.3-bookworm + +ARG IRRD_VERSION=4.4.4 + +COPY init.sh /app/irrd/init.sh + +RUN apt-get update \ + && apt-get install -y --no-install-recommends build-essential gcc gnupg dumb-init cron + +RUN pip install --no-cache-dir -U pip psycopg2 \ + && pip install --no-cache-dir irrd==$IRRD_VERSION + +RUN apt-get clean autoclean \ + && apt-get autoremove -y \ + && rm -rf /var/lib/apt/lists/* + +RUN mkdir /var/run/irrd +RUN chown daemon:daemon /var/run/irrd + +CMD ["/app/irrd/init.sh"] diff --git a/irrd/docker/docker-compose.yml b/irrd/docker/docker-compose.yml new file mode 100644 index 000000000..41a27d660 --- /dev/null +++ b/irrd/docker/docker-compose.yml @@ -0,0 +1,48 @@ +--- +services: + irrd: + build: + context: . + dockerfile: Dockerfile + container_name: irrd + volumes: + - ./irrd.yaml:/etc/irrd.yaml:ro + ports: + - 8080:8080 + - 8043:8043 + healthcheck: + test: [ "CMD-SHELL", "curl -LI localhost:8080" ] + interval: 15s + timeout: 15s + retries: 5 + depends_on: + postgres_irrd: + condition: service_healthy + redis_irrd: + condition: service_healthy + + postgres_irrd: + image: postgres + container_name: postgres_irrd + environment: + - "PGUSER=irrd" + - "POSTGRES_USER=irrd" + - "POSTGRES_PASSWORD=irrd" + - "POSTGRES_DB=irrd" + volumes: + # if you want to have a persistent database locally (not in a container) + - ./data/postgresql_irrd:/var/lib/postgresql/data + healthcheck: + test: [ "CMD-SHELL", "pg_isready -d irrd" ] + interval: 15s + timeout: 15s + retries: 5 + + redis_irrd: + image: redis + container_name: redis_irrd + healthcheck: + test: [ "CMD-SHELL", "redis-cli get nil" ] + interval: 60s + timeout: 5s + retries: 5 diff --git a/irrd/docker/init.sh b/irrd/docker/init.sh new file mode 100755 index 000000000..5bc16ae10 --- /dev/null +++ b/irrd/docker/init.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# This script performs the following actions: +# 1. Removes any existing PID files for the IRRD service from the /var/run/irrd directory. +# 2. Upgrades the IRRD database using the configuration file located at /etc/irrd.yaml. +# 3. Starts the IRRD service in the foreground using the configuration file located at /etc/irrd.yaml. + +rm /var/run/irrd/* >/dev/null 2>&1 || true + +irrd_database_upgrade --config=/etc/irrd.yaml +exec /usr/local/bin/irrd --foreground --config=/etc/irrd.yaml + diff --git a/irrd/docker/irrd.yaml b/irrd/docker/irrd.yaml new file mode 100755 index 000000000..171ff0922 --- /dev/null +++ b/irrd/docker/irrd.yaml @@ -0,0 +1,213 @@ +--- +# This YAML configuration file sets up the IRRd (Internet Routing Registry daemon) application. It defines the following key configuration settings: +# +# - Database connection details for the PostgreSQL database used by IRRd. +# - Authentication settings, including the GnuPG keyring location, a password override, and password hashing configuration. +# - Logging settings, including the log level. +# - Redis connection details. +# - Process user and group. +# - Preferences for route object updates and RPKI (Resource Public Key Infrastructure) integration. +# - Access control lists for the HTTP and WHOIS servers. +# - Server settings for the HTTP and WHOIS interfaces. +# - Email notification settings, including the from address, SMTP server, and notification templates. +# - Default and specific source configurations for various IRR (Internet Routing Registry) sources, including full import and NRTM (Notification of Changes) update settings. +irrd: + database_url: postgresql://irrd:irrd@postgres_irrd:5432/irrd?keepalives=1&keepalives_idle=5 + auth: + gnupg_keyring: /root/gnupg-keyring/ + override_password: "so_safe" + webui_auth_failure_rate_limit: "30/hour" + password_hashers: + md5-pw: legacy + log: + level: DEBUG + redis_url: "redis://redis_irrd:6379" + piddir: /var/run/irrd/ + user: daemon + group: daemon + route_object_preference: + update_timer: 3600 + rpki: + roa_source: https://rpki.gin.ntt.net/api/export.json + roa_import_timer: 3600 + pseudo_irr_remarks: | + This AS{asn} route object represents routing data retrieved + from the RPKI. This route object is the result of an automated + RPKI-to-IRR conversion process performed by IRRd. + notify_invalid_subject: route(6) objects in {sources_str} marked RPKI invalid + notify_invalid_header: | + This is to notify that {object_count} route(6) objects for which you are a + contact have been marked as RPKI invalid. This concerns + objects in the {sources_str} database. + + You have received this message because your e-mail address is + listed in one or more of the tech-c or admin-c contacts, on + the maintainer(s) for these route objects. + + The {object_count} route(6) objects listed below have been validated using + RPKI origin validation, and found to be invalid. This means that + these objects are no longer visible on the IRRd instance that + sent this e-mail. + + This may affect routing filters based on queries to this IRRd + instance. It is also no longer possible to modify these objects. + + To resolve this situation, create or modify ROA objects that + result in these route(6) being valid, or not_found. If this + happens, the route(6) objects will return to being visible. + You may also delete these objects if they are no longer + relevant. + access_lists: + http_database_status: + - "::/0" + - "0.0.0.0/0" + server: + http: + interface: "::0" + port: 8080 + status_access_list: http_database_status + url: "http://localhost/" + whois: + interface: "::0" + port: 8043 + # max_connections: 50 + # log: + # logfile_path: /var/log/irrd.log + # level: WARNING + email: + from: irrd@example.com + smtp: localhost + footer: '' + notification_header: | + This is to notify you of changes in the {sources_str} database + or object authorisation failures. + + You may receive this message because you are listed in + the notify attribute on the changed object(s), because + you are listed in the mnt-nfy or upd-to attribute on a maintainer + of the object(s), or the upd-to attribute on the maintainer of a + parent of newly created object(s). + sources_default: + - RPKI + - ALTDB + - AFRINIC + - APNIC + - ARIN + - LACNIC + - RIPE + - RADB + - TC + sources: + # if you need to add a new routing registry, check https://irr.net/registry/ + ALTDB: + # Run a full import at first, then periodic NRTM updates. + authoritative: false + keep_journal: true + import_source: "ftp://ftp.altdb.net/pub/altdb/altdb.db.gz" + import_serial_source: "ftp://ftp.altdb.net/pub/altdb/ALTDB.CURRENTSERIAL" + nrtm_host: whois.altdb.net + nrtm_port: 43 + import_timer: 900 # every 15 minutes + AFRINIC: + # Run a full import at first, then periodic NRTM updates. + authoritative: false + keep_journal: true + import_source: "https://ftp.afrinic.net/pub/dbase/afrinic.db.gz" + import_serial_source: "https://ftp.afrinic.net/pub/dbase/AFRINIC.CURRENTSERIAL" + nrtm_host: whois.afrinic.net + nrtm_port: 43003 + import_timer: 900 # every 15 minutes + APNIC: + # Run a full import at first, then periodic NRTM updates. + authoritative: false + keep_journal: true + import_source: + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.as-block.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.as-set.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.aut-num.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.domain.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.filter-set.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.inet-rtr.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.inet6num.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.inetnum.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.irt.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.key-cert.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.limerick.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.mntner.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.organisation.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.peering-set.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.role.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.route-set.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.route.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.route6.gz" + - "ftp://ftp.apnic.net/apnic/whois/apnic.db.rtr-set.gz" + import_serial_source: "ftp://ftp.apnic.net/pub/apnic/whois/APNIC.CURRENTSERIAL" + nrtm_host: whois.apnic.net + nrtm_port: 43 + import_timer: 900 # every 15 minutes + ARIN: + # Run a full import at first, then periodic NRTM updates. + authoritative: false + keep_journal: true + import_source: "https://ftp.arin.net/pub/rr/arin.db.gz" + import_serial_source: "https://ftp.arin.net/pub/rr/ARIN.CURRENTSERIAL" + nrtm_host: rr.arin.net + nrtm_port: 43 + import_timer: 900 # every 15 minutes + LACNIC: + # Run a full import at first, then periodic NRTM updates. + authoritative: false + keep_journal: true + import_source: "https://irr.lacnic.net/lacnic.db.gz" + import_serial_source: "https://irr.lacnic.net/LACNIC.CURRENTSERIAL" + nrtm_host: irr.lacnic.net + nrtm_port: 43 + import_timer: 900 # every 15 minutes + RIPE: + # Run a full import at first, then periodic NRTM updates. + authoritative: false + keep_journal: true + import_source: + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.as-block.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.as-set.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.aut-num.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.domain.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.filter-set.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.inet-rtr.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.inet6num.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.inetnum.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.irt.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.key-cert.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.mntner.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.organisation.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.peering-set.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.person.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.poem.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.poetic-form.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.role.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.route-set.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.route.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.route6.gz" + - "https://ftp.ripe.net/ripe/dbase/split/ripe.db.rtr-set.gz" + import_serial_source: "https://ftp.ripe.net/ripe/dbase/RIPE.CURRENTSERIAL" + nrtm_host: whois.ripe.net + nrtm_port: 4444 + import_timer: 900 # every 15 minutes + RADB: + # Run a full import at first, then periodic NRTM updates. + authoritative: false + keep_journal: true + import_source: "ftp://ftp.radb.net/radb/dbase/radb.db.gz" + import_serial_source: "ftp://ftp.radb.net/radb/dbase/RADB.CURRENTSERIAL" + nrtm_host: nrtm.radb.net + nrtm_port: 43 + import_timer: 900 # every 15 minutes + TC: + # Run a full import at first, then periodic NRTM updates. + authoritative: false + keep_journal: true + import_source: "https://ftp.bgp.net.br/tc.db.gz" + import_serial_source: "https://ftp.bgp.net.br/TC.CURRENTSERIAL" + nrtm_host: irr.bgp.net.br + nrtm_port: 43 + import_timer: 900 # every 15 minutes