Skip to content

feat: try to implement single level subdomain A records#2425

Open
kencho51 wants to merge 10 commits into
gigascience:developfrom
kencho51:update-portainer-dns-records
Open

feat: try to implement single level subdomain A records#2425
kencho51 wants to merge 10 commits into
gigascience:developfrom
kencho51:update-portainer-dns-records

Conversation

@kencho51

@kencho51 kencho51 commented Aug 6, 2025

Copy link
Copy Markdown
Contributor

Pull request for issue: #2393

This is a pull request for the following functionalities:

  1. Configured cloudfllare SSL/TLS encryption mode from Flexible to Full (strict)
  2. Updated the Nginx HTTP block for port 80 to redirect all HTTP traffic to HTTPS
  3. Updated the Nginx HTTP block for port 80 to allow access to /.well-known/acme-challenge/ to handle challenge requests for the Let's Encrypt when creating a new cert using certbot.
  4. Refactored the portainer container to include the TRUSTED_ORIGINS environment variable
  5. Upgraded the already EOL php fpm base image from buster to bullseye in the production app dockerfile which will be fixed in Make partial pipeline pass #2426

How to test?

In dev

No changes to dev

In Staging

  1. Migrate DNS to Cloudflare (optional)

Create new A record for your production ips, as below:

type name content proxy
A $name-staging $staging-web-eip on
A portainer-$name-staging $staging-web-eip on
A files-$name-staging $staging-files-eip on

By doing this, all domains will be centralized to Cloudflare DNS, and save cost from managing your own DNS for development.

  1. Update REMOTE_FILES_PUBLIC_URL, REMOTE_HOME_URL, REMOTE_HOSTNAME, remote_fileserver_hostname` in your gitlab variable page as in the new A record table.
  2. Delete all the existing tls certs in your gitlab variable page, which will trigger the setup_cert.sh to create new cert for the new domain names during sd_gigadb.
  3. Follow the steps in docs/SETUP_PROVISIONING.md and docs/SETUP_CI_CD_PIPELINE.md to spin up servers and execute the CI/CD pipeline
  4. When sd_gigadb is passed, go to $name-staging.gigadb.org and portainer-$name-staging.gigadb.org to check

In Live

Repeat the steps in In Staing, except the for DNA A record which should be:

type name content proxy
A $name-live $live-web-eip on
A portainer-$name-live $live-web-eip on
A files-$name-live $live-files-eip on

And also follow docs/RELEASE_PROCESS.md to make a live deployment.

How have functionalities been implemented?

HTTP vs HTTPS request

Originally, the cloudflare SSL/TLS encryption mode was set to Flexible and with proxy is turned on, from user to cloudflare is a HTTPS request, but from cloudflare to portainer server is a HTTP request. When Nginx server receives this request on port 80, it matches the server block intended for HTTP traffic in the nginx.target_deployment.http.conf, the location block contains try_files $uri $uri/ /index.php$is_args$args;, this directive tells Nginx to serve a file from the local disk, which fails and results in the browser being told to download a file.

It could be simply fixed by changing the SSL/TLS encryption mode to FULL (strict), it will make sure the requests from user to cloudflare then to portainer server is all HTTPS as Browser --(HTTPS)--> Cloudflare --(HTTPS)--> Server, this encrypts traffic and verifies the Let's Encrypt certificate is valid. And more importantly, by redirecting all HTTP requests to the corresponding HTTPS URL with a 301 Moved Permanently status code, this preserves the code's integrity removes the dependency on Cloudflare.

CSRF issue

When tried visit portainer behind the cloudflare proxy, the request has been configured to https only, user cannot log in portainer from the Chrome browser because of this error:

2025/08/07 05:17AM ERR github.com/portainer/portainer/api/http/csrf/csrf.go:100 > Failed to validate Origin or Referer | error="origin invalid" forwarded= host=portainer:9000 origin=https://portainer-ken-staging.gigadb.org referer=https://portainer-ken-staging.gigadb.org/ request_url=/api/auth trusted_origins=[] x_forwarded_proto=https

As reported in https://www.portainer.io/blog/origin-invalid-errors-with-portainer-2-27-7-behind-reverse-proxies, portainer has updated a third-party library (gorilla/csrf) introduced since version 2.27.7, the new version of gorilla/csrf was stricter on requirements around Origin and Referer headers than the previous release had been, so they have enabled the --trusted-origins CLI option (and the equivalent TRUSTED_ORIGINS environment variable) for the Portainer container.

The fix for this is to update the production portainer container with this environment variable:

    environment:
      - TRUSTED_ORIGINS=portainer-$REMOTE_HOSTNAME

Any issues with implementation?

Describe any problems with your implementation

None.

Any changes to automated tests?

None.

Any changes to documentation?

None.

Any technical debt repayment?

Updated ops/configuration/nginx-conf/sites/nginx.target_deployment.http.conf.dist to redirect all http request to https for the portainer.

Upgraded the already EOL php fpm base image from buster to bullseye in the production app dockerfile

Any improvements to CI/CD pipeline?

Describe any improvements to the Gitlab pipeline

Summary by CodeRabbit

  • Bug Fixes

    • Improved accessibility of Portainer when deployed behind a Cloudflare proxy.
  • Chores

    • Updated configuration files and environment variables to use hyphenated subdomain naming for Portainer.
    • Enhanced SSL security by removing outdated protocols and updating cipher suites.
    • Adjusted Docker Compose and certificate setup scripts to align with new subdomain format.
    • Updated documentation to reflect these changes.

@coderabbitai

coderabbitai Bot commented Aug 6, 2025

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This change updates configuration files and scripts to switch the Portainer subdomain naming convention from a dot separator (e.g., portainer.example.com) to a hyphen separator (e.g., portainer-example.com). Related Nginx configuration, Docker Compose environment variables, certificate setup scripts, and the changelog were updated accordingly, with some SSL and proxy enhancements.

Changes

Cohort / File(s) Change Summary
Changelog Update
CHANGELOG.md
Added an entry under "Unreleased" noting the fix for Portainer accessibility behind Cloudflare proxy.
Nginx HTTP Config Update
ops/configuration/nginx-conf/sites/nginx.target_deployment.http.conf.dist
Changed server_name to use hyphen; removed root, index, static file caching, and .well-known blocks; main location now redirects to HTTPS.
Nginx HTTPS Config & SSL Update
ops/configuration/nginx-conf/sites/nginx.target_deployment.https.conf.dist
Changed server_name to hyphen format; added DNS resolver; updated proxy pass to use variables; removed root/index; updated SSL protocols/ciphers; removed HSTS header.
Docker Compose Env Update
ops/deployment/docker-compose.production-envs.yml
Added TRUSTED_ORIGINS=portainer-$REMOTE_HOSTNAME to the Portainer service environment variables.
Certificate Script Update
ops/scripts/setup_cert.sh
Changed certbot domain argument from dot to hyphen separator for Portainer.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Nginx (HTTP)
    participant Nginx (HTTPS)
    participant Portainer

    User->>Nginx (HTTP): Request http://portainer-$SERVER_HOSTNAME/
    Nginx (HTTP)-->>User: 301 Redirect to https://portainer-$SERVER_HOSTNAME/

    User->>Nginx (HTTPS): Request https://portainer-$SERVER_HOSTNAME/
    Nginx (HTTPS)->>Portainer: Proxy request using $upstream_portainer
    Portainer-->>Nginx (HTTPS): Response
    Nginx (HTTPS)-->>User: Response
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Suggested labels

pr:simple

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@kencho51

kencho51 commented Aug 7, 2025

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 7, 2025

Copy link
Copy Markdown
✅ Actions performed

Full review triggered.

@kencho51 kencho51 force-pushed the update-portainer-dns-records branch from c8987d1 to 4b7cb7b Compare August 7, 2025 15:22
@gigascience gigascience deleted a comment from coderabbitai Bot Aug 11, 2025
@kencho51 kencho51 marked this pull request as ready for review August 11, 2025 01:45
@kencho51 kencho51 requested review from pli888 and rija as code owners August 11, 2025 01:45
@kencho51 kencho51 moved this from Draft to Reviewing Required in Backlog: Pull Requests Aug 11, 2025
@rija rija moved this from Reviewing Required to Under Review in Backlog: Pull Requests Aug 13, 2025
@rija rija added the Rija label Aug 13, 2025

@rija rija left a comment

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.

Hi @kencho51,

question: After deploying this PR (following the instructions in PR) I encountered “too many redirect” errors when navigating to both my gigadb and portainer endpoints on staging (Tried with Safari and Firefox).
Turning off the Cloudflare proxy doesn’t seem to make a difference.

https://rija-staging.gigadb.host/

https://portainer-rija-staging.gigadb.host/

I then redeployed another branch and the gigadb website was reachable normally (with Cloudflare proxy still on).

Is there something I missed, or is there something in need of tweaking in the nginx configuration files?

(I’ve now redeployed your branch so you can see for yourself)

@rija rija removed the Rija label Aug 14, 2025
@rija rija moved this from Under Review to Reviewing Required in Backlog: Pull Requests Aug 14, 2025
@kencho51 kencho51 force-pushed the update-portainer-dns-records branch from 151dd1a to 7fc7bdc Compare August 15, 2025 02:00
@kencho51

Copy link
Copy Markdown
Contributor Author

Hi @rija,

question: After deploying this PR (following the instructions in PR) I encountered “too many redirect” errors

Regarding this error, I think the reason for it is your domains are not from Cloudflare DNS, so when your nginx instance receives a secure HTTPS request, it will then forward the request to the application/portainer over an insecure channel (HTTP), which then would send a redirect back to the browser, telling it to use HTTPS, which starts the loop all over again.

A quick fix is to migrate your URLs to Cloudflare DNS, it will make sure the request to the application contains the header X-Forwarded-Proto, which indicate the connection from the nginx instance to the application/portainer is secure too, no need to redirect.

But in order to make the nginx configuration robust enough to handle both direct connections and proxied connections correctly (Cloudflare), the nginx https config need to updated as well, which is in the a88bce0.

@kencho51 kencho51 force-pushed the update-portainer-dns-records branch from a88bce0 to 4262bfd Compare August 15, 2025 06:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Reviewing Required

Development

Successfully merging this pull request may close these issues.

2 participants