[{"data":1,"prerenderedAt":1675},["ShallowReactive",2],{"navigation":3,"/docs/deployment-and-production/configuring-ssl":229,"/docs/deployment-and-production/configuring-ssl-surround":1670},[4],{"title":5,"path":6,"stem":7,"children":8},"Docs","/docs","docs",[9,12,56,85,132,153,186,203,216],{"title":10,"path":6,"stem":11},"","docs/index",{"title":13,"path":14,"stem":15,"children":16,"icon":55},"Getting Started","/docs/getting-started","docs/1.getting-started/1.index",[17,19,23,27,31,35,39,43,47,51],{"title":18,"path":14,"stem":15},"Introduction",{"title":20,"path":21,"stem":22},"Container Basics","/docs/getting-started/container-basics","docs/1.getting-started/2.container-basics",{"title":24,"path":25,"stem":26},"Installation","/docs/getting-started/installation","docs/1.getting-started/3.installation",{"title":28,"path":29,"stem":30},"These Images vs Others","/docs/getting-started/these-images-vs-others","docs/1.getting-started/4.these-images-vs-others",{"title":32,"path":33,"stem":34},"Choosing an Image","/docs/getting-started/choosing-an-image","docs/1.getting-started/5.choosing-an-image",{"title":36,"path":37,"stem":38},"Default Configurations","/docs/getting-started/default-configurations","docs/1.getting-started/6.default-configurations",{"title":40,"path":41,"stem":42},"Upgrade Guide","/docs/getting-started/upgrade-guide","docs/1.getting-started/7.upgrade-guide",{"title":44,"path":45,"stem":46},"Changelog","/docs/getting-started/changelog","docs/1.getting-started/8.changelog",{"title":48,"path":49,"stem":50},"About","/docs/getting-started/about","docs/1.getting-started/9.about",{"title":52,"path":53,"stem":54},"Contributing","/docs/getting-started/contributing","docs/1.getting-started/99.contributing",false,{"title":57,"path":58,"stem":59,"children":60,"page":55},"Image Variations","/docs/image-variations","docs/2.image-variations",[61,65,69,73,77,81],{"title":62,"path":63,"stem":64},"CLI","/docs/image-variations/cli","docs/2.image-variations/cli",{"title":66,"path":67,"stem":68},"FPM","/docs/image-variations/fpm","docs/2.image-variations/fpm",{"title":70,"path":71,"stem":72},"FPM-Apache","/docs/image-variations/fpm-apache","docs/2.image-variations/fpm-apache",{"title":74,"path":75,"stem":76},"FPM-NGINX","/docs/image-variations/fpm-nginx","docs/2.image-variations/fpm-nginx",{"title":78,"path":79,"stem":80},"FrankenPHP","/docs/image-variations/frankenphp","docs/2.image-variations/frankenphp",{"title":82,"path":83,"stem":84},"Unit (Deprecated)","/docs/image-variations/unit","docs/2.image-variations/unit",{"title":86,"path":87,"stem":88,"children":89,"page":55},"Framework Guides","/docs/framework-guides","docs/3.framework-guides",[90,123],{"title":91,"icon":55,"defaultOpen":55,"path":92,"stem":93,"children":94,"page":55},"Laravel","/docs/framework-guides/laravel","docs/3.framework-guides/1.laravel",[95,99,103,107,111,115,119],{"title":96,"path":97,"stem":98},"Automations","/docs/framework-guides/laravel/automations","docs/3.framework-guides/1.laravel/1.automations",{"title":100,"path":101,"stem":102},"Task Scheduler","/docs/framework-guides/laravel/task-scheduler","docs/3.framework-guides/1.laravel/2.task-scheduler",{"title":104,"path":105,"stem":106},"Queue","/docs/framework-guides/laravel/queue","docs/3.framework-guides/1.laravel/3.queue",{"title":108,"path":109,"stem":110},"Horizon","/docs/framework-guides/laravel/horizon","docs/3.framework-guides/1.laravel/4.horizon",{"title":112,"path":113,"stem":114},"Reverb","/docs/framework-guides/laravel/reverb","docs/3.framework-guides/1.laravel/4.reverb",{"title":116,"path":117,"stem":118},"Nightwatch","/docs/framework-guides/laravel/nightwatch","docs/3.framework-guides/1.laravel/5.nightwatch",{"title":120,"path":121,"stem":122},"Octane","/docs/framework-guides/laravel/octane","docs/3.framework-guides/1.laravel/octane",{"title":124,"icon":55,"defaultOpen":55,"path":125,"stem":126,"children":127,"page":55},"WordPress","/docs/framework-guides/wordpress","docs/3.framework-guides/2.wordpress",[128],{"title":129,"path":130,"stem":131},"Using Docker with WordPress","/docs/framework-guides/wordpress/using-wordpress-with-docker","docs/3.framework-guides/2.wordpress/4.using-wordpress-with-docker",{"title":133,"path":134,"stem":135,"children":136,"page":55},"Deployment And Production","/docs/deployment-and-production","docs/4.deployment-and-production",[137,141,145,149],{"title":138,"path":139,"stem":140},"Development to Production","/docs/deployment-and-production/development-to-production","docs/4.deployment-and-production/2.development-to-production",{"title":142,"path":143,"stem":144},"Packaging Your App for Deployment","/docs/deployment-and-production/packaging-your-app-for-deployment","docs/4.deployment-and-production/3.packaging-your-app-for-deployment",{"title":146,"path":147,"stem":148},"Configuring SSL","/docs/deployment-and-production/configuring-ssl","docs/4.deployment-and-production/4.configuring-ssl",{"title":150,"path":151,"stem":152},"Choosing a Host","/docs/deployment-and-production/choosing-a-host","docs/4.deployment-and-production/5.choosing-a-host",{"title":154,"icon":55,"defaultOpen":55,"path":155,"stem":156,"children":157,"page":55},"Advanced Guides","/docs/guide","docs/5.guide",[158,162,166,170,174,178,182],{"title":159,"path":160,"stem":161},"Migrating from official PHP images","/docs/guide/migrating-from-official-php-images","docs/5.guide/1.migrating-from-official-php-images",{"title":163,"path":164,"stem":165},"Using Healthchecks With Laravel","/docs/guide/using-healthchecks-with-laravel","docs/5.guide/2.using-healthchecks-with-laravel",{"title":167,"path":168,"stem":169},"Using S6 Overlay","/docs/guide/using-s6-overlay","docs/5.guide/2.using-s6-overlay",{"title":171,"path":172,"stem":173},"Understanding File Permissions","/docs/guide/understanding-file-permissions","docs/5.guide/3.understanding-file-permissions",{"title":175,"path":176,"stem":177},"Configuring Trusted Proxies","/docs/guide/configuring-trusted-proxies","docs/5.guide/4.configuring-trusted-proxies",{"title":179,"path":180,"stem":181},"Major version migrations","/docs/guide/major-version-migrations","docs/5.guide/5.major-version-migrations",{"title":183,"path":184,"stem":185},"Production performance tuning","/docs/guide/production-performance-tuning","docs/5.guide/6.production-performance-tuning",{"title":187,"icon":55,"defaultOpen":55,"path":188,"stem":189,"children":190,"page":55},"Customization","/docs/customizing-the-image","docs/6.customizing-the-image",[191,195,199],{"title":192,"path":193,"stem":194},"Changing php.ini settings","/docs/customizing-the-image/changing-common-php-settings","docs/6.customizing-the-image/1.changing-common-php-settings",{"title":196,"path":197,"stem":198},"Installing PHP extensions","/docs/customizing-the-image/installing-additional-php-extensions","docs/6.customizing-the-image/2.installing-additional-php-extensions",{"title":200,"path":201,"stem":202},"Adding Start Up Scripts","/docs/customizing-the-image/adding-your-own-start-up-scripts","docs/6.customizing-the-image/3.adding-your-own-start-up-scripts",{"title":204,"path":205,"stem":206,"children":207,"page":55},"Troubleshooting","/docs/troubleshooting","docs/7.troubleshooting",[208,212],{"title":209,"path":210,"stem":211},"Common Issues","/docs/troubleshooting/common-issues","docs/7.troubleshooting/1.common-issues",{"title":213,"path":214,"stem":215},"Getting Help","/docs/troubleshooting/getting-help","docs/7.troubleshooting/2.getting-help",{"title":217,"path":218,"stem":219,"children":220,"page":55},"Reference","/docs/reference","docs/8.reference",[221,225],{"title":222,"path":223,"stem":224},"Environment Variable Specification","/docs/reference/environment-variable-specification","docs/8.reference/1.environment-variable-specification",{"title":226,"path":227,"stem":228},"Command Reference","/docs/reference/command-reference","docs/8.reference/2.command-reference",{"id":230,"title":146,"body":231,"description":1663,"extension":583,"links":1664,"meta":1665,"navigation":1004,"path":147,"redirect":1664,"seo":1668,"stem":148,"__hash__":1669},"docs/docs/4.deployment-and-production/4.configuring-ssl.md",{"type":232,"value":233,"toc":1653},"minimark",[234,241,246,249,338,342,349,394,398,401,483,488,494,518,521,531,534,547,552,561,570,586,590,596,599,610,614,617,719,723,726,766,785,789,792,825,841,845,848,1066,1070,1078,1083,1087,1108,1114,1151,1167,1185,1236,1240,1254,1257,1266,1501,1505,1516,1521,1525,1530,1548,1626,1629,1633,1641,1649],[235,236,237],"lead-p",{},[238,239,240],"p",{},"SSL encryption is natively supported in our images. With FrankenPHP, a trusted certificate can automatically be generated by Let's Encrypt. You can also bring your own certificates or have a self-signed certificate generated for you.",[242,243,245],"h2",{"id":244},"supported-variations","Supported Variations",[238,247,248],{},"SSL is natively supported in the following variations:",[250,251,252,268],"table",{},[253,254,255],"thead",{},[256,257,258,262,265],"tr",{},[259,260,261],"th",{},"Variation",[259,263,264],{},"SSL Support",[259,266,267],{},"Automated, Signed Certificate Support (via Let's Encrypt)",[269,270,271,286,297,314,327],"tbody",{},[256,272,273,280,283],{},[274,275,276],"td",{},[277,278,279],"code",{},"cli",[274,281,282],{},"❌ No",[274,284,285],{},"-",[256,287,288,293,295],{},[274,289,290],{},[277,291,292],{},"fpm",[274,294,282],{},[274,296,285],{},[256,298,299,304,307],{},[274,300,301],{},[277,302,303],{},"fpm-nginx",[274,305,306],{},"✅ Yes",[274,308,309,310,313],{},"❌ No ",[311,312],"br",{},"(requires a reverse proxy in front of the container)",[256,315,316,321,323],{},[274,317,318],{},[277,319,320],{},"fpm-apache",[274,322,306],{},[274,324,309,325,313],{},[311,326],{},[256,328,329,334,336],{},[274,330,331],{},[277,332,333],{},"frankenphp",[274,335,306],{},[274,337,306],{},[242,339,341],{"id":340},"ssl-modes","SSL Modes",[238,343,344,345,348],{},"You can control SSL behavior with the ",[277,346,347],{},"SSL_MODE"," environment variable:",[250,350,351,361],{},[253,352,353],{},[256,354,355,358],{},[259,356,357],{},"SSL Mode",[259,359,360],{},"Description",[269,362,363,374,384],{},[256,364,365,371],{},[274,366,367,370],{},[277,368,369],{},"off"," (default)",[274,372,373],{},"HTTP only.",[256,375,376,381],{},[274,377,378],{},[277,379,380],{},"mixed",[274,382,383],{},"HTTP and HTTPS.",[256,385,386,391],{},[274,387,388],{},[277,389,390],{},"full",[274,392,393],{},"HTTPS only. HTTP requests will be redirected to HTTPS.",[242,395,397],{"id":396},"choose-how-to-run-ssl-in-production","Choose How to Run SSL in Production",[238,399,400],{},"You have a few options for running SSL in production:",[250,402,403,422],{},[253,404,405],{},[256,406,407,410,413,416,419],{},[259,408,409],{},"Approach",[259,411,412],{},"Certificate Type",[259,414,415],{},"Management Type",[259,417,418],{},"Zero-Downtime Deployments",[259,420,421],{},"Minimal Number of Containers",[269,423,424,440,454,469],{},[256,425,426,429,432,435,437],{},[274,427,428],{},"Reverse Proxy (like Traefik or Caddy)",[274,430,431],{},"✅ Trusted Certificate (via Let's Encrypt)",[274,433,434],{},"✅ Automatic",[274,436,306],{},[274,438,439],{},"⚠️ 2",[256,441,442,445,447,449,451],{},[274,443,444],{},"FrankenPHP's built-in automatic HTTPS",[274,446,431],{},[274,448,434],{},[274,450,282],{},[274,452,453],{},"✅ 1",[256,455,456,459,462,465,467],{},[274,457,458],{},"Bring Your Own Certificate",[274,460,461],{},"✅ Trusted Certificate (through any vendor)",[274,463,464],{},"❌ Manual",[274,466,282],{},[274,468,453],{},[256,470,471,474,477,479,481],{},[274,472,473],{},"Self-signed",[274,475,476],{},"❌ Self-signed Certificate",[274,478,434],{},[274,480,282],{},[274,482,453],{},[484,485,487],"h3",{"id":486},"reverse-proxy-recommended","Reverse Proxy (recommended)",[489,490,491],"tip",{},[238,492,493],{},"Reverse proxies don't just terminate SSL—they also give you zero-downtime with rolling updates.",[238,495,496,502,503,511,512,517],{},[497,498],"img",{":zoom":499,"alt":500,"src":501},"false","Reverse Proxy","images/docs/reverse-proxy-ssl-zerodowntime.png","\nOur recommended approach is to use a reverse proxy like ",[504,505,510],"a",{"href":506,"rel":507,"target":509},"https://traefik.io/traefik/",[508],"nofollow","_blank","Traefik"," or ",[504,513,516],{"href":514,"rel":515,"target":509},"https://caddyserver.com/",[508],"Caddy"," that listens on ports 80 (HTTP) and 443 (HTTPS). The reverse proxy will forward traffic to your container on the non-privileged ports of 8080 (HTTP) or 8443 (HTTPS).",[238,519,520],{},"Using a reverse proxy unlocks two major benefits:",[522,523,524,528],"ol",{},[525,526,527],"li",{},"Automatic SSL certificate management (via Let's Encrypt)",[525,529,530],{},"Zero-downtime deployments",[238,532,533],{},"When you're running updates on containers, the reverse proxy stays online while updates are deployed to your containers in the background. Configuring a reverse proxy is outside the scope of this documentation, but you can reference the links below to learn more:",[535,536,537,542],"ul",{},[525,538,539],{},[504,540,510],{"href":506,"rel":541,"target":509},[508],[525,543,544],{},[504,545,516],{"href":514,"rel":546,"target":509},[508],[548,549,551],"h4",{"id":550},"use-a-reverse-proxy-when-you-want","Use a Reverse Proxy When You Want...",[535,553,554,556,558],{},[525,555,530],{},[525,557,527],{},[525,559,560],{},"Load balancing",[238,562,563,564,569],{},"If you want a simple way to run your own reverse proxy with zero-downtime deployments, consider using ",[504,565,568],{"href":566,"rel":567,"target":509},"https://serversideup.net/open-source/spin/",[508],"Spin",".",[571,572],"u-button",{"ariaLabel":573,"className":574,"color":582,"label":573,"size":583,"target":509,"to":566,"trailing-icon":584,"variant":585},"Learn more about Spin",[575,576,577,578,579,580,581],"font-bold","ring","ring-inset","ring-blue-600","text-blue-600","hover:ring-blue-500","hover:text-blue-500","primary","md","i-lucide-arrow-right","outline",[484,587,589],{"id":588},"frankenphps-built-in-automatic-https","FrankenPHP's Built-in Automatic HTTPS",[591,592,593],"warning",{},[238,594,595],{},"Zero-downtime deployments are not possible with FrankenPHP's built-in automatic HTTPS.",[238,597,598],{},"FrankenPHP provides automated HTTPS through Caddy. To directly expose FrankenPHP to the internet, you'll need to configure the following:",[522,600,601,604,607],{},[525,602,603],{},"Environment variables (for Caddy configuration)",[525,605,606],{},"Ports (for direct exposure of ports 80 and 443)",[525,608,609],{},"Volumes (for certificate files)",[548,611,613],{"id":612},"environment-variables","Environment Variables",[238,615,616],{},"Configure the following environment variables:",[250,618,619,631],{},[253,620,621],{},[256,622,623,626,629],{},[259,624,625],{},"Variable",[259,627,628],{},"Expected Value",[259,630,360],{},[269,632,633,663,700],{},[256,634,635,647,652],{},[274,636,637,640,641,643],{},[277,638,639],{},"CADDY_AUTO_HTTPS"," ",[311,642],{},[644,645,646],"em",{},"Default: \"off\"",[274,648,649],{},[277,650,651],{},"on",[274,653,654,655,662],{},"Turn on Caddy's ",[504,656,659],{"href":657,"rel":658,"target":509},"https://caddyserver.com/docs/caddyfile/options#auto-https",[508],[277,660,661],{},"auto_https"," global directive.",[256,664,665,675,683],{},[274,666,667,640,670,672],{},[277,668,669],{},"CADDY_HTTPS_SERVER_ADDRESS",[311,671],{},[644,673,674],{},"Default: \"https://\"",[274,676,677,511,680],{},[277,678,679],{},"example.com",[277,681,682],{},"https://example.com",[274,684,685,686,691,692,695,696,699],{},"Set the ",[504,687,690],{"href":688,"rel":689,"target":509},"https://caddyserver.com/docs/caddyfile/concepts#addresses",[508],"server address"," for HTTPS. Pro tip: You can use ",[277,693,694],{},"$APP_URL"," from your ",[277,697,698],{},".env"," file to set this value.",[256,701,702,710,716],{},[274,703,704,640,706,708],{},[277,705,347],{},[311,707],{},[644,709,646],{},[274,711,712,511,714],{},[277,713,390],{},[277,715,380],{},[274,717,718],{},"Configure how Caddy handles HTTP and HTTPS requests.",[548,720,722],{"id":721},"ports","Ports",[238,724,725],{},"Configure the following ports:",[250,727,728,737],{},[253,729,730],{},[256,731,732,735],{},[259,733,734],{},"Ports to Publish",[259,736,360],{},[269,738,739,753],{},[256,740,741,750],{},[274,742,743,746,747],{},[277,744,745],{},"80"," → ",[277,748,749],{},"8080",[274,751,752],{},"HTTP traffic will be proxied to the container on port 8080.",[256,754,755,763],{},[274,756,757,746,760],{},[277,758,759],{},"443",[277,761,762],{},"8443",[274,764,765],{},"HTTPS traffic will be proxied to the container on port 8443.",[767,768,769],"note",{},[238,770,771,772,775,776,779,780,784],{},"Our port mapping remains ",[277,773,774],{},"80:8080"," and ",[277,777,778],{},"443:8443"," because our containers are ",[781,782,783],"strong",{},"unprivileged"," by default, meaning we cannot bind to ports less than 1024 (without additional modification).",[548,786,788],{"id":787},"volumes","Volumes",[238,790,791],{},"Configure the following volumes:",[250,793,794,803],{},[253,795,796],{},[256,797,798,801],{},[259,799,800],{},"Container Directory to Mount",[259,802,360],{},[269,804,805,815],{},[256,806,807,812],{},[274,808,809],{},[277,810,811],{},"/config",[274,813,814],{},"Directory for Caddy's configuration files (such as Caddyfile or JSON) that must persist for settings to be retained.",[256,816,817,822],{},[274,818,819],{},[277,820,821],{},"/data",[274,823,824],{},"Directory where Caddy stores SSL/TLS certificates and CA information, required for automatic HTTPS to consistently function.",[767,826,827],{},[238,828,829,830,775,833,836,837,840],{},"The ",[277,831,832],{},"config",[277,834,835],{},"data"," volumes must have read/write permissions for the ",[277,838,839],{},"www-data"," user. Caddy will store its configuration and certificates in these volumes (and you want those to persist).",[548,842,844],{"id":843},"example","Example",[238,846,847],{},"Here's an example of directly exposing FrankenPHP to the internet with automatic HTTPS via Let's Encrypt:",[849,850,852,1030],"code-tree",{"default-value":851},"compose.yml",[853,854,858],"pre",{"className":855,"code":856,"filename":851,"language":857,"meta":10,"style":10},"language-yml shiki shiki-themes github-dark","services:\n  php:\n    image: serversideup/php:8.5-frankenphp\n    ports:\n      - 80:8080\n      - 443:8443\n    environment:\n      CADDY_AUTO_HTTPS: \"on\"\n      CADDY_HTTPS_SERVER_ADDRESS: \"https://example.com\"\n      SSL_MODE: \"full\"\n    # Mount the current directory to /var/www/html\n    volumes:\n      - .:/var/www/html\n      - config:/config\n      - data:/data\n\n  volumes:\n    config:\n    data:\n","yml",[277,859,860,873,881,894,902,911,919,927,938,949,960,967,975,983,991,999,1006,1014,1022],{"__ignoreMap":10},[861,862,865,869],"span",{"class":863,"line":864},"line",1,[861,866,868],{"class":867},"s4JwU","services",[861,870,872],{"class":871},"s95oV",":\n",[861,874,876,879],{"class":863,"line":875},2,[861,877,878],{"class":867},"  php",[861,880,872],{"class":871},[861,882,884,887,890],{"class":863,"line":883},3,[861,885,886],{"class":867},"    image",[861,888,889],{"class":871},": ",[861,891,893],{"class":892},"sU2Wk","serversideup/php:8.5-frankenphp\n",[861,895,897,900],{"class":863,"line":896},4,[861,898,899],{"class":867},"    ports",[861,901,872],{"class":871},[861,903,905,908],{"class":863,"line":904},5,[861,906,907],{"class":871},"      - ",[861,909,910],{"class":892},"80:8080\n",[861,912,914,916],{"class":863,"line":913},6,[861,915,907],{"class":871},[861,917,918],{"class":892},"443:8443\n",[861,920,922,925],{"class":863,"line":921},7,[861,923,924],{"class":867},"    environment",[861,926,872],{"class":871},[861,928,930,933,935],{"class":863,"line":929},8,[861,931,932],{"class":867},"      CADDY_AUTO_HTTPS",[861,934,889],{"class":871},[861,936,937],{"class":892},"\"on\"\n",[861,939,941,944,946],{"class":863,"line":940},9,[861,942,943],{"class":867},"      CADDY_HTTPS_SERVER_ADDRESS",[861,945,889],{"class":871},[861,947,948],{"class":892},"\"https://example.com\"\n",[861,950,952,955,957],{"class":863,"line":951},10,[861,953,954],{"class":867},"      SSL_MODE",[861,956,889],{"class":871},[861,958,959],{"class":892},"\"full\"\n",[861,961,963],{"class":863,"line":962},11,[861,964,966],{"class":965},"sAwPA","    # Mount the current directory to /var/www/html\n",[861,968,970,973],{"class":863,"line":969},12,[861,971,972],{"class":867},"    volumes",[861,974,872],{"class":871},[861,976,978,980],{"class":863,"line":977},13,[861,979,907],{"class":871},[861,981,982],{"class":892},".:/var/www/html\n",[861,984,986,988],{"class":863,"line":985},14,[861,987,907],{"class":871},[861,989,990],{"class":892},"config:/config\n",[861,992,994,996],{"class":863,"line":993},15,[861,995,907],{"class":871},[861,997,998],{"class":892},"data:/data\n",[861,1000,1002],{"class":863,"line":1001},16,[861,1003,1005],{"emptyLinePlaceholder":1004},true,"\n",[861,1007,1009,1012],{"class":863,"line":1008},17,[861,1010,1011],{"class":867},"  volumes",[861,1013,872],{"class":871},[861,1015,1017,1020],{"class":863,"line":1016},18,[861,1018,1019],{"class":867},"    config",[861,1021,872],{"class":871},[861,1023,1025,1028],{"class":863,"line":1024},19,[861,1026,1027],{"class":867},"    data",[861,1029,872],{"class":871},[853,1031,1036],{"className":1032,"code":1033,"filename":1034,"language":1035,"meta":10,"style":10},"language-php shiki shiki-themes github-dark","\u003C?php\n// Let's just print out some PHP info\nphpinfo();\n?>\n","public/index.php","php",[277,1037,1038,1048,1053,1061],{"__ignoreMap":10},[861,1039,1040,1044],{"class":863,"line":864},[861,1041,1043],{"class":1042},"snl16","\u003C?",[861,1045,1047],{"class":1046},"sDLfK","php\n",[861,1049,1050],{"class":863,"line":875},[861,1051,1052],{"class":965},"// Let's just print out some PHP info\n",[861,1054,1055,1058],{"class":863,"line":883},[861,1056,1057],{"class":1046},"phpinfo",[861,1059,1060],{"class":871},"();\n",[861,1062,1063],{"class":863,"line":896},[861,1064,1065],{"class":1042},"?>\n",[548,1067,1069],{"id":1068},"use-frankenphps-built-in-automatic-https-when-you-want","Use FrankenPHP's Built-in Automatic HTTPS When You Want...",[535,1071,1072,1075],{},[525,1073,1074],{},"To run your application and handle SSL termination all in one container",[525,1076,1077],{},"A simple setup without needing zero-downtime deployments",[767,1079,1080],{},[238,1081,1082],{},"You can achieve zero-downtime deployments with FrankenPHP by placing a reverse proxy in front of the container.",[548,1084,1086],{"id":1085},"short-lived-ip-address-certificates","Short-lived & IP-address certificates",[238,1088,1089,1090,1098,1099,1102,1103,569],{},"Let's Encrypt offers a ",[504,1091,1094,1097],{"href":1092,"rel":1093,"target":509},"https://letsencrypt.org/docs/profiles/",[508],[277,1095,1096],{},"shortlived"," certificate profile"," that issues ~6-day certificates. Because they expire so quickly, they don't rely on revocation (OCSP/CRL). This same profile is also ",[781,1100,1101],{},"required"," for ",[504,1104,1107],{"href":1105,"rel":1106,"target":509},"https://letsencrypt.org/2026/01/15/6day-and-ip-general-availability",[508],"IP-address certificates",[238,1109,1110,1111,348],{},"Enable it with the ",[277,1112,1113],{},"CADDY_ACME_PROFILE",[250,1115,1116,1126],{},[253,1117,1118],{},[256,1119,1120,1122,1124],{},[259,1121,625],{},[259,1123,628],{},[259,1125,360],{},[269,1127,1128],{},[256,1129,1130,1138,1142],{},[274,1131,1132,640,1134,1136],{},[277,1133,1113],{},[311,1135],{},[644,1137,646],{},[274,1139,1140],{},[277,1141,1096],{},[274,1143,1144,1145,775,1148,569],{},"Select a Let's Encrypt certificate profile. Also accepts ",[277,1146,1147],{},"tlsserver",[277,1149,1150],{},"classic",[591,1152,1153],{},[238,1154,1155,1156,1159,1160,1163,1164,1166],{},"Enabling a profile configures Caddy's ",[277,1157,1158],{},"cert_issuer",", which pins issuance to ",[781,1161,1162],{},"Let's Encrypt only"," (the default ZeroSSL fallback is dropped). Short-lived certificates also renew roughly every 2 days, so the container needs reliable egress to the ACME CA. Leave it ",[277,1165,369],{}," unless you specifically want this behavior.",[238,1168,1169,1172,1173,1180,1181,1184],{},[781,1170,1171],{},"Raw-IP / SNI-less access:"," clients connecting by IP address send no SNI, so Caddy needs a ",[504,1174,1177],{"href":1175,"rel":1176,"target":509},"https://caddyserver.com/docs/caddyfile/options#default-sni",[508],[277,1178,1179],{},"default_sni"," to know which certificate to serve. There's no dedicated variable for this because the value is your own domain/IP — set it through ",[277,1182,1183],{},"CADDY_GLOBAL_OPTIONS",":",[853,1186,1188],{"className":855,"code":1187,"language":857,"meta":10,"style":10},"environment:\n  CADDY_AUTO_HTTPS: \"on\"\n  CADDY_ACME_PROFILE: \"shortlived\"\n  # Fallback identity for connections that send no SNI (e.g. by IP).\n  # Reference your own variable if you like: \"default_sni {$APP_DOMAIN}\"\n  CADDY_GLOBAL_OPTIONS: \"default_sni example.com\"\n",[277,1189,1190,1197,1206,1216,1221,1226],{"__ignoreMap":10},[861,1191,1192,1195],{"class":863,"line":864},[861,1193,1194],{"class":867},"environment",[861,1196,872],{"class":871},[861,1198,1199,1202,1204],{"class":863,"line":875},[861,1200,1201],{"class":867},"  CADDY_AUTO_HTTPS",[861,1203,889],{"class":871},[861,1205,937],{"class":892},[861,1207,1208,1211,1213],{"class":863,"line":883},[861,1209,1210],{"class":867},"  CADDY_ACME_PROFILE",[861,1212,889],{"class":871},[861,1214,1215],{"class":892},"\"shortlived\"\n",[861,1217,1218],{"class":863,"line":896},[861,1219,1220],{"class":965},"  # Fallback identity for connections that send no SNI (e.g. by IP).\n",[861,1222,1223],{"class":863,"line":904},[861,1224,1225],{"class":965},"  # Reference your own variable if you like: \"default_sni {$APP_DOMAIN}\"\n",[861,1227,1228,1231,1233],{"class":863,"line":913},[861,1229,1230],{"class":867},"  CADDY_GLOBAL_OPTIONS",[861,1232,889],{"class":871},[861,1234,1235],{"class":892},"\"default_sni example.com\"\n",[484,1237,1239],{"id":1238},"bringing-your-own-certificate","Bringing Your Own Certificate",[238,1241,1242,1243,1248,1249,569],{},"If automatic HTTPS isn't an option, you can provide your own certificate from a vendor like ",[504,1244,1247],{"href":1245,"rel":1246,"target":509},"https://www.ssls.com/",[508],"ssls.com",". Ensure your certificate issuer provides certificates compatible with your web server in ",[504,1250,1253],{"href":1251,"rel":1252,"target":509},"https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail",[508],"PEM format",[238,1255,1256],{},"To add your own certificate, mount the certificate files to the container:",[489,1258,1259],{},[238,1260,1261,1262,1265],{},"Set your private key file permissions to ",[277,1263,1264],{},"600"," (read/write for owner only). Incorrect permissions will cause errors when loading the private key.",[849,1267,1268,1373,1397,1435],{"default-value":851},[853,1269,1272],{"className":855,"code":1270,"filename":851,"highlights":1271,"language":857,"meta":10,"style":10},"services:\n  php:\n    image: serversideup/php:8.5-fpm-nginx\n    ports:\n      - 80:8080\n      - 443:8443\n    environment:\n      SSL_MODE: \"mixed\"\n      SSL_PRIVATE_KEY_FILE: \"/etc/ssl/custom/test-key.pem\"\n      SSL_CERTIFICATE_FILE: \"/etc/ssl/custom/test.pem\"\n    volumes:\n      - .:/var/www/html/\n      - ./certs/:/etc/ssl/custom/\n",[929,940,951,977],[277,1273,1274,1280,1286,1295,1301,1307,1313,1319,1330,1341,1352,1358,1365],{"__ignoreMap":10},[861,1275,1276,1278],{"class":863,"line":864},[861,1277,868],{"class":867},[861,1279,872],{"class":871},[861,1281,1282,1284],{"class":863,"line":875},[861,1283,878],{"class":867},[861,1285,872],{"class":871},[861,1287,1288,1290,1292],{"class":863,"line":883},[861,1289,886],{"class":867},[861,1291,889],{"class":871},[861,1293,1294],{"class":892},"serversideup/php:8.5-fpm-nginx\n",[861,1296,1297,1299],{"class":863,"line":896},[861,1298,899],{"class":867},[861,1300,872],{"class":871},[861,1302,1303,1305],{"class":863,"line":904},[861,1304,907],{"class":871},[861,1306,910],{"class":892},[861,1308,1309,1311],{"class":863,"line":913},[861,1310,907],{"class":871},[861,1312,918],{"class":892},[861,1314,1315,1317],{"class":863,"line":921},[861,1316,924],{"class":867},[861,1318,872],{"class":871},[861,1320,1323,1325,1327],{"class":1321,"line":929},[863,1322],"highlight",[861,1324,954],{"class":867},[861,1326,889],{"class":871},[861,1328,1329],{"class":892},"\"mixed\"\n",[861,1331,1333,1336,1338],{"class":1332,"line":940},[863,1322],[861,1334,1335],{"class":867},"      SSL_PRIVATE_KEY_FILE",[861,1337,889],{"class":871},[861,1339,1340],{"class":892},"\"/etc/ssl/custom/test-key.pem\"\n",[861,1342,1344,1347,1349],{"class":1343,"line":951},[863,1322],[861,1345,1346],{"class":867},"      SSL_CERTIFICATE_FILE",[861,1348,889],{"class":871},[861,1350,1351],{"class":892},"\"/etc/ssl/custom/test.pem\"\n",[861,1353,1354,1356],{"class":863,"line":962},[861,1355,972],{"class":867},[861,1357,872],{"class":871},[861,1359,1360,1362],{"class":863,"line":969},[861,1361,907],{"class":871},[861,1363,1364],{"class":892},".:/var/www/html/\n",[861,1366,1368,1370],{"class":1367,"line":977},[863,1322],[861,1369,907],{"class":871},[861,1371,1372],{"class":892},"./certs/:/etc/ssl/custom/\n",[853,1374,1375],{"className":1032,"code":1033,"filename":1034,"language":1035,"meta":10,"style":10},[277,1376,1377,1383,1387,1393],{"__ignoreMap":10},[861,1378,1379,1381],{"class":863,"line":864},[861,1380,1043],{"class":1042},[861,1382,1047],{"class":1046},[861,1384,1385],{"class":863,"line":875},[861,1386,1052],{"class":965},[861,1388,1389,1391],{"class":863,"line":883},[861,1390,1057],{"class":1046},[861,1392,1060],{"class":871},[861,1394,1395],{"class":863,"line":896},[861,1396,1065],{"class":1042},[853,1398,1403],{"className":1399,"code":1400,"filename":1401,"language":1402,"meta":10,"style":10},"language-pem shiki shiki-themes github-dark","-----BEGIN PRIVATE KEY-----\nEXAMPLE_PRIVATE_KEY_DO_NOT_USE\nMIIEvQIBADANBgkqhkiG9w0BAQEFASCBKwggSjAgEAAoIBAQDExampleKeyData\nThisIsNotARealPrivateKeyAndShouldNotBeUsedInProduction123456789\nReplaceThisWithYourActualPrivateKeyFile\n-----END PRIVATE KEY-----\n","certs/test-key.pem","pem",[277,1404,1405,1410,1415,1420,1425,1430],{"__ignoreMap":10},[861,1406,1407],{"class":863,"line":864},[861,1408,1409],{},"-----BEGIN PRIVATE KEY-----\n",[861,1411,1412],{"class":863,"line":875},[861,1413,1414],{},"EXAMPLE_PRIVATE_KEY_DO_NOT_USE\n",[861,1416,1417],{"class":863,"line":883},[861,1418,1419],{},"MIIEvQIBADANBgkqhkiG9w0BAQEFASCBKwggSjAgEAAoIBAQDExampleKeyData\n",[861,1421,1422],{"class":863,"line":896},[861,1423,1424],{},"ThisIsNotARealPrivateKeyAndShouldNotBeUsedInProduction123456789\n",[861,1426,1427],{"class":863,"line":904},[861,1428,1429],{},"ReplaceThisWithYourActualPrivateKeyFile\n",[861,1431,1432],{"class":863,"line":913},[861,1433,1434],{},"-----END PRIVATE KEY-----\n",[853,1436,1439],{"className":1399,"code":1437,"filename":1438,"language":1402,"meta":10,"style":10},"-----BEGIN CERTIFICATE-----\nEXAMPLE_CERTIFICATE_DO_NOT_USE\nMIIEIDCCAwigAwIBAgIQCqH+3yBp80lQ9OVmbNmbRzANBgkqhkiG9w0BAQsFADBh\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nd3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\nQTAeFw0yMTA0MjkwMDAwMDBaFw0zMjA0MjgyMzU5NTlaMFsxCzAJBgNVBAYTAlVT\nMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\nb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEAumQB+ILtbVLaKTeQeGviJLbfBxMIRZACMpbs\nQFmylhSTSSpLc1bNPrRVWWVmv+Lt8i3HuLjPQF+3M2NzBWVYB7Gixgd13KZBquor\n2W4Sj5SfR2onVzULfBy6SrwxfSTnnykA1NAzGLbGSukNkY4fO7N4V3C1mLGvL8H\n-----END CERTIFICATE-----\n","certs/test.pem",[277,1440,1441,1446,1451,1456,1461,1466,1471,1476,1481,1486,1491,1496],{"__ignoreMap":10},[861,1442,1443],{"class":863,"line":864},[861,1444,1445],{},"-----BEGIN CERTIFICATE-----\n",[861,1447,1448],{"class":863,"line":875},[861,1449,1450],{},"EXAMPLE_CERTIFICATE_DO_NOT_USE\n",[861,1452,1453],{"class":863,"line":883},[861,1454,1455],{},"MIIEIDCCAwigAwIBAgIQCqH+3yBp80lQ9OVmbNmbRzANBgkqhkiG9w0BAQsFADBh\n",[861,1457,1458],{"class":863,"line":896},[861,1459,1460],{},"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n",[861,1462,1463],{"class":863,"line":904},[861,1464,1465],{},"d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n",[861,1467,1468],{"class":863,"line":913},[861,1469,1470],{},"QTAeFw0yMTA0MjkwMDAwMDBaFw0zMjA0MjgyMzU5NTlaMFsxCzAJBgNVBAYTAlVT\n",[861,1472,1473],{"class":863,"line":921},[861,1474,1475],{},"MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n",[861,1477,1478],{"class":863,"line":929},[861,1479,1480],{},"b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\n",[861,1482,1483],{"class":863,"line":940},[861,1484,1485],{},"9w0BAQEFAAOCAQ8AMIIBCgKCAQEAumQB+ILtbVLaKTeQeGviJLbfBxMIRZACMpbs\n",[861,1487,1488],{"class":863,"line":951},[861,1489,1490],{},"QFmylhSTSSpLc1bNPrRVWWVmv+Lt8i3HuLjPQF+3M2NzBWVYB7Gixgd13KZBquor\n",[861,1492,1493],{"class":863,"line":962},[861,1494,1495],{},"2W4Sj5SfR2onVzULfBy6SrwxfSTnnykA1NAzGLbGSukNkY4fO7N4V3C1mLGvL8H\n",[861,1497,1498],{"class":863,"line":969},[861,1499,1500],{},"-----END CERTIFICATE-----\n",[548,1502,1504],{"id":1503},"use-your-own-certificates-when-you","Use Your Own Certificates When You...",[535,1506,1507,1510,1513],{},[525,1508,1509],{},"Cannot use Let's Encrypt (corporate policy, network restrictions, etc.)",[525,1511,1512],{},"Have a specific certificate vendor requirement",[525,1514,1515],{},"Don't need zero-downtime deployments",[767,1517,1518],{},[238,1519,1520],{},"You can also bring your own certificate and configure it with a reverse proxy to get zero-downtime deployments.",[484,1522,1524],{"id":1523},"self-signed-certificate","Self-Signed Certificate",[591,1526,1527],{},[238,1528,1529],{},"Self-signed certificates will display warnings in the browser.",[238,1531,1532,1533,1535,1536,511,1538,1540,1541,775,1544,1547],{},"While browsers will show warnings, self-signed certificates are useful for specific use cases, such as encrypting traffic between containers in a cluster. If you set ",[277,1534,347],{}," to ",[277,1537,380],{},[277,1539,390],{}," without providing a certificate at ",[277,1542,1543],{},"$SSL_CERTIFICATE_FILE",[277,1545,1546],{},"$SSL_PRIVATE_KEY_FILE",", a self-signed certificate will be automatically generated.",[853,1549,1552],{"className":855,"code":1550,"filename":851,"highlights":1551,"language":857,"meta":10,"style":10},"services:\n  php:\n    image: serversideup/php:8.5-fpm-nginx\n    ports:\n      - 80:8080\n      - 443:8443\n    environment:\n      # Set SSL mode to \"mixed\" (HTTP + HTTPS)\n      SSL_MODE: \"mixed\"\n    volumes:\n      - .:/var/www/html\n",[921,929,940],[277,1553,1554,1560,1566,1574,1580,1586,1592,1599,1605,1614,1620],{"__ignoreMap":10},[861,1555,1556,1558],{"class":863,"line":864},[861,1557,868],{"class":867},[861,1559,872],{"class":871},[861,1561,1562,1564],{"class":863,"line":875},[861,1563,878],{"class":867},[861,1565,872],{"class":871},[861,1567,1568,1570,1572],{"class":863,"line":883},[861,1569,886],{"class":867},[861,1571,889],{"class":871},[861,1573,1294],{"class":892},[861,1575,1576,1578],{"class":863,"line":896},[861,1577,899],{"class":867},[861,1579,872],{"class":871},[861,1581,1582,1584],{"class":863,"line":904},[861,1583,907],{"class":871},[861,1585,910],{"class":892},[861,1587,1588,1590],{"class":863,"line":913},[861,1589,907],{"class":871},[861,1591,918],{"class":892},[861,1593,1595,1597],{"class":1594,"line":921},[863,1322],[861,1596,924],{"class":867},[861,1598,872],{"class":871},[861,1600,1602],{"class":1601,"line":929},[863,1322],[861,1603,1604],{"class":965},"      # Set SSL mode to \"mixed\" (HTTP + HTTPS)\n",[861,1606,1608,1610,1612],{"class":1607,"line":940},[863,1322],[861,1609,954],{"class":867},[861,1611,889],{"class":871},[861,1613,1329],{"class":892},[861,1615,1616,1618],{"class":863,"line":951},[861,1617,972],{"class":867},[861,1619,872],{"class":871},[861,1621,1622,1624],{"class":863,"line":962},[861,1623,907],{"class":871},[861,1625,982],{"class":892},[238,1627,1628],{},"The above will generate a self-signed certificate and configure the server to listen on both HTTP (port 80) and HTTPS (port 443).",[548,1630,1632],{"id":1631},"use-a-self-signed-certificate-when-you","Use a Self-Signed Certificate When You...",[535,1634,1635,1638],{},[525,1636,1637],{},"Have a reverse proxy in front of the container handling SSL termination",[525,1639,1640],{},"Need all traffic to be encrypted (even on the internal network between containers)",[767,1642,1643],{},[238,1644,1645,1646,1648],{},"If you have a reverse proxy in front of the container handling SSL termination, you don't need to use ",[277,1647,347],{}," at all. You can configure your reverse proxy to communicate with your PHP container via HTTP (port 8080), eliminating the need to configure SSL within the container.",[1650,1651,1652],"style",{},"html pre.shiki code .s4JwU, html code.shiki .s4JwU{--shiki-default:#85E89D}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}",{"title":10,"searchDepth":875,"depth":875,"links":1654},[1655,1656,1657],{"id":244,"depth":875,"text":245},{"id":340,"depth":875,"text":341},{"id":396,"depth":875,"text":397,"children":1658},[1659,1660,1661,1662],{"id":486,"depth":883,"text":487},{"id":588,"depth":883,"text":589},{"id":1238,"depth":883,"text":1239},{"id":1523,"depth":883,"text":1524},"Learn how to use SSL with the serversideup/php images.",null,{"head":1666,"layout":7},{"title":1667},"Configuring SSL - Docker PHP - Server Side Up",{"title":146,"description":1663},"-8MICOQR78AU6K_nDwOC7LrymwlmbvQaK9eQnRBqhuM",[1671,1673],{"title":142,"path":143,"stem":144,"description":1672,"children":-1},"Learn how to properly package your PHP application into production-ready Docker images.",{"title":150,"path":151,"stem":152,"description":1674,"children":-1},"Learn how to choose the right hosting provider for your containerized PHP application.",1789148864865]