Skip to content

Support setup with only an IPv4 address, but no domain#894

Closed
missytake wants to merge 8 commits intomainfrom
ipv4-only
Closed

Support setup with only an IPv4 address, but no domain#894
missytake wants to merge 8 commits intomainfrom
ipv4-only

Conversation

@missytake
Copy link
Copy Markdown
Contributor

@missytake missytake commented Mar 12, 2026

This PR enables to run cmdeploy init 13.12.131.2 and then continue with cmdeploy run as expected.

It federates successfully with https://172.238.97.168/, and nine.testrun.org, I tested both manually.

It can be tested with https://github.com/chatmail/hetzner-relay --ipv4only, I didn't adjust CI yet as things are in motion anyway right now.

@missytake missytake temporarily deployed to staging2.testrun.org March 12, 2026 22:18 — with GitHub Actions Inactive
@missytake missytake temporarily deployed to staging-ipv4.testrun.org March 12, 2026 22:18 — with GitHub Actions Inactive
Copy link
Copy Markdown
Contributor

@hpk42 hpk42 left a comment

Choose a reason for hiding this comment

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

nice :)

documentation is missing ("### experimental support for 'dns-free' IP-based relays" or so somehwere) with a note that this support is WIP and might change without prior notice.

Comment thread cmdeploy/src/cmdeploy/postfix/main.cf.j2


def test_init(tmp_path, maildomain):
def test_init(tmp_path, maildomain_sanitized):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In the tests i would make maildomain fixture return the "[]"-stripped ip-address so you don't need to change tests much. "config.mail_domain" would still have the "[]" spelling where needed. sshdomain/imap/smtp fixtures can use maildomain directly then.

Comment thread cmdeploy/src/cmdeploy/cmdeploy.py
@j-g00da j-g00da self-requested a review March 13, 2026 07:57
Copy link
Copy Markdown
Collaborator

@j-g00da j-g00da left a comment

Choose a reason for hiding this comment

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

Nice :D I would also add support for IPv6 domain-literals as this doesn't require that much more changes.

Suggested PR title/commit message:
feat: No-DNS relay deployment

Current title makes it a bit confusing, as relays with IPv4 maildomain can still operate over IPv6 (and we most likely want to also support IPv6 maildomains).

Comment on lines +166 to +172
def is_valid_ipv4(address: str) -> bool:
"""Check if a mail_domain is an IPv4 address."""
try:
ipaddress.IPv4Address(address)
return True
except ValueError:
return False
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I would introduce something like format_maildomain that would check if it is either a domain, IPv4 or IPv6 and then either don't change it in case of a domain, or format it as a domain-literal. It would be nice to accept IPv6, as the only change needed would be adding IPv6: prefix inside the square brackets.

Copy link
Copy Markdown
Contributor

@j4n j4n left a comment

Choose a reason for hiding this comment

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

looks good to me apart from the aspects raised by the others.

out.red("Deploy completed but letsencrypt not configured")
out.red("Run 'cmdeploy run' again")
else:
out.green("Deploy completed, call `cmdeploy dns` next.")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should be skipped if it's an IP-only relay or cmdeploy dns amended to fail gracefully:

(venv) ~/delta/relay2 [ipv4-only] % cmdeploy dns
ssh: Could not resolve hostname [46.224.103.73]: Name or service not known
Traceback (most recent call last):
...
  File "/home/ja/delta/relay2/venv/lib/python3.10/site-packages/execnet/gateway_bootstrap.py", line 55, in bootstrap_exec
    raise HostNotFound(io.remoteaddress) from None
execnet.gateway_bootstrap.HostNotFound: root@[46.224.103.73]

Comment thread cmdeploy/src/cmdeploy/cmdeploy.py
Comment thread chatmaild/src/chatmaild/config.py
def sshdomain(maildomain):
return os.environ.get("CHATMAIL_SSH", maildomain)
def maildomain_sanitized(maildomain):
return maildomain.strip("[").strip("]")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is good, should be used everywhere.

@missytake
Copy link
Copy Markdown
Contributor Author

I'm continuing this effort in #919 :)

@missytake missytake closed this Apr 14, 2026
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.

4 participants