{"id":3259,"date":"2026-02-26T01:46:43","date_gmt":"2026-02-26T01:46:43","guid":{"rendered":"https:\/\/muhammadsoliman.com\/?p=3259"},"modified":"2026-02-26T02:20:59","modified_gmt":"2026-02-26T02:20:59","slug":"how-to-deploy-traefik-on-vps","status":"publish","type":"post","link":"https:\/\/muhammadsoliman.com\/index.php\/2026\/02\/26\/how-to-deploy-traefik-on-vps\/","title":{"rendered":"how to Deploy Traefik on VPS"},"content":{"rendered":"<style>.kb-image3259_51e518-10 .kb-image-has-overlay:after{opacity:0.3;}<\/style>\n<div class=\"wp-block-kadence-image kb-image3259_51e518-10\"><figure class=\"aligncenter size-full image-is-svg\"><img decoding=\"async\" src=\"http:\/\/muhammadsoliman.com\/wp-content\/uploads\/2026\/02\/Traefik_Logo.svg\" alt=\"\" class=\"kb-img wp-image-3260\"\/><\/figure><\/div>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>Deploying Traefik v3 Reverse Proxy With Cloudflare DNS &amp; Docker on AlmaLinux 10<\/strong><\/h1>\n\n\n\n<p>A Complete Step-by-Step Guide with Cloudlfrare <\/p>\n\n\n\n<p>This guide walks through deploying Traefik v3 as a secure reverse proxy on AlmaLinux 10, using Cloudflare DNS-01 challenge for automatic HTTPS certificates. The setup includes preparing the server, configuring Traefik\u2019s static and dynamic configuration files, enabling Cloudflare DNS validation, and getting Traefik running behind Docker.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>1. Prepare Your Server Directory Structure<\/strong><\/h1>\n\n\n\n<p>Create the Traefik working directory and configuration folders:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p \/root\/traefik\/data\ncd \/root\/traefik\/data\ntouch traefik.yml config.yml acme.json\nchmod 600 acme.json\n<\/code><\/pre>\n\n\n\n<p>Your final structure will look like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/root\/traefik\n\u251c\u2500\u2500 docker-compose.yml\n\u2514\u2500\u2500 data\n    \u251c\u2500\u2500 traefik.yml\n    \u251c\u2500\u2500 config.yml\n    \u2514\u2500\u2500 acme.json\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>2. Create a Cloudflare API Token<\/strong><\/h1>\n\n\n\n<p>Traefik uses the Cloudflare DNS-01 challenge to generate HTTPS certificates automatically.<\/p>\n\n\n\n<p>In Cloudflare:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Go to <strong>My Profile \u2192 API Tokens<\/strong><\/li>\n\n\n\n<li>Click <strong>Create Token<\/strong><\/li>\n\n\n\n<li>Choose template <strong>&#8220;Edit zone DNS&#8221;<\/strong><\/li>\n\n\n\n<li>Permissions required:\n<ul class=\"wp-block-list\">\n<li>Zone \u2192 DNS \u2192 Edit<\/li>\n\n\n\n<li>Zone \u2192 Zone \u2192 Read<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Select your zone (domain)<\/li>\n\n\n\n<li>Leave IP filtering empty<\/li>\n\n\n\n<li>Save your API token<\/li>\n<\/ol>\n\n\n\n<p>This token will later be added to Docker Compose.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>3. Create Traefik Static Configuration (<code>traefik.yml<\/code>)<\/strong><\/h1>\n\n\n\n<p>This file defines:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Dashboard<\/li>\n\n\n\n<li>EntryPoints (80\/443)<\/li>\n\n\n\n<li>Providers (Docker + File)<\/li>\n\n\n\n<li>Cloudflare ACME resolver<\/li>\n<\/ul>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>api:\n  dashboard: true\n  debug: true\n\nentryPoints:\n  http:\n    address: \":80\"\n    http:\n      redirections:\n        entryPoint:\n          to: https\n          scheme: https\n\n  https:\n    address: \":443\"\n\nproviders:\n  docker:\n    endpoint: \"unix:\/\/\/var\/run\/docker.sock\"\n    exposedByDefault: false\n\n  file:\n    filename: \/config.yml\n    watch: true\n\ncertificatesResolvers:\n  cloudflare:\n    acme:\n      email: your-email@example.com\n      storage: \/acme.json\n      dnsChallenge:\n        provider: cloudflare\n        resolvers:\n          - \"1.1.1.1:53\"\n          - \"1.0.0.1:53\"\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>4. Create Traefik Dynamic Configuration (<code>config.yml<\/code>)<\/strong><\/h1>\n\n\n\n<p>Here you define:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Dashboard router<\/li>\n\n\n\n<li>Authentication middleware<\/li>\n\n\n\n<li>Security headers<\/li>\n<\/ul>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>http:\n  routers:\n    traefik-secure:\n      rule: \"Host(`traefik.yourdomain.com`)\"\n      entryPoints:\n        - https\n      service: api@internal\n      tls:\n        certResolver: cloudflare\n      middlewares:\n        - default-headers\n        - auth\n\n  middlewares:\n    auth:\n      basicAuth:\n        users:\n          - \"USER:HASHED_PASSWORD_HERE\"\n\n    default-headers:\n      headers:\n        frameDeny: true\n        contentTypeNosniff: true\n        browserXssFilter: true\n        forceSTSHeader: true\n        stsIncludeSubdomains: true\n        stsPreload: true\n        stsSeconds: 31536000\n<\/code><\/pre>\n\n\n\n<p>(Replace with your domain and hash.)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>5. Create the Docker Network<\/strong><\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>docker network create proxy\n<\/code><\/pre>\n\n\n\n<p>This network allows Traefik to communicate with your other containers.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>6. Generate a Basic Auth Password<\/strong><\/h1>\n\n\n\n<p>Install the htpasswd tool:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dnf install -y httpd-tools\n<\/code><\/pre>\n\n\n\n<p>Generate password hash:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>htpasswd -nb USER YOURPASSWORD | sed -e s\/\\\\$\/\\\\$\\\\$\/g\n<\/code><\/pre>\n\n\n\n<p>Paste the generated hash into <code>config.yml<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>7. Create <code>docker-compose.yml<\/code> for Traefik<\/strong><\/h1>\n\n\n\n<p>This file launches the Traefik container with access to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ports 80\/443<\/li>\n\n\n\n<li>Cloudflare DNS token<\/li>\n\n\n\n<li>Mounted config files<\/li>\n\n\n\n<li>Docker socket<\/li>\n\n\n\n<li>Routers and middleware definitions<\/li>\n<\/ul>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>services:\n  traefik:\n    image: traefik:latest\n    container_name: traefik\n    restart: unless-stopped\n\n    command:\n      - \"--configFile=\/traefik.yml\"\n\n    networks:\n      - proxy\n\n    ports:\n      - \"80:80\"\n      - \"443:443\"\n\n    environment:\n      - CF_DNS_API_TOKEN=YOUR_CLOUDFLARE_API_TOKEN\n\n    volumes:\n      - \/etc\/localtime:\/etc\/localtime:ro\n      - \/var\/run\/docker.sock:\/var\/run\/docker.sock:ro\n      - \/root\/traefik\/data\/traefik.yml:\/traefik.yml:ro\n      - \/root\/traefik\/data\/acme.json:\/acme.json\n      - \/root\/traefik\/data\/config.yml:\/config.yml:ro\n\n    labels:\n      - \"traefik.enable=true\"\n      - \"traefik.http.routers.traefik.entrypoints=http\"\n      - \"traefik.http.routers.traefik.rule=Host(`traefik.yourdomain.com`)\"\n      - \"traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https\"\n      - \"traefik.http.routers.traefik.middlewares=redirect-to-https\"\n      - \"traefik.http.routers.traefik-secure.entrypoints=https\"\n      - \"traefik.http.routers.traefik-secure.rule=Host(`traefik.yourdomain.com`)\"\n      - \"traefik.http.routers.traefik-secure.tls=true\"\n      - \"traefik.http.routers.traefik-secure.tls.certresolver=cloudflare\"\n      - \"traefik.http.routers.traefik-secure.service=api@internal\"\n\nnetworks:\n  proxy:\n    external: true\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>8. Start Traefik<\/strong><\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>cd \/root\/traefik\ndocker compose up -d\n<\/code><\/pre>\n\n\n\n<p>Traefik will:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Start reverse proxy engine<\/li>\n\n\n\n<li>Load static &amp; dynamic configs<\/li>\n\n\n\n<li>Connect to Docker<\/li>\n\n\n\n<li>Request HTTPS certificates automatically from Let&#8217;s Encrypt via Cloudflare<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>9. Create DNS Records in Cloudflare<\/strong><\/h1>\n\n\n\n<p>Add an <strong>A record<\/strong>:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Type<\/th><th>Name<\/th><th>Value<\/th><th>Proxy<\/th><\/tr><\/thead><tbody><tr><td>A<\/td><td>traefik<\/td><td>YOUR_SERVER_IP<\/td><td>DNS Only (Gray Cloud)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>| A | service | YOUR_SERVER_IP | DNS Only |<\/p>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>10. Access the Traefik Dashboard<\/strong><\/h1>\n\n\n\n<p>Visit:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;traefik.yourdomain.com\n<\/code><\/pre>\n\n\n\n<p>You will see:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Valid Let\u2019s Encrypt SSL certificate<\/li>\n\n\n\n<li>Basic authentication prompt<\/li>\n\n\n\n<li>Traefik dashboard<\/li>\n<\/ul>\n\n\n\n<p>Traefik is now fully operational as a secure reverse proxy.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\ud83c\udf89 <strong>Conclusion<\/strong><\/h1>\n\n\n\n<p>You have successfully:<\/p>\n\n\n\n<p>\u2714 Deployed Traefik v3 on AlmaLinux<br>\u2714 Configured Docker networking<br>\u2714 Enabled Cloudflare DNS-01 challenge<br>\u2714 Installed full HTTPS with automatic certificate renewal<br>\u2714 Added Basic Auth protection<br>\u2714 Prepared the system for additional apps (Portainer, Proxmox, n8n, etc.)<\/p>\n\n\n\n<p>This is a <strong>production-grade, secure Traefik reverse proxy stack<\/strong> ready for your entire infrastructure.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n","protected":false},"excerpt":{"rendered":"<p>Deploying Traefik v3 Reverse Proxy With Cloudflare DNS &amp; Docker on AlmaLinux 10 A Complete Step-by-Step&#8230;<\/p>\n","protected":false},"author":1,"featured_media":3262,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_kad_blocks_custom_css":"","_kad_blocks_head_custom_js":"","_kad_blocks_body_custom_js":"","_kad_blocks_footer_custom_js":"","_kadence_starter_templates_imported_post":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"categories":[24,28,18],"tags":[],"class_list":["post-3259","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai","category-docker","category-linux-server"],"taxonomy_info":{"category":[{"value":24,"label":"AI"},{"value":28,"label":"Docker"},{"value":18,"label":"linux server"}]},"featured_image_src_large":["https:\/\/muhammadsoliman.com\/wp-content\/uploads\/2026\/02\/webui-dashboard-1024x849.png",1024,849,true],"author_info":{"display_name":"Muhammad Soliman","author_link":"https:\/\/muhammadsoliman.com\/author\/muhmmad-soliman\/"},"comment_info":0,"category_info":[{"term_id":24,"name":"AI","slug":"ai","term_group":0,"term_taxonomy_id":24,"taxonomy":"category","description":"","parent":0,"count":2,"filter":"raw","cat_ID":24,"category_count":2,"category_description":"","cat_name":"AI","category_nicename":"ai","category_parent":0},{"term_id":28,"name":"Docker","slug":"docker","term_group":0,"term_taxonomy_id":28,"taxonomy":"category","description":"","parent":0,"count":1,"filter":"raw","cat_ID":28,"category_count":1,"category_description":"","cat_name":"Docker","category_nicename":"docker","category_parent":0},{"term_id":18,"name":"linux server","slug":"linux-server","term_group":0,"term_taxonomy_id":18,"taxonomy":"category","description":"","parent":0,"count":2,"filter":"raw","cat_ID":18,"category_count":2,"category_description":"","cat_name":"linux server","category_nicename":"linux-server","category_parent":0}],"tag_info":false,"_links":{"self":[{"href":"https:\/\/muhammadsoliman.com\/index.php\/wp-json\/wp\/v2\/posts\/3259","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/muhammadsoliman.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/muhammadsoliman.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/muhammadsoliman.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/muhammadsoliman.com\/index.php\/wp-json\/wp\/v2\/comments?post=3259"}],"version-history":[{"count":0,"href":"https:\/\/muhammadsoliman.com\/index.php\/wp-json\/wp\/v2\/posts\/3259\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/muhammadsoliman.com\/index.php\/wp-json\/wp\/v2\/media\/3262"}],"wp:attachment":[{"href":"https:\/\/muhammadsoliman.com\/index.php\/wp-json\/wp\/v2\/media?parent=3259"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/muhammadsoliman.com\/index.php\/wp-json\/wp\/v2\/categories?post=3259"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/muhammadsoliman.com\/index.php\/wp-json\/wp\/v2\/tags?post=3259"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}