diff --git a/03dbc155.99988d36.js b/03dbc155.99988d36.js new file mode 100644 index 0000000000..aca88a60f6 --- /dev/null +++ b/03dbc155.99988d36.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[8],{156:function(e,t,a){"use strict";a.r(t),a.d(t,"frontMatter",(function(){return s})),a.d(t,"metadata",(function(){return u})),a.d(t,"rightToc",(function(){return p})),a.d(t,"default",(function(){return m}));var o=a(1),n=a(9),r=(a(0),a(457)),l=a(456),i=a(471),c=a(469),b=a(461),s={last_modified_on:"2024-09-18",$schema:"/.meta/.schemas/guides.json",title:"Migrate your application from Heroku to AWS",description:"Guide on how to migrate all your applications from Heroku to AWS with your databases",author_github:"https://github.com/evoxmusic",tags:["type: tutorial","installation_guide: aws"],hide_pagination:!0},u={categories:[{name:"tutorial",title:"Tutorial",description:"Additional step-by-step resources to leverage even more Qovery",permalink:"/guides/tutorial"}],coverLabel:"Migrate your application from Heroku to AWS",description:"Guide on how to migrate all your applications from Heroku to AWS with your databases",permalink:"/guides/tutorial/migrate-your-application-from-heroku-to-aws",readingTime:"12 min read",source:"@site/guides/tutorial/migrate-your-application-from-heroku-to-aws.md",tags:[{label:"type: tutorial",permalink:"/guides/tags/type-tutorial"},{label:"installation_guide: aws",permalink:"/guides/tags/installation-guide-aws"}],title:"Migrate your application from Heroku to AWS",truncated:!1,prevItem:{title:"Microservices",permalink:"/guides/advanced/microservices"},nextItem:{title:"Migration",permalink:"/guides/advanced/migration"}},p=[{value:"Migration Steps",id:"migration-steps",children:[]},{value:"1. Create your Dockerfile",id:"1-create-your-dockerfile",children:[{value:"Test your Dockerfile",id:"test-your-dockerfile",children:[]},{value:"Environment variables at the build time",id:"environment-variables-at-the-build-time",children:[]},{value:"Add your Dockerfile to Git",id:"add-your-dockerfile-to-git",children:[]},{value:"Loop",id:"loop",children:[]}]},{value:"2. Create resources on Qovery",id:"2-create-resources-on-qovery",children:[{value:"Application",id:"application",children:[]},{value:"Database",id:"database",children:[]}]},{value:"3. Configure your Environment Variables and Secrets",id:"3-configure-your-environment-variables-and-secrets",children:[{value:"Connect your frontend app to your backend app",id:"connect-your-frontend-app-to-your-backend-app",children:[]},{value:"Connect your backend app to your database",id:"connect-your-backend-app-to-your-database",children:[]}]},{value:"4. Copy data from your Heroku databases to your AWS databases",id:"4-copy-data-from-your-heroku-databases-to-your-aws-databases",children:[]},{value:"5. Deploy your apps!",id:"5-deploy-your-apps",children:[]},{value:"FAQ by Heroku users",id:"faq-by-heroku-users",children:[{value:"How to create a custom domain?",id:"how-to-create-a-custom-domain",children:[]},{value:"How to monitor my apps?",id:"how-to-monitor-my-apps",children:[]},{value:"Do you have Heroku "Review App" equivalent?",id:"do-you-have-heroku-review-app-equivalent",children:[]},{value:"How to rollback?",id:"how-to-rollback",children:[]},{value:"How auto-scaling works?",id:"how-auto-scaling-works",children:[]},{value:"How to manage database migration?",id:"how-to-manage-database-migration",children:[]},{value:"Is it possible to get a shell / connect to my app?",id:"is-it-possible-to-get-a-shell--connect-to-my-app",children:[]},{value:"Can I use Terraform and Infrastructure as Code?",id:"can-i-use-terraform-and-infrastructure-as-code",children:[]},{value:"How can I connect my app to MongoDB Atlas?",id:"how-can-i-connect-my-app-to-mongodb-atlas",children:[]},{value:"How can I connect my app to an AWS service not managed by Qovery?",id:"how-can-i-connect-my-app-to-an-aws-service-not-managed-by-qovery",children:[]}]},{value:"Wrapping up",id:"wrapping-up",children:[]}],d={rightToc:p};function m(e){var t=e.components,a=Object(n.a)(e,["components"]);return Object(r.b)("wrapper",Object(o.a)({},d,a,{components:t,mdxType:"MDXLayout"}),Object(r.b)(l.a,{type:"success",mdxType:"Alert"},Object(r.b)("p",null,"This guide also work for migrating your application from Heroku to GCP, Azure, Scaleway and ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/getting-started/install-qovery/"}),"all cloud provider")," supported by Qovery.")),Object(r.b)("p",null,"This guide describes how to migrate your application running on Heroku to AWS with Qovery. It covers all required steps you need to take to deploy your application on AWS and transfer your data from Heroku Postgres to the database managed by AWS via Qovery."),Object(r.b)("blockquote",null,Object(r.b)("p",{parentName:"blockquote"},"We have created a new AI agent capable of migrating from Heroku to AWS, GCP, Scaleway or Azure in a few clicks. Check our ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://www.qovery.com/blog/open-source-devops-ai-agent--effortless-migration-from-heroku-to-aws/?utm_campaign=migration-ai-agent-email"}),"announcement here"),".")),Object(r.b)(b.a,{name:"guide",mdxType:"Assumptions"},Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},"You are familiar with Heroku basics, have a Heroku account and access to Heroku CLI"),Object(r.b)("li",{parentName:"ul"},"You have ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"https://start.qovery.com"}),"sign in on Qovery")),Object(r.b)("li",{parentName:"ul"},"You have ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"/guides/installation-guide/guide-amazon-web-services/"}),"set up your AWS account")," with Qovery"))),Object(r.b)("h2",{id:"migration-steps"},"Migration Steps"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#1-create-your-dockerfile"}),"Create your Dockerfile")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#2-create-resources-on-qovery"}),"Create resources on Qovery")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#3-configure-your-environment-variables-and-secrets"}),"Configure Environment Variables and Secrets")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#4-copy-data-from-your-heroku-databases-to-your-aws-databases"}),"Copy data from your Heroku databases to your AWS databases")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#5-deploy-your-apps-"}),"Deploy your apps")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#faq-by-heroku-users"}),"FAQ by Heroku users"))),Object(r.b)("h2",{id:"1-create-your-dockerfile"},"1. Create your Dockerfile"),Object(r.b)("p",null,"Qovery supports two ways to build and run your application coming from Heroku:"),Object(r.b)("blockquote",null,Object(r.b)("p",{parentName:"blockquote"},"Are you familiar with Dockerfile? If not, I do recommend reading ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/how-to-write-a-dockerfile/"}),"this article"),".")),Object(r.b)("p",null,"Here we will create our Dockerfiles to build and run our applications. Qovery will handle the build and the run of your applications, but need to have at least a Dockerfile to do it."),Object(r.b)("h4",{id:"find-dockerfile-template"},"Find Dockerfile template"),Object(r.b)("p",null,"Pick one Dockerfile template according to the programming language or framework you are using for your app:"),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"Your framework or language is missing? Open a thread on ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/"}),"our forum"),", and we will provide you one.")),Object(r.b)(c.a,{centered:!1,className:"square",defaultValue:"rails",select:!1,size:null,values:[{group:"Files",label:"Rails",value:"rails"},{group:"Files",label:"NodeJS",value:"nodejs"},{group:"Files",label:"React",value:"react"},{group:"Files",label:"VueJS",value:"vuejs"},{group:"Files",label:"NextJS",value:"nextjs"},{group:"Files",label:"Golang",value:"golang"},{group:"Files",label:"Flask",value:"flask"},{group:"Files",label:"Django",value:"django"},{group:"Files",label:"Laravel",value:"laravel"},{group:"Files",label:"Symfony",value:"symfony"},{group:"Files",label:"Spring",value:"spring"},{group:"Files",label:"Rust",value:"rust"}],mdxType:"Tabs"},Object(r.b)(i.a,{value:"rails",mdxType:"TabItem"},Object(r.b)("p",null,"Here is the Dockerfile for your Rails application listening on the PORT 3000"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell",metastring:'title="Dockerfile"',title:'"Dockerfile"'}),'# syntax=docker/dockerfile:1\nFROM ruby:2.7\nRUN apt-get update -qq && apt-get install -y nodejs postgresql-client\nWORKDIR /myapp\nCOPY Gemfile Gemfile\nCOPY Gemfile.lock Gemfile.lock\nRUN bundle install\n\nCOPY . .\n\nEXPOSE 3000\n\n# Configure the main process to run when running the image\nCMD ["rails", "server", "-b", "0.0.0.0", "-p", "3000"]\n')),Object(r.b)("details",null,Object(r.b)("summary",null,"Dockerfile for Sidekiq"),Object(r.b)("p",null,"Here is the Dockerfile for your Rails app running as a worker mode with Sidekiq."),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"There is no listening port since it is consuming resources from a queuing system (E.g. Redis)")),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell",metastring:'title="Dockerfile for Sidekiq"',title:'"Dockerfile',for:!0,'Sidekiq"':!0}),'# syntax=docker/dockerfile:1\nFROM ruby:2.7\nRUN apt-get update -qq && apt-get install -y nodejs postgresql-client # add mysql client if you need to\nWORKDIR /myapp\nCOPY Gemfile Gemfile\nCOPY Gemfile.lock Gemfile.lock\nRUN bundle install\n\nCOPY . .\n\nCMD ["bundle", "exec", "sidekiq"]\n')))),Object(r.b)(i.a,{value:"nodejs",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"react",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"vuejs",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"nextjs",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"golang",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"flask",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"django",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"laravel",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"symfony",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"spring",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"rust",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n")))),Object(r.b)("h4",{id:"copy-template"},"Copy template"),Object(r.b)("p",null,"Copy your Dockerfile at the root of your project. By convention, you can name your file ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile"),". If you already have a Dockerfile, feel free to name it ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile.qovery"),". If you are using multiple Dockerfile for Qovery, feel free to give a name like ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile-sidekiq.qovery"),"."),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"Read ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/t/904"}),"this forum post")," to know how to use the same Dockerfile with different CMD parameters.")),Object(r.b)("p",null,"For our example of migrating a Rails app and a Rails Sidekiq app, I will have at the root of my project a ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile.qovery")," and a ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile-sidekiq.qovery"),"."),Object(r.b)("h3",{id:"test-your-dockerfile"},"Test your Dockerfile"),Object(r.b)(b.a,{mdxType:"Assumptions"},Object(r.b)("p",null,"You need to ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://docs.docker.com/get-docker/"}),"install Docker")," to test your Dockerfile")),Object(r.b)("p",null,"To test your Dockerfile we will locally our container. You just need to run the following commands:"),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,"Don't forget the ",Object(r.b)("inlineCode",{parentName:"p"},".")," (dot) at the end of the ",Object(r.b)("inlineCode",{parentName:"p"},"docker build")," command.")),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"docker build -f Dockerfile.qovery .\n")),Object(r.b)("p",null,"If everything goes well you should get the finale image ID at the end of the output."),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"[+] Building 19.0s (16/16) FINISHED\n => [internal] load build definition from Dockerfile 0.0s\n => => transferring dockerfile: 37B 0.0s\n => [internal] load .dockerignore 0.0s\n ...\n => [7/7] COPY . . 0.2s\n => exporting to image 0.0s\n => exporting layers 0.4s\n => writing image sha256:a0f90a6ec8bc4036a7b268479a0c0773ca324ba2de11fdef31309650743f4055 0.0s\n")),Object(r.b)("p",null,"To run your image you can run:"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"docker run a0f90a6ec8bc4036a7b268479a0c0773ca324ba2de11fdef31309650743f4055\n")),Object(r.b)("p",null,"If your app required a database to starts, then it can be normal that it fails to start. Otherwise, if your app is supposed to start and does not, then you will need to fix the issue and rebuild your app with ",Object(r.b)("inlineCode",{parentName:"p"},"docker build -f Dockerfile.qovery .")),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"This step is one of the most complex, but once you successfully build your application with Docker, your app will run anywhere (not only on AWS with Qovery).")),Object(r.b)("p",null,"Any error while building your container image? 2 solutions:"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},'Read the error message and try to understand from where the problem is coming from. You can "Google" the error if it is not related to your code.'),Object(r.b)("li",{parentName:"ol"},"Open a thread on ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"https://discuss.qovery.com/"}),"our forum")," if you don't find the answer there, we will be happy to assist you.")),Object(r.b)("h3",{id:"environment-variables-at-the-build-time"},"Environment variables at the build time"),Object(r.b)("p",null,"Does your app use some environment variables at the build time? Then you will need to modify your Dockerfile to includes the environment variables. Let's imagine your app uses the environment variable ",Object(r.b)("inlineCode",{parentName:"p"},"CONTENT_API_KEY"),", then you will need to add the following instructions in your Dockerfile:"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell",metastring:'title="Dockerfile with environment variables"',title:'"Dockerfile',with:!0,environment:!0,'variables"':!0}),"...\nARG CONTENT_API_KEY\nENV CONTENT_API_KEY $CONTENT_API_KEY\n...\n")),Object(r.b)("p",null,"The value of the ",Object(r.b)("inlineCode",{parentName:"p"},"CONTENT_API_KEY")," environment variable will be taken from the specified environment variables in Qovery."),Object(r.b)(l.a,{type:"success",mdxType:"Alert"},Object(r.b)("p",null,"Qovery injects Environment Variables and Secrets at the build and run time of your app.")),Object(r.b)("h3",{id:"add-your-dockerfile-to-git"},"Add your Dockerfile to Git"),Object(r.b)("p",null,"Now, add your new Dockerfile to git with the following commands:"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),'git add Dockerfile.qovery\ngit commit -m "Add Qovery Dockerfile"\ngit push origin\n')),Object(r.b)("h3",{id:"loop"},"Loop"),Object(r.b)("p",null,"If you have multiple applications to deploy, create a Dockerfile for each of them."),Object(r.b)("h2",{id:"2-create-resources-on-qovery"},"2. Create resources on Qovery"),Object(r.b)("h3",{id:"application"},"Application"),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"Are you a new Qovery user? Watch ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/getting-started/deploy-your-first-application/"}),"this tutorial")," to learn how to deploy your first app.")),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/9246ae68c68f42debc3d5183d2b4f7f8",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"Steps:"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},"Connect to the ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"https://start.qovery.com"}),"Qovery console"),"."),Object(r.b)("li",{parentName:"ol"},"Create your ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/organization/"}),"Organization")," and your ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/project/"}),"Project"),"."),Object(r.b)("li",{parentName:"ol"},"Create an environment with the name ",Object(r.b)("inlineCode",{parentName:"li"},"production")," (it can be changed after)."),Object(r.b)("li",{parentName:"ol"},"Create an application and give it a name (you can give the name of your repo if you have no idea)"),Object(r.b)("li",{parentName:"ol"},"Select your app repository from your GitHub, GitLab or Bitbucket."),Object(r.b)("li",{parentName:"ol"},"Select the branch you want to deploy."),Object(r.b)("li",{parentName:"ol"},"Specify the local listening port of your application."),Object(r.b)("li",{parentName:"ol"},'Click on "create"')),Object(r.b)("p",null,"Congrats! Your application is created \ud83c\udf89"),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,'Your application is created but not deployed yet! You can configure the vCPU, Memory, Environment Variables... before deploying it. If you want to deploy it before finishing the configuration you can click on "Actions" > "Deploy".')),Object(r.b)("p",null,"If you deploy an app from a mono-repository, we have a must-read guide for you ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/advanced/monorepository/"}),"here"),"."),Object(r.b)("h3",{id:"database"},"Database"),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"Are you a new Qovery user? Watch ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/getting-started/create-a-database/"}),"this tutorial")," to learn how to deploy your database.")),Object(r.b)("p",null,"Here are the steps to deploy your database:"),Object(r.b)(b.a,{mdxType:"Assumptions"},Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},"You have created an application before"))),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/d7e10be0e5964f6799b158dc631bbbd1",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"Steps:"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},"Go to your ",Object(r.b)("inlineCode",{parentName:"li"},"production")," environment."),Object(r.b)("li",{parentName:"ol"},'Add your database by clicking on "Add" > "Database".'),Object(r.b)("li",{parentName:"ol"},"Select the database (PostgreSQL, MySQL, MongoDB, Redis..) and the version you want to deploy."),Object(r.b)("li",{parentName:"ol"},"Select ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/database/#general"}),"Managed or Container mode")," for your database."),Object(r.b)("li",{parentName:"ol"},"Select ",Object(r.b)("inlineCode",{parentName:"li"},"Public")," accessibility (set ",Object(r.b)("inlineCode",{parentName:"li"},"Private")," if you don't want to restore your data from an existing Heroku database).")),Object(r.b)("p",null,"Congrats! Your database is created as well \ud83c\udf89"),Object(r.b)("p",null,"If you use MongoDB Atlas, or an existing database on AWS that you want to connect to your application deployed by Qovery. Check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/aws-vpc-peering-with-qovery/"}),"our tutorial about VPC peering")," and how to securely connect to your existing database."),Object(r.b)("h2",{id:"3-configure-your-environment-variables-and-secrets"},"3. Configure your Environment Variables and Secrets"),Object(r.b)(l.a,{type:"success",mdxType:"Alert"},Object(r.b)("p",null,"Qovery supports Doppler integration - it's the easiest way to migrate your Environment Variables and Secrets from Heroku to Qovery. ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/integration/secret-manager/doppler/"}),"More info here"),".")),Object(r.b)("p",null,"Qovery makes the difference between an environment variable and a secret. Basically, a Secret is similar to an Environment Variable but the value is encrypted and can't be revealed. Both are injected as environment variables during the build and the run of your applications. ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment-variable/"}),"More info here")),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"I recommend reading our ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/getting-started/managing-environment-variables/"}),"Getting Started with Environment Variables")," guide.")),Object(r.b)("p",null,"To extract your environment variables from Heroku, we recommend using the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://devcenter.heroku.com/articles/heroku-cli"}),"Heroku CLI")," and exporting all the environment variables and secrets in an .env (dot env) file. Qovery supports the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/import-your-environment-variables-with-the-qovery-cli/"}),"import of a dot env file")," via the Qovery web interface and the Qovery CLI."),Object(r.b)("p",null,Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://devcenter.heroku.com/articles/config-vars#view-current-config-var-values"}),"Export your environment variable via the Heroku CLI")," with the command:"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"# To install Heroku CLI: https://devcenter.heroku.com/articles/heroku-cli\nheroku config\n\nGREETINGS: hello world\nSTRIPE_API_KEY: xxx-yyy-zzz\nIS_PRODUCTION: true\n")),Object(r.b)("p",null,"Then you can create your environment variables via the web interface (watch the video below)"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/50899d7fa3d84a418f0db69f54f970d3",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"Or via the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/interface/cli/"}),"Qovery CLI"),":"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell",metastring:'title="Import Heroku environment variables with the Qovery CLI"',title:'"Import',Heroku:!0,environment:!0,variables:!0,with:!0,the:!0,Qovery:!0,'CLI"':!0}),"# auth yourself\nqovery auth\n\n# selection the app where you want to import your environment variables\nqovery context set\n\n# import your Heroku environment variables\nheroku config --app --json | \\\n qovery env parse --heroku-json > heroku.env && \\\n qovery env import heroku.env && \\\n rm heroku.env\n\nQovery: dot env file to import: 'heroku.env'\n? Do you want to import Environment Variables or Secrets? Environment Variables\n? What environment variables do you want to import? [Use arrows to move, space to select, to all, to none, type to filter]\n [x] GREETINGS=hello world\n [ ] STRIPE_API_KEY=xxx-yyy-zzz\n> [x] IS_PRODUCTION=true\n\nQovery: \u2705 Environment Variables successfully imported!\n")),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,"Import sensitive data (E.g. API keys, credentials...) as ",Object(r.b)("inlineCode",{parentName:"p"},"Secret")," and not ",Object(r.b)("inlineCode",{parentName:"p"},"Environment Variable"),".")),Object(r.b)("h3",{id:"connect-your-frontend-app-to-your-backend-app"},"Connect your frontend app to your backend app"),Object(r.b)("p",null,"To connect your frontend app your backend app we will create an ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment-variable/#alias-environment-variable"}),"environment variable alias"),"."),Object(r.b)("p",null,"Here is how to create a frontend app:"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/bafbbda93bd64d04afb3189bf4a1a201",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"And now how to connect your frontend app with your backend app:"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/f820925f2175465f9271b97ef414bb42",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"You can also take a look at ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/t/918"}),"this forum reply")," to learn how to do it."),Object(r.b)("h3",{id:"connect-your-backend-app-to-your-database"},"Connect your backend app to your database"),Object(r.b)("p",null,"Same as connecting your frontend app to your backend app, you can create an environment variable alias ",Object(r.b)("inlineCode",{parentName:"p"},"DATABASE_URL")," for the ",Object(r.b)("em",{parentName:"p"},"built-in")," secret finishing with ",Object(r.b)("inlineCode",{parentName:"p"},"_DATABASE_URL_INTERNAL"),"."),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,"Create an alias on ",Object(r.b)("inlineCode",{parentName:"p"},"_DATABASE_URL_INTERNAL")," and not ",Object(r.b)("inlineCode",{parentName:"p"},"_DATABASE_URL"))),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/59f8368eb3c14796a807c7e39e9c0ab0",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("h2",{id:"4-copy-data-from-your-heroku-databases-to-your-aws-databases"},"4. Copy data from your Heroku databases to your AWS databases"),Object(r.b)("p",null,Object(r.b)("em",{parentName:"p"},"Coming soon with ",Object(r.b)("a",Object(o.a)({parentName:"em"},{href:"https://www.replibyte.com"}),"Replibyte"))),Object(r.b)("h2",{id:"5-deploy-your-apps"},"5. Deploy your apps!"),Object(r.b)("p",null,"We are finally ready to deploy my applications on AWS!"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/0589d2f2aa4149edb605dc23f4efd23d",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"Watch the final result \ud83d\ude0e"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/da31c21f9c104eae9270e4c4db59055e",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("h2",{id:"faq-by-heroku-users"},"FAQ by Heroku users"),Object(r.b)("h3",{id:"how-to-create-a-custom-domain"},"How to create a custom domain?"),Object(r.b)("p",null,"Check out the documentation on ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/getting-started/setting-custom-domain/"}),"how to configure your custom domain"),"."),Object(r.b)("h3",{id:"how-to-monitor-my-apps"},"How to monitor my apps?"),Object(r.b)("p",null,"We do recommend using ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://www.datadoghq.com"}),"Datadog")," or any other monitoring products for monitoring your apps deployed by Qovery. Check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/kubernetes-observability-and-monitoring-with-datadog/"}),"our tutorial on how to install Datadog"),"."),Object(r.b)("h3",{id:"do-you-have-heroku-review-app-equivalent"},'Do you have Heroku "Review App" equivalent?'),Object(r.b)("p",null,"Yes, it's what we call ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment/#preview-environment"}),"Preview Environment")),Object(r.b)("h3",{id:"how-to-rollback"},"How to rollback?"),Object(r.b)("p",null,"Check out the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/deployment-actions/#deploy-other-version"}),"app rollback documentation")),Object(r.b)("h3",{id:"how-auto-scaling-works"},"How auto-scaling works?"),Object(r.b)("p",null,"Check out the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/application/#auto-scaling"}),"app auto-scaling documentation")),Object(r.b)("h3",{id:"how-to-manage-database-migration"},"How to manage database migration?"),Object(r.b)("p",null,"Check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/t/951"}),"our forum reply")),Object(r.b)("h3",{id:"is-it-possible-to-get-a-shell--connect-to-my-app"},"Is it possible to get a shell / connect to my app?"),Object(r.b)("p",null,"Absolutely, you can connect directly to your application with a shell by clicking on the Qovery cloud shell button (1):"),Object(r.b)("p",{align:"center"},Object(r.b)("img",{src:"/img/qovery_cloud_shell.png",alt:"Qovery Cloud Shell"})),Object(r.b)("p",null,"Then you just have to select the pod (2) and the container (3)."),Object(r.b)("p",null,"You can also check out our ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/interface/cli/#shell"}),"CLI")," and the ",Object(r.b)("inlineCode",{parentName:"p"},"qovery shell")," command."),Object(r.b)("h3",{id:"can-i-use-terraform-and-infrastructure-as-code"},"Can I use Terraform and Infrastructure as Code?"),Object(r.b)("p",null,"Absolutely, we have a ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/integration/terraform-provider/"}),"Qovery Terraform provider")," available."),Object(r.b)("h3",{id:"how-can-i-connect-my-app-to-mongodb-atlas"},"How can I connect my app to MongoDB Atlas?"),Object(r.b)("p",null,"If you use MongoDB Atlas check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/aws-vpc-peering-with-qovery/"}),"our tutorial about VPC peering")," and how to securely connect to your existing MongoDB Atlas database."),Object(r.b)("h3",{id:"how-can-i-connect-my-app-to-an-aws-service-not-managed-by-qovery"},"How can I connect my app to an AWS service not managed by Qovery?"),Object(r.b)("p",null,"If you want to connect your app to an AWS service not managed by Qovery, check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/aws-vpc-peering-with-qovery/"}),"our tutorial about VPC peering")," and how to securely connect to this AWS service."),Object(r.b)("hr",null),Object(r.b)("p",null,"If you have a common question about Qovery, we have a more general ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/useful-resources/faq/"}),"FAQ section")," available."),Object(r.b)("h2",{id:"wrapping-up"},"Wrapping up"),Object(r.b)("p",null,"Congrats! You have migrated from Heroku to AWS. Feel free to check out our ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/"}),"forum")," and open a thread if you have any question."))}m.isMDXComponent=!0},456:function(e,t,a){"use strict";a(458);var o=a(0),n=a.n(o),r=a(455),l=a.n(r);a(132);t.a=function(e){var t=e.children,a=e.classNames,o=e.fill,r=e.icon,i=e.type,c=null;switch(i){case"danger":c="alert-triangle";break;case"success":c="check-circle";break;case"warning":c="alert-triangle";break;default:c="info"}return n.a.createElement("div",{className:l()(a,"alert","alert--"+i,{"alert--fill":o,"alert--icon":!1!==r}),role:"alert"},!1!==r&&n.a.createElement("i",{className:l()("feather","icon-"+(r||c))}),t)}},460:function(e,t,a){var o=a(28).f,n=Function.prototype,r=/^\s*function ([^ (]*)/;"name"in n||a(10)&&o(n,"name",{configurable:!0,get:function(){try{return(""+this).match(r)[1]}catch(e){return""}}})},461:function(e,t,a){"use strict";a(460);var o=a(0),n=a.n(o),r=a(456);t.a=function(e){var t=e.children,a=e.name;return n.a.createElement(r.a,{type:"info",fill:!0,icon:!1,rounded:!0,className:"list--icons list--icons--arrow list--tight list--indent margin-bottom--lg"},n.a.createElement("p",{class:"text--lg margin-bottom--sm",style:{marginTop:"-0.25em"}},"Before you begin, this ",a||"page"," assumes the following:"),t)}},469:function(e,t,a){"use strict";var o=a(1),n=(a(473),a(470),a(52),a(29),a(22),a(21),a(0)),r=a.n(n),l=a(477),i=a(455),c=a.n(i),b=a(463),s=a.n(b),u=a(476),p=37,d=39;function m(e){var t=e.block,a=e.centered,o=e.changeSelectedValue,n=e.className,l=e.handleKeydown,i=e.style,b=e.values,s=e.selectedValue,u=e.tabRefs;return r.a.createElement("div",{className:a?"tabs--centered":null},r.a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:c()("tabs",n,{"tabs--block":t}),style:i},b.map((function(e){var t=e.value,a=e.label;return r.a.createElement("li",{role:"tab",tabIndex:"0","aria-selected":s===t,className:c()("tab-item",{"tab-item--active":s===t}),key:t,ref:function(e){return u.push(e)},onKeyDown:function(e){return l(u,e.target,e)},onFocus:function(){return o(t)},onClick:function(){return o(t)}},a)}))))}function h(e){var t=e.placeholder,a=e.selectedValue,o=e.changeSelectedValue,n=e.size,i=e.values,c=i;if(c[0].group){var b=_.groupBy(c,"group");c=Object.keys(b).map((function(e){return{label:e,options:b[e]}}))}return r.a.createElement(l.a,{className:"react-select-container react-select--"+n,classNamePrefix:"react-select",options:c,isClearable:a,placeholder:t,value:i.find((function(e){return e.value==a})),onChange:function(e){return o(e?e.value:null)}})}t.a=function(e){e.block,e.centered;var t=e.children,a=e.defaultValue,l=e.groupId,i=e.label,c=e.placeholder,b=e.select,y=e.size,f=(e.style,e.values),O=e.urlKey,j=Object(u.a)(),g=j.tabGroupChoices,v=j.setTabGroupChoices,w=Object(n.useState)(a),k=w[0],N=w[1];if(null!=l){var C=g[l];null!=C&&C!==k&&N(C)}var T=function(e){N(e),null!=l&&v(l,e)},A=[],D=function(e,t,a){switch(a.keyCode){case d:!function(e,t){var a=e.indexOf(t)+1;e[a]?e[a].focus():e[0].focus()}(e,t);break;case p:!function(e,t){var a=e.indexOf(t)-1;e[a]?e[a].focus():e[e.length-1].focus()}(e,t)}};return Object(n.useEffect)((function(){if("undefined"!=typeof window&&window.location&&O){var e=s.a.parse(window.location.search);e[O]&&N(e[O])}}),[]),r.a.createElement(r.a.Fragment,null,r.a.createElement("div",{className:"margin-bottom--"+(y||"md")},i&&r.a.createElement("div",{className:"margin-vert--sm"},i),f.length>1&&(b?r.a.createElement(h,Object(o.a)({changeSelectedValue:T,handleKeydown:D,placeholder:c,selectedValue:k,size:y,tabRefs:A},e)):r.a.createElement(m,Object(o.a)({changeSelectedValue:T,handleKeydown:D,selectedValue:k,tabRefs:A},e)))),n.Children.toArray(t).filter((function(e){return e.props.value===k}))[0])}},471:function(e,t,a){"use strict";var o=a(0),n=a.n(o);t.a=function(e){return n.a.createElement(n.a.Fragment,null,e.children)}}}]); \ No newline at end of file diff --git a/03dbc155.c90d5099.js b/03dbc155.c90d5099.js deleted file mode 100644 index 53ab18f468..0000000000 --- a/03dbc155.c90d5099.js +++ /dev/null @@ -1 +0,0 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[8],{156:function(e,t,a){"use strict";a.r(t),a.d(t,"frontMatter",(function(){return u})),a.d(t,"metadata",(function(){return s})),a.d(t,"rightToc",(function(){return p})),a.d(t,"default",(function(){return m}));var o=a(1),n=a(9),r=(a(0),a(457)),l=a(456),i=a(471),c=a(469),b=a(461),u={last_modified_on:"2024-08-12",$schema:"/.meta/.schemas/guides.json",title:"Migrate your application from Heroku to AWS",description:"Guide on how to migrate all your applications from Heroku to AWS with your databases",author_github:"https://github.com/evoxmusic",tags:["type: tutorial","installation_guide: aws"],hide_pagination:!0},s={categories:[{name:"tutorial",title:"Tutorial",description:"Additional step-by-step resources to leverage even more Qovery",permalink:"/guides/tutorial"}],coverLabel:"Migrate your application from Heroku to AWS",description:"Guide on how to migrate all your applications from Heroku to AWS with your databases",permalink:"/guides/tutorial/migrate-your-application-from-heroku-to-aws",readingTime:"13 min read",source:"@site/guides/tutorial/migrate-your-application-from-heroku-to-aws.md",tags:[{label:"type: tutorial",permalink:"/guides/tags/type-tutorial"},{label:"installation_guide: aws",permalink:"/guides/tags/installation-guide-aws"}],title:"Migrate your application from Heroku to AWS",truncated:!1,prevItem:{title:"Microservices",permalink:"/guides/advanced/microservices"},nextItem:{title:"Migration",permalink:"/guides/advanced/migration"}},p=[{value:"Migration Steps",id:"migration-steps",children:[]},{value:"1. Create your Dockerfile or Use Buildpacks",id:"1-create-your-dockerfile-or-use-buildpacks",children:[{value:"Choose your Dockerfile template",id:"choose-your-dockerfile-template",children:[]},{value:"Test your Dockerfile",id:"test-your-dockerfile",children:[]},{value:"Environment variables at the build time",id:"environment-variables-at-the-build-time",children:[]},{value:"Add your Dockerfile to Git",id:"add-your-dockerfile-to-git",children:[]},{value:"Loop",id:"loop",children:[]},{value:"Limitations",id:"limitations",children:[]}]},{value:"2. Create resources on Qovery",id:"2-create-resources-on-qovery",children:[{value:"Application",id:"application",children:[]},{value:"Database",id:"database",children:[]}]},{value:"3. Configure your Environment Variables and Secrets",id:"3-configure-your-environment-variables-and-secrets",children:[{value:"Connect your frontend app to your backend app",id:"connect-your-frontend-app-to-your-backend-app",children:[]},{value:"Connect your backend app to your database",id:"connect-your-backend-app-to-your-database",children:[]}]},{value:"4. Copy data from your Heroku databases to your AWS databases",id:"4-copy-data-from-your-heroku-databases-to-your-aws-databases",children:[]},{value:"5. Deploy your apps!",id:"5-deploy-your-apps",children:[]},{value:"FAQ by Heroku users",id:"faq-by-heroku-users",children:[{value:"How to create a custom domain?",id:"how-to-create-a-custom-domain",children:[]},{value:"How to monitor my apps?",id:"how-to-monitor-my-apps",children:[]},{value:"Do you have Heroku "Review App" equivalent?",id:"do-you-have-heroku-review-app-equivalent",children:[]},{value:"How to rollback?",id:"how-to-rollback",children:[]},{value:"How auto-scaling works?",id:"how-auto-scaling-works",children:[]},{value:"How to manage database migration?",id:"how-to-manage-database-migration",children:[]},{value:"Is it possible to get a shell / connect to my app?",id:"is-it-possible-to-get-a-shell--connect-to-my-app",children:[]},{value:"Can I use Terraform and Infrastructure as Code?",id:"can-i-use-terraform-and-infrastructure-as-code",children:[]},{value:"How can I connect my app to MongoDB Atlas?",id:"how-can-i-connect-my-app-to-mongodb-atlas",children:[]},{value:"How can I connect my app to an AWS service not managed by Qovery?",id:"how-can-i-connect-my-app-to-an-aws-service-not-managed-by-qovery",children:[]}]},{value:"Wrapping up",id:"wrapping-up",children:[]}],d={rightToc:p};function m(e){var t=e.components,a=Object(n.a)(e,["components"]);return Object(r.b)("wrapper",Object(o.a)({},d,a,{components:t,mdxType:"MDXLayout"}),Object(r.b)(l.a,{type:"success",mdxType:"Alert"},Object(r.b)("p",null,"This guide also work for migrating your application from Heroku to GCP, Azure, Scaleway and ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/getting-started/install-qovery/"}),"all cloud provider")," supported by Qovery.")),Object(r.b)("p",null,"This guide describes how to migrate your application running on Heroku to AWS with Qovery. It covers all required steps you need to take to deploy your application on AWS and transfer your data from Heroku Postgres to the database managed by AWS via Qovery."),Object(r.b)("blockquote",null,Object(r.b)("p",{parentName:"blockquote"},"Please contact us via ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/"}),"our forum")," if you experience any problem while migrating from Heroku to AWS with Qovery.")),Object(r.b)(b.a,{name:"guide",mdxType:"Assumptions"},Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},"You are familiar with Heroku basics, have a Heroku account and access to Heroku CLI"),Object(r.b)("li",{parentName:"ul"},"You have ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"https://start.qovery.com"}),"sign in on Qovery")),Object(r.b)("li",{parentName:"ul"},"You have ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"/guides/installation-guide/guide-amazon-web-services/"}),"set up your AWS account")," with Qovery"))),Object(r.b)("h2",{id:"migration-steps"},"Migration Steps"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#1-create-your-dockerfile-or-use-buildpacks"}),"Use Buildpacks or Create your Dockerfile")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#2-create-resources-on-qovery"}),"Create resources on Qovery")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#3-configure-your-environment-variables-and-secrets"}),"Configure Environment Variables and Secrets")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#4-copy-data-from-your-heroku-databases-to-your-aws-databases"}),"Copy data from your Heroku databases to your AWS databases")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#5-deploy-your-apps-"}),"Deploy your apps")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#faq-by-heroku-users"}),"FAQ by Heroku users"))),Object(r.b)("h2",{id:"1-create-your-dockerfile-or-use-buildpacks"},"1. Create your Dockerfile or Use Buildpacks"),Object(r.b)("p",null,"Qovery supports two ways to build and run your application coming from Heroku:"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},"Buildpacks"),Object(r.b)("li",{parentName:"ol"},"Docker")),Object(r.b)("p",null,"Both options build a container image that is runnable by a container engine (E.g. Docker). Qovery runs containers on Kubernetes."),Object(r.b)("p",null,"Choose the option that better fits you:"),Object(r.b)(c.a,{centered:!0,className:"rounded",defaultValue:"buildpacks",placeholder:"Use Buildpacks or Create your Dockerfile",select:!1,size:null,values:[{group:"Platforms",label:"Use Buildpacks",value:"buildpacks"},{group:"Platforms",label:"Create your Dockerfile",value:"dockerfile"}],mdxType:"Tabs"},Object(r.b)(i.a,{value:"dockerfile",mdxType:"TabItem"},Object(r.b)("blockquote",null,Object(r.b)("p",{parentName:"blockquote"},"Are you familiar with Dockerfile? If not, I do recommend reading ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/how-to-write-a-dockerfile/"}),"this article"),".")),Object(r.b)("p",null,"Here we will create our Dockerfiles to build and run our applications. Qovery will handle the build and the run of your applications, but need to have at least a Dockerfile to do it."),Object(r.b)("h3",{id:"choose-your-dockerfile-template"},"Choose your Dockerfile template"),Object(r.b)("p",null,"To get started,"),Object(r.b)("h4",{id:"find-dockerfile-template"},"Find Dockerfile template"),Object(r.b)("p",null,"Pick one Dockerfile template according to the programming language or framework you are using for your app:"),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"Your framework or language is missing? Open a thread on ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/"}),"our forum"),", and we will provide you one.")),Object(r.b)(c.a,{centered:!1,className:"square",defaultValue:"rails",select:!1,size:null,values:[{group:"Files",label:"Rails",value:"rails"},{group:"Files",label:"NodeJS",value:"nodejs"},{group:"Files",label:"React",value:"react"},{group:"Files",label:"VueJS",value:"vuejs"},{group:"Files",label:"NextJS",value:"nextjs"},{group:"Files",label:"Golang",value:"golang"},{group:"Files",label:"Flask",value:"flask"},{group:"Files",label:"Django",value:"django"},{group:"Files",label:"Laravel",value:"laravel"},{group:"Files",label:"Symfony",value:"symfony"},{group:"Files",label:"Spring",value:"spring"},{group:"Files",label:"Rust",value:"rust"}],mdxType:"Tabs"},Object(r.b)(i.a,{value:"rails",mdxType:"TabItem"},Object(r.b)("p",null,"Here is the Dockerfile for your Rails application listening on the PORT 3000"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell",metastring:'title="Dockerfile"',title:'"Dockerfile"'}),'# syntax=docker/dockerfile:1\nFROM ruby:2.7\nRUN apt-get update -qq && apt-get install -y nodejs postgresql-client\nWORKDIR /myapp\nCOPY Gemfile Gemfile\nCOPY Gemfile.lock Gemfile.lock\nRUN bundle install\n\nCOPY . .\n\nEXPOSE 3000\n\n# Configure the main process to run when running the image\nCMD ["rails", "server", "-b", "0.0.0.0", "-p", "3000"]\n')),Object(r.b)("details",null,Object(r.b)("summary",null,"Dockerfile for Sidekiq"),Object(r.b)("p",null,"Here is the Dockerfile for your Rails app running as a worker mode with Sidekiq."),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"There is no listening port since it is consuming resources from a queuing system (E.g. Redis)")),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell",metastring:'title="Dockerfile for Sidekiq"',title:'"Dockerfile',for:!0,'Sidekiq"':!0}),'# syntax=docker/dockerfile:1\nFROM ruby:2.7\nRUN apt-get update -qq && apt-get install -y nodejs postgresql-client # add mysql client if you need to\nWORKDIR /myapp\nCOPY Gemfile Gemfile\nCOPY Gemfile.lock Gemfile.lock\nRUN bundle install\n\nCOPY . .\n\nCMD ["bundle", "exec", "sidekiq"]\n')))),Object(r.b)(i.a,{value:"nodejs",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"react",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"vuejs",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"nextjs",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"golang",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"flask",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"django",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"laravel",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"symfony",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"spring",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"rust",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n")))),Object(r.b)("h4",{id:"copy-template"},"Copy template"),Object(r.b)("p",null,"Copy your Dockerfile at the root of your project. By convention, you can name your file ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile"),". If you already have a Dockerfile, feel free to name it ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile.qovery"),". If you are using multiple Dockerfile for Qovery, feel free to give a name like ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile-sidekiq.qovery"),"."),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"Read ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/t/904"}),"this forum post")," to know how to use the same Dockerfile with different CMD parameters.")),Object(r.b)("p",null,"For our example of migrating a Rails app and a Rails Sidekiq app, I will have at the root of my project a ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile.qovery")," and a ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile-sidekiq.qovery"),"."),Object(r.b)("h3",{id:"test-your-dockerfile"},"Test your Dockerfile"),Object(r.b)(b.a,{mdxType:"Assumptions"},Object(r.b)("p",null,"You need to ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://docs.docker.com/get-docker/"}),"install Docker")," to test your Dockerfile")),Object(r.b)("p",null,"To test your Dockerfile we will locally our container. You just need to run the following commands:"),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,"Don't forget the ",Object(r.b)("inlineCode",{parentName:"p"},".")," (dot) at the end of the ",Object(r.b)("inlineCode",{parentName:"p"},"docker build")," command.")),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"docker build -f Dockerfile.qovery .\n")),Object(r.b)("p",null,"If everything goes well you should get the finale image ID at the end of the output."),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"[+] Building 19.0s (16/16) FINISHED\n => [internal] load build definition from Dockerfile 0.0s\n => => transferring dockerfile: 37B 0.0s\n => [internal] load .dockerignore 0.0s\n ...\n => [7/7] COPY . . 0.2s\n => exporting to image 0.0s\n => exporting layers 0.4s\n => writing image sha256:a0f90a6ec8bc4036a7b268479a0c0773ca324ba2de11fdef31309650743f4055 0.0s\n")),Object(r.b)("p",null,"To run your image you can run:"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"docker run a0f90a6ec8bc4036a7b268479a0c0773ca324ba2de11fdef31309650743f4055\n")),Object(r.b)("p",null,"If your app required a database to starts, then it can be normal that it fails to start. Otherwise, if your app is supposed to start and does not, then you will need to fix the issue and rebuild your app with ",Object(r.b)("inlineCode",{parentName:"p"},"docker build -f Dockerfile.qovery .")),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"This step is one of the most complex, but once you successfully build your application with Docker, your app will run anywhere (not only on AWS with Qovery).")),Object(r.b)("p",null,"Any error while building your container image? 2 solutions:"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},'Read the error message and try to understand from where the problem is coming from. You can "Google" the error if it is not related to your code.'),Object(r.b)("li",{parentName:"ol"},"Open a thread on ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"https://discuss.qovery.com/"}),"our forum")," if you don't find the answer there, we will be happy to assist you.")),Object(r.b)("h3",{id:"environment-variables-at-the-build-time"},"Environment variables at the build time"),Object(r.b)("p",null,"Does your app use some environment variables at the build time? Then you will need to modify your Dockerfile to includes the environment variables. Let's imagine your app uses the environment variable ",Object(r.b)("inlineCode",{parentName:"p"},"CONTENT_API_KEY"),", then you will need to add the following instructions in your Dockerfile:"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell",metastring:'title="Dockerfile with environment variables"',title:'"Dockerfile',with:!0,environment:!0,'variables"':!0}),"...\nARG CONTENT_API_KEY\nENV CONTENT_API_KEY $CONTENT_API_KEY\n...\n")),Object(r.b)("p",null,"The value of the ",Object(r.b)("inlineCode",{parentName:"p"},"CONTENT_API_KEY")," environment variable will be taken from the specified environment variables in Qovery."),Object(r.b)(l.a,{type:"success",mdxType:"Alert"},Object(r.b)("p",null,"Qovery injects Environment Variables and Secrets at the build and run time of your app.")),Object(r.b)("h3",{id:"add-your-dockerfile-to-git"},"Add your Dockerfile to Git"),Object(r.b)("p",null,"Now, add your new Dockerfile to git with the following commands:"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),'git add Dockerfile.qovery\ngit commit -m "Add Qovery Dockerfile"\ngit push origin\n')),Object(r.b)("h3",{id:"loop"},"Loop"),Object(r.b)("p",null,"If you have multiple applications to deploy, create a Dockerfile for each of them.")),Object(r.b)(i.a,{value:"buildpacks",mdxType:"TabItem"},Object(r.b)("p",null,Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://buildpacks.io/"}),"Buildpacks")," automatically detects the language and the framework your application is using. Buildpacks builds and runs your app. Here is the list of ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/application/#option-1-buildpacks"}),"supported languages and frameworks"),"."),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,"We do recommend using Docker to keep the full control of what's going on behind the scene. Buildpacks is a great technology but difficult to debug when something goes wrong. You can try deploying your apps on AWS with Qovery with Buildpacks, if you do not succeed, we do recommend switching for Docker.")),Object(r.b)("h3",{id:"limitations"},"Limitations"),Object(r.b)("p",null,"Here are some limitations due to our Buildpacks implementation:"),Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},"Qovery Buildpacks does not support Procfile with multiple commands at the moment."),Object(r.b)("li",{parentName:"ul"},"Qovery does not support custom Buildpacks.")),Object(r.b)("p",null,"Those limitations will be solved in the coming months."))),Object(r.b)("h2",{id:"2-create-resources-on-qovery"},"2. Create resources on Qovery"),Object(r.b)("h3",{id:"application"},"Application"),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"Are you a new Qovery user? Watch ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/getting-started/deploy-your-first-application/"}),"this tutorial")," to learn how to deploy your first app.")),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/9246ae68c68f42debc3d5183d2b4f7f8",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"Steps:"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},"Connect to the ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"https://start.qovery.com"}),"Qovery console"),"."),Object(r.b)("li",{parentName:"ol"},"Create your ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/organization/"}),"Organization")," and your ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/project/"}),"Project"),"."),Object(r.b)("li",{parentName:"ol"},"Create an environment with the name ",Object(r.b)("inlineCode",{parentName:"li"},"production")," (it can be changed after)."),Object(r.b)("li",{parentName:"ol"},"Create an application and give it a name (you can give the name of your repo if you have no idea)"),Object(r.b)("li",{parentName:"ol"},"Select your app repository from your GitHub, GitLab or Bitbucket."),Object(r.b)("li",{parentName:"ol"},"Select the branch you want to deploy."),Object(r.b)("li",{parentName:"ol"},"Select the Build mode for ",Object(r.b)("inlineCode",{parentName:"li"},"Buildpacks")," or ",Object(r.b)("inlineCode",{parentName:"li"},"Dockerfile")," according to what you want."),Object(r.b)("li",{parentName:"ol"},"Specify the local listening port of your application."),Object(r.b)("li",{parentName:"ol"},'Click on "create"')),Object(r.b)("p",null,"Congrats! Your application is created \ud83c\udf89"),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,'Your application is created but not deployed yet! You can configure the vCPU, Memory, Environment Variables... before deploying it. If you want to deploy it before finishing the configuration you can click on "Actions" > "Deploy".')),Object(r.b)("p",null,"If you deploy an app from a mono-repository, we have a must-read guide for you ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/advanced/monorepository/"}),"here"),"."),Object(r.b)("h3",{id:"database"},"Database"),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"Are you a new Qovery user? Watch ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/getting-started/create-a-database/"}),"this tutorial")," to learn how to deploy your database.")),Object(r.b)("p",null,"Here are the steps to deploy your database:"),Object(r.b)(b.a,{mdxType:"Assumptions"},Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},"You have created an application before"))),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/d7e10be0e5964f6799b158dc631bbbd1",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"Steps:"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},"Go to your ",Object(r.b)("inlineCode",{parentName:"li"},"production")," environment."),Object(r.b)("li",{parentName:"ol"},'Add your database by clicking on "Add" > "Database".'),Object(r.b)("li",{parentName:"ol"},"Select the database (PostgreSQL, MySQL, MongoDB, Redis..) and the version you want to deploy."),Object(r.b)("li",{parentName:"ol"},"Select ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/database/#general"}),"Managed or Container mode")," for your database."),Object(r.b)("li",{parentName:"ol"},"Select ",Object(r.b)("inlineCode",{parentName:"li"},"Public")," accessibility (set ",Object(r.b)("inlineCode",{parentName:"li"},"Private")," if you don't want to restore your data from an existing Heroku database).")),Object(r.b)("p",null,"Congrats! Your database is created as well \ud83c\udf89"),Object(r.b)("p",null,"If you use MongoDB Atlas, or an existing database on AWS that you want to connect to your application deployed by Qovery. Check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/aws-vpc-peering-with-qovery/"}),"our tutorial about VPC peering")," and how to securely connect to your existing database."),Object(r.b)("h2",{id:"3-configure-your-environment-variables-and-secrets"},"3. Configure your Environment Variables and Secrets"),Object(r.b)(l.a,{type:"success",mdxType:"Alert"},Object(r.b)("p",null,"Qovery supports Doppler integration - it's the easiest way to migrate your Environment Variables and Secrets from Heroku to Qovery. ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/integration/secret-manager/doppler/"}),"More info here"),".")),Object(r.b)("p",null,"Qovery makes the difference between an environment variable and a secret. Basically, a Secret is similar to an Environment Variable but the value is encrypted and can't be revealed. Both are injected as environment variables during the build and the run of your applications. ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment-variable/"}),"More info here")),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"I recommend reading our ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/getting-started/managing-environment-variables/"}),"Getting Started with Environment Variables")," guide.")),Object(r.b)("p",null,"To extract your environment variables from Heroku, we recommend using the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://devcenter.heroku.com/articles/heroku-cli"}),"Heroku CLI")," and exporting all the environment variables and secrets in an .env (dot env) file. Qovery supports the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/import-your-environment-variables-with-the-qovery-cli/"}),"import of a dot env file")," via the Qovery web interface and the Qovery CLI."),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,"If you use Buildpacks for one of your app AND you have indicated a local listening port of your application, you will need to add an environment variable ",Object(r.b)("inlineCode",{parentName:"p"},"PORT")," with the value of your port to make your application starting properly. Otherwise, Qovery will fail to deploy your app!")),Object(r.b)("p",null,Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://devcenter.heroku.com/articles/config-vars#view-current-config-var-values"}),"Export your environment variable via the Heroku CLI")," with the command:"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"# To install Heroku CLI: https://devcenter.heroku.com/articles/heroku-cli\nheroku config\n\nGREETINGS: hello world\nSTRIPE_API_KEY: xxx-yyy-zzz\nIS_PRODUCTION: true\n")),Object(r.b)("p",null,"Then you can create your environment variables via the web interface (watch the video below)"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/50899d7fa3d84a418f0db69f54f970d3",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"Or via the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/interface/cli/"}),"Qovery CLI"),":"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell",metastring:'title="Import Heroku environment variables with the Qovery CLI"',title:'"Import',Heroku:!0,environment:!0,variables:!0,with:!0,the:!0,Qovery:!0,'CLI"':!0}),"# auth yourself\nqovery auth\n\n# selection the app where you want to import your environment variables\nqovery context set\n\n# import your Heroku environment variables\nheroku config --app --json | \\\n qovery env parse --heroku-json > heroku.env && \\\n qovery env import heroku.env && \\\n rm heroku.env\n\nQovery: dot env file to import: 'heroku.env'\n? Do you want to import Environment Variables or Secrets? Environment Variables\n? What environment variables do you want to import? [Use arrows to move, space to select, to all, to none, type to filter]\n [x] GREETINGS=hello world\n [ ] STRIPE_API_KEY=xxx-yyy-zzz\n> [x] IS_PRODUCTION=true\n\nQovery: \u2705 Environment Variables successfully imported!\n")),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,"Import sensitive data (E.g. API keys, credentials...) as ",Object(r.b)("inlineCode",{parentName:"p"},"Secret")," and not ",Object(r.b)("inlineCode",{parentName:"p"},"Environment Variable"),".")),Object(r.b)("h3",{id:"connect-your-frontend-app-to-your-backend-app"},"Connect your frontend app to your backend app"),Object(r.b)("p",null,"To connect your frontend app your backend app we will create an ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment-variable/#alias-environment-variable"}),"environment variable alias"),"."),Object(r.b)("p",null,"Here is how to create a frontend app:"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/bafbbda93bd64d04afb3189bf4a1a201",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"And now how to connect your frontend app with your backend app:"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/f820925f2175465f9271b97ef414bb42",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"You can also take a look at ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/t/918"}),"this forum reply")," to learn how to do it."),Object(r.b)("h3",{id:"connect-your-backend-app-to-your-database"},"Connect your backend app to your database"),Object(r.b)("p",null,"Same as connecting your frontend app to your backend app, you can create an environment variable alias ",Object(r.b)("inlineCode",{parentName:"p"},"DATABASE_URL")," for the ",Object(r.b)("em",{parentName:"p"},"built-in")," secret finishing with ",Object(r.b)("inlineCode",{parentName:"p"},"_DATABASE_URL_INTERNAL"),"."),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,"Create an alias on ",Object(r.b)("inlineCode",{parentName:"p"},"_DATABASE_URL_INTERNAL")," and not ",Object(r.b)("inlineCode",{parentName:"p"},"_DATABASE_URL"))),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/59f8368eb3c14796a807c7e39e9c0ab0",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("h2",{id:"4-copy-data-from-your-heroku-databases-to-your-aws-databases"},"4. Copy data from your Heroku databases to your AWS databases"),Object(r.b)("p",null,Object(r.b)("em",{parentName:"p"},"Coming soon with ",Object(r.b)("a",Object(o.a)({parentName:"em"},{href:"https://www.replibyte.com"}),"Replibyte"))),Object(r.b)("h2",{id:"5-deploy-your-apps"},"5. Deploy your apps!"),Object(r.b)("p",null,"We are finally ready to deploy my applications on AWS!"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/0589d2f2aa4149edb605dc23f4efd23d",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"Watch the final result \ud83d\ude0e"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/da31c21f9c104eae9270e4c4db59055e",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("h2",{id:"faq-by-heroku-users"},"FAQ by Heroku users"),Object(r.b)("h3",{id:"how-to-create-a-custom-domain"},"How to create a custom domain?"),Object(r.b)("p",null,"Check out the documentation on ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/getting-started/setting-custom-domain/"}),"how to configure your custom domain"),"."),Object(r.b)("h3",{id:"how-to-monitor-my-apps"},"How to monitor my apps?"),Object(r.b)("p",null,"We do recommend using ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://www.datadoghq.com"}),"Datadog")," or any other monitoring products for monitoring your apps deployed by Qovery. Check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/kubernetes-observability-and-monitoring-with-datadog/"}),"our tutorial on how to install Datadog"),"."),Object(r.b)("h3",{id:"do-you-have-heroku-review-app-equivalent"},'Do you have Heroku "Review App" equivalent?'),Object(r.b)("p",null,"Yes, it's what we call ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment/#preview-environment"}),"Preview Environment")),Object(r.b)("h3",{id:"how-to-rollback"},"How to rollback?"),Object(r.b)("p",null,"Check out the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/deployment-actions/#deploy-other-version"}),"app rollback documentation")),Object(r.b)("h3",{id:"how-auto-scaling-works"},"How auto-scaling works?"),Object(r.b)("p",null,"Check out the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/application/#auto-scaling"}),"app auto-scaling documentation")),Object(r.b)("h3",{id:"how-to-manage-database-migration"},"How to manage database migration?"),Object(r.b)("p",null,"Check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/t/951"}),"our forum reply")),Object(r.b)("h3",{id:"is-it-possible-to-get-a-shell--connect-to-my-app"},"Is it possible to get a shell / connect to my app?"),Object(r.b)("p",null,"Absolutely, you can connect directly to your application with a shell by clicking on the Qovery cloud shell button (1):"),Object(r.b)("p",{align:"center"},Object(r.b)("img",{src:"/img/qovery_cloud_shell.png",alt:"Qovery Cloud Shell"})),Object(r.b)("p",null,"Then you just have to select the pod (2) and the container (3)."),Object(r.b)("p",null,"You can also check out our ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/interface/cli/#shell"}),"CLI")," and the ",Object(r.b)("inlineCode",{parentName:"p"},"qovery shell")," command."),Object(r.b)("h3",{id:"can-i-use-terraform-and-infrastructure-as-code"},"Can I use Terraform and Infrastructure as Code?"),Object(r.b)("p",null,"Absolutely, we have a ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/integration/terraform-provider/"}),"Qovery Terraform provider")," available."),Object(r.b)("h3",{id:"how-can-i-connect-my-app-to-mongodb-atlas"},"How can I connect my app to MongoDB Atlas?"),Object(r.b)("p",null,"If you use MongoDB Atlas check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/aws-vpc-peering-with-qovery/"}),"our tutorial about VPC peering")," and how to securely connect to your existing MongoDB Atlas database."),Object(r.b)("h3",{id:"how-can-i-connect-my-app-to-an-aws-service-not-managed-by-qovery"},"How can I connect my app to an AWS service not managed by Qovery?"),Object(r.b)("p",null,"If you want to connect your app to an AWS service not managed by Qovery, check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/aws-vpc-peering-with-qovery/"}),"our tutorial about VPC peering")," and how to securely connect to this AWS service."),Object(r.b)("hr",null),Object(r.b)("p",null,"If you have a common question about Qovery, we have a more general ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/useful-resources/faq/"}),"FAQ section")," available."),Object(r.b)("h2",{id:"wrapping-up"},"Wrapping up"),Object(r.b)("p",null,"Congrats! You have migrated from Heroku to AWS. Feel free to check out our ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/"}),"forum")," and open a thread if you have any question."))}m.isMDXComponent=!0},456:function(e,t,a){"use strict";a(458);var o=a(0),n=a.n(o),r=a(455),l=a.n(r);a(132);t.a=function(e){var t=e.children,a=e.classNames,o=e.fill,r=e.icon,i=e.type,c=null;switch(i){case"danger":c="alert-triangle";break;case"success":c="check-circle";break;case"warning":c="alert-triangle";break;default:c="info"}return n.a.createElement("div",{className:l()(a,"alert","alert--"+i,{"alert--fill":o,"alert--icon":!1!==r}),role:"alert"},!1!==r&&n.a.createElement("i",{className:l()("feather","icon-"+(r||c))}),t)}},460:function(e,t,a){var o=a(28).f,n=Function.prototype,r=/^\s*function ([^ (]*)/;"name"in n||a(10)&&o(n,"name",{configurable:!0,get:function(){try{return(""+this).match(r)[1]}catch(e){return""}}})},461:function(e,t,a){"use strict";a(460);var o=a(0),n=a.n(o),r=a(456);t.a=function(e){var t=e.children,a=e.name;return n.a.createElement(r.a,{type:"info",fill:!0,icon:!1,rounded:!0,className:"list--icons list--icons--arrow list--tight list--indent margin-bottom--lg"},n.a.createElement("p",{class:"text--lg margin-bottom--sm",style:{marginTop:"-0.25em"}},"Before you begin, this ",a||"page"," assumes the following:"),t)}},469:function(e,t,a){"use strict";var o=a(1),n=(a(473),a(470),a(52),a(29),a(22),a(21),a(0)),r=a.n(n),l=a(477),i=a(455),c=a.n(i),b=a(463),u=a.n(b),s=a(476),p=37,d=39;function m(e){var t=e.block,a=e.centered,o=e.changeSelectedValue,n=e.className,l=e.handleKeydown,i=e.style,b=e.values,u=e.selectedValue,s=e.tabRefs;return r.a.createElement("div",{className:a?"tabs--centered":null},r.a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:c()("tabs",n,{"tabs--block":t}),style:i},b.map((function(e){var t=e.value,a=e.label;return r.a.createElement("li",{role:"tab",tabIndex:"0","aria-selected":u===t,className:c()("tab-item",{"tab-item--active":u===t}),key:t,ref:function(e){return s.push(e)},onKeyDown:function(e){return l(s,e.target,e)},onFocus:function(){return o(t)},onClick:function(){return o(t)}},a)}))))}function h(e){var t=e.placeholder,a=e.selectedValue,o=e.changeSelectedValue,n=e.size,i=e.values,c=i;if(c[0].group){var b=_.groupBy(c,"group");c=Object.keys(b).map((function(e){return{label:e,options:b[e]}}))}return r.a.createElement(l.a,{className:"react-select-container react-select--"+n,classNamePrefix:"react-select",options:c,isClearable:a,placeholder:t,value:i.find((function(e){return e.value==a})),onChange:function(e){return o(e?e.value:null)}})}t.a=function(e){e.block,e.centered;var t=e.children,a=e.defaultValue,l=e.groupId,i=e.label,c=e.placeholder,b=e.select,y=e.size,f=(e.style,e.values),O=e.urlKey,j=Object(s.a)(),g=j.tabGroupChoices,v=j.setTabGroupChoices,w=Object(n.useState)(a),k=w[0],N=w[1];if(null!=l){var T=g[l];null!=T&&T!==k&&N(T)}var C=function(e){N(e),null!=l&&v(l,e)},D=[],A=function(e,t,a){switch(a.keyCode){case d:!function(e,t){var a=e.indexOf(t)+1;e[a]?e[a].focus():e[0].focus()}(e,t);break;case p:!function(e,t){var a=e.indexOf(t)-1;e[a]?e[a].focus():e[e.length-1].focus()}(e,t)}};return Object(n.useEffect)((function(){if("undefined"!=typeof window&&window.location&&O){var e=u.a.parse(window.location.search);e[O]&&N(e[O])}}),[]),r.a.createElement(r.a.Fragment,null,r.a.createElement("div",{className:"margin-bottom--"+(y||"md")},i&&r.a.createElement("div",{className:"margin-vert--sm"},i),f.length>1&&(b?r.a.createElement(h,Object(o.a)({changeSelectedValue:C,handleKeydown:A,placeholder:c,selectedValue:k,size:y,tabRefs:D},e)):r.a.createElement(m,Object(o.a)({changeSelectedValue:C,handleKeydown:A,selectedValue:k,tabRefs:D},e)))),n.Children.toArray(t).filter((function(e){return e.props.value===k}))[0])}},471:function(e,t,a){"use strict";var o=a(0),n=a.n(o);t.a=function(e){return n.a.createElement(n.a.Fragment,null,e.children)}}}]); \ No newline at end of file diff --git a/404.html b/404.html index 9910ec0c07..ceead6f16a 100644 --- a/404.html +++ b/404.html @@ -26,7 +26,7 @@ - + @@ -39,7 +39,7 @@ - + diff --git a/6ce627d6.232caa44.js b/6ce627d6.232caa44.js new file mode 100644 index 0000000000..466040d676 --- /dev/null +++ b/6ce627d6.232caa44.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[132],{283:function(e,t,a){"use strict";a.r(t),a.d(t,"frontMatter",(function(){return s})),a.d(t,"metadata",(function(){return u})),a.d(t,"rightToc",(function(){return p})),a.d(t,"default",(function(){return m}));var o=a(1),n=a(9),r=(a(0),a(457)),l=a(456),i=a(471),c=a(469),b=a(461),s={last_modified_on:"2024-09-18",$schema:"/.meta/.schemas/guides.json",title:"Migrate your application from Heroku to AWS",description:"Guide on how to migrate all your applications from Heroku to AWS with your databases",author_github:"https://github.com/evoxmusic",tags:["type: tutorial","installation_guide: aws"],hide_pagination:!0},u={categories:[{name:"tutorial",title:"Tutorial",description:"Additional step-by-step resources to leverage even more Qovery",permalink:"/guides/tutorial"}],coverLabel:"Migrate your application from Heroku to AWS",description:"Guide on how to migrate all your applications from Heroku to AWS with your databases",permalink:"/guides/tutorial/migrate-your-application-from-heroku-to-aws",readingTime:"12 min read",source:"@site/guides/tutorial/migrate-your-application-from-heroku-to-aws.md",tags:[{label:"type: tutorial",permalink:"/guides/tags/type-tutorial"},{label:"installation_guide: aws",permalink:"/guides/tags/installation-guide-aws"}],title:"Migrate your application from Heroku to AWS",truncated:!1,prevItem:{title:"Microservices",permalink:"/guides/advanced/microservices"},nextItem:{title:"Migration",permalink:"/guides/advanced/migration"}},p=[{value:"Migration Steps",id:"migration-steps",children:[]},{value:"1. Create your Dockerfile",id:"1-create-your-dockerfile",children:[{value:"Test your Dockerfile",id:"test-your-dockerfile",children:[]},{value:"Environment variables at the build time",id:"environment-variables-at-the-build-time",children:[]},{value:"Add your Dockerfile to Git",id:"add-your-dockerfile-to-git",children:[]},{value:"Loop",id:"loop",children:[]}]},{value:"2. Create resources on Qovery",id:"2-create-resources-on-qovery",children:[{value:"Application",id:"application",children:[]},{value:"Database",id:"database",children:[]}]},{value:"3. Configure your Environment Variables and Secrets",id:"3-configure-your-environment-variables-and-secrets",children:[{value:"Connect your frontend app to your backend app",id:"connect-your-frontend-app-to-your-backend-app",children:[]},{value:"Connect your backend app to your database",id:"connect-your-backend-app-to-your-database",children:[]}]},{value:"4. Copy data from your Heroku databases to your AWS databases",id:"4-copy-data-from-your-heroku-databases-to-your-aws-databases",children:[]},{value:"5. Deploy your apps!",id:"5-deploy-your-apps",children:[]},{value:"FAQ by Heroku users",id:"faq-by-heroku-users",children:[{value:"How to create a custom domain?",id:"how-to-create-a-custom-domain",children:[]},{value:"How to monitor my apps?",id:"how-to-monitor-my-apps",children:[]},{value:"Do you have Heroku "Review App" equivalent?",id:"do-you-have-heroku-review-app-equivalent",children:[]},{value:"How to rollback?",id:"how-to-rollback",children:[]},{value:"How auto-scaling works?",id:"how-auto-scaling-works",children:[]},{value:"How to manage database migration?",id:"how-to-manage-database-migration",children:[]},{value:"Is it possible to get a shell / connect to my app?",id:"is-it-possible-to-get-a-shell--connect-to-my-app",children:[]},{value:"Can I use Terraform and Infrastructure as Code?",id:"can-i-use-terraform-and-infrastructure-as-code",children:[]},{value:"How can I connect my app to MongoDB Atlas?",id:"how-can-i-connect-my-app-to-mongodb-atlas",children:[]},{value:"How can I connect my app to an AWS service not managed by Qovery?",id:"how-can-i-connect-my-app-to-an-aws-service-not-managed-by-qovery",children:[]}]},{value:"Wrapping up",id:"wrapping-up",children:[]}],d={rightToc:p};function m(e){var t=e.components,a=Object(n.a)(e,["components"]);return Object(r.b)("wrapper",Object(o.a)({},d,a,{components:t,mdxType:"MDXLayout"}),Object(r.b)(l.a,{type:"success",mdxType:"Alert"},Object(r.b)("p",null,"This guide also work for migrating your application from Heroku to GCP, Azure, Scaleway and ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/getting-started/install-qovery/"}),"all cloud provider")," supported by Qovery.")),Object(r.b)("p",null,"This guide describes how to migrate your application running on Heroku to AWS with Qovery. It covers all required steps you need to take to deploy your application on AWS and transfer your data from Heroku Postgres to the database managed by AWS via Qovery."),Object(r.b)("blockquote",null,Object(r.b)("p",{parentName:"blockquote"},"We have created a new AI agent capable of migrating from Heroku to AWS, GCP, Scaleway or Azure in a few clicks. Check our ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://www.qovery.com/blog/open-source-devops-ai-agent--effortless-migration-from-heroku-to-aws/?utm_campaign=migration-ai-agent-email"}),"announcement here"),".")),Object(r.b)(b.a,{name:"guide",mdxType:"Assumptions"},Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},"You are familiar with Heroku basics, have a Heroku account and access to Heroku CLI"),Object(r.b)("li",{parentName:"ul"},"You have ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"https://start.qovery.com"}),"sign in on Qovery")),Object(r.b)("li",{parentName:"ul"},"You have ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"/guides/installation-guide/guide-amazon-web-services/"}),"set up your AWS account")," with Qovery"))),Object(r.b)("h2",{id:"migration-steps"},"Migration Steps"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#1-create-your-dockerfile"}),"Create your Dockerfile")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#2-create-resources-on-qovery"}),"Create resources on Qovery")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#3-configure-your-environment-variables-and-secrets"}),"Configure Environment Variables and Secrets")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#4-copy-data-from-your-heroku-databases-to-your-aws-databases"}),"Copy data from your Heroku databases to your AWS databases")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#5-deploy-your-apps-"}),"Deploy your apps")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#faq-by-heroku-users"}),"FAQ by Heroku users"))),Object(r.b)("h2",{id:"1-create-your-dockerfile"},"1. Create your Dockerfile"),Object(r.b)("p",null,"Qovery supports two ways to build and run your application coming from Heroku:"),Object(r.b)("blockquote",null,Object(r.b)("p",{parentName:"blockquote"},"Are you familiar with Dockerfile? If not, I do recommend reading ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/how-to-write-a-dockerfile/"}),"this article"),".")),Object(r.b)("p",null,"Here we will create our Dockerfiles to build and run our applications. Qovery will handle the build and the run of your applications, but need to have at least a Dockerfile to do it."),Object(r.b)("h4",{id:"find-dockerfile-template"},"Find Dockerfile template"),Object(r.b)("p",null,"Pick one Dockerfile template according to the programming language or framework you are using for your app:"),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"Your framework or language is missing? Open a thread on ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/"}),"our forum"),", and we will provide you one.")),Object(r.b)(c.a,{centered:!1,className:"square",defaultValue:"rails",select:!1,size:null,values:[{group:"Files",label:"Rails",value:"rails"},{group:"Files",label:"NodeJS",value:"nodejs"},{group:"Files",label:"React",value:"react"},{group:"Files",label:"VueJS",value:"vuejs"},{group:"Files",label:"NextJS",value:"nextjs"},{group:"Files",label:"Golang",value:"golang"},{group:"Files",label:"Flask",value:"flask"},{group:"Files",label:"Django",value:"django"},{group:"Files",label:"Laravel",value:"laravel"},{group:"Files",label:"Symfony",value:"symfony"},{group:"Files",label:"Spring",value:"spring"},{group:"Files",label:"Rust",value:"rust"}],mdxType:"Tabs"},Object(r.b)(i.a,{value:"rails",mdxType:"TabItem"},Object(r.b)("p",null,"Here is the Dockerfile for your Rails application listening on the PORT 3000"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell",metastring:'title="Dockerfile"',title:'"Dockerfile"'}),'# syntax=docker/dockerfile:1\nFROM ruby:2.7\nRUN apt-get update -qq && apt-get install -y nodejs postgresql-client\nWORKDIR /myapp\nCOPY Gemfile Gemfile\nCOPY Gemfile.lock Gemfile.lock\nRUN bundle install\n\nCOPY . .\n\nEXPOSE 3000\n\n# Configure the main process to run when running the image\nCMD ["rails", "server", "-b", "0.0.0.0", "-p", "3000"]\n')),Object(r.b)("details",null,Object(r.b)("summary",null,"Dockerfile for Sidekiq"),Object(r.b)("p",null,"Here is the Dockerfile for your Rails app running as a worker mode with Sidekiq."),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"There is no listening port since it is consuming resources from a queuing system (E.g. Redis)")),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell",metastring:'title="Dockerfile for Sidekiq"',title:'"Dockerfile',for:!0,'Sidekiq"':!0}),'# syntax=docker/dockerfile:1\nFROM ruby:2.7\nRUN apt-get update -qq && apt-get install -y nodejs postgresql-client # add mysql client if you need to\nWORKDIR /myapp\nCOPY Gemfile Gemfile\nCOPY Gemfile.lock Gemfile.lock\nRUN bundle install\n\nCOPY . .\n\nCMD ["bundle", "exec", "sidekiq"]\n')))),Object(r.b)(i.a,{value:"nodejs",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"react",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"vuejs",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"nextjs",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"golang",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"flask",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"django",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"laravel",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"symfony",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"spring",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"rust",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n")))),Object(r.b)("h4",{id:"copy-template"},"Copy template"),Object(r.b)("p",null,"Copy your Dockerfile at the root of your project. By convention, you can name your file ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile"),". If you already have a Dockerfile, feel free to name it ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile.qovery"),". If you are using multiple Dockerfile for Qovery, feel free to give a name like ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile-sidekiq.qovery"),"."),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"Read ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/t/904"}),"this forum post")," to know how to use the same Dockerfile with different CMD parameters.")),Object(r.b)("p",null,"For our example of migrating a Rails app and a Rails Sidekiq app, I will have at the root of my project a ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile.qovery")," and a ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile-sidekiq.qovery"),"."),Object(r.b)("h3",{id:"test-your-dockerfile"},"Test your Dockerfile"),Object(r.b)(b.a,{mdxType:"Assumptions"},Object(r.b)("p",null,"You need to ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://docs.docker.com/get-docker/"}),"install Docker")," to test your Dockerfile")),Object(r.b)("p",null,"To test your Dockerfile we will locally our container. You just need to run the following commands:"),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,"Don't forget the ",Object(r.b)("inlineCode",{parentName:"p"},".")," (dot) at the end of the ",Object(r.b)("inlineCode",{parentName:"p"},"docker build")," command.")),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"docker build -f Dockerfile.qovery .\n")),Object(r.b)("p",null,"If everything goes well you should get the finale image ID at the end of the output."),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"[+] Building 19.0s (16/16) FINISHED\n => [internal] load build definition from Dockerfile 0.0s\n => => transferring dockerfile: 37B 0.0s\n => [internal] load .dockerignore 0.0s\n ...\n => [7/7] COPY . . 0.2s\n => exporting to image 0.0s\n => exporting layers 0.4s\n => writing image sha256:a0f90a6ec8bc4036a7b268479a0c0773ca324ba2de11fdef31309650743f4055 0.0s\n")),Object(r.b)("p",null,"To run your image you can run:"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"docker run a0f90a6ec8bc4036a7b268479a0c0773ca324ba2de11fdef31309650743f4055\n")),Object(r.b)("p",null,"If your app required a database to starts, then it can be normal that it fails to start. Otherwise, if your app is supposed to start and does not, then you will need to fix the issue and rebuild your app with ",Object(r.b)("inlineCode",{parentName:"p"},"docker build -f Dockerfile.qovery .")),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"This step is one of the most complex, but once you successfully build your application with Docker, your app will run anywhere (not only on AWS with Qovery).")),Object(r.b)("p",null,"Any error while building your container image? 2 solutions:"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},'Read the error message and try to understand from where the problem is coming from. You can "Google" the error if it is not related to your code.'),Object(r.b)("li",{parentName:"ol"},"Open a thread on ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"https://discuss.qovery.com/"}),"our forum")," if you don't find the answer there, we will be happy to assist you.")),Object(r.b)("h3",{id:"environment-variables-at-the-build-time"},"Environment variables at the build time"),Object(r.b)("p",null,"Does your app use some environment variables at the build time? Then you will need to modify your Dockerfile to includes the environment variables. Let's imagine your app uses the environment variable ",Object(r.b)("inlineCode",{parentName:"p"},"CONTENT_API_KEY"),", then you will need to add the following instructions in your Dockerfile:"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell",metastring:'title="Dockerfile with environment variables"',title:'"Dockerfile',with:!0,environment:!0,'variables"':!0}),"...\nARG CONTENT_API_KEY\nENV CONTENT_API_KEY $CONTENT_API_KEY\n...\n")),Object(r.b)("p",null,"The value of the ",Object(r.b)("inlineCode",{parentName:"p"},"CONTENT_API_KEY")," environment variable will be taken from the specified environment variables in Qovery."),Object(r.b)(l.a,{type:"success",mdxType:"Alert"},Object(r.b)("p",null,"Qovery injects Environment Variables and Secrets at the build and run time of your app.")),Object(r.b)("h3",{id:"add-your-dockerfile-to-git"},"Add your Dockerfile to Git"),Object(r.b)("p",null,"Now, add your new Dockerfile to git with the following commands:"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),'git add Dockerfile.qovery\ngit commit -m "Add Qovery Dockerfile"\ngit push origin\n')),Object(r.b)("h3",{id:"loop"},"Loop"),Object(r.b)("p",null,"If you have multiple applications to deploy, create a Dockerfile for each of them."),Object(r.b)("h2",{id:"2-create-resources-on-qovery"},"2. Create resources on Qovery"),Object(r.b)("h3",{id:"application"},"Application"),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"Are you a new Qovery user? Watch ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/getting-started/deploy-your-first-application/"}),"this tutorial")," to learn how to deploy your first app.")),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/9246ae68c68f42debc3d5183d2b4f7f8",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"Steps:"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},"Connect to the ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"https://start.qovery.com"}),"Qovery console"),"."),Object(r.b)("li",{parentName:"ol"},"Create your ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/organization/"}),"Organization")," and your ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/project/"}),"Project"),"."),Object(r.b)("li",{parentName:"ol"},"Create an environment with the name ",Object(r.b)("inlineCode",{parentName:"li"},"production")," (it can be changed after)."),Object(r.b)("li",{parentName:"ol"},"Create an application and give it a name (you can give the name of your repo if you have no idea)"),Object(r.b)("li",{parentName:"ol"},"Select your app repository from your GitHub, GitLab or Bitbucket."),Object(r.b)("li",{parentName:"ol"},"Select the branch you want to deploy."),Object(r.b)("li",{parentName:"ol"},"Specify the local listening port of your application."),Object(r.b)("li",{parentName:"ol"},'Click on "create"')),Object(r.b)("p",null,"Congrats! Your application is created \ud83c\udf89"),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,'Your application is created but not deployed yet! You can configure the vCPU, Memory, Environment Variables... before deploying it. If you want to deploy it before finishing the configuration you can click on "Actions" > "Deploy".')),Object(r.b)("p",null,"If you deploy an app from a mono-repository, we have a must-read guide for you ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/advanced/monorepository/"}),"here"),"."),Object(r.b)("h3",{id:"database"},"Database"),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"Are you a new Qovery user? Watch ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/getting-started/create-a-database/"}),"this tutorial")," to learn how to deploy your database.")),Object(r.b)("p",null,"Here are the steps to deploy your database:"),Object(r.b)(b.a,{mdxType:"Assumptions"},Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},"You have created an application before"))),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/d7e10be0e5964f6799b158dc631bbbd1",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"Steps:"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},"Go to your ",Object(r.b)("inlineCode",{parentName:"li"},"production")," environment."),Object(r.b)("li",{parentName:"ol"},'Add your database by clicking on "Add" > "Database".'),Object(r.b)("li",{parentName:"ol"},"Select the database (PostgreSQL, MySQL, MongoDB, Redis..) and the version you want to deploy."),Object(r.b)("li",{parentName:"ol"},"Select ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/database/#general"}),"Managed or Container mode")," for your database."),Object(r.b)("li",{parentName:"ol"},"Select ",Object(r.b)("inlineCode",{parentName:"li"},"Public")," accessibility (set ",Object(r.b)("inlineCode",{parentName:"li"},"Private")," if you don't want to restore your data from an existing Heroku database).")),Object(r.b)("p",null,"Congrats! Your database is created as well \ud83c\udf89"),Object(r.b)("p",null,"If you use MongoDB Atlas, or an existing database on AWS that you want to connect to your application deployed by Qovery. Check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/aws-vpc-peering-with-qovery/"}),"our tutorial about VPC peering")," and how to securely connect to your existing database."),Object(r.b)("h2",{id:"3-configure-your-environment-variables-and-secrets"},"3. Configure your Environment Variables and Secrets"),Object(r.b)(l.a,{type:"success",mdxType:"Alert"},Object(r.b)("p",null,"Qovery supports Doppler integration - it's the easiest way to migrate your Environment Variables and Secrets from Heroku to Qovery. ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/integration/secret-manager/doppler/"}),"More info here"),".")),Object(r.b)("p",null,"Qovery makes the difference between an environment variable and a secret. Basically, a Secret is similar to an Environment Variable but the value is encrypted and can't be revealed. Both are injected as environment variables during the build and the run of your applications. ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment-variable/"}),"More info here")),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"I recommend reading our ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/getting-started/managing-environment-variables/"}),"Getting Started with Environment Variables")," guide.")),Object(r.b)("p",null,"To extract your environment variables from Heroku, we recommend using the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://devcenter.heroku.com/articles/heroku-cli"}),"Heroku CLI")," and exporting all the environment variables and secrets in an .env (dot env) file. Qovery supports the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/import-your-environment-variables-with-the-qovery-cli/"}),"import of a dot env file")," via the Qovery web interface and the Qovery CLI."),Object(r.b)("p",null,Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://devcenter.heroku.com/articles/config-vars#view-current-config-var-values"}),"Export your environment variable via the Heroku CLI")," with the command:"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"# To install Heroku CLI: https://devcenter.heroku.com/articles/heroku-cli\nheroku config\n\nGREETINGS: hello world\nSTRIPE_API_KEY: xxx-yyy-zzz\nIS_PRODUCTION: true\n")),Object(r.b)("p",null,"Then you can create your environment variables via the web interface (watch the video below)"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/50899d7fa3d84a418f0db69f54f970d3",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"Or via the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/interface/cli/"}),"Qovery CLI"),":"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell",metastring:'title="Import Heroku environment variables with the Qovery CLI"',title:'"Import',Heroku:!0,environment:!0,variables:!0,with:!0,the:!0,Qovery:!0,'CLI"':!0}),"# auth yourself\nqovery auth\n\n# selection the app where you want to import your environment variables\nqovery context set\n\n# import your Heroku environment variables\nheroku config --app --json | \\\n qovery env parse --heroku-json > heroku.env && \\\n qovery env import heroku.env && \\\n rm heroku.env\n\nQovery: dot env file to import: 'heroku.env'\n? Do you want to import Environment Variables or Secrets? Environment Variables\n? What environment variables do you want to import? [Use arrows to move, space to select, to all, to none, type to filter]\n [x] GREETINGS=hello world\n [ ] STRIPE_API_KEY=xxx-yyy-zzz\n> [x] IS_PRODUCTION=true\n\nQovery: \u2705 Environment Variables successfully imported!\n")),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,"Import sensitive data (E.g. API keys, credentials...) as ",Object(r.b)("inlineCode",{parentName:"p"},"Secret")," and not ",Object(r.b)("inlineCode",{parentName:"p"},"Environment Variable"),".")),Object(r.b)("h3",{id:"connect-your-frontend-app-to-your-backend-app"},"Connect your frontend app to your backend app"),Object(r.b)("p",null,"To connect your frontend app your backend app we will create an ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment-variable/#alias-environment-variable"}),"environment variable alias"),"."),Object(r.b)("p",null,"Here is how to create a frontend app:"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/bafbbda93bd64d04afb3189bf4a1a201",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"And now how to connect your frontend app with your backend app:"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/f820925f2175465f9271b97ef414bb42",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"You can also take a look at ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/t/918"}),"this forum reply")," to learn how to do it."),Object(r.b)("h3",{id:"connect-your-backend-app-to-your-database"},"Connect your backend app to your database"),Object(r.b)("p",null,"Same as connecting your frontend app to your backend app, you can create an environment variable alias ",Object(r.b)("inlineCode",{parentName:"p"},"DATABASE_URL")," for the ",Object(r.b)("em",{parentName:"p"},"built-in")," secret finishing with ",Object(r.b)("inlineCode",{parentName:"p"},"_DATABASE_URL_INTERNAL"),"."),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,"Create an alias on ",Object(r.b)("inlineCode",{parentName:"p"},"_DATABASE_URL_INTERNAL")," and not ",Object(r.b)("inlineCode",{parentName:"p"},"_DATABASE_URL"))),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/59f8368eb3c14796a807c7e39e9c0ab0",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("h2",{id:"4-copy-data-from-your-heroku-databases-to-your-aws-databases"},"4. Copy data from your Heroku databases to your AWS databases"),Object(r.b)("p",null,Object(r.b)("em",{parentName:"p"},"Coming soon with ",Object(r.b)("a",Object(o.a)({parentName:"em"},{href:"https://www.replibyte.com"}),"Replibyte"))),Object(r.b)("h2",{id:"5-deploy-your-apps"},"5. Deploy your apps!"),Object(r.b)("p",null,"We are finally ready to deploy my applications on AWS!"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/0589d2f2aa4149edb605dc23f4efd23d",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"Watch the final result \ud83d\ude0e"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/da31c21f9c104eae9270e4c4db59055e",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("h2",{id:"faq-by-heroku-users"},"FAQ by Heroku users"),Object(r.b)("h3",{id:"how-to-create-a-custom-domain"},"How to create a custom domain?"),Object(r.b)("p",null,"Check out the documentation on ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/getting-started/setting-custom-domain/"}),"how to configure your custom domain"),"."),Object(r.b)("h3",{id:"how-to-monitor-my-apps"},"How to monitor my apps?"),Object(r.b)("p",null,"We do recommend using ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://www.datadoghq.com"}),"Datadog")," or any other monitoring products for monitoring your apps deployed by Qovery. Check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/kubernetes-observability-and-monitoring-with-datadog/"}),"our tutorial on how to install Datadog"),"."),Object(r.b)("h3",{id:"do-you-have-heroku-review-app-equivalent"},'Do you have Heroku "Review App" equivalent?'),Object(r.b)("p",null,"Yes, it's what we call ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment/#preview-environment"}),"Preview Environment")),Object(r.b)("h3",{id:"how-to-rollback"},"How to rollback?"),Object(r.b)("p",null,"Check out the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/deployment-actions/#deploy-other-version"}),"app rollback documentation")),Object(r.b)("h3",{id:"how-auto-scaling-works"},"How auto-scaling works?"),Object(r.b)("p",null,"Check out the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/application/#auto-scaling"}),"app auto-scaling documentation")),Object(r.b)("h3",{id:"how-to-manage-database-migration"},"How to manage database migration?"),Object(r.b)("p",null,"Check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/t/951"}),"our forum reply")),Object(r.b)("h3",{id:"is-it-possible-to-get-a-shell--connect-to-my-app"},"Is it possible to get a shell / connect to my app?"),Object(r.b)("p",null,"Absolutely, you can connect directly to your application with a shell by clicking on the Qovery cloud shell button (1):"),Object(r.b)("p",{align:"center"},Object(r.b)("img",{src:"/img/qovery_cloud_shell.png",alt:"Qovery Cloud Shell"})),Object(r.b)("p",null,"Then you just have to select the pod (2) and the container (3)."),Object(r.b)("p",null,"You can also check out our ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/interface/cli/#shell"}),"CLI")," and the ",Object(r.b)("inlineCode",{parentName:"p"},"qovery shell")," command."),Object(r.b)("h3",{id:"can-i-use-terraform-and-infrastructure-as-code"},"Can I use Terraform and Infrastructure as Code?"),Object(r.b)("p",null,"Absolutely, we have a ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/integration/terraform-provider/"}),"Qovery Terraform provider")," available."),Object(r.b)("h3",{id:"how-can-i-connect-my-app-to-mongodb-atlas"},"How can I connect my app to MongoDB Atlas?"),Object(r.b)("p",null,"If you use MongoDB Atlas check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/aws-vpc-peering-with-qovery/"}),"our tutorial about VPC peering")," and how to securely connect to your existing MongoDB Atlas database."),Object(r.b)("h3",{id:"how-can-i-connect-my-app-to-an-aws-service-not-managed-by-qovery"},"How can I connect my app to an AWS service not managed by Qovery?"),Object(r.b)("p",null,"If you want to connect your app to an AWS service not managed by Qovery, check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/aws-vpc-peering-with-qovery/"}),"our tutorial about VPC peering")," and how to securely connect to this AWS service."),Object(r.b)("hr",null),Object(r.b)("p",null,"If you have a common question about Qovery, we have a more general ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/useful-resources/faq/"}),"FAQ section")," available."),Object(r.b)("h2",{id:"wrapping-up"},"Wrapping up"),Object(r.b)("p",null,"Congrats! You have migrated from Heroku to AWS. Feel free to check out our ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/"}),"forum")," and open a thread if you have any question."))}m.isMDXComponent=!0},456:function(e,t,a){"use strict";a(458);var o=a(0),n=a.n(o),r=a(455),l=a.n(r);a(132);t.a=function(e){var t=e.children,a=e.classNames,o=e.fill,r=e.icon,i=e.type,c=null;switch(i){case"danger":c="alert-triangle";break;case"success":c="check-circle";break;case"warning":c="alert-triangle";break;default:c="info"}return n.a.createElement("div",{className:l()(a,"alert","alert--"+i,{"alert--fill":o,"alert--icon":!1!==r}),role:"alert"},!1!==r&&n.a.createElement("i",{className:l()("feather","icon-"+(r||c))}),t)}},460:function(e,t,a){var o=a(28).f,n=Function.prototype,r=/^\s*function ([^ (]*)/;"name"in n||a(10)&&o(n,"name",{configurable:!0,get:function(){try{return(""+this).match(r)[1]}catch(e){return""}}})},461:function(e,t,a){"use strict";a(460);var o=a(0),n=a.n(o),r=a(456);t.a=function(e){var t=e.children,a=e.name;return n.a.createElement(r.a,{type:"info",fill:!0,icon:!1,rounded:!0,className:"list--icons list--icons--arrow list--tight list--indent margin-bottom--lg"},n.a.createElement("p",{class:"text--lg margin-bottom--sm",style:{marginTop:"-0.25em"}},"Before you begin, this ",a||"page"," assumes the following:"),t)}},469:function(e,t,a){"use strict";var o=a(1),n=(a(473),a(470),a(52),a(29),a(22),a(21),a(0)),r=a.n(n),l=a(477),i=a(455),c=a.n(i),b=a(463),s=a.n(b),u=a(476),p=37,d=39;function m(e){var t=e.block,a=e.centered,o=e.changeSelectedValue,n=e.className,l=e.handleKeydown,i=e.style,b=e.values,s=e.selectedValue,u=e.tabRefs;return r.a.createElement("div",{className:a?"tabs--centered":null},r.a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:c()("tabs",n,{"tabs--block":t}),style:i},b.map((function(e){var t=e.value,a=e.label;return r.a.createElement("li",{role:"tab",tabIndex:"0","aria-selected":s===t,className:c()("tab-item",{"tab-item--active":s===t}),key:t,ref:function(e){return u.push(e)},onKeyDown:function(e){return l(u,e.target,e)},onFocus:function(){return o(t)},onClick:function(){return o(t)}},a)}))))}function h(e){var t=e.placeholder,a=e.selectedValue,o=e.changeSelectedValue,n=e.size,i=e.values,c=i;if(c[0].group){var b=_.groupBy(c,"group");c=Object.keys(b).map((function(e){return{label:e,options:b[e]}}))}return r.a.createElement(l.a,{className:"react-select-container react-select--"+n,classNamePrefix:"react-select",options:c,isClearable:a,placeholder:t,value:i.find((function(e){return e.value==a})),onChange:function(e){return o(e?e.value:null)}})}t.a=function(e){e.block,e.centered;var t=e.children,a=e.defaultValue,l=e.groupId,i=e.label,c=e.placeholder,b=e.select,y=e.size,f=(e.style,e.values),O=e.urlKey,j=Object(u.a)(),g=j.tabGroupChoices,v=j.setTabGroupChoices,w=Object(n.useState)(a),k=w[0],N=w[1];if(null!=l){var C=g[l];null!=C&&C!==k&&N(C)}var T=function(e){N(e),null!=l&&v(l,e)},A=[],D=function(e,t,a){switch(a.keyCode){case d:!function(e,t){var a=e.indexOf(t)+1;e[a]?e[a].focus():e[0].focus()}(e,t);break;case p:!function(e,t){var a=e.indexOf(t)-1;e[a]?e[a].focus():e[e.length-1].focus()}(e,t)}};return Object(n.useEffect)((function(){if("undefined"!=typeof window&&window.location&&O){var e=s.a.parse(window.location.search);e[O]&&N(e[O])}}),[]),r.a.createElement(r.a.Fragment,null,r.a.createElement("div",{className:"margin-bottom--"+(y||"md")},i&&r.a.createElement("div",{className:"margin-vert--sm"},i),f.length>1&&(b?r.a.createElement(h,Object(o.a)({changeSelectedValue:T,handleKeydown:D,placeholder:c,selectedValue:k,size:y,tabRefs:A},e)):r.a.createElement(m,Object(o.a)({changeSelectedValue:T,handleKeydown:D,selectedValue:k,tabRefs:A},e)))),n.Children.toArray(t).filter((function(e){return e.props.value===k}))[0])}},471:function(e,t,a){"use strict";var o=a(0),n=a.n(o);t.a=function(e){return n.a.createElement(n.a.Fragment,null,e.children)}}}]); \ No newline at end of file diff --git a/6ce627d6.9634ea7f.js b/6ce627d6.9634ea7f.js deleted file mode 100644 index 6f811573c7..0000000000 --- a/6ce627d6.9634ea7f.js +++ /dev/null @@ -1 +0,0 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[132],{283:function(e,t,a){"use strict";a.r(t),a.d(t,"frontMatter",(function(){return u})),a.d(t,"metadata",(function(){return s})),a.d(t,"rightToc",(function(){return p})),a.d(t,"default",(function(){return m}));var o=a(1),n=a(9),r=(a(0),a(457)),l=a(456),i=a(471),c=a(469),b=a(461),u={last_modified_on:"2024-08-12",$schema:"/.meta/.schemas/guides.json",title:"Migrate your application from Heroku to AWS",description:"Guide on how to migrate all your applications from Heroku to AWS with your databases",author_github:"https://github.com/evoxmusic",tags:["type: tutorial","installation_guide: aws"],hide_pagination:!0},s={categories:[{name:"tutorial",title:"Tutorial",description:"Additional step-by-step resources to leverage even more Qovery",permalink:"/guides/tutorial"}],coverLabel:"Migrate your application from Heroku to AWS",description:"Guide on how to migrate all your applications from Heroku to AWS with your databases",permalink:"/guides/tutorial/migrate-your-application-from-heroku-to-aws",readingTime:"13 min read",source:"@site/guides/tutorial/migrate-your-application-from-heroku-to-aws.md",tags:[{label:"type: tutorial",permalink:"/guides/tags/type-tutorial"},{label:"installation_guide: aws",permalink:"/guides/tags/installation-guide-aws"}],title:"Migrate your application from Heroku to AWS",truncated:!1,prevItem:{title:"Microservices",permalink:"/guides/advanced/microservices"},nextItem:{title:"Migration",permalink:"/guides/advanced/migration"}},p=[{value:"Migration Steps",id:"migration-steps",children:[]},{value:"1. Create your Dockerfile or Use Buildpacks",id:"1-create-your-dockerfile-or-use-buildpacks",children:[{value:"Choose your Dockerfile template",id:"choose-your-dockerfile-template",children:[]},{value:"Test your Dockerfile",id:"test-your-dockerfile",children:[]},{value:"Environment variables at the build time",id:"environment-variables-at-the-build-time",children:[]},{value:"Add your Dockerfile to Git",id:"add-your-dockerfile-to-git",children:[]},{value:"Loop",id:"loop",children:[]},{value:"Limitations",id:"limitations",children:[]}]},{value:"2. Create resources on Qovery",id:"2-create-resources-on-qovery",children:[{value:"Application",id:"application",children:[]},{value:"Database",id:"database",children:[]}]},{value:"3. Configure your Environment Variables and Secrets",id:"3-configure-your-environment-variables-and-secrets",children:[{value:"Connect your frontend app to your backend app",id:"connect-your-frontend-app-to-your-backend-app",children:[]},{value:"Connect your backend app to your database",id:"connect-your-backend-app-to-your-database",children:[]}]},{value:"4. Copy data from your Heroku databases to your AWS databases",id:"4-copy-data-from-your-heroku-databases-to-your-aws-databases",children:[]},{value:"5. Deploy your apps!",id:"5-deploy-your-apps",children:[]},{value:"FAQ by Heroku users",id:"faq-by-heroku-users",children:[{value:"How to create a custom domain?",id:"how-to-create-a-custom-domain",children:[]},{value:"How to monitor my apps?",id:"how-to-monitor-my-apps",children:[]},{value:"Do you have Heroku "Review App" equivalent?",id:"do-you-have-heroku-review-app-equivalent",children:[]},{value:"How to rollback?",id:"how-to-rollback",children:[]},{value:"How auto-scaling works?",id:"how-auto-scaling-works",children:[]},{value:"How to manage database migration?",id:"how-to-manage-database-migration",children:[]},{value:"Is it possible to get a shell / connect to my app?",id:"is-it-possible-to-get-a-shell--connect-to-my-app",children:[]},{value:"Can I use Terraform and Infrastructure as Code?",id:"can-i-use-terraform-and-infrastructure-as-code",children:[]},{value:"How can I connect my app to MongoDB Atlas?",id:"how-can-i-connect-my-app-to-mongodb-atlas",children:[]},{value:"How can I connect my app to an AWS service not managed by Qovery?",id:"how-can-i-connect-my-app-to-an-aws-service-not-managed-by-qovery",children:[]}]},{value:"Wrapping up",id:"wrapping-up",children:[]}],d={rightToc:p};function m(e){var t=e.components,a=Object(n.a)(e,["components"]);return Object(r.b)("wrapper",Object(o.a)({},d,a,{components:t,mdxType:"MDXLayout"}),Object(r.b)(l.a,{type:"success",mdxType:"Alert"},Object(r.b)("p",null,"This guide also work for migrating your application from Heroku to GCP, Azure, Scaleway and ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/getting-started/install-qovery/"}),"all cloud provider")," supported by Qovery.")),Object(r.b)("p",null,"This guide describes how to migrate your application running on Heroku to AWS with Qovery. It covers all required steps you need to take to deploy your application on AWS and transfer your data from Heroku Postgres to the database managed by AWS via Qovery."),Object(r.b)("blockquote",null,Object(r.b)("p",{parentName:"blockquote"},"Please contact us via ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/"}),"our forum")," if you experience any problem while migrating from Heroku to AWS with Qovery.")),Object(r.b)(b.a,{name:"guide",mdxType:"Assumptions"},Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},"You are familiar with Heroku basics, have a Heroku account and access to Heroku CLI"),Object(r.b)("li",{parentName:"ul"},"You have ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"https://start.qovery.com"}),"sign in on Qovery")),Object(r.b)("li",{parentName:"ul"},"You have ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"/guides/installation-guide/guide-amazon-web-services/"}),"set up your AWS account")," with Qovery"))),Object(r.b)("h2",{id:"migration-steps"},"Migration Steps"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#1-create-your-dockerfile-or-use-buildpacks"}),"Use Buildpacks or Create your Dockerfile")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#2-create-resources-on-qovery"}),"Create resources on Qovery")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#3-configure-your-environment-variables-and-secrets"}),"Configure Environment Variables and Secrets")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#4-copy-data-from-your-heroku-databases-to-your-aws-databases"}),"Copy data from your Heroku databases to your AWS databases")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#5-deploy-your-apps-"}),"Deploy your apps")),Object(r.b)("li",{parentName:"ol"},Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"#faq-by-heroku-users"}),"FAQ by Heroku users"))),Object(r.b)("h2",{id:"1-create-your-dockerfile-or-use-buildpacks"},"1. Create your Dockerfile or Use Buildpacks"),Object(r.b)("p",null,"Qovery supports two ways to build and run your application coming from Heroku:"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},"Buildpacks"),Object(r.b)("li",{parentName:"ol"},"Docker")),Object(r.b)("p",null,"Both options build a container image that is runnable by a container engine (E.g. Docker). Qovery runs containers on Kubernetes."),Object(r.b)("p",null,"Choose the option that better fits you:"),Object(r.b)(c.a,{centered:!0,className:"rounded",defaultValue:"buildpacks",placeholder:"Use Buildpacks or Create your Dockerfile",select:!1,size:null,values:[{group:"Platforms",label:"Use Buildpacks",value:"buildpacks"},{group:"Platforms",label:"Create your Dockerfile",value:"dockerfile"}],mdxType:"Tabs"},Object(r.b)(i.a,{value:"dockerfile",mdxType:"TabItem"},Object(r.b)("blockquote",null,Object(r.b)("p",{parentName:"blockquote"},"Are you familiar with Dockerfile? If not, I do recommend reading ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/how-to-write-a-dockerfile/"}),"this article"),".")),Object(r.b)("p",null,"Here we will create our Dockerfiles to build and run our applications. Qovery will handle the build and the run of your applications, but need to have at least a Dockerfile to do it."),Object(r.b)("h3",{id:"choose-your-dockerfile-template"},"Choose your Dockerfile template"),Object(r.b)("p",null,"To get started,"),Object(r.b)("h4",{id:"find-dockerfile-template"},"Find Dockerfile template"),Object(r.b)("p",null,"Pick one Dockerfile template according to the programming language or framework you are using for your app:"),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"Your framework or language is missing? Open a thread on ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/"}),"our forum"),", and we will provide you one.")),Object(r.b)(c.a,{centered:!1,className:"square",defaultValue:"rails",select:!1,size:null,values:[{group:"Files",label:"Rails",value:"rails"},{group:"Files",label:"NodeJS",value:"nodejs"},{group:"Files",label:"React",value:"react"},{group:"Files",label:"VueJS",value:"vuejs"},{group:"Files",label:"NextJS",value:"nextjs"},{group:"Files",label:"Golang",value:"golang"},{group:"Files",label:"Flask",value:"flask"},{group:"Files",label:"Django",value:"django"},{group:"Files",label:"Laravel",value:"laravel"},{group:"Files",label:"Symfony",value:"symfony"},{group:"Files",label:"Spring",value:"spring"},{group:"Files",label:"Rust",value:"rust"}],mdxType:"Tabs"},Object(r.b)(i.a,{value:"rails",mdxType:"TabItem"},Object(r.b)("p",null,"Here is the Dockerfile for your Rails application listening on the PORT 3000"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell",metastring:'title="Dockerfile"',title:'"Dockerfile"'}),'# syntax=docker/dockerfile:1\nFROM ruby:2.7\nRUN apt-get update -qq && apt-get install -y nodejs postgresql-client\nWORKDIR /myapp\nCOPY Gemfile Gemfile\nCOPY Gemfile.lock Gemfile.lock\nRUN bundle install\n\nCOPY . .\n\nEXPOSE 3000\n\n# Configure the main process to run when running the image\nCMD ["rails", "server", "-b", "0.0.0.0", "-p", "3000"]\n')),Object(r.b)("details",null,Object(r.b)("summary",null,"Dockerfile for Sidekiq"),Object(r.b)("p",null,"Here is the Dockerfile for your Rails app running as a worker mode with Sidekiq."),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"There is no listening port since it is consuming resources from a queuing system (E.g. Redis)")),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell",metastring:'title="Dockerfile for Sidekiq"',title:'"Dockerfile',for:!0,'Sidekiq"':!0}),'# syntax=docker/dockerfile:1\nFROM ruby:2.7\nRUN apt-get update -qq && apt-get install -y nodejs postgresql-client # add mysql client if you need to\nWORKDIR /myapp\nCOPY Gemfile Gemfile\nCOPY Gemfile.lock Gemfile.lock\nRUN bundle install\n\nCOPY . .\n\nCMD ["bundle", "exec", "sidekiq"]\n')))),Object(r.b)(i.a,{value:"nodejs",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"react",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"vuejs",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"nextjs",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"golang",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"flask",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"django",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"laravel",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"symfony",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"spring",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n"))),Object(r.b)(i.a,{value:"rust",mdxType:"TabItem"},Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"\nTODO\n\n")))),Object(r.b)("h4",{id:"copy-template"},"Copy template"),Object(r.b)("p",null,"Copy your Dockerfile at the root of your project. By convention, you can name your file ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile"),". If you already have a Dockerfile, feel free to name it ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile.qovery"),". If you are using multiple Dockerfile for Qovery, feel free to give a name like ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile-sidekiq.qovery"),"."),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"Read ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/t/904"}),"this forum post")," to know how to use the same Dockerfile with different CMD parameters.")),Object(r.b)("p",null,"For our example of migrating a Rails app and a Rails Sidekiq app, I will have at the root of my project a ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile.qovery")," and a ",Object(r.b)("inlineCode",{parentName:"p"},"Dockerfile-sidekiq.qovery"),"."),Object(r.b)("h3",{id:"test-your-dockerfile"},"Test your Dockerfile"),Object(r.b)(b.a,{mdxType:"Assumptions"},Object(r.b)("p",null,"You need to ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://docs.docker.com/get-docker/"}),"install Docker")," to test your Dockerfile")),Object(r.b)("p",null,"To test your Dockerfile we will locally our container. You just need to run the following commands:"),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,"Don't forget the ",Object(r.b)("inlineCode",{parentName:"p"},".")," (dot) at the end of the ",Object(r.b)("inlineCode",{parentName:"p"},"docker build")," command.")),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"docker build -f Dockerfile.qovery .\n")),Object(r.b)("p",null,"If everything goes well you should get the finale image ID at the end of the output."),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"[+] Building 19.0s (16/16) FINISHED\n => [internal] load build definition from Dockerfile 0.0s\n => => transferring dockerfile: 37B 0.0s\n => [internal] load .dockerignore 0.0s\n ...\n => [7/7] COPY . . 0.2s\n => exporting to image 0.0s\n => exporting layers 0.4s\n => writing image sha256:a0f90a6ec8bc4036a7b268479a0c0773ca324ba2de11fdef31309650743f4055 0.0s\n")),Object(r.b)("p",null,"To run your image you can run:"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"docker run a0f90a6ec8bc4036a7b268479a0c0773ca324ba2de11fdef31309650743f4055\n")),Object(r.b)("p",null,"If your app required a database to starts, then it can be normal that it fails to start. Otherwise, if your app is supposed to start and does not, then you will need to fix the issue and rebuild your app with ",Object(r.b)("inlineCode",{parentName:"p"},"docker build -f Dockerfile.qovery .")),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"This step is one of the most complex, but once you successfully build your application with Docker, your app will run anywhere (not only on AWS with Qovery).")),Object(r.b)("p",null,"Any error while building your container image? 2 solutions:"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},'Read the error message and try to understand from where the problem is coming from. You can "Google" the error if it is not related to your code.'),Object(r.b)("li",{parentName:"ol"},"Open a thread on ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"https://discuss.qovery.com/"}),"our forum")," if you don't find the answer there, we will be happy to assist you.")),Object(r.b)("h3",{id:"environment-variables-at-the-build-time"},"Environment variables at the build time"),Object(r.b)("p",null,"Does your app use some environment variables at the build time? Then you will need to modify your Dockerfile to includes the environment variables. Let's imagine your app uses the environment variable ",Object(r.b)("inlineCode",{parentName:"p"},"CONTENT_API_KEY"),", then you will need to add the following instructions in your Dockerfile:"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell",metastring:'title="Dockerfile with environment variables"',title:'"Dockerfile',with:!0,environment:!0,'variables"':!0}),"...\nARG CONTENT_API_KEY\nENV CONTENT_API_KEY $CONTENT_API_KEY\n...\n")),Object(r.b)("p",null,"The value of the ",Object(r.b)("inlineCode",{parentName:"p"},"CONTENT_API_KEY")," environment variable will be taken from the specified environment variables in Qovery."),Object(r.b)(l.a,{type:"success",mdxType:"Alert"},Object(r.b)("p",null,"Qovery injects Environment Variables and Secrets at the build and run time of your app.")),Object(r.b)("h3",{id:"add-your-dockerfile-to-git"},"Add your Dockerfile to Git"),Object(r.b)("p",null,"Now, add your new Dockerfile to git with the following commands:"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),'git add Dockerfile.qovery\ngit commit -m "Add Qovery Dockerfile"\ngit push origin\n')),Object(r.b)("h3",{id:"loop"},"Loop"),Object(r.b)("p",null,"If you have multiple applications to deploy, create a Dockerfile for each of them.")),Object(r.b)(i.a,{value:"buildpacks",mdxType:"TabItem"},Object(r.b)("p",null,Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://buildpacks.io/"}),"Buildpacks")," automatically detects the language and the framework your application is using. Buildpacks builds and runs your app. Here is the list of ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/application/#option-1-buildpacks"}),"supported languages and frameworks"),"."),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,"We do recommend using Docker to keep the full control of what's going on behind the scene. Buildpacks is a great technology but difficult to debug when something goes wrong. You can try deploying your apps on AWS with Qovery with Buildpacks, if you do not succeed, we do recommend switching for Docker.")),Object(r.b)("h3",{id:"limitations"},"Limitations"),Object(r.b)("p",null,"Here are some limitations due to our Buildpacks implementation:"),Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},"Qovery Buildpacks does not support Procfile with multiple commands at the moment."),Object(r.b)("li",{parentName:"ul"},"Qovery does not support custom Buildpacks.")),Object(r.b)("p",null,"Those limitations will be solved in the coming months."))),Object(r.b)("h2",{id:"2-create-resources-on-qovery"},"2. Create resources on Qovery"),Object(r.b)("h3",{id:"application"},"Application"),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"Are you a new Qovery user? Watch ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/getting-started/deploy-your-first-application/"}),"this tutorial")," to learn how to deploy your first app.")),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/9246ae68c68f42debc3d5183d2b4f7f8",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"Steps:"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},"Connect to the ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"https://start.qovery.com"}),"Qovery console"),"."),Object(r.b)("li",{parentName:"ol"},"Create your ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/organization/"}),"Organization")," and your ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/project/"}),"Project"),"."),Object(r.b)("li",{parentName:"ol"},"Create an environment with the name ",Object(r.b)("inlineCode",{parentName:"li"},"production")," (it can be changed after)."),Object(r.b)("li",{parentName:"ol"},"Create an application and give it a name (you can give the name of your repo if you have no idea)"),Object(r.b)("li",{parentName:"ol"},"Select your app repository from your GitHub, GitLab or Bitbucket."),Object(r.b)("li",{parentName:"ol"},"Select the branch you want to deploy."),Object(r.b)("li",{parentName:"ol"},"Select the Build mode for ",Object(r.b)("inlineCode",{parentName:"li"},"Buildpacks")," or ",Object(r.b)("inlineCode",{parentName:"li"},"Dockerfile")," according to what you want."),Object(r.b)("li",{parentName:"ol"},"Specify the local listening port of your application."),Object(r.b)("li",{parentName:"ol"},'Click on "create"')),Object(r.b)("p",null,"Congrats! Your application is created \ud83c\udf89"),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,'Your application is created but not deployed yet! You can configure the vCPU, Memory, Environment Variables... before deploying it. If you want to deploy it before finishing the configuration you can click on "Actions" > "Deploy".')),Object(r.b)("p",null,"If you deploy an app from a mono-repository, we have a must-read guide for you ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/advanced/monorepository/"}),"here"),"."),Object(r.b)("h3",{id:"database"},"Database"),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"Are you a new Qovery user? Watch ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/getting-started/create-a-database/"}),"this tutorial")," to learn how to deploy your database.")),Object(r.b)("p",null,"Here are the steps to deploy your database:"),Object(r.b)(b.a,{mdxType:"Assumptions"},Object(r.b)("ul",null,Object(r.b)("li",{parentName:"ul"},"You have created an application before"))),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/d7e10be0e5964f6799b158dc631bbbd1",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"Steps:"),Object(r.b)("ol",null,Object(r.b)("li",{parentName:"ol"},"Go to your ",Object(r.b)("inlineCode",{parentName:"li"},"production")," environment."),Object(r.b)("li",{parentName:"ol"},'Add your database by clicking on "Add" > "Database".'),Object(r.b)("li",{parentName:"ol"},"Select the database (PostgreSQL, MySQL, MongoDB, Redis..) and the version you want to deploy."),Object(r.b)("li",{parentName:"ol"},"Select ",Object(r.b)("a",Object(o.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/database/#general"}),"Managed or Container mode")," for your database."),Object(r.b)("li",{parentName:"ol"},"Select ",Object(r.b)("inlineCode",{parentName:"li"},"Public")," accessibility (set ",Object(r.b)("inlineCode",{parentName:"li"},"Private")," if you don't want to restore your data from an existing Heroku database).")),Object(r.b)("p",null,"Congrats! Your database is created as well \ud83c\udf89"),Object(r.b)("p",null,"If you use MongoDB Atlas, or an existing database on AWS that you want to connect to your application deployed by Qovery. Check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/aws-vpc-peering-with-qovery/"}),"our tutorial about VPC peering")," and how to securely connect to your existing database."),Object(r.b)("h2",{id:"3-configure-your-environment-variables-and-secrets"},"3. Configure your Environment Variables and Secrets"),Object(r.b)(l.a,{type:"success",mdxType:"Alert"},Object(r.b)("p",null,"Qovery supports Doppler integration - it's the easiest way to migrate your Environment Variables and Secrets from Heroku to Qovery. ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/integration/secret-manager/doppler/"}),"More info here"),".")),Object(r.b)("p",null,"Qovery makes the difference between an environment variable and a secret. Basically, a Secret is similar to an Environment Variable but the value is encrypted and can't be revealed. Both are injected as environment variables during the build and the run of your applications. ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment-variable/"}),"More info here")),Object(r.b)(l.a,{type:"info",mdxType:"Alert"},Object(r.b)("p",null,"I recommend reading our ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/getting-started/managing-environment-variables/"}),"Getting Started with Environment Variables")," guide.")),Object(r.b)("p",null,"To extract your environment variables from Heroku, we recommend using the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://devcenter.heroku.com/articles/heroku-cli"}),"Heroku CLI")," and exporting all the environment variables and secrets in an .env (dot env) file. Qovery supports the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/import-your-environment-variables-with-the-qovery-cli/"}),"import of a dot env file")," via the Qovery web interface and the Qovery CLI."),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,"If you use Buildpacks for one of your app AND you have indicated a local listening port of your application, you will need to add an environment variable ",Object(r.b)("inlineCode",{parentName:"p"},"PORT")," with the value of your port to make your application starting properly. Otherwise, Qovery will fail to deploy your app!")),Object(r.b)("p",null,Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://devcenter.heroku.com/articles/config-vars#view-current-config-var-values"}),"Export your environment variable via the Heroku CLI")," with the command:"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell"}),"# To install Heroku CLI: https://devcenter.heroku.com/articles/heroku-cli\nheroku config\n\nGREETINGS: hello world\nSTRIPE_API_KEY: xxx-yyy-zzz\nIS_PRODUCTION: true\n")),Object(r.b)("p",null,"Then you can create your environment variables via the web interface (watch the video below)"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/50899d7fa3d84a418f0db69f54f970d3",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"Or via the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/interface/cli/"}),"Qovery CLI"),":"),Object(r.b)("pre",null,Object(r.b)("code",Object(o.a)({parentName:"pre"},{className:"language-shell",metastring:'title="Import Heroku environment variables with the Qovery CLI"',title:'"Import',Heroku:!0,environment:!0,variables:!0,with:!0,the:!0,Qovery:!0,'CLI"':!0}),"# auth yourself\nqovery auth\n\n# selection the app where you want to import your environment variables\nqovery context set\n\n# import your Heroku environment variables\nheroku config --app --json | \\\n qovery env parse --heroku-json > heroku.env && \\\n qovery env import heroku.env && \\\n rm heroku.env\n\nQovery: dot env file to import: 'heroku.env'\n? Do you want to import Environment Variables or Secrets? Environment Variables\n? What environment variables do you want to import? [Use arrows to move, space to select, to all, to none, type to filter]\n [x] GREETINGS=hello world\n [ ] STRIPE_API_KEY=xxx-yyy-zzz\n> [x] IS_PRODUCTION=true\n\nQovery: \u2705 Environment Variables successfully imported!\n")),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,"Import sensitive data (E.g. API keys, credentials...) as ",Object(r.b)("inlineCode",{parentName:"p"},"Secret")," and not ",Object(r.b)("inlineCode",{parentName:"p"},"Environment Variable"),".")),Object(r.b)("h3",{id:"connect-your-frontend-app-to-your-backend-app"},"Connect your frontend app to your backend app"),Object(r.b)("p",null,"To connect your frontend app your backend app we will create an ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment-variable/#alias-environment-variable"}),"environment variable alias"),"."),Object(r.b)("p",null,"Here is how to create a frontend app:"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/bafbbda93bd64d04afb3189bf4a1a201",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"And now how to connect your frontend app with your backend app:"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/f820925f2175465f9271b97ef414bb42",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"You can also take a look at ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/t/918"}),"this forum reply")," to learn how to do it."),Object(r.b)("h3",{id:"connect-your-backend-app-to-your-database"},"Connect your backend app to your database"),Object(r.b)("p",null,"Same as connecting your frontend app to your backend app, you can create an environment variable alias ",Object(r.b)("inlineCode",{parentName:"p"},"DATABASE_URL")," for the ",Object(r.b)("em",{parentName:"p"},"built-in")," secret finishing with ",Object(r.b)("inlineCode",{parentName:"p"},"_DATABASE_URL_INTERNAL"),"."),Object(r.b)(l.a,{type:"warning",mdxType:"Alert"},Object(r.b)("p",null,"Create an alias on ",Object(r.b)("inlineCode",{parentName:"p"},"_DATABASE_URL_INTERNAL")," and not ",Object(r.b)("inlineCode",{parentName:"p"},"_DATABASE_URL"))),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/59f8368eb3c14796a807c7e39e9c0ab0",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("h2",{id:"4-copy-data-from-your-heroku-databases-to-your-aws-databases"},"4. Copy data from your Heroku databases to your AWS databases"),Object(r.b)("p",null,Object(r.b)("em",{parentName:"p"},"Coming soon with ",Object(r.b)("a",Object(o.a)({parentName:"em"},{href:"https://www.replibyte.com"}),"Replibyte"))),Object(r.b)("h2",{id:"5-deploy-your-apps"},"5. Deploy your apps!"),Object(r.b)("p",null,"We are finally ready to deploy my applications on AWS!"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/0589d2f2aa4149edb605dc23f4efd23d",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("p",null,"Watch the final result \ud83d\ude0e"),Object(r.b)("div",{class:"video-container"},Object(r.b)("p",{align:"center"},Object(r.b)("iframe",{src:"https://www.loom.com/embed/da31c21f9c104eae9270e4c4db59055e",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:!0,mozallowfullscreen:!0,allowfullscreen:!0}))),Object(r.b)("h2",{id:"faq-by-heroku-users"},"FAQ by Heroku users"),Object(r.b)("h3",{id:"how-to-create-a-custom-domain"},"How to create a custom domain?"),Object(r.b)("p",null,"Check out the documentation on ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/getting-started/setting-custom-domain/"}),"how to configure your custom domain"),"."),Object(r.b)("h3",{id:"how-to-monitor-my-apps"},"How to monitor my apps?"),Object(r.b)("p",null,"We do recommend using ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://www.datadoghq.com"}),"Datadog")," or any other monitoring products for monitoring your apps deployed by Qovery. Check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/kubernetes-observability-and-monitoring-with-datadog/"}),"our tutorial on how to install Datadog"),"."),Object(r.b)("h3",{id:"do-you-have-heroku-review-app-equivalent"},'Do you have Heroku "Review App" equivalent?'),Object(r.b)("p",null,"Yes, it's what we call ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment/#preview-environment"}),"Preview Environment")),Object(r.b)("h3",{id:"how-to-rollback"},"How to rollback?"),Object(r.b)("p",null,"Check out the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/deployment-actions/#deploy-other-version"}),"app rollback documentation")),Object(r.b)("h3",{id:"how-auto-scaling-works"},"How auto-scaling works?"),Object(r.b)("p",null,"Check out the ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/application/#auto-scaling"}),"app auto-scaling documentation")),Object(r.b)("h3",{id:"how-to-manage-database-migration"},"How to manage database migration?"),Object(r.b)("p",null,"Check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/t/951"}),"our forum reply")),Object(r.b)("h3",{id:"is-it-possible-to-get-a-shell--connect-to-my-app"},"Is it possible to get a shell / connect to my app?"),Object(r.b)("p",null,"Absolutely, you can connect directly to your application with a shell by clicking on the Qovery cloud shell button (1):"),Object(r.b)("p",{align:"center"},Object(r.b)("img",{src:"/img/qovery_cloud_shell.png",alt:"Qovery Cloud Shell"})),Object(r.b)("p",null,"Then you just have to select the pod (2) and the container (3)."),Object(r.b)("p",null,"You can also check out our ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/interface/cli/#shell"}),"CLI")," and the ",Object(r.b)("inlineCode",{parentName:"p"},"qovery shell")," command."),Object(r.b)("h3",{id:"can-i-use-terraform-and-infrastructure-as-code"},"Can I use Terraform and Infrastructure as Code?"),Object(r.b)("p",null,"Absolutely, we have a ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/using-qovery/integration/terraform-provider/"}),"Qovery Terraform provider")," available."),Object(r.b)("h3",{id:"how-can-i-connect-my-app-to-mongodb-atlas"},"How can I connect my app to MongoDB Atlas?"),Object(r.b)("p",null,"If you use MongoDB Atlas check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/aws-vpc-peering-with-qovery/"}),"our tutorial about VPC peering")," and how to securely connect to your existing MongoDB Atlas database."),Object(r.b)("h3",{id:"how-can-i-connect-my-app-to-an-aws-service-not-managed-by-qovery"},"How can I connect my app to an AWS service not managed by Qovery?"),Object(r.b)("p",null,"If you want to connect your app to an AWS service not managed by Qovery, check out ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/guides/tutorial/aws-vpc-peering-with-qovery/"}),"our tutorial about VPC peering")," and how to securely connect to this AWS service."),Object(r.b)("hr",null),Object(r.b)("p",null,"If you have a common question about Qovery, we have a more general ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"/docs/useful-resources/faq/"}),"FAQ section")," available."),Object(r.b)("h2",{id:"wrapping-up"},"Wrapping up"),Object(r.b)("p",null,"Congrats! You have migrated from Heroku to AWS. Feel free to check out our ",Object(r.b)("a",Object(o.a)({parentName:"p"},{href:"https://discuss.qovery.com/"}),"forum")," and open a thread if you have any question."))}m.isMDXComponent=!0},456:function(e,t,a){"use strict";a(458);var o=a(0),n=a.n(o),r=a(455),l=a.n(r);a(132);t.a=function(e){var t=e.children,a=e.classNames,o=e.fill,r=e.icon,i=e.type,c=null;switch(i){case"danger":c="alert-triangle";break;case"success":c="check-circle";break;case"warning":c="alert-triangle";break;default:c="info"}return n.a.createElement("div",{className:l()(a,"alert","alert--"+i,{"alert--fill":o,"alert--icon":!1!==r}),role:"alert"},!1!==r&&n.a.createElement("i",{className:l()("feather","icon-"+(r||c))}),t)}},460:function(e,t,a){var o=a(28).f,n=Function.prototype,r=/^\s*function ([^ (]*)/;"name"in n||a(10)&&o(n,"name",{configurable:!0,get:function(){try{return(""+this).match(r)[1]}catch(e){return""}}})},461:function(e,t,a){"use strict";a(460);var o=a(0),n=a.n(o),r=a(456);t.a=function(e){var t=e.children,a=e.name;return n.a.createElement(r.a,{type:"info",fill:!0,icon:!1,rounded:!0,className:"list--icons list--icons--arrow list--tight list--indent margin-bottom--lg"},n.a.createElement("p",{class:"text--lg margin-bottom--sm",style:{marginTop:"-0.25em"}},"Before you begin, this ",a||"page"," assumes the following:"),t)}},469:function(e,t,a){"use strict";var o=a(1),n=(a(473),a(470),a(52),a(29),a(22),a(21),a(0)),r=a.n(n),l=a(477),i=a(455),c=a.n(i),b=a(463),u=a.n(b),s=a(476),p=37,d=39;function m(e){var t=e.block,a=e.centered,o=e.changeSelectedValue,n=e.className,l=e.handleKeydown,i=e.style,b=e.values,u=e.selectedValue,s=e.tabRefs;return r.a.createElement("div",{className:a?"tabs--centered":null},r.a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:c()("tabs",n,{"tabs--block":t}),style:i},b.map((function(e){var t=e.value,a=e.label;return r.a.createElement("li",{role:"tab",tabIndex:"0","aria-selected":u===t,className:c()("tab-item",{"tab-item--active":u===t}),key:t,ref:function(e){return s.push(e)},onKeyDown:function(e){return l(s,e.target,e)},onFocus:function(){return o(t)},onClick:function(){return o(t)}},a)}))))}function h(e){var t=e.placeholder,a=e.selectedValue,o=e.changeSelectedValue,n=e.size,i=e.values,c=i;if(c[0].group){var b=_.groupBy(c,"group");c=Object.keys(b).map((function(e){return{label:e,options:b[e]}}))}return r.a.createElement(l.a,{className:"react-select-container react-select--"+n,classNamePrefix:"react-select",options:c,isClearable:a,placeholder:t,value:i.find((function(e){return e.value==a})),onChange:function(e){return o(e?e.value:null)}})}t.a=function(e){e.block,e.centered;var t=e.children,a=e.defaultValue,l=e.groupId,i=e.label,c=e.placeholder,b=e.select,y=e.size,f=(e.style,e.values),O=e.urlKey,j=Object(s.a)(),g=j.tabGroupChoices,v=j.setTabGroupChoices,w=Object(n.useState)(a),k=w[0],N=w[1];if(null!=l){var T=g[l];null!=T&&T!==k&&N(T)}var C=function(e){N(e),null!=l&&v(l,e)},D=[],A=function(e,t,a){switch(a.keyCode){case d:!function(e,t){var a=e.indexOf(t)+1;e[a]?e[a].focus():e[0].focus()}(e,t);break;case p:!function(e,t){var a=e.indexOf(t)-1;e[a]?e[a].focus():e[e.length-1].focus()}(e,t)}};return Object(n.useEffect)((function(){if("undefined"!=typeof window&&window.location&&O){var e=u.a.parse(window.location.search);e[O]&&N(e[O])}}),[]),r.a.createElement(r.a.Fragment,null,r.a.createElement("div",{className:"margin-bottom--"+(y||"md")},i&&r.a.createElement("div",{className:"margin-vert--sm"},i),f.length>1&&(b?r.a.createElement(h,Object(o.a)({changeSelectedValue:C,handleKeydown:A,placeholder:c,selectedValue:k,size:y,tabRefs:D},e)):r.a.createElement(m,Object(o.a)({changeSelectedValue:C,handleKeydown:A,selectedValue:k,tabRefs:D},e)))),n.Children.toArray(t).filter((function(e){return e.props.value===k}))[0])}},471:function(e,t,a){"use strict";var o=a(0),n=a.n(o);t.a=function(e){return n.a.createElement(n.a.Fragment,null,e.children)}}}]); \ No newline at end of file diff --git a/8d5726d6.663659ee.js b/8d5726d6.663659ee.js deleted file mode 100644 index c155038372..0000000000 --- a/8d5726d6.663659ee.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see 8d5726d6.663659ee.js.LICENSE.txt */ -(window.webpackJsonp=window.webpackJsonp||[]).push([[158],{310:function(e,t,n){"use strict";n.r(t),n.d(t,"frontMatter",(function(){return s})),n.d(t,"metadata",(function(){return b})),n.d(t,"rightToc",(function(){return p})),n.d(t,"default",(function(){return d}));var a=n(1),o=n(9),i=(n(0),n(457)),r=n(464),c=(n(465),n(456)),l=n(461),s={last_modified_on:"2024-08-27",title:"Application",description:"Learn how to configure your Application on Qovery"},b={id:"using-qovery/configuration/application",title:"Application",description:"Learn how to configure your Application on Qovery",source:"@site/docs/using-qovery/configuration/application.md",permalink:"/docs/using-qovery/configuration/application",sidebar:"docs",previous:{title:"Environment",permalink:"/docs/using-qovery/configuration/environment"},next:{title:"Helm",permalink:"/docs/using-qovery/configuration/helm"}},p=[{value:"Deploying from a Git Repository",id:"deploying-from-a-git-repository",children:[]},{value:"Deploying from a Container Registry",id:"deploying-from-a-container-registry",children:[]},{value:"Create an Application",id:"create-an-application",children:[]},{value:"Deployment Management",id:"deployment-management",children:[]},{value:"Configuration",id:"configuration",children:[{value:"General",id:"general",children:[]},{value:"Resources",id:"resources",children:[]},{value:"Storage",id:"storage",children:[]},{value:"Ports",id:"ports",children:[]},{value:"Health Checks",id:"health-checks",children:[]},{value:"Deployment Restrictions",id:"deployment-restrictions",children:[]}]},{value:"Connecting from the internet",id:"connecting-from-the-internet",children:[{value:"Qovery provided domains",id:"qovery-provided-domains",children:[]},{value:"Custom domains",id:"custom-domains",children:[]}]},{value:"Connecting to a database",id:"connecting-to-a-database",children:[]},{value:"Connecting to another application",id:"connecting-to-another-application",children:[]},{value:"Environment Variable",id:"environment-variable",children:[]},{value:"Secrets",id:"secrets",children:[]},{value:"Logs",id:"logs",children:[]},{value:"SSH",id:"ssh",children:[]},{value:"Clone",id:"clone",children:[]},{value:"Advanced Settings",id:"advanced-settings",children:[]},{value:"Delete an Application",id:"delete-an-application",children:[]}],u={rightToc:p};function d(e){var t=e.components,n=Object(o.a)(e,["components"]);return Object(i.b)("wrapper",Object(a.a)({},u,n,{components:t,mdxType:"MDXLayout"}),Object(i.b)(l.a,{name:"documentation",mdxType:"Assumptions"},Object(i.b)("p",null,"You have created an ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment/"}),"Environment"),".")),Object(i.b)("p",null,"An ",Object(i.b)("strong",{parentName:"p"},"application")," is part of a ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/project/"}),"Project")," within an ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment/"}),"Environment")," and is a container unit. Multiple applications can be part of the same ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment/"}),"Environment"),", be connected to a set of dependencies (databases and other services), and can communicate with other applications within the same Environment."),Object(i.b)("p",null,"Qovery allows you to create and deploy applications from two different sources: Git Repository or Container Registry"),Object(i.b)("h2",{id:"deploying-from-a-git-repository"},"Deploying from a Git Repository"),Object(i.b)("p",null,"In this configuration, Qovery will pull the code from the chosen repository, build the application and deploy it on your kubernetes cluster."),Object(i.b)("p",null,"The list of Git repositories available during the setup is strictly tied to the permissions of your git account (by default Qovery can access all your repositories). If you want to restrict the Qovery access only to a few repositories, user the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/organization/git-repository-access/"}),"GitHub Qovery Application")," (only for Github)."),Object(i.b)("h2",{id:"deploying-from-a-container-registry"},"Deploying from a Container Registry"),Object(i.b)("p",null,"In this configuration, Qovery will pull the chosen container registry an image you have pre-built and deploy it on your kubernetes cluster."),Object(i.b)("p",null,"To improve security and avoid deploying images from non-authorized registries, we have decided to restrict the list of Container Registry you can use during the setup process. Only an administrator with the right permissions can manage it from the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/organization/container-registry/"}),"Container Registry Management page")),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,'Make sure that the image tag used are unique (do not use "latest", "dev", "master" etc..), see ',Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/image-mirroring/#why-unique-image-tags-are-necessary"}),"this section")," for more information.")),Object(i.b)("h2",{id:"create-an-application"},"Create an Application"),Object(i.b)(r.a,{headingDepth:3,mdxType:"Steps"},Object(i.b)("ol",null,Object(i.b)("li",null,Object(i.b)("p",null,'Go into the chosen environment and press the "New Service" button and then the "Create application" button'),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/creation_1.png",alt:"Creation"}))),Object(i.b)("li",null,Object(i.b)("p",null,"Select the following fields:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Application Name: give a name to your application"),Object(i.b)("li",{parentName:"ul"},"Application Source: Chose between Git Repository or Container Registry, depending on the source location of your application")),Object(i.b)("p",null,"If you want to deploy an application from a Git Repository you will have to select:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Git Repository: Select the git provider hosting your code (it can be hosted on GitHub, GitLab or Bitbucket). You can add a new git access by clicking on ",Object(i.b)("inlineCode",{parentName:"li"},"New git access"),"."),Object(i.b)("li",{parentName:"ul"},"Branch: Select branch that Qovery should use to deploy your application"),Object(i.b)("li",{parentName:"ul"},"Root Application Path: base folder in which the application resides in your repository"),Object(i.b)("li",{parentName:"ul"},"Build Mode: choose between Docker or Buildpack. For more information, go to ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/application/#build-mode"}),"this section"))),Object(i.b)("p",null,"If you want to deploy an application from a Container Registry you will have to select:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Registry: select the container registry storing the image of your application. You can add a new container registry by clicking on ",Object(i.b)("inlineCode",{parentName:"li"},"New registry"),"."),Object(i.b)("li",{parentName:"ul"},"Image name: the name of the image to be deployed with this application (example: postgres)"),Object(i.b)("li",{parentName:"ul"},"Image tag: the tag of the image to be deployed with this application (example: 1.0). "),Object(i.b)("li",{parentName:"ul"},"Image Entrypoint: the entrypoint to be used to launch your application (not mandatory)"),Object(i.b)("li",{parentName:"ul"},"CMD Arguments: the arguments to be passed to launch your application (not mandatory) separated with a space. Example: ",Object(i.b)("inlineCode",{parentName:"li"},'rails -h 0.0.0.0 -p 8080 string "complex arg"'),".")),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,'Make sure that the image tag used are unique (do not use "latest", "dev", "master" etc..), see ',Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/image-mirroring/#why-unique-image-tags-are-necessary"}),"this section")," for more information.")),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,"If the base image in your Dockerfile is from a private registry, you just have to add the access to this registry before creating your application. See ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/organization/container-registry/"}),"Container Registry Management page")," for more information.")),Object(i.b)("p",null,Object(i.b)("strong",{parentName:"p"}," Auto Deploy ")),Object(i.b)("p",null,"See the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/deploying-with-auto-deploy/"}),"Deploying with auto-deploy feature")," section."),Object(i.b)("p",null,Object(i.b)("strong",{parentName:"p"}," Extra labels/annotations (optional)")),Object(i.b)("p",null,"Add your extra annotation/label groups. See the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/organization/labels-annotations/"}),"Add annotation/label group")," section for more information.")),Object(i.b)("li",null,Object(i.b)("p",null,"Within this section, you will need to define the resources to be assigned to your application at run time."),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"vCPU: the vCPU assigned to each instance of your application. The default is 500m (0.5 vCPU)."),Object(i.b)("li",{parentName:"ul"},"RAM: the amount of RAM assigned to each instance of your application. The default is 512MB."),Object(i.b)("li",{parentName:"ul"},"Number of instances (Application Auto-scaling): select the minimum and the maximum number of instances of your application that can run within your cluster. The number of instances running at an insant t is automatically managed by Kubernetes (Application auto-scaling) and it is based on real-time CPU consumption. When your app goes above 60% of CPU consumption for 5 minutes, your app will be auto-scaled and more instances will be added. It is transparent.\nQovery runs your application on Kubernetes and relies on ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"https://github.com/kubernetes-sigs/metrics-server"}),"metrics-server")," service to auto-scale your app.")),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,"Please note that in this section you configure the CPU/RAM allocated by the cluster for your application and that cannot consume more than this value. Even if the application is underused and consume less resources, the cluster will still reserve the selected amount of CPU/RAM.")),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/application_creation_resources.png",alt:"Resources"}))),Object(i.b)("li",null,Object(i.b)("p",null,"You can now define one or more ports for your Application. Most of the application needs to be accessed by other services inside or outside your environment over different L7/L4 protocols.\nToday Qovery supports the following protocols:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"HTTPS (Select this protocol if you need to run Websockets)"),Object(i.b)("li",{parentName:"ul"},"gRPC"),Object(i.b)("li",{parentName:"ul"},"TCP"),Object(i.b)("li",{parentName:"ul"},"UDP")),Object(i.b)("p",null,"By default ports are accessible only from inside your environment. You can also expose them publicly, making them accessible over the public network via a dedicated public domain that will be assigned to your application by Qovery during the deployment (See the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"#qovery-provided-domains"}),"Qovery Provided Domains section"),"). Note that HTTPS/gRPC ports are always exposed over the port 443."),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/application_creation_port.png",alt:"Application Ports"})),Object(i.b)("p",null,Object(i.b)("strong",{parentName:"p"},"Important Informations")),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Most of the ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/service-health-checks/"}),"Kubernetes Health Checks")," are based on the port declared in this section. Make sure you declare the right port and that you configure the health checks properly."),Object(i.b)("li",{parentName:"ul"},"Connections on public ports are automatically closed after 60 seconds. If you want to implement long living connection (like for websockets) please make sure to use the rigth ingress timeouts in the ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/advanced-settings/#network-settings"}),"advanced settings section")),Object(i.b)("li",{parentName:"ul"},"Exposing publicly TCP/UDP ports requires to create a dedicated load balancer and it takes a few minutes before having it ready (~15 minutes). Note also that this has a direct impact on your cloud provider bill."),Object(i.b)("li",{parentName:"ul"},"You can configure your application to use the ",Object(i.b)("strong",{parentName:"li"},"PORT")," environment variable by adding the ",Object(i.b)("strong",{parentName:"li"},"PORT")," on your application env variables page."),Object(i.b)("li",{parentName:"ul"},"A Note on Listening IPs: It is best for your application to listen on ",Object(i.b)("inlineCode",{parentName:"li"},"0.0.0.0:$PORT"),". While most things work with ",Object(i.b)("inlineCode",{parentName:"li"},"127.0.0.1")," and ",Object(i.b)("inlineCode",{parentName:"li"},"localhost"),", some do not (NodeJS for example)"))),Object(i.b)("li",null,Object(i.b)("p",null,"(Optional) If a port has been defined for your application, you can define the health check probes to run in order to verify the state of your application"),Object(i.b)("p",null,"To know more about how to configure your Liveness and Readiness probes, have a look at ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/application-health-checks/"}),"the health-checks section"))),Object(i.b)("li",null,Object(i.b)("p",null,"Define any input variable required by your application to run. Any declared variable will be injected as environment variables based on the selected scope (project, environment, service)\nAny additional environment variable can be added later from the environment variable section"),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/job/variables.png",alt:"Input Variables"}))),Object(i.b)("li",null,Object(i.b)("p",null,"You will find a recap of your application setup and you can now decide to:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Go back to one of the previous steps and change your application settings"),Object(i.b)("li",{parentName:"ul"},"Create your application without deploying it"),Object(i.b)("li",{parentName:"ul"},"Create and deploy your application")),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/application_creation_recap.png",alt:"Application"}))))),Object(i.b)("h2",{id:"deployment-management"},"Deployment Management"),Object(i.b)("p",null,"Have a look at the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/"}),"Deployment Management")," section for more information."),Object(i.b)("h2",{id:"configuration"},"Configuration"),Object(i.b)("p",null,"Once created, you can access the configuration of an application at any time via the Settings tab available on the application section"),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/settings.png",alt:"Application Settings"})),Object(i.b)("p",null,"You can find below the description of each of the tabs available in this section"),Object(i.b)("h3",{id:"general"},"General"),Object(i.b)("p",null,"General settings section allows you to set up your application name and the source code location (git repository or image registry) ."),Object(i.b)("h4",{id:"git-repository"},"Git Repository"),Object(i.b)("p",null,"If your application is built and deployed from a git repository, within this section you can:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Modify the git provider where your code is stored (it can be hosted on GitHub, GitLab or Bitbucket)."),Object(i.b)("li",{parentName:"ul"},"Modify the branch that Qovery should use for deploying your application"),Object(i.b)("li",{parentName:"ul"},"Modify ",Object(i.b)("inlineCode",{parentName:"li"},"Root Application Path")," - base folder in which the application resides in your repository")),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/app-general-git.png",alt:"General Settings Git"})),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,"Qovery supports mono repositories. ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/guides/advanced/monorepository/"}),"See our advanced guide for more details."))),Object(i.b)(c.a,{type:"warning",mdxType:"Alert"},Object(i.b)("p",null,"If your repository contains private submodules using SSH protocol, you will need to add a secret beginning with GIT",Object(i.b)("em",{parentName:"p"},"SSH_KEY"),", containing a private SSH key with access rights to your sumbodules repositories."),Object(i.b)("p",null,"Secret names examples:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"GIT_SSH_KEY_GITHUB"),Object(i.b)("li",{parentName:"ul"},"GIT_SSH_KEY_GITLAB"),Object(i.b)("li",{parentName:"ul"},"GIT_SSH_KEY_MYAPP"))),Object(i.b)("h4",{id:"container-registry"},"Container Registry"),Object(i.b)("p",null,"If your application is deployed from an image registry, within this section you can modify:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Registry: select the container registry storing the image of your application. Note: only pre-configured registry are available in this list, check the ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/organization/container-registry/"}),"Container Registry Management page")," for more information."),Object(i.b)("li",{parentName:"ul"},"Image name: the name of the image to be deployed with this application (example: postgres)"),Object(i.b)("li",{parentName:"ul"},"Image tag: the tag of the image to be deployed with this application (example: 1.0)."),Object(i.b)("li",{parentName:"ul"},"Image Entrypoint: the entrypoint to be used to launch your applicaiton (not mandatory)"),Object(i.b)("li",{parentName:"ul"},"CMD Arguments: the arguments to be passed to launch your applicaiton (not mandatory). We expect the format to be an array. Example ",'["rails", "-h", "0.0.0.0", "-p", "8080", "string"]')),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,'Make sure that the image tag used are unique (do not use "latest", "dev", "master" etc..), see ',Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/image-mirroring/#why-unique-image-tags-are-necessary"}),"this section")," for more information.")),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/app-general-registry.png",alt:"General Settings Git"})),Object(i.b)("h4",{id:"build-mode"},"Build Mode"),Object(i.b)("p",null,'This option is available only if you have selected "Git Repository" as source'),Object(i.b)("h4",{id:"option-1-buildpacks"},"Option 1: Buildpacks"),Object(i.b)("p",null,"To simplify the application build for the developer, Qovery supports ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://buildpacks.io"}),"Buildpacks")," out of the box. Buildpacks determine the build process for an app and which assets and runtimes should be made available to your code at runtime. If your complex apps are running multiple languages, you can also use multiple buildpacks within a single app.\nMeaning, as a developer, you don't need to write a ",Object(i.b)("inlineCode",{parentName:"p"},"Dockerfile")," to build and run your app. Qovery Buildpacks takes care of everything for you."),Object(i.b)("p",null,Object(i.b)("strong",{parentName:"p"},"Supported languages")),Object(i.b)("table",null,Object(i.b)("thead",{parentName:"table"},Object(i.b)("tr",{parentName:"thead"},Object(i.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"language"),Object(i.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"version"))),Object(i.b)("tbody",{parentName:"table"},Object(i.b)("tr",{parentName:"tbody"},Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Node.JS"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"any")),Object(i.b)("tr",{parentName:"tbody"},Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Clojure"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"any")),Object(i.b)("tr",{parentName:"tbody"},Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Python"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"any")),Object(i.b)("tr",{parentName:"tbody"},Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Java"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"any")),Object(i.b)("tr",{parentName:"tbody"},Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Gradle"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"any")),Object(i.b)("tr",{parentName:"tbody"},Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"JVM"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"any")),Object(i.b)("tr",{parentName:"tbody"},Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Grails"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"any")),Object(i.b)("tr",{parentName:"tbody"},Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Scala"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"any")),Object(i.b)("tr",{parentName:"tbody"},Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Play"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"any")),Object(i.b)("tr",{parentName:"tbody"},Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"PHP"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"any")),Object(i.b)("tr",{parentName:"tbody"},Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Go"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"any")))),Object(i.b)("p",null,"You don't find a cool language? ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://roadmap.qovery.com/roadmap"}),"Suggest us to support it")),Object(i.b)("h4",{id:"option-2-dockerfile"},"Option 2: Dockerfile"),Object(i.b)("p",null,'If your job is built via the Qovery CI (Source="Git Repository"), this section allows you to define the Dockerfile location. '),Object(i.b)("p",null,"If you don't have one, you can use the ",Object(i.b)("inlineCode",{parentName:"p"},"docker init")," command to generate one for your application (check the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://docs.docker.com/reference/cli/docker/init/"}),"documentation here"),"). After creating a Dockerfile, specify the location of your Dockerfile in ",Object(i.b)("inlineCode",{parentName:"p"},"Dockefile path")," field."),Object(i.b)("h4",{id:"auto-deploy"},"Auto Deploy"),Object(i.b)("p",null,"See the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/deploying-with-auto-deploy/"}),"Deploying with auto-deploy feature")," section."),Object(i.b)("h4",{id:"extra-labelsannotations"},"Extra labels/annotations"),Object(i.b)("p",null,"Add your extra annotation/label groups. See the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/organization/labels-annotations/"}),"Add annotation/label group")," section for more information."),Object(i.b)("h3",{id:"resources"},"Resources"),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/app-13.png",alt:"CPU"})),Object(i.b)("h4",{id:"cpu"},"CPU"),Object(i.b)("p",null,"To configure the number of CPUs that your app needs, adjust the setting in the ",Object(i.b)("inlineCode",{parentName:"p"},"Resources")," section of the application configuration."),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,"Default is 500m (0.5 vCPU). ")),Object(i.b)("p",null,"Please note that in this section you configure the CPU allocated by the cluster for your application and that cannot consume more than this value. Even if the application is underused and consumes fewer resources, the cluster will still reserve the selected amount of CPU."),Object(i.b)("h4",{id:"ram"},"RAM"),Object(i.b)("p",null,"To configure the amount of RAM that your app needs, adjust the setting in ",Object(i.b)("inlineCode",{parentName:"p"},"Resources")," section of the application configuration."),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,"Default is 512MB.")),Object(i.b)("p",null,"Please note that in this section you configure the CPU allocated by the cluster for your application and that cannot consume more than this value. Even if the application is underused and consume less resources, the cluster will still reserve the selected amount of CPU. If your application requires more RAM than requested, it will be killed by the kubernetes scheduler."),Object(i.b)("h4",{id:"auto-scaling"},"Auto-scaling"),Object(i.b)("p",null,"Application auto-scaling is based on real-time CPU consumption. When your app goes above 60% of CPU consumption for 15 seconds, your app will be auto-scaled and more instances will be added. It is transparent. The downscale will happen if the CPU consumption is lower than 60% for at least 5 minutes.\nYou can adjust the minimum and maximum of instances you need in your application settings. Qovery runs your application on Kubernetes and relies on ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://github.com/kubernetes-sigs/metrics-server"}),"metrics-server")," service to auto-scale your app."),Object(i.b)("h3",{id:"storage"},"Storage"),Object(i.b)("h4",{id:"block-storage"},"Block Storage"),Object(i.b)("p",null,"The default filesystem for applications running on Qovery is ephemeral. Application data isn\u2019t persisted across deploys and restarts, which works just fine for most apps because they use managed databases to persist data."),Object(i.b)("p",null,"However, many applications need persistent disk storage that isn\u2019t ephemeral. These include:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Blogging platforms and CMSs like WordPress, Ghost, and Strapi."),Object(i.b)("li",{parentName:"ul"},"Collaboration apps like Mattermost, GitLab, and Discourse.")),Object(i.b)("p",null,"This is where Qovery block Storage comes in. Qovery applications can use storage to store data that persists across deploys and restarts, making it easy to deploy stateful applications."),Object(i.b)(c.a,{type:"warning",mdxType:"Alert"},Object(i.b)("p",null,"For most use cases, it is better to use ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/object-storage/"}),"Object Storage")," instead of Block Storage.")),Object(i.b)("h6",{id:"use-cases"},"Use cases"),Object(i.b)("h6",{id:"-good-use-cases"},"\u2705 Good use cases"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"For I/O intensive applications (E.g. database)"),Object(i.b)("li",{parentName:"ul"},"To store temporary files")),Object(i.b)("h6",{id:"-bad-use-cases"},"\u274c Bad use cases"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"To store file > 1 TB"),Object(i.b)("li",{parentName:"ul"},"To expose files from an application (E.g. images)")),Object(i.b)("h5",{id:"types-of-block-storage"},"Types of Block Storage"),Object(i.b)("p",null,"Qovery Storage supports:"),Object(i.b)("table",null,Object(i.b)("thead",{parentName:"table"},Object(i.b)("tr",{parentName:"thead"},Object(i.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"Type"),Object(i.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"Max IOPS"),Object(i.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"Max Throughput"),Object(i.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"Min Size"),Object(i.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"Max Size"),Object(i.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"Use cases"))),Object(i.b)("tbody",{parentName:"table"},Object(i.b)("tr",{parentName:"tbody"},Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"fast_ssd"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"64000"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"1GB/s"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"5GB"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"10GB ",Object(i.b)("inlineCode",{parentName:"td"},"Community")," / 1TB paid plans"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Critical business applications that require sustained IOPS like databases")))),Object(i.b)("h5",{id:"configuration-1"},"Configuration"),Object(i.b)("p",null,"You can set up your Block Storage in ",Object(i.b)("inlineCode",{parentName:"p"},"Storage")," section of your application configuration."),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/app-7.png",alt:"Application Storage"})),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,"Storage can be added only if the application has never been deployed before AND if it runs only with one instance (check the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/application/#resources"}),"Resources section"),")")),Object(i.b)("h3",{id:"ports"},"Ports"),Object(i.b)("p",null,"Within this section you can define the port exposed by your application to the other services or even over the internet.\nYou can edit the existing ports or declare new ones by specifying:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Application port: this is the port exposed internally by your application for the other services. "),Object(i.b)("li",{parentName:"ul"},"Protocol: you can select the protocol used by your application : HTTP (for both standard HTTP or websocket communications), gRPC, TCP, UDP."),Object(i.b)("li",{parentName:"ul"},"Publicly exposed: it allows you to expose over the public network your service. A public domain will be assigned to your application during the deployment (see ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"#connecting-from-the-internet"}),"Connecting from the internet section"),")"),Object(i.b)("li",{parentName:"ul"},"If Publicly Exposed is selected:",Object(i.b)("ul",{parentName:"li"},Object(i.b)("li",{parentName:"ul"},"External port: it is the port that can be used to access this service over the internet (when exposed publicly). Note that for HTTP and gRPC the port is set by default to 443."),Object(i.b)("li",{parentName:"ul"},"Port Name: it is the name assigned to the port. When multiple ports are exposed publicly, its value is used to route the traffic to the right port based on the called subdomain (which will contain the port name value). Since each port is exposed on the port 443, having a different subdomain is the only way to have multiple ports exposed over the internet. If not set, the default value is ",Object(i.b)("inlineCode",{parentName:"li"},"p")," (see ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"#qovery-provided-domains"}),"Qovery Provided Domain section")," for more information)")))),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/app-15.png",alt:"Application Ports"})),Object(i.b)("h4",{id:"important-informations"},"Important Informations"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Most of the Kubernetes Health Checks]",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/service-health-checks/"}),"docs.using-qovery.configuration.service-health-checks")," are based on the port declared in this section. Make sure you declare the right port and that you configure the health checks properly."),Object(i.b)("li",{parentName:"ul"},"Connections on public ports are automatically closed after 60 seconds. If you want to implement long living connection (like for websockets) please make sure to use the rigth ingress timeouts in the ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/advanced-settings/#network-settings"}),"advanced settings section")),Object(i.b)("li",{parentName:"ul"},"Exposing publicly TCP/UDP ports requires to create a dedicated load balancer and it takes a few minutes before having it ready (~15 minutes). Note also that this has a direct impact on your cloud provider bill."),Object(i.b)("li",{parentName:"ul"},"You can configure your application to use the ",Object(i.b)("strong",{parentName:"li"},"PORT")," environment variable by adding the ",Object(i.b)("strong",{parentName:"li"},"PORT")," on your application env variables page."),Object(i.b)("li",{parentName:"ul"},"A Note on Listening IPs: It's best for your application to listen on ",Object(i.b)("inlineCode",{parentName:"li"},"0.0.0.0:$PORT"),". While most things work with ",Object(i.b)("inlineCode",{parentName:"li"},"127.0.0.1")," and ",Object(i.b)("inlineCode",{parentName:"li"},"localhost"),", some do not (NodeJS for example)")),Object(i.b)("h3",{id:"health-checks"},"Health Checks"),Object(i.b)("p",null,"To know more about how to configure your Liveness and Readiness probes, have a look at ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/application-health-checks/"}),"the health-checks section")),Object(i.b)("h3",{id:"deployment-restrictions"},"Deployment Restrictions"),Object(i.b)("p",null,"This section allows to specify which changes on your repository should trigger an auto-deploy (if enabled). To know more about how to configure your Deployment Restrictions, have a look at the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/deploying-with-auto-deploy/#filtering-commits-triggering-the-auto-deploy"}),"deployment restrictions section"),"."),Object(i.b)("h2",{id:"connecting-from-the-internet"},"Connecting from the internet"),Object(i.b)("p",null,"Your application can be reached from the internet by publicly exposing at least one of its ports (See the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"#ports"}),"Ports")," section to know more). Once this is done, Qovery will generate and assign a domain to your application (See ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"#qovery-provided-domains"}),"this section")," to know more). You can customize the domain assigned to your application via the ",Object(i.b)("inlineCode",{parentName:"p"},"Domain")," section in the settings (see ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"#custom-domains"}),"this section")," to know more)."),Object(i.b)("h3",{id:"qovery-provided-domains"},"Qovery provided domains"),Object(i.b)("p",null,"For each port publicly exposed, a domain is automatically assigned by Qovery to your application. Qovery will manage for you the networking and the TLS configuration for these domains. "),Object(i.b)("p",null,"Example: ",Object(i.b)("inlineCode",{parentName:"p"},"p80-zdf72de72-z709e1a88-gtw.za8ad0657.bool.sh")," or ",Object(i.b)("inlineCode",{parentName:"p"},"-p80-zdf72de72-z709e1a88-gtw.za8ad0657.bool.sh")," for helm services."),Object(i.b)("p",null,"Note:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"each service deployed on the same cluster will have the same root domain assigned (example: ",Object(i.b)("inlineCode",{parentName:"li"},"za8ad0657.bool.sh"),")"),Object(i.b)("li",{parentName:"ul"},"the first characters of the domain (before the ",Object(i.b)("inlineCode",{parentName:"li"},"-"),") is based on the portName given to the port associated with this domain (See the ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"#ports"}),"port section"),")"),Object(i.b)("li",{parentName:"ul"},"a default domain (without the portName) is assigned to the ",Object(i.b)("inlineCode",{parentName:"li"},"default port"),"(See the ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"#ports"}),"port section"),"). Example ",Object(i.b)("inlineCode",{parentName:"li"},"zdf72de72-z709e1a88-gtw.za8ad0657.bool.sh"))),Object(i.b)("p",null,Object(i.b)("strong",{parentName:"p"},"Special Case - Preview Environment"),"\nFor each port exposed publicly, an additional domain will be created with the following pattern ",Object(i.b)("inlineCode",{parentName:"p"},"portName-prId-srvName-envSourceName.cluster_domain"),":"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"portName: is the port name, as explained above"),Object(i.b)("li",{parentName:"ul"},"prID: is the id of the PR that has generated the preview environment"),Object(i.b)("li",{parentName:"ul"},"srvName: is the name of the service"),Object(i.b)("li",{parentName:"ul"},"envSourceName: is the name of the blueprint environment that has created the current preview environment")),Object(i.b)("p",null,"domain example: ",Object(i.b)("inlineCode",{parentName:"p"},"p80-123-frontend-blueprint.za8ad0657.bool.sh")),Object(i.b)("h3",{id:"custom-domains"},"Custom domains"),Object(i.b)("p",null,'If you prefer to assign your own domain to the application, you can customize it from the "Domain" section within the application settings.'),Object(i.b)("p",null,"You can customize the domain of your application in different ways, depending on what you want to achieve:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"You want to use your own domain for your application"),Object(i.b)("li",{parentName:"ul"},"You want to modify the subdomain assigned to your application by Qovery (i.e. change ",Object(i.b)("inlineCode",{parentName:"li"},"p80-zdf72de72-z709e1a88-gtw.za8ad0657.bool.sh")," into ",Object(i.b)("inlineCode",{parentName:"li"},"my-app-domain.za8ad0657.bool.sh"),"). See ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"#qovery-provided-domains"}),"this section")," to know more about these domains.")),Object(i.b)("p",null,"In both cases, you can assign the new custom domain by pressing the ",Object(i.b)("inlineCode",{parentName:"p"},"Add Domain")," button."),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/app-16.png",alt:"Application Domains"})),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,"This configuration will be ",Object(i.b)("strong",{parentName:"p"},"automatically removed")," on every cloned environment or preview environment in order to avoid domain collision.")),Object(i.b)("p",null,"For each custom domain, a green checkmark will appear if the domain is correctly configured. You can perform another check by clicking on the checkmark. If you're behind a CDN, we will only check if your custom domain resolves to an IP address."),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/domain_check.png",alt:"Check Domains"})),Object(i.b)("p",null,"If there's an issue with a domain, a global error message will be displayed, and you can view the error details by hovering over the red cross. After correcting your configuration, you can perform another check by clicking on the red cross."),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/domain_check_error.png",alt:"Check Domains"})),Object(i.b)("h4",{id:"configuring-your-own-domain"},"Configuring your own domain"),Object(i.b)("p",null,"Once the domain is added within the Qovery console (Example: mydomain.com), you need to configure within your DNS two ",Object(i.b)("inlineCode",{parentName:"p"},"CNAME")," records pointing to the domain provided by Qovery, as shown in the UI (example: mydomain.com CNAME za7cc1b71-z4b8474b3-gtw.zc531a994.rustrocks.cloud and *.mydomain.com CNAME za7cc1b71-z4b8474b3-gtw.zc531a994.rustrocks.cloud). "),Object(i.b)("p",null,"Having a wildcard domain entry (example: *.mydomain.com) configured on your DNS will avoid you to modify the Qovery setup every time you want to add a new subdomain. If ",Object(i.b)("inlineCode",{parentName:"p"},"wildcard")," is not supported by your DNS provider, you will have to configure each subdomain manually."),Object(i.b)("p",null,"If a service needs to expose more than one port publicly, you can define a dedicated subdomain to redirect the traffic on the right port by setting the \u201cPort Name\u201d value within the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"#ports"}),"port settings"),"."),Object(i.b)("p",null,"After re-deploying the service, Qovery will automatically handle the TLS/SSL certificate creation and renewal for the configured domain."),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/custom-domain.png",alt:"Custom Domain"})),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/guides/getting-started/setting-custom-domain/"}),"We prepared a guide and video tutorial that explains how to set up your custom domain."))),Object(i.b)("p",null,Object(i.b)("strong",{parentName:"p"}," Special case - domain behind a CDN ")),Object(i.b)("p",null,"If your service is behind a CDN using a ",Object(i.b)("inlineCode",{parentName:"p"},"proxy mode")," (i.e. the traffic is routed through the CDN to Qovery), make sure to enable the option ",Object(i.b)("inlineCode",{parentName:"p"},"Domain behind a CDN"),' and disable the option "Generate certificate" on the domain setup. Since the certificate of your domain is directly managed by the CDN, Qovery won\'t be able to do that for you and it will raise warnings on your application status.'),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/cdn-proxy.png",alt:"CDN Proxy"})),Object(i.b)("p",null,"If you are using Cloudflare to manage your CDN, we can also manage automatically your custom domain configuration via a wildcard domain setup for the whole cluster. Check our ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/clusters/#use-custom-domain-and-wildcard-tls-for-the-whole-cluster-beta"}),"documentation here")),Object(i.b)("h4",{id:"change-the-auto-assigned-sub-domain"},"Change the auto assigned sub-domain"),Object(i.b)("p",null,"You can specify a different sub-domain for your application as long as it belongs to the assigned cluster domain (see ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"#qovery-provided-domains"}),"Qovery provided domains"),").\nExample: "),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"your current domain is zdf72de71-z709e1a85-gtw.za8ad0659.bool.sh (so your assigned cluster domain is ",Object(i.b)("inlineCode",{parentName:"li"},"za8ad0659.bool.sh"),")"),Object(i.b)("li",{parentName:"ul"},"you can enter a new custom domain ",Object(i.b)("inlineCode",{parentName:"li"},"myfrontend.za8ad0659.bool.sh")," (since it is a subdomain of the cluster domain)")),Object(i.b)("p",null,"The application will now be accessible from both the default and the new custom domain."),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,"Qovery does not check collision in the domain declaration. Make sure you assign a unique subdomain within your cluster.")),Object(i.b)("h2",{id:"connecting-to-a-database"},"Connecting to a database"),Object(i.b)("p",null,"To know how to access your database from your application, ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment-variable/#connecting-to-a-database"}),"have a look at the database section"),"."),Object(i.b)("h2",{id:"connecting-to-another-application"},"Connecting to another application"),Object(i.b)("p",null,"To know how to access your database from your application, ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment-variable/#connecting-to-another-application"}),"have a look at the database section"),"."),Object(i.b)("h2",{id:"environment-variable"},"Environment Variable"),Object(i.b)("p",null,"To learn how to set up environment variables in your projects and applications, navigate to ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment-variable/"}),"configuring Environment Variables")," section."),Object(i.b)("h2",{id:"secrets"},"Secrets"),Object(i.b)("p",null,"To learn how to set up secrets in your projects and applications, navigate to ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment-variable/"}),"configuring Secrets")," section."),Object(i.b)("h2",{id:"logs"},"Logs"),Object(i.b)("p",null,"To learn how to display your application logs, navigate to ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/logs/#live-logs"}),"logs section")),Object(i.b)("h2",{id:"ssh"},"SSH"),Object(i.b)("p",null,"To connect to your application via SSH, please use the via the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/interface/cli/"}),"Qovery SSH command")," available on our CLI."),Object(i.b)("h2",{id:"clone"},"Clone"),Object(i.b)("p",null,"You can create a clone of the service via the clone feature. A new service with the same configuration (see below for exceptions) will be created into the target environment."),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/clone_service.png",alt:"Clone Service"})),Object(i.b)("p",null,"The target environment can be the same as the current environment or even another one in a completely different project."),Object(i.b)("p",null,Object(i.b)("strong",{parentName:"p"}," Important information ")),Object(i.b)("p",null,"Not every configuration parameter will be copied within the new service for consistency reasons. The configuration is fully or partially copied depending on the target environment:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"same environment:",Object(i.b)("ul",{parentName:"li"},Object(i.b)("li",{parentName:"ul"},"custom domain: this setup is not copied into the new service (to avoid collision)"))),Object(i.b)("li",{parentName:"ul"},"another environment:",Object(i.b)("ul",{parentName:"li"},Object(i.b)("li",{parentName:"ul"},"custom domain: this setup is not copied into the new service (to avoid collision)"),Object(i.b)("li",{parentName:"ul"},"environment variable: aliases defined on environment variables are not copied (since the aliased env var might not exist)"),Object(i.b)("li",{parentName:"ul"},"deployment pipeline: stage setup is not copied (since the target stage might not exist)"),Object(i.b)("li",{parentName:"ul"},"number of instances: if the target environment runs on a Qovery EC2 cluster, the max number of instances is set to 1 (Qovery EC2 constraint)")))),Object(i.b)("p",null,"Please check the configuration of the new service before deploying it."),Object(i.b)("h2",{id:"advanced-settings"},"Advanced Settings"),Object(i.b)("p",null,"You can further customize the service behaviour via the service advanced settings. Check ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/advanced-settings/"}),"this documentation")," to know more."),Object(i.b)("h2",{id:"delete-an-application"},"Delete an Application"),Object(i.b)(r.a,{headingDepth:3,mdxType:"Steps"},Object(i.b)("ol",null,Object(i.b)("li",null,Object(i.b)("p",null,"Choose your application")),Object(i.b)("li",null,Object(i.b)("p",null,"In the application overview, click on the ",Object(i.b)("inlineCode",{parentName:"p"},"3 dots")," button and remove the application."),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/app-1.png",alt:"Application"}))))))}d.isMDXComponent=!0},455:function(e,t,n){var a;!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=o.a.createContext({}),b=function(e){var t=o.a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):c({},t,{},e)),n},p=function(e){var t=b(e.components);return o.a.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.a.createElement(o.a.Fragment,{},t)}},d=Object(a.forwardRef)((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,r=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),p=b(n),d=a,m=p["".concat(r,".").concat(d)]||p[d]||u[d]||i;return n?o.a.createElement(m,c({ref:t},s,{components:n})):o.a.createElement(m,c({ref:t},s))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,r=new Array(i);r[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:a,r[1]=c;for(var s=2;s1?arguments[1]:void 0,n),l=r>2?arguments[2]:void 0,s=void 0===l?n:o(l,n);s>c;)t[c++]=e;return t}},460:function(e,t,n){var a=n(28).f,o=Function.prototype,i=/^\s*function ([^ (]*)/;"name"in o||n(10)&&a(o,"name",{configurable:!0,get:function(){try{return(""+this).match(i)[1]}catch(e){return""}}})},461:function(e,t,n){"use strict";n(460);var a=n(0),o=n.n(a),i=n(456);t.a=function(e){var t=e.children,n=e.name;return o.a.createElement(i.a,{type:"info",fill:!0,icon:!1,rounded:!0,className:"list--icons list--icons--arrow list--tight list--indent margin-bottom--lg"},o.a.createElement("p",{class:"text--lg margin-bottom--sm",style:{marginTop:"-0.25em"}},"Before you begin, this ",n||"page"," assumes the following:"),t)}},462:function(e,t,n){"use strict";var a=n(1),o=n(0),i=n.n(o),r=n(39),c=n(466),l=n(20),s=n.n(l);t.a=function(e){var t,n=e.to,l=e.href,b=n||l,p=Object(c.a)(b),u=Object(o.useRef)(!1),d=s.a.canUseIntersectionObserver;return Object(o.useEffect)((function(){return!d&&p&&window.docusaurus.prefetch(b),function(){d&&t&&t.disconnect()}}),[b,d,p]),b&&p?i.a.createElement(r.b,Object(a.a)({},e,{onMouseEnter:function(){u.current||(window.docusaurus.preload(b),u.current=!0)},innerRef:function(e){var n,a;d&&e&&p&&(n=e,a=function(){window.docusaurus.prefetch(b)},(t=new window.IntersectionObserver((function(e){e.forEach((function(e){n===e.target&&(e.isIntersecting||e.intersectionRatio>0)&&(t.unobserve(n),t.disconnect(),a())}))}))).observe(n))},to:b})):i.a.createElement("a",Object(a.a)({},e,{href:b}))}},463:function(e,t,n){"use strict";var a=n(467),o=n(51);function i(e,t){return t.encode?t.strict?a(e):encodeURIComponent(e):e}t.extract=function(e){return e.split("?")[1]||""},t.parse=function(e,t){var n=function(e){var t;switch(e.arrayFormat){case"index":return function(e,n,a){t=/\[(\d*)\]$/.exec(e),e=e.replace(/\[\d*\]$/,""),t?(void 0===a[e]&&(a[e]={}),a[e][t[1]]=n):a[e]=n};case"bracket":return function(e,n,a){t=/(\[\])$/.exec(e),e=e.replace(/\[\]$/,""),t?void 0!==a[e]?a[e]=[].concat(a[e],n):a[e]=[n]:a[e]=n};default:return function(e,t,n){void 0!==n[e]?n[e]=[].concat(n[e],t):n[e]=t}}}(t=o({arrayFormat:"none"},t)),a=Object.create(null);return"string"!=typeof e?a:(e=e.trim().replace(/^(\?|#|&)/,""))?(e.split("&").forEach((function(e){var t=e.replace(/\+/g," ").split("="),o=t.shift(),i=t.length>0?t.join("="):void 0;i=void 0===i?null:decodeURIComponent(i),n(decodeURIComponent(o),i,a)})),Object.keys(a).sort().reduce((function(e,t){var n=a[t];return Boolean(n)&&"object"==typeof n&&!Array.isArray(n)?e[t]=function e(t){return Array.isArray(t)?t.sort():"object"==typeof t?e(Object.keys(t)).sort((function(e,t){return Number(e)-Number(t)})).map((function(e){return t[e]})):t}(n):e[t]=n,e}),Object.create(null))):a},t.stringify=function(e,t){var n=function(e){switch(e.arrayFormat){case"index":return function(t,n,a){return null===n?[i(t,e),"[",a,"]"].join(""):[i(t,e),"[",i(a,e),"]=",i(n,e)].join("")};case"bracket":return function(t,n){return null===n?i(t,e):[i(t,e),"[]=",i(n,e)].join("")};default:return function(t,n){return null===n?i(t,e):[i(t,e),"=",i(n,e)].join("")}}}(t=o({encode:!0,strict:!0,arrayFormat:"none"},t));return e?Object.keys(e).sort().map((function(a){var o=e[a];if(void 0===o)return"";if(null===o)return i(a,t);if(Array.isArray(o)){var r=[];return o.slice().forEach((function(e){void 0!==e&&r.push(n(a,e,r.length))})),r.join("&")}return i(a,t)+"="+i(o,t)})).filter((function(e){return e.length>0})).join("&"):""}},464:function(e,t,n){"use strict";var a=n(0),o=n.n(a),i=(n(455),n(463)),r=n.n(i);n(133);t.a=function(e){var t=e.children,n=e.headingDepth,i=e.hideFeedbackQuestion,c="undefined"!=typeof window?window.location:null,l={title:"Tutorial on "+c+" failed",body:"The tutorial on:\n\n"+c+"\n\nHere's what went wrong:\n\n\x3c!-- Insert command output and details. Thank you for reporting! :) --\x3e"},s="https://github.com/qovery/documentation/issues/new?"+r.a.stringify(l),b=Object(a.useState)(null),p=b[0],u=b[1];return o.a.createElement("div",{className:"steps steps--h"+n},t,!i&&!p&&o.a.createElement("div",{className:"steps--feedback"},"How was it? Did this tutorial work?\xa0\xa0",o.a.createElement("span",{className:"button button--sm button--primary",onClick:function(){return u("yes")}},"Yes"),"\xa0\xa0",o.a.createElement("a",{href:s,target:"_blank",className:"button button--sm button--primary"},"No")),"yes"==p&&o.a.createElement("div",{className:"steps--feedback steps--feedback--success"},"Thanks! If you're enjoying Qovery please consider ",o.a.createElement("a",{href:"https://github.com/qovery/documentation/",target:"_blank"},"starring our Github repo"),"."))}},465:function(e,t,n){"use strict";var a=n(0),o=n.n(a),i=n(462),r=n(455),c=n.n(r);n(134);t.a=function(e){var t=e.children,n=e.className,a=e.badge,r=e.leftIcon,l=e.rightIcon,s=e.size,b=e.target,p=e.to,u=c()("jump-to","jump-to--"+s,n),d=o.a.createElement("div",{className:"jump-to--inner"},o.a.createElement("div",{className:"jump-to--inner-2"},r&&o.a.createElement("div",{className:"jump-to--left"},o.a.createElement("i",{className:"feather icon-"+r})),o.a.createElement("div",{className:"jump-to--main"},a?o.a.createElement("span",{className:"badge badge--primary badge--right"},a):"",t),o.a.createElement("div",{className:"jump-to--right"},o.a.createElement("i",{className:"feather icon-"+(l||"chevron-right")+" arrow"}))));return b?o.a.createElement("a",{href:p,target:b,className:u},d):o.a.createElement(i.a,{to:p,className:u},d)}},466:function(e,t,n){"use strict";function a(e){return!1===/^(https?:|\/\/)/.test(e)}n.d(t,"a",(function(){return a}))},467:function(e,t,n){"use strict";e.exports=function(e){return encodeURIComponent(e).replace(/[!'()*]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}}}]); \ No newline at end of file diff --git a/8d5726d6.90562f3c.js b/8d5726d6.90562f3c.js new file mode 100644 index 0000000000..9721749f8c --- /dev/null +++ b/8d5726d6.90562f3c.js @@ -0,0 +1,2 @@ +/*! For license information please see 8d5726d6.90562f3c.js.LICENSE.txt */ +(window.webpackJsonp=window.webpackJsonp||[]).push([[158],{310:function(e,t,n){"use strict";n.r(t),n.d(t,"frontMatter",(function(){return s})),n.d(t,"metadata",(function(){return p})),n.d(t,"rightToc",(function(){return b})),n.d(t,"default",(function(){return d}));var a=n(1),o=n(9),i=(n(0),n(457)),r=n(464),c=(n(465),n(456)),l=n(461),s={last_modified_on:"2024-09-18",title:"Application",description:"Learn how to configure your Application on Qovery"},p={id:"using-qovery/configuration/application",title:"Application",description:"Learn how to configure your Application on Qovery",source:"@site/docs/using-qovery/configuration/application.md",permalink:"/docs/using-qovery/configuration/application",sidebar:"docs",previous:{title:"Environment",permalink:"/docs/using-qovery/configuration/environment"},next:{title:"Helm",permalink:"/docs/using-qovery/configuration/helm"}},b=[{value:"Deploying from a Git Repository",id:"deploying-from-a-git-repository",children:[]},{value:"Deploying from a Container Registry",id:"deploying-from-a-container-registry",children:[]},{value:"Create an Application",id:"create-an-application",children:[]},{value:"Deployment Management",id:"deployment-management",children:[]},{value:"Configuration",id:"configuration",children:[{value:"General",id:"general",children:[]},{value:"Resources",id:"resources",children:[]},{value:"Storage",id:"storage",children:[]},{value:"Ports",id:"ports",children:[]},{value:"Health Checks",id:"health-checks",children:[]},{value:"Deployment Restrictions",id:"deployment-restrictions",children:[]}]},{value:"Connecting from the internet",id:"connecting-from-the-internet",children:[{value:"Qovery provided domains",id:"qovery-provided-domains",children:[]},{value:"Custom domains",id:"custom-domains",children:[]}]},{value:"Connecting to a database",id:"connecting-to-a-database",children:[]},{value:"Connecting to another application",id:"connecting-to-another-application",children:[]},{value:"Environment Variable",id:"environment-variable",children:[]},{value:"Secrets",id:"secrets",children:[]},{value:"Logs",id:"logs",children:[]},{value:"SSH",id:"ssh",children:[]},{value:"Clone",id:"clone",children:[]},{value:"Advanced Settings",id:"advanced-settings",children:[]},{value:"Delete an Application",id:"delete-an-application",children:[]}],u={rightToc:b};function d(e){var t=e.components,n=Object(o.a)(e,["components"]);return Object(i.b)("wrapper",Object(a.a)({},u,n,{components:t,mdxType:"MDXLayout"}),Object(i.b)(l.a,{name:"documentation",mdxType:"Assumptions"},Object(i.b)("p",null,"You have created an ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment/"}),"Environment"),".")),Object(i.b)("p",null,"An ",Object(i.b)("strong",{parentName:"p"},"application")," is part of a ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/project/"}),"Project")," within an ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment/"}),"Environment")," and is a container unit. Multiple applications can be part of the same ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment/"}),"Environment"),", be connected to a set of dependencies (databases and other services), and can communicate with other applications within the same Environment."),Object(i.b)("p",null,"Qovery allows you to create and deploy applications from two different sources: Git Repository or Container Registry"),Object(i.b)("h2",{id:"deploying-from-a-git-repository"},"Deploying from a Git Repository"),Object(i.b)("p",null,"In this configuration, Qovery will pull the code from the chosen repository, build the application and deploy it on your kubernetes cluster."),Object(i.b)("p",null,"The list of Git repositories available during the setup is strictly tied to the permissions of your git account (by default Qovery can access all your repositories). If you want to restrict the Qovery access only to a few repositories, user the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/organization/git-repository-access/"}),"GitHub Qovery Application")," (only for Github)."),Object(i.b)("h2",{id:"deploying-from-a-container-registry"},"Deploying from a Container Registry"),Object(i.b)("p",null,"In this configuration, Qovery will pull the chosen container registry an image you have pre-built and deploy it on your kubernetes cluster."),Object(i.b)("p",null,"To improve security and avoid deploying images from non-authorized registries, we have decided to restrict the list of Container Registry you can use during the setup process. Only an administrator with the right permissions can manage it from the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/organization/container-registry/"}),"Container Registry Management page")),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,'Make sure that the image tag used are unique (do not use "latest", "dev", "master" etc..), see ',Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/image-mirroring/#why-unique-image-tags-are-necessary"}),"this section")," for more information.")),Object(i.b)("h2",{id:"create-an-application"},"Create an Application"),Object(i.b)(r.a,{headingDepth:3,mdxType:"Steps"},Object(i.b)("ol",null,Object(i.b)("li",null,Object(i.b)("p",null,'Go into the chosen environment and press the "New Service" button and then the "Create application" button'),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/creation_1.png",alt:"Creation"}))),Object(i.b)("li",null,Object(i.b)("p",null,"Select the following fields:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Application Name: give a name to your application"),Object(i.b)("li",{parentName:"ul"},"Application Source: Chose between Git Repository or Container Registry, depending on the source location of your application")),Object(i.b)("p",null,"If you want to deploy an application from a Git Repository you will have to select:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Git Repository: Select the git provider hosting your code (it can be hosted on GitHub, GitLab or Bitbucket). You can add a new git access by clicking on ",Object(i.b)("inlineCode",{parentName:"li"},"New git access"),"."),Object(i.b)("li",{parentName:"ul"},"Branch: Select branch that Qovery should use to deploy your application"),Object(i.b)("li",{parentName:"ul"},"Root Application Path: base folder in which the application resides in your repository"),Object(i.b)("li",{parentName:"ul"},"Build and deploy: configure your Dockerfile location. For more information, go to ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/application/#build-and-deploy"}),"this section"))),Object(i.b)("p",null,"If you want to deploy an application from a Container Registry you will have to select:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Registry: select the container registry storing the image of your application. You can add a new container registry by clicking on ",Object(i.b)("inlineCode",{parentName:"li"},"New registry"),"."),Object(i.b)("li",{parentName:"ul"},"Image name: the name of the image to be deployed with this application (example: postgres)"),Object(i.b)("li",{parentName:"ul"},"Image tag: the tag of the image to be deployed with this application (example: 1.0). "),Object(i.b)("li",{parentName:"ul"},"Image Entrypoint: the entrypoint to be used to launch your application (not mandatory)"),Object(i.b)("li",{parentName:"ul"},"CMD Arguments: the arguments to be passed to launch your application (not mandatory) separated with a space. Example: ",Object(i.b)("inlineCode",{parentName:"li"},'rails -h 0.0.0.0 -p 8080 string "complex arg"'),".")),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,'Make sure that the image tag used are unique (do not use "latest", "dev", "master" etc..), see ',Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/image-mirroring/#why-unique-image-tags-are-necessary"}),"this section")," for more information.")),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,"If the base image in your Dockerfile is from a private registry, you just have to add the access to this registry before creating your application. See ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/organization/container-registry/"}),"Container Registry Management page")," for more information.")),Object(i.b)("p",null,Object(i.b)("strong",{parentName:"p"}," Auto Deploy ")),Object(i.b)("p",null,"See the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/deploying-with-auto-deploy/"}),"Deploying with auto-deploy feature")," section."),Object(i.b)("p",null,Object(i.b)("strong",{parentName:"p"}," Extra labels/annotations (optional)")),Object(i.b)("p",null,"Add your extra annotation/label groups. See the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/organization/labels-annotations/"}),"Add annotation/label group")," section for more information.")),Object(i.b)("li",null,Object(i.b)("p",null,"Within this section, you will need to define the resources to be assigned to your application at run time."),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"vCPU: the vCPU assigned to each instance of your application. The default is 500m (0.5 vCPU)."),Object(i.b)("li",{parentName:"ul"},"RAM: the amount of RAM assigned to each instance of your application. The default is 512MB."),Object(i.b)("li",{parentName:"ul"},"Number of instances (Application Auto-scaling): select the minimum and the maximum number of instances of your application that can run within your cluster. The number of instances running at an insant t is automatically managed by Kubernetes (Application auto-scaling) and it is based on real-time CPU consumption. When your app goes above 60% of CPU consumption for 5 minutes, your app will be auto-scaled and more instances will be added. It is transparent.\nQovery runs your application on Kubernetes and relies on ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"https://github.com/kubernetes-sigs/metrics-server"}),"metrics-server")," service to auto-scale your app.")),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,"Please note that in this section you configure the CPU/RAM allocated by the cluster for your application and that cannot consume more than this value. Even if the application is underused and consume less resources, the cluster will still reserve the selected amount of CPU/RAM.")),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/application_creation_resources.png",alt:"Resources"}))),Object(i.b)("li",null,Object(i.b)("p",null,"You can now define one or more ports for your Application. Most of the application needs to be accessed by other services inside or outside your environment over different L7/L4 protocols.\nToday Qovery supports the following protocols:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"HTTPS (Select this protocol if you need to run Websockets)"),Object(i.b)("li",{parentName:"ul"},"gRPC"),Object(i.b)("li",{parentName:"ul"},"TCP"),Object(i.b)("li",{parentName:"ul"},"UDP")),Object(i.b)("p",null,"By default ports are accessible only from inside your environment. You can also expose them publicly, making them accessible over the public network via a dedicated public domain that will be assigned to your application by Qovery during the deployment (See the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"#qovery-provided-domains"}),"Qovery Provided Domains section"),"). Note that HTTPS/gRPC ports are always exposed over the port 443."),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/application_creation_port.png",alt:"Application Ports"})),Object(i.b)("p",null,Object(i.b)("strong",{parentName:"p"},"Important Informations")),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Most of the ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/service-health-checks/"}),"Kubernetes Health Checks")," are based on the port declared in this section. Make sure you declare the right port and that you configure the health checks properly."),Object(i.b)("li",{parentName:"ul"},"Connections on public ports are automatically closed after 60 seconds. If you want to implement long living connection (like for websockets) please make sure to use the rigth ingress timeouts in the ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/advanced-settings/#network-settings"}),"advanced settings section")),Object(i.b)("li",{parentName:"ul"},"Exposing publicly TCP/UDP ports requires to create a dedicated load balancer and it takes a few minutes before having it ready (~15 minutes). Note also that this has a direct impact on your cloud provider bill."),Object(i.b)("li",{parentName:"ul"},"You can configure your application to use the ",Object(i.b)("strong",{parentName:"li"},"PORT")," environment variable by adding the ",Object(i.b)("strong",{parentName:"li"},"PORT")," on your application env variables page."),Object(i.b)("li",{parentName:"ul"},"A Note on Listening IPs: It is best for your application to listen on ",Object(i.b)("inlineCode",{parentName:"li"},"0.0.0.0:$PORT"),". While most things work with ",Object(i.b)("inlineCode",{parentName:"li"},"127.0.0.1")," and ",Object(i.b)("inlineCode",{parentName:"li"},"localhost"),", some do not (NodeJS for example)"))),Object(i.b)("li",null,Object(i.b)("p",null,"(Optional) If a port has been defined for your application, you can define the health check probes to run in order to verify the state of your application"),Object(i.b)("p",null,"To know more about how to configure your Liveness and Readiness probes, have a look at ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/application-health-checks/"}),"the health-checks section"))),Object(i.b)("li",null,Object(i.b)("p",null,"Define any input variable required by your application to run. Any declared variable will be injected as environment variables based on the selected scope (project, environment, service)\nAny additional environment variable can be added later from the environment variable section"),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/job/variables.png",alt:"Input Variables"}))),Object(i.b)("li",null,Object(i.b)("p",null,"You will find a recap of your application setup and you can now decide to:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Go back to one of the previous steps and change your application settings"),Object(i.b)("li",{parentName:"ul"},"Create your application without deploying it"),Object(i.b)("li",{parentName:"ul"},"Create and deploy your application")),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/application_creation_recap.png",alt:"Application"}))))),Object(i.b)("h2",{id:"deployment-management"},"Deployment Management"),Object(i.b)("p",null,"Have a look at the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/"}),"Deployment Management")," section for more information."),Object(i.b)("h2",{id:"configuration"},"Configuration"),Object(i.b)("p",null,"Once created, you can access the configuration of an application at any time via the Settings tab available on the application section"),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/settings.png",alt:"Application Settings"})),Object(i.b)("p",null,"You can find below the description of each of the tabs available in this section"),Object(i.b)("h3",{id:"general"},"General"),Object(i.b)("p",null,"General settings section allows you to set up your application name and the source code location (git repository or image registry) ."),Object(i.b)("h4",{id:"git-repository"},"Git Repository"),Object(i.b)("p",null,"If your application is built and deployed from a git repository, within this section you can:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Modify the git provider where your code is stored (it can be hosted on GitHub, GitLab or Bitbucket)."),Object(i.b)("li",{parentName:"ul"},"Modify the branch that Qovery should use for deploying your application"),Object(i.b)("li",{parentName:"ul"},"Modify ",Object(i.b)("inlineCode",{parentName:"li"},"Root Application Path")," - base folder in which the application resides in your repository")),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/app-general-git.png",alt:"General Settings Git"})),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,"Qovery supports mono repositories. ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/guides/advanced/monorepository/"}),"See our advanced guide for more details."))),Object(i.b)(c.a,{type:"warning",mdxType:"Alert"},Object(i.b)("p",null,"If your repository contains private submodules using SSH protocol, you will need to add a secret beginning with GIT",Object(i.b)("em",{parentName:"p"},"SSH_KEY"),", containing a private SSH key with access rights to your sumbodules repositories."),Object(i.b)("p",null,"Secret names examples:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"GIT_SSH_KEY_GITHUB"),Object(i.b)("li",{parentName:"ul"},"GIT_SSH_KEY_GITLAB"),Object(i.b)("li",{parentName:"ul"},"GIT_SSH_KEY_MYAPP"))),Object(i.b)("h4",{id:"container-registry"},"Container Registry"),Object(i.b)("p",null,"If your application is deployed from an image registry, within this section you can modify:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Registry: select the container registry storing the image of your application. Note: only pre-configured registry are available in this list, check the ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/organization/container-registry/"}),"Container Registry Management page")," for more information."),Object(i.b)("li",{parentName:"ul"},"Image name: the name of the image to be deployed with this application (example: postgres)"),Object(i.b)("li",{parentName:"ul"},"Image tag: the tag of the image to be deployed with this application (example: 1.0)."),Object(i.b)("li",{parentName:"ul"},"Image Entrypoint: the entrypoint to be used to launch your applicaiton (not mandatory)"),Object(i.b)("li",{parentName:"ul"},"CMD Arguments: the arguments to be passed to launch your applicaiton (not mandatory). We expect the format to be an array. Example ",'["rails", "-h", "0.0.0.0", "-p", "8080", "string"]')),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,'Make sure that the image tag used are unique (do not use "latest", "dev", "master" etc..), see ',Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/image-mirroring/#why-unique-image-tags-are-necessary"}),"this section")," for more information.")),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/app-general-registry.png",alt:"General Settings Git"})),Object(i.b)("h4",{id:"build-and-deploy"},"Build and Deploy"),Object(i.b)("p",null,'If your job is built via the Qovery CI (Source="Git Repository"), this section allows you to define the Dockerfile location. '),Object(i.b)("p",null,"If you don't have one, you can use the ",Object(i.b)("inlineCode",{parentName:"p"},"docker init")," command to generate one for your application (check the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://docs.docker.com/reference/cli/docker/init/"}),"documentation here"),"). After creating a Dockerfile, specify the location of your Dockerfile in ",Object(i.b)("inlineCode",{parentName:"p"},"Dockefile path")," field."),Object(i.b)("h4",{id:"auto-deploy"},"Auto Deploy"),Object(i.b)("p",null,"See the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/deploying-with-auto-deploy/"}),"Deploying with auto-deploy feature")," section."),Object(i.b)("h4",{id:"extra-labelsannotations"},"Extra labels/annotations"),Object(i.b)("p",null,"Add your extra annotation/label groups. See the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/organization/labels-annotations/"}),"Add annotation/label group")," section for more information."),Object(i.b)("h3",{id:"resources"},"Resources"),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/app-13.png",alt:"CPU"})),Object(i.b)("h4",{id:"cpu"},"CPU"),Object(i.b)("p",null,"To configure the number of CPUs that your app needs, adjust the setting in the ",Object(i.b)("inlineCode",{parentName:"p"},"Resources")," section of the application configuration."),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,"Default is 500m (0.5 vCPU). ")),Object(i.b)("p",null,"Please note that in this section you configure the CPU allocated by the cluster for your application and that cannot consume more than this value. Even if the application is underused and consumes fewer resources, the cluster will still reserve the selected amount of CPU."),Object(i.b)("h4",{id:"ram"},"RAM"),Object(i.b)("p",null,"To configure the amount of RAM that your app needs, adjust the setting in ",Object(i.b)("inlineCode",{parentName:"p"},"Resources")," section of the application configuration."),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,"Default is 512MB.")),Object(i.b)("p",null,"Please note that in this section you configure the CPU allocated by the cluster for your application and that cannot consume more than this value. Even if the application is underused and consume less resources, the cluster will still reserve the selected amount of CPU. If your application requires more RAM than requested, it will be killed by the kubernetes scheduler."),Object(i.b)("h4",{id:"auto-scaling"},"Auto-scaling"),Object(i.b)("p",null,"Application auto-scaling is based on real-time CPU consumption. When your app goes above 60% of CPU consumption for 15 seconds, your app will be auto-scaled and more instances will be added. It is transparent. The downscale will happen if the CPU consumption is lower than 60% for at least 5 minutes.\nYou can adjust the minimum and maximum of instances you need in your application settings. Qovery runs your application on Kubernetes and relies on ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://github.com/kubernetes-sigs/metrics-server"}),"metrics-server")," service to auto-scale your app."),Object(i.b)("h3",{id:"storage"},"Storage"),Object(i.b)("h4",{id:"block-storage"},"Block Storage"),Object(i.b)("p",null,"The default filesystem for applications running on Qovery is ephemeral. Application data isn\u2019t persisted across deploys and restarts, which works just fine for most apps because they use managed databases to persist data."),Object(i.b)("p",null,"However, many applications need persistent disk storage that isn\u2019t ephemeral. These include:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Blogging platforms and CMSs like WordPress, Ghost, and Strapi."),Object(i.b)("li",{parentName:"ul"},"Collaboration apps like Mattermost, GitLab, and Discourse.")),Object(i.b)("p",null,"This is where Qovery block Storage comes in. Qovery applications can use storage to store data that persists across deploys and restarts, making it easy to deploy stateful applications."),Object(i.b)(c.a,{type:"warning",mdxType:"Alert"},Object(i.b)("p",null,"For most use cases, it is better to use ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/object-storage/"}),"Object Storage")," instead of Block Storage.")),Object(i.b)("h6",{id:"use-cases"},"Use cases"),Object(i.b)("h6",{id:"-good-use-cases"},"\u2705 Good use cases"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"For I/O intensive applications (E.g. database)"),Object(i.b)("li",{parentName:"ul"},"To store temporary files")),Object(i.b)("h6",{id:"-bad-use-cases"},"\u274c Bad use cases"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"To store file > 1 TB"),Object(i.b)("li",{parentName:"ul"},"To expose files from an application (E.g. images)")),Object(i.b)("h5",{id:"types-of-block-storage"},"Types of Block Storage"),Object(i.b)("p",null,"Qovery Storage supports:"),Object(i.b)("table",null,Object(i.b)("thead",{parentName:"table"},Object(i.b)("tr",{parentName:"thead"},Object(i.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"Type"),Object(i.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"Max IOPS"),Object(i.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"Max Throughput"),Object(i.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"Min Size"),Object(i.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"Max Size"),Object(i.b)("th",Object(a.a)({parentName:"tr"},{align:null}),"Use cases"))),Object(i.b)("tbody",{parentName:"table"},Object(i.b)("tr",{parentName:"tbody"},Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"fast_ssd"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"64000"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"1GB/s"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"5GB"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"10GB ",Object(i.b)("inlineCode",{parentName:"td"},"Community")," / 1TB paid plans"),Object(i.b)("td",Object(a.a)({parentName:"tr"},{align:null}),"Critical business applications that require sustained IOPS like databases")))),Object(i.b)("h5",{id:"configuration-1"},"Configuration"),Object(i.b)("p",null,"You can set up your Block Storage in ",Object(i.b)("inlineCode",{parentName:"p"},"Storage")," section of your application configuration."),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/app-7.png",alt:"Application Storage"})),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,"Storage can be added only if the application has never been deployed before AND if it runs only with one instance (check the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/application/#resources"}),"Resources section"),")")),Object(i.b)("h3",{id:"ports"},"Ports"),Object(i.b)("p",null,"Within this section you can define the port exposed by your application to the other services or even over the internet.\nYou can edit the existing ports or declare new ones by specifying:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Application port: this is the port exposed internally by your application for the other services. "),Object(i.b)("li",{parentName:"ul"},"Protocol: you can select the protocol used by your application : HTTP (for both standard HTTP or websocket communications), gRPC, TCP, UDP."),Object(i.b)("li",{parentName:"ul"},"Publicly exposed: it allows you to expose over the public network your service. A public domain will be assigned to your application during the deployment (see ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"#connecting-from-the-internet"}),"Connecting from the internet section"),")"),Object(i.b)("li",{parentName:"ul"},"If Publicly Exposed is selected:",Object(i.b)("ul",{parentName:"li"},Object(i.b)("li",{parentName:"ul"},"External port: it is the port that can be used to access this service over the internet (when exposed publicly). Note that for HTTP and gRPC the port is set by default to 443."),Object(i.b)("li",{parentName:"ul"},"Port Name: it is the name assigned to the port. When multiple ports are exposed publicly, its value is used to route the traffic to the right port based on the called subdomain (which will contain the port name value). Since each port is exposed on the port 443, having a different subdomain is the only way to have multiple ports exposed over the internet. If not set, the default value is ",Object(i.b)("inlineCode",{parentName:"li"},"p")," (see ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"#qovery-provided-domains"}),"Qovery Provided Domain section")," for more information)")))),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/app-15.png",alt:"Application Ports"})),Object(i.b)("h4",{id:"important-informations"},"Important Informations"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Most of the Kubernetes Health Checks]",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/service-health-checks/"}),"docs.using-qovery.configuration.service-health-checks")," are based on the port declared in this section. Make sure you declare the right port and that you configure the health checks properly."),Object(i.b)("li",{parentName:"ul"},"Connections on public ports are automatically closed after 60 seconds. If you want to implement long living connection (like for websockets) please make sure to use the rigth ingress timeouts in the ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"/docs/using-qovery/configuration/advanced-settings/#network-settings"}),"advanced settings section")),Object(i.b)("li",{parentName:"ul"},"Exposing publicly TCP/UDP ports requires to create a dedicated load balancer and it takes a few minutes before having it ready (~15 minutes). Note also that this has a direct impact on your cloud provider bill."),Object(i.b)("li",{parentName:"ul"},"You can configure your application to use the ",Object(i.b)("strong",{parentName:"li"},"PORT")," environment variable by adding the ",Object(i.b)("strong",{parentName:"li"},"PORT")," on your application env variables page."),Object(i.b)("li",{parentName:"ul"},"A Note on Listening IPs: It's best for your application to listen on ",Object(i.b)("inlineCode",{parentName:"li"},"0.0.0.0:$PORT"),". While most things work with ",Object(i.b)("inlineCode",{parentName:"li"},"127.0.0.1")," and ",Object(i.b)("inlineCode",{parentName:"li"},"localhost"),", some do not (NodeJS for example)")),Object(i.b)("h3",{id:"health-checks"},"Health Checks"),Object(i.b)("p",null,"To know more about how to configure your Liveness and Readiness probes, have a look at ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/application-health-checks/"}),"the health-checks section")),Object(i.b)("h3",{id:"deployment-restrictions"},"Deployment Restrictions"),Object(i.b)("p",null,"This section allows to specify which changes on your repository should trigger an auto-deploy (if enabled). To know more about how to configure your Deployment Restrictions, have a look at the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/deploying-with-auto-deploy/#filtering-commits-triggering-the-auto-deploy"}),"deployment restrictions section"),"."),Object(i.b)("h2",{id:"connecting-from-the-internet"},"Connecting from the internet"),Object(i.b)("p",null,"Your application can be reached from the internet by publicly exposing at least one of its ports (See the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"#ports"}),"Ports")," section to know more). Once this is done, Qovery will generate and assign a domain to your application (See ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"#qovery-provided-domains"}),"this section")," to know more). You can customize the domain assigned to your application via the ",Object(i.b)("inlineCode",{parentName:"p"},"Domain")," section in the settings (see ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"#custom-domains"}),"this section")," to know more)."),Object(i.b)("h3",{id:"qovery-provided-domains"},"Qovery provided domains"),Object(i.b)("p",null,"For each port publicly exposed, a domain is automatically assigned by Qovery to your application. Qovery will manage for you the networking and the TLS configuration for these domains. "),Object(i.b)("p",null,"Example: ",Object(i.b)("inlineCode",{parentName:"p"},"p80-zdf72de72-z709e1a88-gtw.za8ad0657.bool.sh")," or ",Object(i.b)("inlineCode",{parentName:"p"},"-p80-zdf72de72-z709e1a88-gtw.za8ad0657.bool.sh")," for helm services."),Object(i.b)("p",null,"Note:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"each service deployed on the same cluster will have the same root domain assigned (example: ",Object(i.b)("inlineCode",{parentName:"li"},"za8ad0657.bool.sh"),")"),Object(i.b)("li",{parentName:"ul"},"the first characters of the domain (before the ",Object(i.b)("inlineCode",{parentName:"li"},"-"),") is based on the portName given to the port associated with this domain (See the ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"#ports"}),"port section"),")"),Object(i.b)("li",{parentName:"ul"},"a default domain (without the portName) is assigned to the ",Object(i.b)("inlineCode",{parentName:"li"},"default port"),"(See the ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"#ports"}),"port section"),"). Example ",Object(i.b)("inlineCode",{parentName:"li"},"zdf72de72-z709e1a88-gtw.za8ad0657.bool.sh"))),Object(i.b)("p",null,Object(i.b)("strong",{parentName:"p"},"Special Case - Preview Environment"),"\nFor each port exposed publicly, an additional domain will be created with the following pattern ",Object(i.b)("inlineCode",{parentName:"p"},"portName-prId-srvName-envSourceName.cluster_domain"),":"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"portName: is the port name, as explained above"),Object(i.b)("li",{parentName:"ul"},"prID: is the id of the PR that has generated the preview environment"),Object(i.b)("li",{parentName:"ul"},"srvName: is the name of the service"),Object(i.b)("li",{parentName:"ul"},"envSourceName: is the name of the blueprint environment that has created the current preview environment")),Object(i.b)("p",null,"domain example: ",Object(i.b)("inlineCode",{parentName:"p"},"p80-123-frontend-blueprint.za8ad0657.bool.sh")),Object(i.b)("h3",{id:"custom-domains"},"Custom domains"),Object(i.b)("p",null,'If you prefer to assign your own domain to the application, you can customize it from the "Domain" section within the application settings.'),Object(i.b)("p",null,"You can customize the domain of your application in different ways, depending on what you want to achieve:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"You want to use your own domain for your application"),Object(i.b)("li",{parentName:"ul"},"You want to modify the subdomain assigned to your application by Qovery (i.e. change ",Object(i.b)("inlineCode",{parentName:"li"},"p80-zdf72de72-z709e1a88-gtw.za8ad0657.bool.sh")," into ",Object(i.b)("inlineCode",{parentName:"li"},"my-app-domain.za8ad0657.bool.sh"),"). See ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"#qovery-provided-domains"}),"this section")," to know more about these domains.")),Object(i.b)("p",null,"In both cases, you can assign the new custom domain by pressing the ",Object(i.b)("inlineCode",{parentName:"p"},"Add Domain")," button."),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/app-16.png",alt:"Application Domains"})),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,"This configuration will be ",Object(i.b)("strong",{parentName:"p"},"automatically removed")," on every cloned environment or preview environment in order to avoid domain collision.")),Object(i.b)("p",null,"For each custom domain, a green checkmark will appear if the domain is correctly configured. You can perform another check by clicking on the checkmark. If you're behind a CDN, we will only check if your custom domain resolves to an IP address."),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/domain_check.png",alt:"Check Domains"})),Object(i.b)("p",null,"If there's an issue with a domain, a global error message will be displayed, and you can view the error details by hovering over the red cross. After correcting your configuration, you can perform another check by clicking on the red cross."),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/domain_check_error.png",alt:"Check Domains"})),Object(i.b)("h4",{id:"configuring-your-own-domain"},"Configuring your own domain"),Object(i.b)("p",null,"Once the domain is added within the Qovery console (Example: mydomain.com), you need to configure within your DNS two ",Object(i.b)("inlineCode",{parentName:"p"},"CNAME")," records pointing to the domain provided by Qovery, as shown in the UI (example: mydomain.com CNAME za7cc1b71-z4b8474b3-gtw.zc531a994.rustrocks.cloud and *.mydomain.com CNAME za7cc1b71-z4b8474b3-gtw.zc531a994.rustrocks.cloud). "),Object(i.b)("p",null,"Having a wildcard domain entry (example: *.mydomain.com) configured on your DNS will avoid you to modify the Qovery setup every time you want to add a new subdomain. If ",Object(i.b)("inlineCode",{parentName:"p"},"wildcard")," is not supported by your DNS provider, you will have to configure each subdomain manually."),Object(i.b)("p",null,"If a service needs to expose more than one port publicly, you can define a dedicated subdomain to redirect the traffic on the right port by setting the \u201cPort Name\u201d value within the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"#ports"}),"port settings"),"."),Object(i.b)("p",null,"After re-deploying the service, Qovery will automatically handle the TLS/SSL certificate creation and renewal for the configured domain."),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/custom-domain.png",alt:"Custom Domain"})),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/guides/getting-started/setting-custom-domain/"}),"We prepared a guide and video tutorial that explains how to set up your custom domain."))),Object(i.b)("p",null,Object(i.b)("strong",{parentName:"p"}," Special case - domain behind a CDN ")),Object(i.b)("p",null,"If your service is behind a CDN using a ",Object(i.b)("inlineCode",{parentName:"p"},"proxy mode")," (i.e. the traffic is routed through the CDN to Qovery), make sure to enable the option ",Object(i.b)("inlineCode",{parentName:"p"},"Domain behind a CDN"),' and disable the option "Generate certificate" on the domain setup. Since the certificate of your domain is directly managed by the CDN, Qovery won\'t be able to do that for you and it will raise warnings on your application status.'),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/cdn-proxy.png",alt:"CDN Proxy"})),Object(i.b)("p",null,"If you are using Cloudflare to manage your CDN, we can also manage automatically your custom domain configuration via a wildcard domain setup for the whole cluster. Check our ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/clusters/#use-custom-domain-and-wildcard-tls-for-the-whole-cluster-beta"}),"documentation here")),Object(i.b)("h4",{id:"change-the-auto-assigned-sub-domain"},"Change the auto assigned sub-domain"),Object(i.b)("p",null,"You can specify a different sub-domain for your application as long as it belongs to the assigned cluster domain (see ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"#qovery-provided-domains"}),"Qovery provided domains"),").\nExample: "),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"your current domain is zdf72de71-z709e1a85-gtw.za8ad0659.bool.sh (so your assigned cluster domain is ",Object(i.b)("inlineCode",{parentName:"li"},"za8ad0659.bool.sh"),")"),Object(i.b)("li",{parentName:"ul"},"you can enter a new custom domain ",Object(i.b)("inlineCode",{parentName:"li"},"myfrontend.za8ad0659.bool.sh")," (since it is a subdomain of the cluster domain)")),Object(i.b)("p",null,"The application will now be accessible from both the default and the new custom domain."),Object(i.b)(c.a,{type:"info",mdxType:"Alert"},Object(i.b)("p",null,"Qovery does not check collision in the domain declaration. Make sure you assign a unique subdomain within your cluster.")),Object(i.b)("h2",{id:"connecting-to-a-database"},"Connecting to a database"),Object(i.b)("p",null,"To know how to access your database from your application, ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment-variable/#connecting-to-a-database"}),"have a look at the database section"),"."),Object(i.b)("h2",{id:"connecting-to-another-application"},"Connecting to another application"),Object(i.b)("p",null,"To know how to access your database from your application, ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment-variable/#connecting-to-another-application"}),"have a look at the database section"),"."),Object(i.b)("h2",{id:"environment-variable"},"Environment Variable"),Object(i.b)("p",null,"To learn how to set up environment variables in your projects and applications, navigate to ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment-variable/"}),"configuring Environment Variables")," section."),Object(i.b)("h2",{id:"secrets"},"Secrets"),Object(i.b)("p",null,"To learn how to set up secrets in your projects and applications, navigate to ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/environment-variable/"}),"configuring Secrets")," section."),Object(i.b)("h2",{id:"logs"},"Logs"),Object(i.b)("p",null,"To learn how to display your application logs, navigate to ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/deployment/logs/#live-logs"}),"logs section")),Object(i.b)("h2",{id:"ssh"},"SSH"),Object(i.b)("p",null,"To connect to your application via SSH, please use the via the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/interface/cli/"}),"Qovery SSH command")," available on our CLI."),Object(i.b)("h2",{id:"clone"},"Clone"),Object(i.b)("p",null,"You can create a clone of the service via the clone feature. A new service with the same configuration (see below for exceptions) will be created into the target environment."),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/clone_service.png",alt:"Clone Service"})),Object(i.b)("p",null,"The target environment can be the same as the current environment or even another one in a completely different project."),Object(i.b)("p",null,Object(i.b)("strong",{parentName:"p"}," Important information ")),Object(i.b)("p",null,"Not every configuration parameter will be copied within the new service for consistency reasons. The configuration is fully or partially copied depending on the target environment:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"same environment:",Object(i.b)("ul",{parentName:"li"},Object(i.b)("li",{parentName:"ul"},"custom domain: this setup is not copied into the new service (to avoid collision)"))),Object(i.b)("li",{parentName:"ul"},"another environment:",Object(i.b)("ul",{parentName:"li"},Object(i.b)("li",{parentName:"ul"},"custom domain: this setup is not copied into the new service (to avoid collision)"),Object(i.b)("li",{parentName:"ul"},"environment variable: aliases defined on environment variables are not copied (since the aliased env var might not exist)"),Object(i.b)("li",{parentName:"ul"},"deployment pipeline: stage setup is not copied (since the target stage might not exist)"),Object(i.b)("li",{parentName:"ul"},"number of instances: if the target environment runs on a Qovery EC2 cluster, the max number of instances is set to 1 (Qovery EC2 constraint)")))),Object(i.b)("p",null,"Please check the configuration of the new service before deploying it."),Object(i.b)("h2",{id:"advanced-settings"},"Advanced Settings"),Object(i.b)("p",null,"You can further customize the service behaviour via the service advanced settings. Check ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/using-qovery/configuration/advanced-settings/"}),"this documentation")," to know more."),Object(i.b)("h2",{id:"delete-an-application"},"Delete an Application"),Object(i.b)(r.a,{headingDepth:3,mdxType:"Steps"},Object(i.b)("ol",null,Object(i.b)("li",null,Object(i.b)("p",null,"Choose your application")),Object(i.b)("li",null,Object(i.b)("p",null,"In the application overview, click on the ",Object(i.b)("inlineCode",{parentName:"p"},"3 dots")," button and remove the application."),Object(i.b)("p",{align:"center"},Object(i.b)("img",{src:"/img/configuration/application/app-1.png",alt:"Application"}))))))}d.isMDXComponent=!0},455:function(e,t,n){var a;!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=o.a.createContext({}),p=function(e){var t=o.a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):c({},t,{},e)),n},b=function(e){var t=p(e.components);return o.a.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.a.createElement(o.a.Fragment,{},t)}},d=Object(a.forwardRef)((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,r=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),b=p(n),d=a,m=b["".concat(r,".").concat(d)]||b[d]||u[d]||i;return n?o.a.createElement(m,c({ref:t},s,{components:n})):o.a.createElement(m,c({ref:t},s))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,r=new Array(i);r[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:a,r[1]=c;for(var s=2;s1?arguments[1]:void 0,n),l=r>2?arguments[2]:void 0,s=void 0===l?n:o(l,n);s>c;)t[c++]=e;return t}},460:function(e,t,n){var a=n(28).f,o=Function.prototype,i=/^\s*function ([^ (]*)/;"name"in o||n(10)&&a(o,"name",{configurable:!0,get:function(){try{return(""+this).match(i)[1]}catch(e){return""}}})},461:function(e,t,n){"use strict";n(460);var a=n(0),o=n.n(a),i=n(456);t.a=function(e){var t=e.children,n=e.name;return o.a.createElement(i.a,{type:"info",fill:!0,icon:!1,rounded:!0,className:"list--icons list--icons--arrow list--tight list--indent margin-bottom--lg"},o.a.createElement("p",{class:"text--lg margin-bottom--sm",style:{marginTop:"-0.25em"}},"Before you begin, this ",n||"page"," assumes the following:"),t)}},462:function(e,t,n){"use strict";var a=n(1),o=n(0),i=n.n(o),r=n(39),c=n(466),l=n(20),s=n.n(l);t.a=function(e){var t,n=e.to,l=e.href,p=n||l,b=Object(c.a)(p),u=Object(o.useRef)(!1),d=s.a.canUseIntersectionObserver;return Object(o.useEffect)((function(){return!d&&b&&window.docusaurus.prefetch(p),function(){d&&t&&t.disconnect()}}),[p,d,b]),p&&b?i.a.createElement(r.b,Object(a.a)({},e,{onMouseEnter:function(){u.current||(window.docusaurus.preload(p),u.current=!0)},innerRef:function(e){var n,a;d&&e&&b&&(n=e,a=function(){window.docusaurus.prefetch(p)},(t=new window.IntersectionObserver((function(e){e.forEach((function(e){n===e.target&&(e.isIntersecting||e.intersectionRatio>0)&&(t.unobserve(n),t.disconnect(),a())}))}))).observe(n))},to:p})):i.a.createElement("a",Object(a.a)({},e,{href:p}))}},463:function(e,t,n){"use strict";var a=n(467),o=n(51);function i(e,t){return t.encode?t.strict?a(e):encodeURIComponent(e):e}t.extract=function(e){return e.split("?")[1]||""},t.parse=function(e,t){var n=function(e){var t;switch(e.arrayFormat){case"index":return function(e,n,a){t=/\[(\d*)\]$/.exec(e),e=e.replace(/\[\d*\]$/,""),t?(void 0===a[e]&&(a[e]={}),a[e][t[1]]=n):a[e]=n};case"bracket":return function(e,n,a){t=/(\[\])$/.exec(e),e=e.replace(/\[\]$/,""),t?void 0!==a[e]?a[e]=[].concat(a[e],n):a[e]=[n]:a[e]=n};default:return function(e,t,n){void 0!==n[e]?n[e]=[].concat(n[e],t):n[e]=t}}}(t=o({arrayFormat:"none"},t)),a=Object.create(null);return"string"!=typeof e?a:(e=e.trim().replace(/^(\?|#|&)/,""))?(e.split("&").forEach((function(e){var t=e.replace(/\+/g," ").split("="),o=t.shift(),i=t.length>0?t.join("="):void 0;i=void 0===i?null:decodeURIComponent(i),n(decodeURIComponent(o),i,a)})),Object.keys(a).sort().reduce((function(e,t){var n=a[t];return Boolean(n)&&"object"==typeof n&&!Array.isArray(n)?e[t]=function e(t){return Array.isArray(t)?t.sort():"object"==typeof t?e(Object.keys(t)).sort((function(e,t){return Number(e)-Number(t)})).map((function(e){return t[e]})):t}(n):e[t]=n,e}),Object.create(null))):a},t.stringify=function(e,t){var n=function(e){switch(e.arrayFormat){case"index":return function(t,n,a){return null===n?[i(t,e),"[",a,"]"].join(""):[i(t,e),"[",i(a,e),"]=",i(n,e)].join("")};case"bracket":return function(t,n){return null===n?i(t,e):[i(t,e),"[]=",i(n,e)].join("")};default:return function(t,n){return null===n?i(t,e):[i(t,e),"=",i(n,e)].join("")}}}(t=o({encode:!0,strict:!0,arrayFormat:"none"},t));return e?Object.keys(e).sort().map((function(a){var o=e[a];if(void 0===o)return"";if(null===o)return i(a,t);if(Array.isArray(o)){var r=[];return o.slice().forEach((function(e){void 0!==e&&r.push(n(a,e,r.length))})),r.join("&")}return i(a,t)+"="+i(o,t)})).filter((function(e){return e.length>0})).join("&"):""}},464:function(e,t,n){"use strict";var a=n(0),o=n.n(a),i=(n(455),n(463)),r=n.n(i);n(133);t.a=function(e){var t=e.children,n=e.headingDepth,i=e.hideFeedbackQuestion,c="undefined"!=typeof window?window.location:null,l={title:"Tutorial on "+c+" failed",body:"The tutorial on:\n\n"+c+"\n\nHere's what went wrong:\n\n\x3c!-- Insert command output and details. Thank you for reporting! :) --\x3e"},s="https://github.com/qovery/documentation/issues/new?"+r.a.stringify(l),p=Object(a.useState)(null),b=p[0],u=p[1];return o.a.createElement("div",{className:"steps steps--h"+n},t,!i&&!b&&o.a.createElement("div",{className:"steps--feedback"},"How was it? Did this tutorial work?\xa0\xa0",o.a.createElement("span",{className:"button button--sm button--primary",onClick:function(){return u("yes")}},"Yes"),"\xa0\xa0",o.a.createElement("a",{href:s,target:"_blank",className:"button button--sm button--primary"},"No")),"yes"==b&&o.a.createElement("div",{className:"steps--feedback steps--feedback--success"},"Thanks! If you're enjoying Qovery please consider ",o.a.createElement("a",{href:"https://github.com/qovery/documentation/",target:"_blank"},"starring our Github repo"),"."))}},465:function(e,t,n){"use strict";var a=n(0),o=n.n(a),i=n(462),r=n(455),c=n.n(r);n(134);t.a=function(e){var t=e.children,n=e.className,a=e.badge,r=e.leftIcon,l=e.rightIcon,s=e.size,p=e.target,b=e.to,u=c()("jump-to","jump-to--"+s,n),d=o.a.createElement("div",{className:"jump-to--inner"},o.a.createElement("div",{className:"jump-to--inner-2"},r&&o.a.createElement("div",{className:"jump-to--left"},o.a.createElement("i",{className:"feather icon-"+r})),o.a.createElement("div",{className:"jump-to--main"},a?o.a.createElement("span",{className:"badge badge--primary badge--right"},a):"",t),o.a.createElement("div",{className:"jump-to--right"},o.a.createElement("i",{className:"feather icon-"+(l||"chevron-right")+" arrow"}))));return p?o.a.createElement("a",{href:b,target:p,className:u},d):o.a.createElement(i.a,{to:b,className:u},d)}},466:function(e,t,n){"use strict";function a(e){return!1===/^(https?:|\/\/)/.test(e)}n.d(t,"a",(function(){return a}))},467:function(e,t,n){"use strict";e.exports=function(e){return encodeURIComponent(e).replace(/[!'()*]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}}}]); \ No newline at end of file diff --git a/8d5726d6.663659ee.js.LICENSE.txt b/8d5726d6.90562f3c.js.LICENSE.txt similarity index 100% rename from 8d5726d6.663659ee.js.LICENSE.txt rename to 8d5726d6.90562f3c.js.LICENSE.txt diff --git a/a9994e72.6e22449d.js b/a9994e72.6e22449d.js new file mode 100644 index 0000000000..9a3243f439 --- /dev/null +++ b/a9994e72.6e22449d.js @@ -0,0 +1,2 @@ +/*! For license information please see a9994e72.6e22449d.js.LICENSE.txt */ +(window.webpackJsonp=window.webpackJsonp||[]).push([[192],{344:function(e,t,n){"use strict";n.r(t),n.d(t,"frontMatter",(function(){return u})),n.d(t,"metadata",(function(){return s})),n.d(t,"rightToc",(function(){return p})),n.d(t,"default",(function(){return d}));var r=n(1),o=n(9),a=(n(0),n(457)),i=n(456),c=n(465),l=n(461),u={last_modified_on:"2024-09-18",$schema:"/.meta/.schemas/guides.json",title:"How to write a Dockerfile",description:"How to write your first Dockerfile in order to deploy your application with Qovery",author_github:"https://github.com/MacLikorne",tags:["type: tutorial","technology: docker"],hide_pagination:!0},s={categories:[{name:"tutorial",title:"Tutorial",description:"Additional step-by-step resources to leverage even more Qovery",permalink:"/guides/tutorial"}],coverLabel:"How to write a Dockerfile",description:"How to write your first Dockerfile in order to deploy your application with Qovery",permalink:"/guides/tutorial/how-to-write-a-dockerfile",readingTime:"5 min read",source:"@site/guides/tutorial/how-to-write-a-dockerfile.md",tags:[{label:"type: tutorial",permalink:"/guides/tags/type-tutorial"},{label:"technology: docker",permalink:"/guides/tags/technology-docker"}],title:"How to write a Dockerfile",truncated:!1,prevItem:{title:"How To Use Lifecycle Job To Deploy Any Kind Of Resources",permalink:"/guides/tutorial/how-to-use-lifecycle-job-to-deploy-any-kind-of-resources"},nextItem:{title:"Import your environment variables with the Qovery CLI",permalink:"/guides/tutorial/import-your-environment-variables-with-the-qovery-cli"}},p=[{value:"My Sweet Dockerfile",id:"my-sweet-dockerfile",children:[{value:"FROM",id:"from",children:[]},{value:"WORKDIR",id:"workdir",children:[]},{value:"COPY",id:"copy",children:[]},{value:"RUN",id:"run",children:[]},{value:"EXPOSE",id:"expose",children:[]},{value:"CMD",id:"cmd",children:[]},{value:"Build your image",id:"build-your-image",children:[]},{value:"Test your image",id:"test-your-image",children:[]}]},{value:"What's next?",id:"whats-next",children:[]}],b={rightToc:p};function d(e){var t=e.components,n=Object(o.a)(e,["components"]);return Object(a.b)("wrapper",Object(r.a)({},b,n,{components:t,mdxType:"MDXLayout"}),Object(a.b)("p",null,"In this article, we'll see, step by step, how to quickly write a proper Dockerfile for any application you would like to deploy."),Object(a.b)(l.a,{name:"guide",mdxType:"Assumptions"},Object(a.b)("ul",null,Object(a.b)("li",{parentName:"ul"},"You have installed the ",Object(a.b)("a",Object(r.a)({parentName:"li"},{href:"https://docs.qovery.com/docs/using-qovery/interface/cli/"}),"Qovery CLI")),Object(a.b)("li",{parentName:"ul"},"You host your code on Github"))),Object(a.b)("hr",null),Object(a.b)("h2",{id:"my-sweet-dockerfile"},"My Sweet Dockerfile"),Object(a.b)("p",null,"If you read this, you probably don't know why Docker is used and what is the purpose of a Dockerfile."),Object(a.b)("p",null,"Docker is a container engine, building and using images to deploy applications in containers. It looks like virtualization, and each container could be compared to a virtual machine with the minimal setup to run an application."),Object(a.b)("p",null,"The Dockerfile is your image builder recipe. When Docker uses it, it will follow all instructions to ",Object(a.b)("strong",{parentName:"p"},"build your application and run it"),"."),Object(a.b)("p",null,"The first step is to create a file named ",Object(a.b)("strong",{parentName:"p"},"Dockerfile")," at your project root level so Qovery would be able to find and use it."),Object(a.b)("p",null,"Also, to avoid unwanted files from your repository (images, .idea, DS_Store etc.), you need to add a ",Object(a.b)("strong",{parentName:"p"},".dockerignore"),". It will prevent heavy copy tasks of useless files, mostly your project dependencies and libraries you'll get back to with your package manager."),Object(a.b)("p",null,"The ",Object(a.b)("strong",{parentName:"p"},".dockerignore")," file works like the ",Object(a.b)("strong",{parentName:"p"},".gitignore"),", so add all the path of the useless files and folders in it."),Object(a.b)("h3",{id:"from"},"FROM"),Object(a.b)("p",null,"The first line you'll add in your Dockerfile is ",Object(a.b)("strong",{parentName:"p"},"FROM"),"."),Object(a.b)("p",null,"It will pull an already existing image from ",Object(a.b)("a",Object(r.a)({parentName:"p"},{href:"https://hub.docker.com/"}),"Docker Hub"),". You should most of the time use an image that fits your application language (Node, Python, Java, etc.), but you can go a step backward and begin with a simple Linux image."),Object(a.b)("p",null,"Your Dockerfile's first line should look like this:"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"FROM :\n")),Object(a.b)("p",null,"For example, with ",Object(a.b)("a",Object(r.a)({parentName:"p"},{href:"https://hub.docker.com/_/python"}),"python"),":"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"FROM python:3\n")),Object(a.b)("h3",{id:"workdir"},"WORKDIR"),Object(a.b)("p",null,"Since most of the images are Linux-based, a good practice is to set up a directory you'll work in. That's the purpose of the ",Object(a.b)("strong",{parentName:"p"},"WORKDIR")," line. It defines a directory and moves you in:"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"FROM :\nWORKDIR /app\n")),Object(a.b)("p",null,"If you now work with a relative path (./), it will be in the ",Object(a.b)("em",{parentName:"p"},"app")," directory."),Object(a.b)("h3",{id:"copy"},"COPY"),Object(a.b)("p",null,"Now you have defined your base image and your working directory, it's time to add your code in. ",Object(a.b)("strong",{parentName:"p"},"COPY")," works like ",Object(a.b)("strong",{parentName:"p"},"cp")," linux command. First argument is the source and second one is the destination."),Object(a.b)("p",null,"It's time to copy your source code in the image."),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"FROM :\nWORKDIR /app\nCOPY . .\n")),Object(a.b)("p",null,"Here, the elements of your ",Object(a.b)("strong",{parentName:"p"},"root")," folder from your current directory will be added inside the ",Object(a.b)("strong",{parentName:"p"},"/app")," folder."),Object(a.b)(i.a,{type:"info",mdxType:"Alert"},Object(a.b)("p",null,"You can use your current repository relative path (",Object(a.b)("strong",{parentName:"p"},".")," can be replaced by ",Object(a.b)("strong",{parentName:"p"},"./"),") if you want to add specific element (except the content of ",Object(a.b)("strong",{parentName:"p"},".dockerignore"),") to your image relative path (as we are already in the ",Object(a.b)("strong",{parentName:"p"},"/app")," folder, we can use ",Object(a.b)("strong",{parentName:"p"},"./"),").")),Object(a.b)("h3",{id:"run"},"RUN"),Object(a.b)("p",null,"One does not simply get source code to run an application."),Object(a.b)("p",null,"Most of the time, you have some stuff to do before an application execution like downloading/installing peer dependencies and build your application."),Object(a.b)("p",null,"That's the purpose of ",Object(a.b)("strong",{parentName:"p"},"RUN")," lines; it will execute a command and wait to finish the task to go forward."),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),'FROM :\nWORKDIR /app\nCOPY . .\nRUN echo "Installing or doing stuff."\nRUN \n')),Object(a.b)("p",null,"You can set as many ",Object(a.b)("strong",{parentName:"p"},"RUN")," lines as you need."),Object(a.b)("h3",{id:"expose"},"EXPOSE"),Object(a.b)("p",null,"If your app needs to be reached from outside the container, you have to open its listening port. ",Object(a.b)("strong",{parentName:"p"},"EXPOSE")," is made for this."),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),'FROM :\nWORKDIR /app\nCOPY . .\nRUN echo "Installing or doing stuff"\nRUN \nEXPOSE \n')),Object(a.b)(i.a,{type:"info",mdxType:"Alert"},Object(a.b)("p",null,"Typical mistakes are made application configuration side. Ensure your application will listen on all interfaces ",Object(a.b)("strong",{parentName:"p"},"0.0.0.0")," and not only localhost ",Object(a.b)("strong",{parentName:"p"},"127.0.0.1"),".")),Object(a.b)("h3",{id:"cmd"},"CMD"),Object(a.b)("p",null,"Your application is now ready to run."),Object(a.b)("p",null,"The last thing to do is to specify how to execute it. Add the ",Object(a.b)("strong",{parentName:"p"},"CMD")," line with the same command with all the arguments you use locally to launch your application."),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),'FROM :\nWORKDIR /app\nCOPY . .\nRUN echo "Installing or doing stuff"\nRUN \nEXPOSE \nCMD [ "", "", "" ]\n')),Object(a.b)("p",null,"Like a local usage, you can set as many arguments as needed."),Object(a.b)("h3",{id:"build-your-image"},"Build your image"),Object(a.b)("p",null,"When Qovery uses your Dockerfile, it first builds it before running it."),Object(a.b)("p",null,"If the build fails, Qovery won't be able to launch our application. To simplify debugging, you can build your image locally if you have Docker installed on your computer."),Object(a.b)("p",null,"Open a terminal and set the path at the Dockerfile location, and use the command:"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"cd ~/my/folder/where/my/code/is\ndocker build .\n")),Object(a.b)("p",null,"It will build your image based on your Dockerfile. You'll see all the logs related to all lines you've added in the Dockerfile."),Object(a.b)("p",null,"If something goes wrong, it will be printed onto the terminal, and you'll be able to ",Object(a.b)("a",Object(r.a)({parentName:"p"},{href:"https://stackoverflow.com/"}),"debug it"),"."),Object(a.b)("h3",{id:"test-your-image"},"Test your image"),Object(a.b)("p",null,"If your image builds properly, you can now check how it will be handle by Qovery with the command:"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"qovery run\n")),Object(a.b)("h2",{id:"whats-next"},"What's next?"),Object(a.b)("p",null,"If you follow this tutorial and everything works perfectly, it's time to deploy your app on Qovery. You will find all the things you need to know ",Object(a.b)("a",Object(r.a)({parentName:"p"},{href:"https://docs.qovery.com/docs/using-qovery/configuration/"}),"here"),"."),Object(a.b)(c.a,{to:"/guides/tutorial/",mdxType:"Jump"},"Tutorial"))}d.isMDXComponent=!0},455:function(e,t,n){var r;!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var u=o.a.createContext({}),s=function(e){var t=o.a.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):c({},t,{},e)),n},p=function(e){var t=s(e.components);return o.a.createElement(u.Provider,{value:t},e.children)},b={inlineCode:"code",wrapper:function(e){var t=e.children;return o.a.createElement(o.a.Fragment,{},t)}},d=Object(r.forwardRef)((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=s(n),d=r,m=p["".concat(i,".").concat(d)]||p[d]||b[d]||a;return n?o.a.createElement(m,c({ref:t},u,{components:n})):o.a.createElement(m,c({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:r,i[1]=c;for(var u=2;u1?arguments[1]:void 0,n),l=i>2?arguments[2]:void 0,u=void 0===l?n:o(l,n);u>c;)t[c++]=e;return t}},460:function(e,t,n){var r=n(28).f,o=Function.prototype,a=/^\s*function ([^ (]*)/;"name"in o||n(10)&&r(o,"name",{configurable:!0,get:function(){try{return(""+this).match(a)[1]}catch(e){return""}}})},461:function(e,t,n){"use strict";n(460);var r=n(0),o=n.n(r),a=n(456);t.a=function(e){var t=e.children,n=e.name;return o.a.createElement(a.a,{type:"info",fill:!0,icon:!1,rounded:!0,className:"list--icons list--icons--arrow list--tight list--indent margin-bottom--lg"},o.a.createElement("p",{class:"text--lg margin-bottom--sm",style:{marginTop:"-0.25em"}},"Before you begin, this ",n||"page"," assumes the following:"),t)}},462:function(e,t,n){"use strict";var r=n(1),o=n(0),a=n.n(o),i=n(39),c=n(466),l=n(20),u=n.n(l);t.a=function(e){var t,n=e.to,l=e.href,s=n||l,p=Object(c.a)(s),b=Object(o.useRef)(!1),d=u.a.canUseIntersectionObserver;return Object(o.useEffect)((function(){return!d&&p&&window.docusaurus.prefetch(s),function(){d&&t&&t.disconnect()}}),[s,d,p]),s&&p?a.a.createElement(i.b,Object(r.a)({},e,{onMouseEnter:function(){b.current||(window.docusaurus.preload(s),b.current=!0)},innerRef:function(e){var n,r;d&&e&&p&&(n=e,r=function(){window.docusaurus.prefetch(s)},(t=new window.IntersectionObserver((function(e){e.forEach((function(e){n===e.target&&(e.isIntersecting||e.intersectionRatio>0)&&(t.unobserve(n),t.disconnect(),r())}))}))).observe(n))},to:s})):a.a.createElement("a",Object(r.a)({},e,{href:s}))}},465:function(e,t,n){"use strict";var r=n(0),o=n.n(r),a=n(462),i=n(455),c=n.n(i);n(134);t.a=function(e){var t=e.children,n=e.className,r=e.badge,i=e.leftIcon,l=e.rightIcon,u=e.size,s=e.target,p=e.to,b=c()("jump-to","jump-to--"+u,n),d=o.a.createElement("div",{className:"jump-to--inner"},o.a.createElement("div",{className:"jump-to--inner-2"},i&&o.a.createElement("div",{className:"jump-to--left"},o.a.createElement("i",{className:"feather icon-"+i})),o.a.createElement("div",{className:"jump-to--main"},r?o.a.createElement("span",{className:"badge badge--primary badge--right"},r):"",t),o.a.createElement("div",{className:"jump-to--right"},o.a.createElement("i",{className:"feather icon-"+(l||"chevron-right")+" arrow"}))));return s?o.a.createElement("a",{href:p,target:s,className:b},d):o.a.createElement(a.a,{to:p,className:b},d)}},466:function(e,t,n){"use strict";function r(e){return!1===/^(https?:|\/\/)/.test(e)}n.d(t,"a",(function(){return r}))}}]); \ No newline at end of file diff --git a/a9994e72.f92806c8.js.LICENSE.txt b/a9994e72.6e22449d.js.LICENSE.txt similarity index 100% rename from a9994e72.f92806c8.js.LICENSE.txt rename to a9994e72.6e22449d.js.LICENSE.txt diff --git a/a9994e72.f92806c8.js b/a9994e72.f92806c8.js deleted file mode 100644 index 03eb497401..0000000000 --- a/a9994e72.f92806c8.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see a9994e72.f92806c8.js.LICENSE.txt */ -(window.webpackJsonp=window.webpackJsonp||[]).push([[192],{344:function(e,t,n){"use strict";n.r(t),n.d(t,"frontMatter",(function(){return u})),n.d(t,"metadata",(function(){return s})),n.d(t,"rightToc",(function(){return p})),n.d(t,"default",(function(){return d}));var r=n(1),o=n(9),a=(n(0),n(457)),i=n(456),c=n(465),l=n(461),u={last_modified_on:"2022-05-04",$schema:"/.meta/.schemas/guides.json",title:"How to write a Dockerfile",description:"How to write your first Dockerfile in order to deploy your application with Qovery",author_github:"https://github.com/MacLikorne",tags:["type: tutorial","technology: docker"],hide_pagination:!0},s={categories:[{name:"tutorial",title:"Tutorial",description:"Additional step-by-step resources to leverage even more Qovery",permalink:"/guides/tutorial"}],coverLabel:"How to write a Dockerfile",description:"How to write your first Dockerfile in order to deploy your application with Qovery",permalink:"/guides/tutorial/how-to-write-a-dockerfile",readingTime:"5 min read",source:"@site/guides/tutorial/how-to-write-a-dockerfile.md",tags:[{label:"type: tutorial",permalink:"/guides/tags/type-tutorial"},{label:"technology: docker",permalink:"/guides/tags/technology-docker"}],title:"How to write a Dockerfile",truncated:!1,prevItem:{title:"How To Use Lifecycle Job To Deploy Any Kind Of Resources",permalink:"/guides/tutorial/how-to-use-lifecycle-job-to-deploy-any-kind-of-resources"},nextItem:{title:"Import your environment variables with the Qovery CLI",permalink:"/guides/tutorial/import-your-environment-variables-with-the-qovery-cli"}},p=[{value:"My Sweet Dockerfile",id:"my-sweet-dockerfile",children:[{value:"FROM",id:"from",children:[]},{value:"WORKDIR",id:"workdir",children:[]},{value:"COPY",id:"copy",children:[]},{value:"RUN",id:"run",children:[]},{value:"EXPOSE",id:"expose",children:[]},{value:"CMD",id:"cmd",children:[]},{value:"Build your image",id:"build-your-image",children:[]},{value:"Test your image",id:"test-your-image",children:[]}]},{value:"What's next?",id:"whats-next",children:[]}],b={rightToc:p};function d(e){var t=e.components,n=Object(o.a)(e,["components"]);return Object(a.b)("wrapper",Object(r.a)({},b,n,{components:t,mdxType:"MDXLayout"}),Object(a.b)("p",null,"With Qovery, there are two ways to build and deploy your application:"),Object(a.b)("ol",null,Object(a.b)("li",{parentName:"ol"},"Without a Dockerfile in your repository: your application is built with ",Object(a.b)("a",Object(r.a)({parentName:"li"},{href:"https://docs.qovery.com/docs/using-qovery/configuration/application/#option-1-buildpacks"}),"Buildpacks")),Object(a.b)("li",{parentName:"ol"},"With a Dockerfile: sometimes Buildpacks won't fit your specific setup, and you'll have to write your Dockerfile.")),Object(a.b)("p",null,"In this article, we'll see, step by step, how to quickly write a proper Dockerfile for any application you would like to deploy."),Object(a.b)(l.a,{name:"guide",mdxType:"Assumptions"},Object(a.b)("ul",null,Object(a.b)("li",{parentName:"ul"},"You have installed the ",Object(a.b)("a",Object(r.a)({parentName:"li"},{href:"https://docs.qovery.com/docs/using-qovery/interface/cli/"}),"Qovery CLI")),Object(a.b)("li",{parentName:"ul"},"You host your code on Github"))),Object(a.b)("hr",null),Object(a.b)("h2",{id:"my-sweet-dockerfile"},"My Sweet Dockerfile"),Object(a.b)("p",null,"If you read this, you probably don't know why Docker is used and what is the purpose of a Dockerfile."),Object(a.b)("p",null,"Docker is a container engine, building and using images to deploy applications in containers. It looks like virtualization, and each container could be compared to a virtual machine with the minimal setup to run an application."),Object(a.b)("p",null,"The Dockerfile is your image builder recipe. When Docker uses it, it will follow all instructions to ",Object(a.b)("strong",{parentName:"p"},"build your application and run it"),"."),Object(a.b)("p",null,"The first step is to create a file named ",Object(a.b)("strong",{parentName:"p"},"Dockerfile")," at your project root level so Qovery would be able to find and use it."),Object(a.b)("p",null,"Also, to avoid unwanted files from your repository (images, .idea, DS_Store etc.), you need to add a ",Object(a.b)("strong",{parentName:"p"},".dockerignore"),". It will prevent heavy copy tasks of useless files, mostly your project dependencies and libraries you'll get back to with your package manager."),Object(a.b)("p",null,"The ",Object(a.b)("strong",{parentName:"p"},".dockerignore")," file works like the ",Object(a.b)("strong",{parentName:"p"},".gitignore"),", so add all the path of the useless files and folders in it."),Object(a.b)("h3",{id:"from"},"FROM"),Object(a.b)("p",null,"The first line you'll add in your Dockerfile is ",Object(a.b)("strong",{parentName:"p"},"FROM"),"."),Object(a.b)("p",null,"It will pull an already existing image from ",Object(a.b)("a",Object(r.a)({parentName:"p"},{href:"https://hub.docker.com/"}),"Docker Hub"),". You should most of the time use an image that fits your application language (Node, Python, Java, etc.), but you can go a step backward and begin with a simple Linux image."),Object(a.b)("p",null,"Your Dockerfile's first line should look like this:"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"FROM :\n")),Object(a.b)("p",null,"For example, with ",Object(a.b)("a",Object(r.a)({parentName:"p"},{href:"https://hub.docker.com/_/python"}),"python"),":"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"FROM python:3\n")),Object(a.b)("h3",{id:"workdir"},"WORKDIR"),Object(a.b)("p",null,"Since most of the images are Linux-based, a good practice is to set up a directory you'll work in. That's the purpose of the ",Object(a.b)("strong",{parentName:"p"},"WORKDIR")," line. It defines a directory and moves you in:"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"FROM :\nWORKDIR /app\n")),Object(a.b)("p",null,"If you now work with a relative path (./), it will be in the ",Object(a.b)("em",{parentName:"p"},"app")," directory."),Object(a.b)("h3",{id:"copy"},"COPY"),Object(a.b)("p",null,"Now you have defined your base image and your working directory, it's time to add your code in. ",Object(a.b)("strong",{parentName:"p"},"COPY")," works like ",Object(a.b)("strong",{parentName:"p"},"cp")," linux command. First argument is the source and second one is the destination."),Object(a.b)("p",null,"It's time to copy your source code in the image."),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"FROM :\nWORKDIR /app\nCOPY . .\n")),Object(a.b)("p",null,"Here, the elements of your ",Object(a.b)("strong",{parentName:"p"},"root")," folder from your current directory will be added inside the ",Object(a.b)("strong",{parentName:"p"},"/app")," folder."),Object(a.b)(i.a,{type:"info",mdxType:"Alert"},Object(a.b)("p",null,"You can use your current repository relative path (",Object(a.b)("strong",{parentName:"p"},".")," can be replaced by ",Object(a.b)("strong",{parentName:"p"},"./"),") if you want to add specific element (except the content of ",Object(a.b)("strong",{parentName:"p"},".dockerignore"),") to your image relative path (as we are already in the ",Object(a.b)("strong",{parentName:"p"},"/app")," folder, we can use ",Object(a.b)("strong",{parentName:"p"},"./"),").")),Object(a.b)("h3",{id:"run"},"RUN"),Object(a.b)("p",null,"One does not simply get source code to run an application."),Object(a.b)("p",null,"Most of the time, you have some stuff to do before an application execution like downloading/installing peer dependencies and build your application."),Object(a.b)("p",null,"That's the purpose of ",Object(a.b)("strong",{parentName:"p"},"RUN")," lines; it will execute a command and wait to finish the task to go forward."),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),'FROM :\nWORKDIR /app\nCOPY . .\nRUN echo "Installing or doing stuff."\nRUN \n')),Object(a.b)("p",null,"You can set as many ",Object(a.b)("strong",{parentName:"p"},"RUN")," lines as you need."),Object(a.b)("h3",{id:"expose"},"EXPOSE"),Object(a.b)("p",null,"If your app needs to be reached from outside the container, you have to open its listening port. ",Object(a.b)("strong",{parentName:"p"},"EXPOSE")," is made for this."),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),'FROM :\nWORKDIR /app\nCOPY . .\nRUN echo "Installing or doing stuff"\nRUN \nEXPOSE \n')),Object(a.b)(i.a,{type:"info",mdxType:"Alert"},Object(a.b)("p",null,"Typical mistakes are made application configuration side. Ensure your application will listen on all interfaces ",Object(a.b)("strong",{parentName:"p"},"0.0.0.0")," and not only localhost ",Object(a.b)("strong",{parentName:"p"},"127.0.0.1"),".")),Object(a.b)("h3",{id:"cmd"},"CMD"),Object(a.b)("p",null,"Your application is now ready to run."),Object(a.b)("p",null,"The last thing to do is to specify how to execute it. Add the ",Object(a.b)("strong",{parentName:"p"},"CMD")," line with the same command with all the arguments you use locally to launch your application."),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),'FROM :\nWORKDIR /app\nCOPY . .\nRUN echo "Installing or doing stuff"\nRUN \nEXPOSE \nCMD [ "", "", "" ]\n')),Object(a.b)("p",null,"Like a local usage, you can set as many arguments as needed."),Object(a.b)("h3",{id:"build-your-image"},"Build your image"),Object(a.b)("p",null,"When Qovery uses your Dockerfile, it first builds it before running it."),Object(a.b)("p",null,"If the build fails, Qovery won't be able to launch our application. To simplify debugging, you can build your image locally if you have Docker installed on your computer."),Object(a.b)("p",null,"Open a terminal and set the path at the Dockerfile location, and use the command:"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"cd ~/my/folder/where/my/code/is\ndocker build .\n")),Object(a.b)("p",null,"It will build your image based on your Dockerfile. You'll see all the logs related to all lines you've added in the Dockerfile."),Object(a.b)("p",null,"If something goes wrong, it will be printed onto the terminal, and you'll be able to ",Object(a.b)("a",Object(r.a)({parentName:"p"},{href:"https://stackoverflow.com/"}),"debug it"),"."),Object(a.b)("h3",{id:"test-your-image"},"Test your image"),Object(a.b)("p",null,"If your image builds properly, you can now check how it will be handle by Qovery with the command:"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"qovery run\n")),Object(a.b)("h2",{id:"whats-next"},"What's next?"),Object(a.b)("p",null,"If you follow this tutorial and everything works perfectly, it's time to deploy your app on Qovery. You will find all the things you need to know ",Object(a.b)("a",Object(r.a)({parentName:"p"},{href:"https://docs.qovery.com/docs/using-qovery/configuration/"}),"here"),"."),Object(a.b)(c.a,{to:"/guides/tutorial/",mdxType:"Jump"},"Tutorial"))}d.isMDXComponent=!0},455:function(e,t,n){var r;!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var u=o.a.createContext({}),s=function(e){var t=o.a.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):c({},t,{},e)),n},p=function(e){var t=s(e.components);return o.a.createElement(u.Provider,{value:t},e.children)},b={inlineCode:"code",wrapper:function(e){var t=e.children;return o.a.createElement(o.a.Fragment,{},t)}},d=Object(r.forwardRef)((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=s(n),d=r,m=p["".concat(i,".").concat(d)]||p[d]||b[d]||a;return n?o.a.createElement(m,c({ref:t},u,{components:n})):o.a.createElement(m,c({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:r,i[1]=c;for(var u=2;u1?arguments[1]:void 0,n),l=i>2?arguments[2]:void 0,u=void 0===l?n:o(l,n);u>c;)t[c++]=e;return t}},460:function(e,t,n){var r=n(28).f,o=Function.prototype,a=/^\s*function ([^ (]*)/;"name"in o||n(10)&&r(o,"name",{configurable:!0,get:function(){try{return(""+this).match(a)[1]}catch(e){return""}}})},461:function(e,t,n){"use strict";n(460);var r=n(0),o=n.n(r),a=n(456);t.a=function(e){var t=e.children,n=e.name;return o.a.createElement(a.a,{type:"info",fill:!0,icon:!1,rounded:!0,className:"list--icons list--icons--arrow list--tight list--indent margin-bottom--lg"},o.a.createElement("p",{class:"text--lg margin-bottom--sm",style:{marginTop:"-0.25em"}},"Before you begin, this ",n||"page"," assumes the following:"),t)}},462:function(e,t,n){"use strict";var r=n(1),o=n(0),a=n.n(o),i=n(39),c=n(466),l=n(20),u=n.n(l);t.a=function(e){var t,n=e.to,l=e.href,s=n||l,p=Object(c.a)(s),b=Object(o.useRef)(!1),d=u.a.canUseIntersectionObserver;return Object(o.useEffect)((function(){return!d&&p&&window.docusaurus.prefetch(s),function(){d&&t&&t.disconnect()}}),[s,d,p]),s&&p?a.a.createElement(i.b,Object(r.a)({},e,{onMouseEnter:function(){b.current||(window.docusaurus.preload(s),b.current=!0)},innerRef:function(e){var n,r;d&&e&&p&&(n=e,r=function(){window.docusaurus.prefetch(s)},(t=new window.IntersectionObserver((function(e){e.forEach((function(e){n===e.target&&(e.isIntersecting||e.intersectionRatio>0)&&(t.unobserve(n),t.disconnect(),r())}))}))).observe(n))},to:s})):a.a.createElement("a",Object(r.a)({},e,{href:s}))}},465:function(e,t,n){"use strict";var r=n(0),o=n.n(r),a=n(462),i=n(455),c=n.n(i);n(134);t.a=function(e){var t=e.children,n=e.className,r=e.badge,i=e.leftIcon,l=e.rightIcon,u=e.size,s=e.target,p=e.to,b=c()("jump-to","jump-to--"+u,n),d=o.a.createElement("div",{className:"jump-to--inner"},o.a.createElement("div",{className:"jump-to--inner-2"},i&&o.a.createElement("div",{className:"jump-to--left"},o.a.createElement("i",{className:"feather icon-"+i})),o.a.createElement("div",{className:"jump-to--main"},r?o.a.createElement("span",{className:"badge badge--primary badge--right"},r):"",t),o.a.createElement("div",{className:"jump-to--right"},o.a.createElement("i",{className:"feather icon-"+(l||"chevron-right")+" arrow"}))));return s?o.a.createElement("a",{href:p,target:s,className:b},d):o.a.createElement(a.a,{to:p,className:b},d)}},466:function(e,t,n){"use strict";function r(e){return!1===/^(https?:|\/\/)/.test(e)}n.d(t,"a",(function(){return r}))}}]); \ No newline at end of file diff --git a/bbfbe73c.addb7406.js b/bbfbe73c.addb7406.js deleted file mode 100644 index 02e379fdd3..0000000000 --- a/bbfbe73c.addb7406.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see bbfbe73c.addb7406.js.LICENSE.txt */ -(window.webpackJsonp=window.webpackJsonp||[]).push([[223],{374:function(e,t,n){"use strict";n.r(t),n.d(t,"frontMatter",(function(){return u})),n.d(t,"metadata",(function(){return s})),n.d(t,"rightToc",(function(){return p})),n.d(t,"default",(function(){return d}));var r=n(1),o=n(9),a=(n(0),n(457)),i=n(456),c=n(465),l=n(461),u={last_modified_on:"2022-05-04",$schema:"/.meta/.schemas/guides.json",title:"How to write a Dockerfile",description:"How to write your first Dockerfile in order to deploy your application with Qovery",author_github:"https://github.com/MacLikorne",tags:["type: tutorial","technology: docker"],hide_pagination:!0},s={categories:[{name:"tutorial",title:"Tutorial",description:"Additional step-by-step resources to leverage even more Qovery",permalink:"/guides/tutorial"}],coverLabel:"How to write a Dockerfile",description:"How to write your first Dockerfile in order to deploy your application with Qovery",permalink:"/guides/tutorial/how-to-write-a-dockerfile",readingTime:"5 min read",source:"@site/guides/tutorial/how-to-write-a-dockerfile.md",tags:[{label:"type: tutorial",permalink:"/guides/tags/type-tutorial"},{label:"technology: docker",permalink:"/guides/tags/technology-docker"}],title:"How to write a Dockerfile",truncated:!1,prevItem:{title:"How To Use Lifecycle Job To Deploy Any Kind Of Resources",permalink:"/guides/tutorial/how-to-use-lifecycle-job-to-deploy-any-kind-of-resources"},nextItem:{title:"Import your environment variables with the Qovery CLI",permalink:"/guides/tutorial/import-your-environment-variables-with-the-qovery-cli"}},p=[{value:"My Sweet Dockerfile",id:"my-sweet-dockerfile",children:[{value:"FROM",id:"from",children:[]},{value:"WORKDIR",id:"workdir",children:[]},{value:"COPY",id:"copy",children:[]},{value:"RUN",id:"run",children:[]},{value:"EXPOSE",id:"expose",children:[]},{value:"CMD",id:"cmd",children:[]},{value:"Build your image",id:"build-your-image",children:[]},{value:"Test your image",id:"test-your-image",children:[]}]},{value:"What's next?",id:"whats-next",children:[]}],b={rightToc:p};function d(e){var t=e.components,n=Object(o.a)(e,["components"]);return Object(a.b)("wrapper",Object(r.a)({},b,n,{components:t,mdxType:"MDXLayout"}),Object(a.b)("p",null,"With Qovery, there are two ways to build and deploy your application:"),Object(a.b)("ol",null,Object(a.b)("li",{parentName:"ol"},"Without a Dockerfile in your repository: your application is built with ",Object(a.b)("a",Object(r.a)({parentName:"li"},{href:"https://docs.qovery.com/docs/using-qovery/configuration/application/#option-1-buildpacks"}),"Buildpacks")),Object(a.b)("li",{parentName:"ol"},"With a Dockerfile: sometimes Buildpacks won't fit your specific setup, and you'll have to write your Dockerfile.")),Object(a.b)("p",null,"In this article, we'll see, step by step, how to quickly write a proper Dockerfile for any application you would like to deploy."),Object(a.b)(l.a,{name:"guide",mdxType:"Assumptions"},Object(a.b)("ul",null,Object(a.b)("li",{parentName:"ul"},"You have installed the ",Object(a.b)("a",Object(r.a)({parentName:"li"},{href:"https://docs.qovery.com/docs/using-qovery/interface/cli/"}),"Qovery CLI")),Object(a.b)("li",{parentName:"ul"},"You host your code on Github"))),Object(a.b)("hr",null),Object(a.b)("h2",{id:"my-sweet-dockerfile"},"My Sweet Dockerfile"),Object(a.b)("p",null,"If you read this, you probably don't know why Docker is used and what is the purpose of a Dockerfile."),Object(a.b)("p",null,"Docker is a container engine, building and using images to deploy applications in containers. It looks like virtualization, and each container could be compared to a virtual machine with the minimal setup to run an application."),Object(a.b)("p",null,"The Dockerfile is your image builder recipe. When Docker uses it, it will follow all instructions to ",Object(a.b)("strong",{parentName:"p"},"build your application and run it"),"."),Object(a.b)("p",null,"The first step is to create a file named ",Object(a.b)("strong",{parentName:"p"},"Dockerfile")," at your project root level so Qovery would be able to find and use it."),Object(a.b)("p",null,"Also, to avoid unwanted files from your repository (images, .idea, DS_Store etc.), you need to add a ",Object(a.b)("strong",{parentName:"p"},".dockerignore"),". It will prevent heavy copy tasks of useless files, mostly your project dependencies and libraries you'll get back to with your package manager."),Object(a.b)("p",null,"The ",Object(a.b)("strong",{parentName:"p"},".dockerignore")," file works like the ",Object(a.b)("strong",{parentName:"p"},".gitignore"),", so add all the path of the useless files and folders in it."),Object(a.b)("h3",{id:"from"},"FROM"),Object(a.b)("p",null,"The first line you'll add in your Dockerfile is ",Object(a.b)("strong",{parentName:"p"},"FROM"),"."),Object(a.b)("p",null,"It will pull an already existing image from ",Object(a.b)("a",Object(r.a)({parentName:"p"},{href:"https://hub.docker.com/"}),"Docker Hub"),". You should most of the time use an image that fits your application language (Node, Python, Java, etc.), but you can go a step backward and begin with a simple Linux image."),Object(a.b)("p",null,"Your Dockerfile's first line should look like this:"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"FROM :\n")),Object(a.b)("p",null,"For example, with ",Object(a.b)("a",Object(r.a)({parentName:"p"},{href:"https://hub.docker.com/_/python"}),"python"),":"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"FROM python:3\n")),Object(a.b)("h3",{id:"workdir"},"WORKDIR"),Object(a.b)("p",null,"Since most of the images are Linux-based, a good practice is to set up a directory you'll work in. That's the purpose of the ",Object(a.b)("strong",{parentName:"p"},"WORKDIR")," line. It defines a directory and moves you in:"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"FROM :\nWORKDIR /app\n")),Object(a.b)("p",null,"If you now work with a relative path (./), it will be in the ",Object(a.b)("em",{parentName:"p"},"app")," directory."),Object(a.b)("h3",{id:"copy"},"COPY"),Object(a.b)("p",null,"Now you have defined your base image and your working directory, it's time to add your code in. ",Object(a.b)("strong",{parentName:"p"},"COPY")," works like ",Object(a.b)("strong",{parentName:"p"},"cp")," linux command. First argument is the source and second one is the destination."),Object(a.b)("p",null,"It's time to copy your source code in the image."),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"FROM :\nWORKDIR /app\nCOPY . .\n")),Object(a.b)("p",null,"Here, the elements of your ",Object(a.b)("strong",{parentName:"p"},"root")," folder from your current directory will be added inside the ",Object(a.b)("strong",{parentName:"p"},"/app")," folder."),Object(a.b)(i.a,{type:"info",mdxType:"Alert"},Object(a.b)("p",null,"You can use your current repository relative path (",Object(a.b)("strong",{parentName:"p"},".")," can be replaced by ",Object(a.b)("strong",{parentName:"p"},"./"),") if you want to add specific element (except the content of ",Object(a.b)("strong",{parentName:"p"},".dockerignore"),") to your image relative path (as we are already in the ",Object(a.b)("strong",{parentName:"p"},"/app")," folder, we can use ",Object(a.b)("strong",{parentName:"p"},"./"),").")),Object(a.b)("h3",{id:"run"},"RUN"),Object(a.b)("p",null,"One does not simply get source code to run an application."),Object(a.b)("p",null,"Most of the time, you have some stuff to do before an application execution like downloading/installing peer dependencies and build your application."),Object(a.b)("p",null,"That's the purpose of ",Object(a.b)("strong",{parentName:"p"},"RUN")," lines; it will execute a command and wait to finish the task to go forward."),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),'FROM :\nWORKDIR /app\nCOPY . .\nRUN echo "Installing or doing stuff."\nRUN \n')),Object(a.b)("p",null,"You can set as many ",Object(a.b)("strong",{parentName:"p"},"RUN")," lines as you need."),Object(a.b)("h3",{id:"expose"},"EXPOSE"),Object(a.b)("p",null,"If your app needs to be reached from outside the container, you have to open its listening port. ",Object(a.b)("strong",{parentName:"p"},"EXPOSE")," is made for this."),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),'FROM :\nWORKDIR /app\nCOPY . .\nRUN echo "Installing or doing stuff"\nRUN \nEXPOSE \n')),Object(a.b)(i.a,{type:"info",mdxType:"Alert"},Object(a.b)("p",null,"Typical mistakes are made application configuration side. Ensure your application will listen on all interfaces ",Object(a.b)("strong",{parentName:"p"},"0.0.0.0")," and not only localhost ",Object(a.b)("strong",{parentName:"p"},"127.0.0.1"),".")),Object(a.b)("h3",{id:"cmd"},"CMD"),Object(a.b)("p",null,"Your application is now ready to run."),Object(a.b)("p",null,"The last thing to do is to specify how to execute it. Add the ",Object(a.b)("strong",{parentName:"p"},"CMD")," line with the same command with all the arguments you use locally to launch your application."),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),'FROM :\nWORKDIR /app\nCOPY . .\nRUN echo "Installing or doing stuff"\nRUN \nEXPOSE \nCMD [ "", "", "" ]\n')),Object(a.b)("p",null,"Like a local usage, you can set as many arguments as needed."),Object(a.b)("h3",{id:"build-your-image"},"Build your image"),Object(a.b)("p",null,"When Qovery uses your Dockerfile, it first builds it before running it."),Object(a.b)("p",null,"If the build fails, Qovery won't be able to launch our application. To simplify debugging, you can build your image locally if you have Docker installed on your computer."),Object(a.b)("p",null,"Open a terminal and set the path at the Dockerfile location, and use the command:"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"cd ~/my/folder/where/my/code/is\ndocker build .\n")),Object(a.b)("p",null,"It will build your image based on your Dockerfile. You'll see all the logs related to all lines you've added in the Dockerfile."),Object(a.b)("p",null,"If something goes wrong, it will be printed onto the terminal, and you'll be able to ",Object(a.b)("a",Object(r.a)({parentName:"p"},{href:"https://stackoverflow.com/"}),"debug it"),"."),Object(a.b)("h3",{id:"test-your-image"},"Test your image"),Object(a.b)("p",null,"If your image builds properly, you can now check how it will be handle by Qovery with the command:"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"qovery run\n")),Object(a.b)("h2",{id:"whats-next"},"What's next?"),Object(a.b)("p",null,"If you follow this tutorial and everything works perfectly, it's time to deploy your app on Qovery. You will find all the things you need to know ",Object(a.b)("a",Object(r.a)({parentName:"p"},{href:"https://docs.qovery.com/docs/using-qovery/configuration/"}),"here"),"."),Object(a.b)(c.a,{to:"/guides/tutorial/",mdxType:"Jump"},"Tutorial"))}d.isMDXComponent=!0},455:function(e,t,n){var r;!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var u=o.a.createContext({}),s=function(e){var t=o.a.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):c({},t,{},e)),n},p=function(e){var t=s(e.components);return o.a.createElement(u.Provider,{value:t},e.children)},b={inlineCode:"code",wrapper:function(e){var t=e.children;return o.a.createElement(o.a.Fragment,{},t)}},d=Object(r.forwardRef)((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=s(n),d=r,m=p["".concat(i,".").concat(d)]||p[d]||b[d]||a;return n?o.a.createElement(m,c({ref:t},u,{components:n})):o.a.createElement(m,c({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:r,i[1]=c;for(var u=2;u1?arguments[1]:void 0,n),l=i>2?arguments[2]:void 0,u=void 0===l?n:o(l,n);u>c;)t[c++]=e;return t}},460:function(e,t,n){var r=n(28).f,o=Function.prototype,a=/^\s*function ([^ (]*)/;"name"in o||n(10)&&r(o,"name",{configurable:!0,get:function(){try{return(""+this).match(a)[1]}catch(e){return""}}})},461:function(e,t,n){"use strict";n(460);var r=n(0),o=n.n(r),a=n(456);t.a=function(e){var t=e.children,n=e.name;return o.a.createElement(a.a,{type:"info",fill:!0,icon:!1,rounded:!0,className:"list--icons list--icons--arrow list--tight list--indent margin-bottom--lg"},o.a.createElement("p",{class:"text--lg margin-bottom--sm",style:{marginTop:"-0.25em"}},"Before you begin, this ",n||"page"," assumes the following:"),t)}},462:function(e,t,n){"use strict";var r=n(1),o=n(0),a=n.n(o),i=n(39),c=n(466),l=n(20),u=n.n(l);t.a=function(e){var t,n=e.to,l=e.href,s=n||l,p=Object(c.a)(s),b=Object(o.useRef)(!1),d=u.a.canUseIntersectionObserver;return Object(o.useEffect)((function(){return!d&&p&&window.docusaurus.prefetch(s),function(){d&&t&&t.disconnect()}}),[s,d,p]),s&&p?a.a.createElement(i.b,Object(r.a)({},e,{onMouseEnter:function(){b.current||(window.docusaurus.preload(s),b.current=!0)},innerRef:function(e){var n,r;d&&e&&p&&(n=e,r=function(){window.docusaurus.prefetch(s)},(t=new window.IntersectionObserver((function(e){e.forEach((function(e){n===e.target&&(e.isIntersecting||e.intersectionRatio>0)&&(t.unobserve(n),t.disconnect(),r())}))}))).observe(n))},to:s})):a.a.createElement("a",Object(r.a)({},e,{href:s}))}},465:function(e,t,n){"use strict";var r=n(0),o=n.n(r),a=n(462),i=n(455),c=n.n(i);n(134);t.a=function(e){var t=e.children,n=e.className,r=e.badge,i=e.leftIcon,l=e.rightIcon,u=e.size,s=e.target,p=e.to,b=c()("jump-to","jump-to--"+u,n),d=o.a.createElement("div",{className:"jump-to--inner"},o.a.createElement("div",{className:"jump-to--inner-2"},i&&o.a.createElement("div",{className:"jump-to--left"},o.a.createElement("i",{className:"feather icon-"+i})),o.a.createElement("div",{className:"jump-to--main"},r?o.a.createElement("span",{className:"badge badge--primary badge--right"},r):"",t),o.a.createElement("div",{className:"jump-to--right"},o.a.createElement("i",{className:"feather icon-"+(l||"chevron-right")+" arrow"}))));return s?o.a.createElement("a",{href:p,target:s,className:b},d):o.a.createElement(a.a,{to:p,className:b},d)}},466:function(e,t,n){"use strict";function r(e){return!1===/^(https?:|\/\/)/.test(e)}n.d(t,"a",(function(){return r}))}}]); \ No newline at end of file diff --git a/bbfbe73c.f879ad12.js b/bbfbe73c.f879ad12.js new file mode 100644 index 0000000000..0f79d7f20e --- /dev/null +++ b/bbfbe73c.f879ad12.js @@ -0,0 +1,2 @@ +/*! For license information please see bbfbe73c.f879ad12.js.LICENSE.txt */ +(window.webpackJsonp=window.webpackJsonp||[]).push([[223],{374:function(e,t,n){"use strict";n.r(t),n.d(t,"frontMatter",(function(){return u})),n.d(t,"metadata",(function(){return s})),n.d(t,"rightToc",(function(){return p})),n.d(t,"default",(function(){return d}));var r=n(1),o=n(9),a=(n(0),n(457)),i=n(456),c=n(465),l=n(461),u={last_modified_on:"2024-09-18",$schema:"/.meta/.schemas/guides.json",title:"How to write a Dockerfile",description:"How to write your first Dockerfile in order to deploy your application with Qovery",author_github:"https://github.com/MacLikorne",tags:["type: tutorial","technology: docker"],hide_pagination:!0},s={categories:[{name:"tutorial",title:"Tutorial",description:"Additional step-by-step resources to leverage even more Qovery",permalink:"/guides/tutorial"}],coverLabel:"How to write a Dockerfile",description:"How to write your first Dockerfile in order to deploy your application with Qovery",permalink:"/guides/tutorial/how-to-write-a-dockerfile",readingTime:"5 min read",source:"@site/guides/tutorial/how-to-write-a-dockerfile.md",tags:[{label:"type: tutorial",permalink:"/guides/tags/type-tutorial"},{label:"technology: docker",permalink:"/guides/tags/technology-docker"}],title:"How to write a Dockerfile",truncated:!1,prevItem:{title:"How To Use Lifecycle Job To Deploy Any Kind Of Resources",permalink:"/guides/tutorial/how-to-use-lifecycle-job-to-deploy-any-kind-of-resources"},nextItem:{title:"Import your environment variables with the Qovery CLI",permalink:"/guides/tutorial/import-your-environment-variables-with-the-qovery-cli"}},p=[{value:"My Sweet Dockerfile",id:"my-sweet-dockerfile",children:[{value:"FROM",id:"from",children:[]},{value:"WORKDIR",id:"workdir",children:[]},{value:"COPY",id:"copy",children:[]},{value:"RUN",id:"run",children:[]},{value:"EXPOSE",id:"expose",children:[]},{value:"CMD",id:"cmd",children:[]},{value:"Build your image",id:"build-your-image",children:[]},{value:"Test your image",id:"test-your-image",children:[]}]},{value:"What's next?",id:"whats-next",children:[]}],b={rightToc:p};function d(e){var t=e.components,n=Object(o.a)(e,["components"]);return Object(a.b)("wrapper",Object(r.a)({},b,n,{components:t,mdxType:"MDXLayout"}),Object(a.b)("p",null,"In this article, we'll see, step by step, how to quickly write a proper Dockerfile for any application you would like to deploy."),Object(a.b)(l.a,{name:"guide",mdxType:"Assumptions"},Object(a.b)("ul",null,Object(a.b)("li",{parentName:"ul"},"You have installed the ",Object(a.b)("a",Object(r.a)({parentName:"li"},{href:"https://docs.qovery.com/docs/using-qovery/interface/cli/"}),"Qovery CLI")),Object(a.b)("li",{parentName:"ul"},"You host your code on Github"))),Object(a.b)("hr",null),Object(a.b)("h2",{id:"my-sweet-dockerfile"},"My Sweet Dockerfile"),Object(a.b)("p",null,"If you read this, you probably don't know why Docker is used and what is the purpose of a Dockerfile."),Object(a.b)("p",null,"Docker is a container engine, building and using images to deploy applications in containers. It looks like virtualization, and each container could be compared to a virtual machine with the minimal setup to run an application."),Object(a.b)("p",null,"The Dockerfile is your image builder recipe. When Docker uses it, it will follow all instructions to ",Object(a.b)("strong",{parentName:"p"},"build your application and run it"),"."),Object(a.b)("p",null,"The first step is to create a file named ",Object(a.b)("strong",{parentName:"p"},"Dockerfile")," at your project root level so Qovery would be able to find and use it."),Object(a.b)("p",null,"Also, to avoid unwanted files from your repository (images, .idea, DS_Store etc.), you need to add a ",Object(a.b)("strong",{parentName:"p"},".dockerignore"),". It will prevent heavy copy tasks of useless files, mostly your project dependencies and libraries you'll get back to with your package manager."),Object(a.b)("p",null,"The ",Object(a.b)("strong",{parentName:"p"},".dockerignore")," file works like the ",Object(a.b)("strong",{parentName:"p"},".gitignore"),", so add all the path of the useless files and folders in it."),Object(a.b)("h3",{id:"from"},"FROM"),Object(a.b)("p",null,"The first line you'll add in your Dockerfile is ",Object(a.b)("strong",{parentName:"p"},"FROM"),"."),Object(a.b)("p",null,"It will pull an already existing image from ",Object(a.b)("a",Object(r.a)({parentName:"p"},{href:"https://hub.docker.com/"}),"Docker Hub"),". You should most of the time use an image that fits your application language (Node, Python, Java, etc.), but you can go a step backward and begin with a simple Linux image."),Object(a.b)("p",null,"Your Dockerfile's first line should look like this:"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"FROM :\n")),Object(a.b)("p",null,"For example, with ",Object(a.b)("a",Object(r.a)({parentName:"p"},{href:"https://hub.docker.com/_/python"}),"python"),":"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"FROM python:3\n")),Object(a.b)("h3",{id:"workdir"},"WORKDIR"),Object(a.b)("p",null,"Since most of the images are Linux-based, a good practice is to set up a directory you'll work in. That's the purpose of the ",Object(a.b)("strong",{parentName:"p"},"WORKDIR")," line. It defines a directory and moves you in:"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"FROM :\nWORKDIR /app\n")),Object(a.b)("p",null,"If you now work with a relative path (./), it will be in the ",Object(a.b)("em",{parentName:"p"},"app")," directory."),Object(a.b)("h3",{id:"copy"},"COPY"),Object(a.b)("p",null,"Now you have defined your base image and your working directory, it's time to add your code in. ",Object(a.b)("strong",{parentName:"p"},"COPY")," works like ",Object(a.b)("strong",{parentName:"p"},"cp")," linux command. First argument is the source and second one is the destination."),Object(a.b)("p",null,"It's time to copy your source code in the image."),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"FROM :\nWORKDIR /app\nCOPY . .\n")),Object(a.b)("p",null,"Here, the elements of your ",Object(a.b)("strong",{parentName:"p"},"root")," folder from your current directory will be added inside the ",Object(a.b)("strong",{parentName:"p"},"/app")," folder."),Object(a.b)(i.a,{type:"info",mdxType:"Alert"},Object(a.b)("p",null,"You can use your current repository relative path (",Object(a.b)("strong",{parentName:"p"},".")," can be replaced by ",Object(a.b)("strong",{parentName:"p"},"./"),") if you want to add specific element (except the content of ",Object(a.b)("strong",{parentName:"p"},".dockerignore"),") to your image relative path (as we are already in the ",Object(a.b)("strong",{parentName:"p"},"/app")," folder, we can use ",Object(a.b)("strong",{parentName:"p"},"./"),").")),Object(a.b)("h3",{id:"run"},"RUN"),Object(a.b)("p",null,"One does not simply get source code to run an application."),Object(a.b)("p",null,"Most of the time, you have some stuff to do before an application execution like downloading/installing peer dependencies and build your application."),Object(a.b)("p",null,"That's the purpose of ",Object(a.b)("strong",{parentName:"p"},"RUN")," lines; it will execute a command and wait to finish the task to go forward."),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),'FROM :\nWORKDIR /app\nCOPY . .\nRUN echo "Installing or doing stuff."\nRUN \n')),Object(a.b)("p",null,"You can set as many ",Object(a.b)("strong",{parentName:"p"},"RUN")," lines as you need."),Object(a.b)("h3",{id:"expose"},"EXPOSE"),Object(a.b)("p",null,"If your app needs to be reached from outside the container, you have to open its listening port. ",Object(a.b)("strong",{parentName:"p"},"EXPOSE")," is made for this."),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),'FROM :\nWORKDIR /app\nCOPY . .\nRUN echo "Installing or doing stuff"\nRUN \nEXPOSE \n')),Object(a.b)(i.a,{type:"info",mdxType:"Alert"},Object(a.b)("p",null,"Typical mistakes are made application configuration side. Ensure your application will listen on all interfaces ",Object(a.b)("strong",{parentName:"p"},"0.0.0.0")," and not only localhost ",Object(a.b)("strong",{parentName:"p"},"127.0.0.1"),".")),Object(a.b)("h3",{id:"cmd"},"CMD"),Object(a.b)("p",null,"Your application is now ready to run."),Object(a.b)("p",null,"The last thing to do is to specify how to execute it. Add the ",Object(a.b)("strong",{parentName:"p"},"CMD")," line with the same command with all the arguments you use locally to launch your application."),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),'FROM :\nWORKDIR /app\nCOPY . .\nRUN echo "Installing or doing stuff"\nRUN \nEXPOSE \nCMD [ "", "", "" ]\n')),Object(a.b)("p",null,"Like a local usage, you can set as many arguments as needed."),Object(a.b)("h3",{id:"build-your-image"},"Build your image"),Object(a.b)("p",null,"When Qovery uses your Dockerfile, it first builds it before running it."),Object(a.b)("p",null,"If the build fails, Qovery won't be able to launch our application. To simplify debugging, you can build your image locally if you have Docker installed on your computer."),Object(a.b)("p",null,"Open a terminal and set the path at the Dockerfile location, and use the command:"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"cd ~/my/folder/where/my/code/is\ndocker build .\n")),Object(a.b)("p",null,"It will build your image based on your Dockerfile. You'll see all the logs related to all lines you've added in the Dockerfile."),Object(a.b)("p",null,"If something goes wrong, it will be printed onto the terminal, and you'll be able to ",Object(a.b)("a",Object(r.a)({parentName:"p"},{href:"https://stackoverflow.com/"}),"debug it"),"."),Object(a.b)("h3",{id:"test-your-image"},"Test your image"),Object(a.b)("p",null,"If your image builds properly, you can now check how it will be handle by Qovery with the command:"),Object(a.b)("pre",null,Object(a.b)("code",Object(r.a)({parentName:"pre"},{}),"qovery run\n")),Object(a.b)("h2",{id:"whats-next"},"What's next?"),Object(a.b)("p",null,"If you follow this tutorial and everything works perfectly, it's time to deploy your app on Qovery. You will find all the things you need to know ",Object(a.b)("a",Object(r.a)({parentName:"p"},{href:"https://docs.qovery.com/docs/using-qovery/configuration/"}),"here"),"."),Object(a.b)(c.a,{to:"/guides/tutorial/",mdxType:"Jump"},"Tutorial"))}d.isMDXComponent=!0},455:function(e,t,n){var r;!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var u=o.a.createContext({}),s=function(e){var t=o.a.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):c({},t,{},e)),n},p=function(e){var t=s(e.components);return o.a.createElement(u.Provider,{value:t},e.children)},b={inlineCode:"code",wrapper:function(e){var t=e.children;return o.a.createElement(o.a.Fragment,{},t)}},d=Object(r.forwardRef)((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=s(n),d=r,m=p["".concat(i,".").concat(d)]||p[d]||b[d]||a;return n?o.a.createElement(m,c({ref:t},u,{components:n})):o.a.createElement(m,c({ref:t},u))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:r,i[1]=c;for(var u=2;u1?arguments[1]:void 0,n),l=i>2?arguments[2]:void 0,u=void 0===l?n:o(l,n);u>c;)t[c++]=e;return t}},460:function(e,t,n){var r=n(28).f,o=Function.prototype,a=/^\s*function ([^ (]*)/;"name"in o||n(10)&&r(o,"name",{configurable:!0,get:function(){try{return(""+this).match(a)[1]}catch(e){return""}}})},461:function(e,t,n){"use strict";n(460);var r=n(0),o=n.n(r),a=n(456);t.a=function(e){var t=e.children,n=e.name;return o.a.createElement(a.a,{type:"info",fill:!0,icon:!1,rounded:!0,className:"list--icons list--icons--arrow list--tight list--indent margin-bottom--lg"},o.a.createElement("p",{class:"text--lg margin-bottom--sm",style:{marginTop:"-0.25em"}},"Before you begin, this ",n||"page"," assumes the following:"),t)}},462:function(e,t,n){"use strict";var r=n(1),o=n(0),a=n.n(o),i=n(39),c=n(466),l=n(20),u=n.n(l);t.a=function(e){var t,n=e.to,l=e.href,s=n||l,p=Object(c.a)(s),b=Object(o.useRef)(!1),d=u.a.canUseIntersectionObserver;return Object(o.useEffect)((function(){return!d&&p&&window.docusaurus.prefetch(s),function(){d&&t&&t.disconnect()}}),[s,d,p]),s&&p?a.a.createElement(i.b,Object(r.a)({},e,{onMouseEnter:function(){b.current||(window.docusaurus.preload(s),b.current=!0)},innerRef:function(e){var n,r;d&&e&&p&&(n=e,r=function(){window.docusaurus.prefetch(s)},(t=new window.IntersectionObserver((function(e){e.forEach((function(e){n===e.target&&(e.isIntersecting||e.intersectionRatio>0)&&(t.unobserve(n),t.disconnect(),r())}))}))).observe(n))},to:s})):a.a.createElement("a",Object(r.a)({},e,{href:s}))}},465:function(e,t,n){"use strict";var r=n(0),o=n.n(r),a=n(462),i=n(455),c=n.n(i);n(134);t.a=function(e){var t=e.children,n=e.className,r=e.badge,i=e.leftIcon,l=e.rightIcon,u=e.size,s=e.target,p=e.to,b=c()("jump-to","jump-to--"+u,n),d=o.a.createElement("div",{className:"jump-to--inner"},o.a.createElement("div",{className:"jump-to--inner-2"},i&&o.a.createElement("div",{className:"jump-to--left"},o.a.createElement("i",{className:"feather icon-"+i})),o.a.createElement("div",{className:"jump-to--main"},r?o.a.createElement("span",{className:"badge badge--primary badge--right"},r):"",t),o.a.createElement("div",{className:"jump-to--right"},o.a.createElement("i",{className:"feather icon-"+(l||"chevron-right")+" arrow"}))));return s?o.a.createElement("a",{href:p,target:s,className:b},d):o.a.createElement(a.a,{to:p,className:b},d)}},466:function(e,t,n){"use strict";function r(e){return!1===/^(https?:|\/\/)/.test(e)}n.d(t,"a",(function(){return r}))}}]); \ No newline at end of file diff --git a/bbfbe73c.addb7406.js.LICENSE.txt b/bbfbe73c.f879ad12.js.LICENSE.txt similarity index 100% rename from bbfbe73c.addb7406.js.LICENSE.txt rename to bbfbe73c.f879ad12.js.LICENSE.txt diff --git a/community/index.html b/community/index.html index bcde910cb4..f2da0350f2 100644 --- a/community/index.html +++ b/community/index.html @@ -26,7 +26,7 @@ - + @@ -47,7 +47,7 @@ - + diff --git a/components/index.html b/components/index.html index b34747f1cd..a2f94d4464 100644 --- a/components/index.html +++ b/components/index.html @@ -26,7 +26,7 @@ - + @@ -47,7 +47,7 @@ - + diff --git a/contact/index.html b/contact/index.html index e1b3f7238f..a3bb9d1143 100644 --- a/contact/index.html +++ b/contact/index.html @@ -26,7 +26,7 @@ - + @@ -47,7 +47,7 @@ - + diff --git a/docs/getting-started/basic-concepts/index.html b/docs/getting-started/basic-concepts/index.html index 40452ed537..23f151834c 100644 --- a/docs/getting-started/basic-concepts/index.html +++ b/docs/getting-started/basic-concepts/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/deploy-my-app/index.html b/docs/getting-started/deploy-my-app/index.html index d282948937..e1719d6642 100644 --- a/docs/getting-started/deploy-my-app/index.html +++ b/docs/getting-started/deploy-my-app/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/how-qovery-works/index.html b/docs/getting-started/how-qovery-works/index.html index f7fe3d2e2a..d7bfb54c17 100644 --- a/docs/getting-started/how-qovery-works/index.html +++ b/docs/getting-started/how-qovery-works/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/index.html b/docs/getting-started/index.html index 2b96047e38..2fc320667a 100644 --- a/docs/getting-started/index.html +++ b/docs/getting-started/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/create-credentials/index.html b/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/create-credentials/index.html index 0e46d491f2..3bcfc099f2 100644 --- a/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/create-credentials/index.html +++ b/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/create-credentials/index.html @@ -26,7 +26,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/faq/index.html b/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/faq/index.html index 5b76258b31..9d2c1a2ecb 100644 --- a/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/faq/index.html +++ b/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/faq/index.html @@ -26,7 +26,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/index.html b/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/index.html index fbf034851a..f071b968b6 100644 --- a/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/index.html +++ b/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/infrastructure/index.html b/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/infrastructure/index.html index bdb177eabb..060644d76f 100644 --- a/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/infrastructure/index.html +++ b/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/infrastructure/index.html @@ -26,7 +26,7 @@ - + @@ -59,7 +59,7 @@ - + diff --git a/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/quickstart/index.html b/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/quickstart/index.html index 2a9da33d0f..27ed43db46 100644 --- a/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/quickstart/index.html +++ b/docs/getting-started/install-qovery/aws/cluster-managed-by-qovery/quickstart/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/install-qovery/aws/index.html b/docs/getting-started/install-qovery/aws/index.html index 6769246782..c89759e09b 100644 --- a/docs/getting-started/install-qovery/aws/index.html +++ b/docs/getting-started/install-qovery/aws/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/install-qovery/aws/self-managed-cluster/index.html b/docs/getting-started/install-qovery/aws/self-managed-cluster/index.html index 262088f4af..c592056c48 100644 --- a/docs/getting-started/install-qovery/aws/self-managed-cluster/index.html +++ b/docs/getting-started/install-qovery/aws/self-managed-cluster/index.html @@ -26,7 +26,7 @@ - + @@ -58,7 +58,7 @@ - + diff --git a/docs/getting-started/install-qovery/azure/cluster-managed-by-qovery/index.html b/docs/getting-started/install-qovery/azure/cluster-managed-by-qovery/index.html index 56a74a5f2b..0a95dcb2c7 100644 --- a/docs/getting-started/install-qovery/azure/cluster-managed-by-qovery/index.html +++ b/docs/getting-started/install-qovery/azure/cluster-managed-by-qovery/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/install-qovery/azure/cluster-managed-by-qovery/quickstart/index.html b/docs/getting-started/install-qovery/azure/cluster-managed-by-qovery/quickstart/index.html index 14a8e1d6f5..003a319024 100644 --- a/docs/getting-started/install-qovery/azure/cluster-managed-by-qovery/quickstart/index.html +++ b/docs/getting-started/install-qovery/azure/cluster-managed-by-qovery/quickstart/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/install-qovery/azure/index.html b/docs/getting-started/install-qovery/azure/index.html index da98704ec2..241f469b9f 100644 --- a/docs/getting-started/install-qovery/azure/index.html +++ b/docs/getting-started/install-qovery/azure/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/install-qovery/azure/self-managed-cluster/index.html b/docs/getting-started/install-qovery/azure/self-managed-cluster/index.html index 636e9258a2..1c610bce70 100644 --- a/docs/getting-started/install-qovery/azure/self-managed-cluster/index.html +++ b/docs/getting-started/install-qovery/azure/self-managed-cluster/index.html @@ -26,7 +26,7 @@ - + @@ -58,7 +58,7 @@ - + diff --git a/docs/getting-started/install-qovery/gcp/cluster-managed-by-qovery/create-credentials/index.html b/docs/getting-started/install-qovery/gcp/cluster-managed-by-qovery/create-credentials/index.html index c014d1b96e..15b9b6e228 100644 --- a/docs/getting-started/install-qovery/gcp/cluster-managed-by-qovery/create-credentials/index.html +++ b/docs/getting-started/install-qovery/gcp/cluster-managed-by-qovery/create-credentials/index.html @@ -26,7 +26,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/docs/getting-started/install-qovery/gcp/cluster-managed-by-qovery/index.html b/docs/getting-started/install-qovery/gcp/cluster-managed-by-qovery/index.html index a2f143601e..b14815aabf 100644 --- a/docs/getting-started/install-qovery/gcp/cluster-managed-by-qovery/index.html +++ b/docs/getting-started/install-qovery/gcp/cluster-managed-by-qovery/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/install-qovery/gcp/cluster-managed-by-qovery/quickstart/index.html b/docs/getting-started/install-qovery/gcp/cluster-managed-by-qovery/quickstart/index.html index 020cd7e9d1..d189dac576 100644 --- a/docs/getting-started/install-qovery/gcp/cluster-managed-by-qovery/quickstart/index.html +++ b/docs/getting-started/install-qovery/gcp/cluster-managed-by-qovery/quickstart/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/install-qovery/gcp/index.html b/docs/getting-started/install-qovery/gcp/index.html index a1caabb487..1aea2e5ea9 100644 --- a/docs/getting-started/install-qovery/gcp/index.html +++ b/docs/getting-started/install-qovery/gcp/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/install-qovery/gcp/self-managed-cluster/index.html b/docs/getting-started/install-qovery/gcp/self-managed-cluster/index.html index d5cd9446d2..11666f159c 100644 --- a/docs/getting-started/install-qovery/gcp/self-managed-cluster/index.html +++ b/docs/getting-started/install-qovery/gcp/self-managed-cluster/index.html @@ -26,7 +26,7 @@ - + @@ -58,7 +58,7 @@ - + diff --git a/docs/getting-started/install-qovery/index.html b/docs/getting-started/install-qovery/index.html index e4f60e322b..25e5316225 100644 --- a/docs/getting-started/install-qovery/index.html +++ b/docs/getting-started/install-qovery/index.html @@ -26,7 +26,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/docs/getting-started/install-qovery/kubernetes/byok-config/index.html b/docs/getting-started/install-qovery/kubernetes/byok-config/index.html index 67e8bd2db8..1d4f78d5d3 100644 --- a/docs/getting-started/install-qovery/kubernetes/byok-config/index.html +++ b/docs/getting-started/install-qovery/kubernetes/byok-config/index.html @@ -26,7 +26,7 @@ - + @@ -58,7 +58,7 @@ - + diff --git a/docs/getting-started/install-qovery/kubernetes/faq/index.html b/docs/getting-started/install-qovery/kubernetes/faq/index.html index 69692966fb..1f2c4347af 100644 --- a/docs/getting-started/install-qovery/kubernetes/faq/index.html +++ b/docs/getting-started/install-qovery/kubernetes/faq/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/install-qovery/kubernetes/index.html b/docs/getting-started/install-qovery/kubernetes/index.html index b3b83afd56..a3603da474 100644 --- a/docs/getting-started/install-qovery/kubernetes/index.html +++ b/docs/getting-started/install-qovery/kubernetes/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/install-qovery/kubernetes/quickstart/index.html b/docs/getting-started/install-qovery/kubernetes/quickstart/index.html index cc40dfe242..968794f634 100644 --- a/docs/getting-started/install-qovery/kubernetes/quickstart/index.html +++ b/docs/getting-started/install-qovery/kubernetes/quickstart/index.html @@ -26,7 +26,7 @@ - + @@ -58,7 +58,7 @@ - + diff --git a/docs/getting-started/install-qovery/kubernetes/validate-installation/index.html b/docs/getting-started/install-qovery/kubernetes/validate-installation/index.html index cccd50c3eb..12f1e458f2 100644 --- a/docs/getting-started/install-qovery/kubernetes/validate-installation/index.html +++ b/docs/getting-started/install-qovery/kubernetes/validate-installation/index.html @@ -26,7 +26,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/docs/getting-started/install-qovery/local/index.html b/docs/getting-started/install-qovery/local/index.html index c3927ace22..f3aae9782b 100644 --- a/docs/getting-started/install-qovery/local/index.html +++ b/docs/getting-started/install-qovery/local/index.html @@ -26,7 +26,7 @@ - + @@ -59,7 +59,7 @@ - + diff --git a/docs/getting-started/install-qovery/scaleway/cluster-managed-by-qovery/create-credentials/index.html b/docs/getting-started/install-qovery/scaleway/cluster-managed-by-qovery/create-credentials/index.html index 483ba9e802..3d3faa142b 100644 --- a/docs/getting-started/install-qovery/scaleway/cluster-managed-by-qovery/create-credentials/index.html +++ b/docs/getting-started/install-qovery/scaleway/cluster-managed-by-qovery/create-credentials/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/install-qovery/scaleway/cluster-managed-by-qovery/faq/index.html b/docs/getting-started/install-qovery/scaleway/cluster-managed-by-qovery/faq/index.html index 6ba87165f4..dd2787a7b9 100644 --- a/docs/getting-started/install-qovery/scaleway/cluster-managed-by-qovery/faq/index.html +++ b/docs/getting-started/install-qovery/scaleway/cluster-managed-by-qovery/faq/index.html @@ -26,7 +26,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/docs/getting-started/install-qovery/scaleway/cluster-managed-by-qovery/index.html b/docs/getting-started/install-qovery/scaleway/cluster-managed-by-qovery/index.html index 959e7fcd49..13dd1a4aee 100644 --- a/docs/getting-started/install-qovery/scaleway/cluster-managed-by-qovery/index.html +++ b/docs/getting-started/install-qovery/scaleway/cluster-managed-by-qovery/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/install-qovery/scaleway/cluster-managed-by-qovery/quickstart/index.html b/docs/getting-started/install-qovery/scaleway/cluster-managed-by-qovery/quickstart/index.html index 952461aad1..6e49e3fe33 100644 --- a/docs/getting-started/install-qovery/scaleway/cluster-managed-by-qovery/quickstart/index.html +++ b/docs/getting-started/install-qovery/scaleway/cluster-managed-by-qovery/quickstart/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/install-qovery/scaleway/index.html b/docs/getting-started/install-qovery/scaleway/index.html index b4bbdc845d..70d42b9d41 100644 --- a/docs/getting-started/install-qovery/scaleway/index.html +++ b/docs/getting-started/install-qovery/scaleway/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/install-qovery/scaleway/self-managed-cluster/index.html b/docs/getting-started/install-qovery/scaleway/self-managed-cluster/index.html index 694264b69d..2e26cb72db 100644 --- a/docs/getting-started/install-qovery/scaleway/self-managed-cluster/index.html +++ b/docs/getting-started/install-qovery/scaleway/self-managed-cluster/index.html @@ -26,7 +26,7 @@ - + @@ -58,7 +58,7 @@ - + diff --git a/docs/getting-started/what-is-qovery/index.html b/docs/getting-started/what-is-qovery/index.html index e14fd0715d..4713449c52 100644 --- a/docs/getting-started/what-is-qovery/index.html +++ b/docs/getting-started/what-is-qovery/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/getting-started/whats-next/index.html b/docs/getting-started/whats-next/index.html index 56b314cdaf..ce4d429ee8 100644 --- a/docs/getting-started/whats-next/index.html +++ b/docs/getting-started/whats-next/index.html @@ -26,7 +26,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/docs/index.html b/docs/index.html index adf35cf2ce..6ed4e911e4 100644 --- a/docs/index.html +++ b/docs/index.html @@ -22,7 +22,7 @@ - + @@ -37,7 +37,7 @@ - + diff --git a/docs/security-and-compliance/backup-and-restore/index.html b/docs/security-and-compliance/backup-and-restore/index.html index 1c5aef12b7..e8d1df556a 100644 --- a/docs/security-and-compliance/backup-and-restore/index.html +++ b/docs/security-and-compliance/backup-and-restore/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/security-and-compliance/encryption/index.html b/docs/security-and-compliance/encryption/index.html index e5b01c5336..53644fae8d 100644 --- a/docs/security-and-compliance/encryption/index.html +++ b/docs/security-and-compliance/encryption/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/security-and-compliance/gdpr/index.html b/docs/security-and-compliance/gdpr/index.html index d5cc5fb50d..b1f51fc1ae 100644 --- a/docs/security-and-compliance/gdpr/index.html +++ b/docs/security-and-compliance/gdpr/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/security-and-compliance/index.html b/docs/security-and-compliance/index.html index 600ed79291..719bddae69 100644 --- a/docs/security-and-compliance/index.html +++ b/docs/security-and-compliance/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/security-and-compliance/soc2/index.html b/docs/security-and-compliance/soc2/index.html index ae0e16161d..bf4293bf28 100644 --- a/docs/security-and-compliance/soc2/index.html +++ b/docs/security-and-compliance/soc2/index.html @@ -26,7 +26,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/docs/useful-resources/faq/index.html b/docs/useful-resources/faq/index.html index 511d38f3fd..bf3a7be93c 100644 --- a/docs/useful-resources/faq/index.html +++ b/docs/useful-resources/faq/index.html @@ -26,7 +26,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/docs/useful-resources/help-and-support/index.html b/docs/useful-resources/help-and-support/index.html index 063f66a12c..9edb30ff52 100644 --- a/docs/useful-resources/help-and-support/index.html +++ b/docs/useful-resources/help-and-support/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/audit-logs/index.html b/docs/using-qovery/audit-logs/index.html index 6c0e5ddd68..7d6abf8641 100644 --- a/docs/using-qovery/audit-logs/index.html +++ b/docs/using-qovery/audit-logs/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/configuration/advanced-settings/index.html b/docs/using-qovery/configuration/advanced-settings/index.html index 855eb0e160..58c3857bd0 100644 --- a/docs/using-qovery/configuration/advanced-settings/index.html +++ b/docs/using-qovery/configuration/advanced-settings/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/configuration/application-health-checks/index.html b/docs/using-qovery/configuration/application-health-checks/index.html index 0181822153..ad1dbe5031 100644 --- a/docs/using-qovery/configuration/application-health-checks/index.html +++ b/docs/using-qovery/configuration/application-health-checks/index.html @@ -26,7 +26,7 @@ - + @@ -59,7 +59,7 @@ - + diff --git a/docs/using-qovery/configuration/application/index.html b/docs/using-qovery/configuration/application/index.html index c7f59aa5da..464f965114 100644 --- a/docs/using-qovery/configuration/application/index.html +++ b/docs/using-qovery/configuration/application/index.html @@ -26,7 +26,7 @@ - + @@ -44,17 +44,16 @@ - +
-

Application

An application is part of a Project within an Environment and is a container unit. Multiple applications can be part of the same Environment, be connected to a set of dependencies (databases and other services), and can communicate with other applications within the same Environment.

Qovery allows you to create and deploy applications from two different sources: Git Repository or Container Registry

Deploying from a Git Repository

In this configuration, Qovery will pull the code from the chosen repository, build the application and deploy it on your kubernetes cluster.

The list of Git repositories available during the setup is strictly tied to the permissions of your git account (by default Qovery can access all your repositories). If you want to restrict the Qovery access only to a few repositories, user the GitHub Qovery Application (only for Github).

Deploying from a Container Registry

In this configuration, Qovery will pull the chosen container registry an image you have pre-built and deploy it on your kubernetes cluster.

To improve security and avoid deploying images from non-authorized registries, we have decided to restrict the list of Container Registry you can use during the setup process. Only an administrator with the right permissions can manage it from the Container Registry Management page

Create an Application

  1. Go into the chosen environment and press the "New Service" button and then the "Create application" button

    Creation

  2. Select the following fields:

    • Application Name: give a name to your application
    • Application Source: Chose between Git Repository or Container Registry, depending on the source location of your application

    If you want to deploy an application from a Git Repository you will have to select:

    • Git Repository: Select the git provider hosting your code (it can be hosted on GitHub, GitLab or Bitbucket). You can add a new git access by clicking on New git access.
    • Branch: Select branch that Qovery should use to deploy your application
    • Root Application Path: base folder in which the application resides in your repository
    • Build Mode: choose between Docker or Buildpack. For more information, go to this section

    If you want to deploy an application from a Container Registry you will have to select:

    • Registry: select the container registry storing the image of your application. You can add a new container registry by clicking on New registry.
    • Image name: the name of the image to be deployed with this application (example: postgres)
    • Image tag: the tag of the image to be deployed with this application (example: 1.0).
    • Image Entrypoint: the entrypoint to be used to launch your application (not mandatory)
    • CMD Arguments: the arguments to be passed to launch your application (not mandatory) separated with a space. Example: rails -h 0.0.0.0 -p 8080 string "complex arg".

    Auto Deploy

    See the Deploying with auto-deploy feature section.

    Extra labels/annotations (optional)

    Add your extra annotation/label groups. See the Add annotation/label group section for more information.

  3. Within this section, you will need to define the resources to be assigned to your application at run time.

    • vCPU: the vCPU assigned to each instance of your application. The default is 500m (0.5 vCPU).
    • RAM: the amount of RAM assigned to each instance of your application. The default is 512MB.
    • Number of instances (Application Auto-scaling): select the minimum and the maximum number of instances of your application that can run within your cluster. The number of instances running at an insant t is automatically managed by Kubernetes (Application auto-scaling) and it is based on real-time CPU consumption. When your app goes above 60% of CPU consumption for 5 minutes, your app will be auto-scaled and more instances will be added. It is transparent. +

      Application

      An application is part of a Project within an Environment and is a container unit. Multiple applications can be part of the same Environment, be connected to a set of dependencies (databases and other services), and can communicate with other applications within the same Environment.

      Qovery allows you to create and deploy applications from two different sources: Git Repository or Container Registry

      Deploying from a Git Repository

      In this configuration, Qovery will pull the code from the chosen repository, build the application and deploy it on your kubernetes cluster.

      The list of Git repositories available during the setup is strictly tied to the permissions of your git account (by default Qovery can access all your repositories). If you want to restrict the Qovery access only to a few repositories, user the GitHub Qovery Application (only for Github).

      Deploying from a Container Registry

      In this configuration, Qovery will pull the chosen container registry an image you have pre-built and deploy it on your kubernetes cluster.

      To improve security and avoid deploying images from non-authorized registries, we have decided to restrict the list of Container Registry you can use during the setup process. Only an administrator with the right permissions can manage it from the Container Registry Management page

      Create an Application

      1. Go into the chosen environment and press the "New Service" button and then the "Create application" button

        Creation

      2. Select the following fields:

        • Application Name: give a name to your application
        • Application Source: Chose between Git Repository or Container Registry, depending on the source location of your application

        If you want to deploy an application from a Git Repository you will have to select:

        • Git Repository: Select the git provider hosting your code (it can be hosted on GitHub, GitLab or Bitbucket). You can add a new git access by clicking on New git access.
        • Branch: Select branch that Qovery should use to deploy your application
        • Root Application Path: base folder in which the application resides in your repository
        • Build and deploy: configure your Dockerfile location. For more information, go to this section

        If you want to deploy an application from a Container Registry you will have to select:

        • Registry: select the container registry storing the image of your application. You can add a new container registry by clicking on New registry.
        • Image name: the name of the image to be deployed with this application (example: postgres)
        • Image tag: the tag of the image to be deployed with this application (example: 1.0).
        • Image Entrypoint: the entrypoint to be used to launch your application (not mandatory)
        • CMD Arguments: the arguments to be passed to launch your application (not mandatory) separated with a space. Example: rails -h 0.0.0.0 -p 8080 string "complex arg".

        Auto Deploy

        See the Deploying with auto-deploy feature section.

        Extra labels/annotations (optional)

        Add your extra annotation/label groups. See the Add annotation/label group section for more information.

      3. Within this section, you will need to define the resources to be assigned to your application at run time.

        • vCPU: the vCPU assigned to each instance of your application. The default is 500m (0.5 vCPU).
        • RAM: the amount of RAM assigned to each instance of your application. The default is 512MB.
        • Number of instances (Application Auto-scaling): select the minimum and the maximum number of instances of your application that can run within your cluster. The number of instances running at an insant t is automatically managed by Kubernetes (Application auto-scaling) and it is based on real-time CPU consumption. When your app goes above 60% of CPU consumption for 5 minutes, your app will be auto-scaled and more instances will be added. It is transparent. Qovery runs your application on Kubernetes and relies on metrics-server service to auto-scale your app.

        Resources

      4. You can now define one or more ports for your Application. Most of the application needs to be accessed by other services inside or outside your environment over different L7/L4 protocols. Today Qovery supports the following protocols:

        • HTTPS (Select this protocol if you need to run Websockets)
        • gRPC
        • TCP
        • UDP

        By default ports are accessible only from inside your environment. You can also expose them publicly, making them accessible over the public network via a dedicated public domain that will be assigned to your application by Qovery during the deployment (See the Qovery Provided Domains section). Note that HTTPS/gRPC ports are always exposed over the port 443.

        Application Ports

        Important Informations

        • Most of the Kubernetes Health Checks are based on the port declared in this section. Make sure you declare the right port and that you configure the health checks properly.
        • Connections on public ports are automatically closed after 60 seconds. If you want to implement long living connection (like for websockets) please make sure to use the rigth ingress timeouts in the advanced settings section
        • Exposing publicly TCP/UDP ports requires to create a dedicated load balancer and it takes a few minutes before having it ready (~15 minutes). Note also that this has a direct impact on your cloud provider bill.
        • You can configure your application to use the PORT environment variable by adding the PORT on your application env variables page.
        • A Note on Listening IPs: It is best for your application to listen on 0.0.0.0:$PORT. While most things work with 127.0.0.1 and localhost, some do not (NodeJS for example)
      5. (Optional) If a port has been defined for your application, you can define the health check probes to run in order to verify the state of your application

        To know more about how to configure your Liveness and Readiness probes, have a look at the health-checks section

      6. Define any input variable required by your application to run. Any declared variable will be injected as environment variables based on the selected scope (project, environment, service) -Any additional environment variable can be added later from the environment variable section

        Input Variables

      7. You will find a recap of your application setup and you can now decide to:

        • Go back to one of the previous steps and change your application settings
        • Create your application without deploying it
        • Create and deploy your application

        Application

      Deployment Management

      Have a look at the Deployment Management section for more information.

      Configuration

      Once created, you can access the configuration of an application at any time via the Settings tab available on the application section

      Application Settings

      You can find below the description of each of the tabs available in this section

      General

      General settings section allows you to set up your application name and the source code location (git repository or image registry) .

      Git Repository

      If your application is built and deployed from a git repository, within this section you can:

      • Modify the git provider where your code is stored (it can be hosted on GitHub, GitLab or Bitbucket).
      • Modify the branch that Qovery should use for deploying your application
      • Modify Root Application Path - base folder in which the application resides in your repository

      General Settings Git

      Container Registry

      If your application is deployed from an image registry, within this section you can modify:

      • Registry: select the container registry storing the image of your application. Note: only pre-configured registry are available in this list, check the Container Registry Management page for more information.
      • Image name: the name of the image to be deployed with this application (example: postgres)
      • Image tag: the tag of the image to be deployed with this application (example: 1.0).
      • Image Entrypoint: the entrypoint to be used to launch your applicaiton (not mandatory)
      • CMD Arguments: the arguments to be passed to launch your applicaiton (not mandatory). We expect the format to be an array. Example ["rails", "-h", "0.0.0.0", "-p", "8080", "string"]

      General Settings Git

      Build Mode

      This option is available only if you have selected "Git Repository" as source

      Option 1: Buildpacks

      To simplify the application build for the developer, Qovery supports Buildpacks out of the box. Buildpacks determine the build process for an app and which assets and runtimes should be made available to your code at runtime. If your complex apps are running multiple languages, you can also use multiple buildpacks within a single app. -Meaning, as a developer, you don't need to write a Dockerfile to build and run your app. Qovery Buildpacks takes care of everything for you.

      Supported languages

      languageversion
      Node.JSany
      Clojureany
      Pythonany
      Javaany
      Gradleany
      JVMany
      Grailsany
      Scalaany
      Playany
      PHPany
      Goany

      You don't find a cool language? Suggest us to support it

      Option 2: Dockerfile

      If your job is built via the Qovery CI (Source="Git Repository"), this section allows you to define the Dockerfile location.

      If you don't have one, you can use the docker init command to generate one for your application (check the documentation here). After creating a Dockerfile, specify the location of your Dockerfile in Dockefile path field.

      Auto Deploy

      See the Deploying with auto-deploy feature section.

      Extra labels/annotations

      Add your extra annotation/label groups. See the Add annotation/label group section for more information.

      Resources

      CPU

      CPU

      To configure the number of CPUs that your app needs, adjust the setting in the Resources section of the application configuration.

      Please note that in this section you configure the CPU allocated by the cluster for your application and that cannot consume more than this value. Even if the application is underused and consumes fewer resources, the cluster will still reserve the selected amount of CPU.

      RAM

      To configure the amount of RAM that your app needs, adjust the setting in Resources section of the application configuration.

      Please note that in this section you configure the CPU allocated by the cluster for your application and that cannot consume more than this value. Even if the application is underused and consume less resources, the cluster will still reserve the selected amount of CPU. If your application requires more RAM than requested, it will be killed by the kubernetes scheduler.

      Auto-scaling

      Application auto-scaling is based on real-time CPU consumption. When your app goes above 60% of CPU consumption for 15 seconds, your app will be auto-scaled and more instances will be added. It is transparent. The downscale will happen if the CPU consumption is lower than 60% for at least 5 minutes. +Any additional environment variable can be added later from the environment variable section

      Input Variables

    • You will find a recap of your application setup and you can now decide to:

      • Go back to one of the previous steps and change your application settings
      • Create your application without deploying it
      • Create and deploy your application

      Application

Deployment Management

Have a look at the Deployment Management section for more information.

Configuration

Once created, you can access the configuration of an application at any time via the Settings tab available on the application section

Application Settings

You can find below the description of each of the tabs available in this section

General

General settings section allows you to set up your application name and the source code location (git repository or image registry) .

Git Repository

If your application is built and deployed from a git repository, within this section you can:

  • Modify the git provider where your code is stored (it can be hosted on GitHub, GitLab or Bitbucket).
  • Modify the branch that Qovery should use for deploying your application
  • Modify Root Application Path - base folder in which the application resides in your repository

General Settings Git

Container Registry

If your application is deployed from an image registry, within this section you can modify:

  • Registry: select the container registry storing the image of your application. Note: only pre-configured registry are available in this list, check the Container Registry Management page for more information.
  • Image name: the name of the image to be deployed with this application (example: postgres)
  • Image tag: the tag of the image to be deployed with this application (example: 1.0).
  • Image Entrypoint: the entrypoint to be used to launch your applicaiton (not mandatory)
  • CMD Arguments: the arguments to be passed to launch your applicaiton (not mandatory). We expect the format to be an array. Example ["rails", "-h", "0.0.0.0", "-p", "8080", "string"]

General Settings Git

Build and Deploy

If your job is built via the Qovery CI (Source="Git Repository"), this section allows you to define the Dockerfile location.

If you don't have one, you can use the docker init command to generate one for your application (check the documentation here). After creating a Dockerfile, specify the location of your Dockerfile in Dockefile path field.

Auto Deploy

See the Deploying with auto-deploy feature section.

Extra labels/annotations

Add your extra annotation/label groups. See the Add annotation/label group section for more information.

Resources

CPU

CPU

To configure the number of CPUs that your app needs, adjust the setting in the Resources section of the application configuration.

Please note that in this section you configure the CPU allocated by the cluster for your application and that cannot consume more than this value. Even if the application is underused and consumes fewer resources, the cluster will still reserve the selected amount of CPU.

RAM

To configure the amount of RAM that your app needs, adjust the setting in Resources section of the application configuration.

Please note that in this section you configure the CPU allocated by the cluster for your application and that cannot consume more than this value. Even if the application is underused and consume less resources, the cluster will still reserve the selected amount of CPU. If your application requires more RAM than requested, it will be killed by the kubernetes scheduler.

Auto-scaling

Application auto-scaling is based on real-time CPU consumption. When your app goes above 60% of CPU consumption for 15 seconds, your app will be auto-scaled and more instances will be added. It is transparent. The downscale will happen if the CPU consumption is lower than 60% for at least 5 minutes. You can adjust the minimum and maximum of instances you need in your application settings. Qovery runs your application on Kubernetes and relies on metrics-server service to auto-scale your app.

Storage

Block Storage

The default filesystem for applications running on Qovery is ephemeral. Application data isn’t persisted across deploys and restarts, which works just fine for most apps because they use managed databases to persist data.

However, many applications need persistent disk storage that isn’t ephemeral. These include:

  • Blogging platforms and CMSs like WordPress, Ghost, and Strapi.
  • Collaboration apps like Mattermost, GitLab, and Discourse.

This is where Qovery block Storage comes in. Qovery applications can use storage to store data that persists across deploys and restarts, making it easy to deploy stateful applications.

Use cases
✅ Good use cases
  • For I/O intensive applications (E.g. database)
  • To store temporary files
❌ Bad use cases
  • To store file > 1 TB
  • To expose files from an application (E.g. images)
Types of Block Storage

Qovery Storage supports:

TypeMax IOPSMax ThroughputMin SizeMax SizeUse cases
fast_ssd640001GB/s5GB10GB Community / 1TB paid plansCritical business applications that require sustained IOPS like databases
Configuration

You can set up your Block Storage in Storage section of your application configuration.

Application Storage

Ports

Within this section you can define the port exposed by your application to the other services or even over the internet. You can edit the existing ports or declare new ones by specifying:

  • Application port: this is the port exposed internally by your application for the other services.
  • Protocol: you can select the protocol used by your application : HTTP (for both standard HTTP or websocket communications), gRPC, TCP, UDP.
  • Publicly exposed: it allows you to expose over the public network your service. A public domain will be assigned to your application during the deployment (see Connecting from the internet section)
  • If Publicly Exposed is selected:
    • External port: it is the port that can be used to access this service over the internet (when exposed publicly). Note that for HTTP and gRPC the port is set by default to 443.
    • Port Name: it is the name assigned to the port. When multiple ports are exposed publicly, its value is used to route the traffic to the right port based on the called subdomain (which will contain the port name value). Since each port is exposed on the port 443, having a different subdomain is the only way to have multiple ports exposed over the internet. If not set, the default value is p<portNumber> (see Qovery Provided Domain section for more information)

Application Ports

Important Informations

  • Most of the Kubernetes Health Checks]docs.using-qovery.configuration.service-health-checks are based on the port declared in this section. Make sure you declare the right port and that you configure the health checks properly.
  • Connections on public ports are automatically closed after 60 seconds. If you want to implement long living connection (like for websockets) please make sure to use the rigth ingress timeouts in the advanced settings section
  • Exposing publicly TCP/UDP ports requires to create a dedicated load balancer and it takes a few minutes before having it ready (~15 minutes). Note also that this has a direct impact on your cloud provider bill.
  • You can configure your application to use the PORT environment variable by adding the PORT on your application env variables page.
  • A Note on Listening IPs: It's best for your application to listen on 0.0.0.0:$PORT. While most things work with 127.0.0.1 and localhost, some do not (NodeJS for example)

Health Checks

To know more about how to configure your Liveness and Readiness probes, have a look at the health-checks section

Deployment Restrictions

This section allows to specify which changes on your repository should trigger an auto-deploy (if enabled). To know more about how to configure your Deployment Restrictions, have a look at the deployment restrictions section.

Connecting from the internet

Your application can be reached from the internet by publicly exposing at least one of its ports (See the Ports section to know more). Once this is done, Qovery will generate and assign a domain to your application (See this section to know more). You can customize the domain assigned to your application via the Domain section in the settings (see this section to know more).

Qovery provided domains

For each port publicly exposed, a domain is automatically assigned by Qovery to your application. Qovery will manage for you the networking and the TLS configuration for these domains.

Example: p80-zdf72de72-z709e1a88-gtw.za8ad0657.bool.sh or <service_name>-p80-zdf72de72-z709e1a88-gtw.za8ad0657.bool.sh for helm services.

Note:

  • each service deployed on the same cluster will have the same root domain assigned (example: za8ad0657.bool.sh)
  • the first characters of the domain (before the -) is based on the portName given to the port associated with this domain (See the port section)
  • a default domain (without the portName) is assigned to the default port(See the port section). Example zdf72de72-z709e1a88-gtw.za8ad0657.bool.sh

Special Case - Preview Environment For each port exposed publicly, an additional domain will be created with the following pattern portName-prId-srvName-envSourceName.cluster_domain:

  • portName: is the port name, as explained above
  • prID: is the id of the PR that has generated the preview environment
  • srvName: is the name of the service
  • envSourceName: is the name of the blueprint environment that has created the current preview environment

domain example: p80-123-frontend-blueprint.za8ad0657.bool.sh

Custom domains

If you prefer to assign your own domain to the application, you can customize it from the "Domain" section within the application settings.

You can customize the domain of your application in different ways, depending on what you want to achieve:

  • You want to use your own domain for your application
  • You want to modify the subdomain assigned to your application by Qovery (i.e. change p80-zdf72de72-z709e1a88-gtw.za8ad0657.bool.sh into my-app-domain.za8ad0657.bool.sh). See this section to know more about these domains.

In both cases, you can assign the new custom domain by pressing the Add Domain button.

Application Domains

For each custom domain, a green checkmark will appear if the domain is correctly configured. You can perform another check by clicking on the checkmark. If you're behind a CDN, we will only check if your custom domain resolves to an IP address.

Check Domains

If there's an issue with a domain, a global error message will be displayed, and you can view the error details by hovering over the red cross. After correcting your configuration, you can perform another check by clicking on the red cross.

Check Domains

Configuring your own domain

Once the domain is added within the Qovery console (Example: mydomain.com), you need to configure within your DNS two CNAME records pointing to the domain provided by Qovery, as shown in the UI (example: mydomain.com CNAME za7cc1b71-z4b8474b3-gtw.zc531a994.rustrocks.cloud and *.mydomain.com CNAME za7cc1b71-z4b8474b3-gtw.zc531a994.rustrocks.cloud).

Having a wildcard domain entry (example: *.mydomain.com) configured on your DNS will avoid you to modify the Qovery setup every time you want to add a new subdomain. If wildcard is not supported by your DNS provider, you will have to configure each subdomain manually.

If a service needs to expose more than one port publicly, you can define a dedicated subdomain to redirect the traffic on the right port by setting the “Port Name” value within the port settings.

After re-deploying the service, Qovery will automatically handle the TLS/SSL certificate creation and renewal for the configured domain.

Custom Domain

Special case - domain behind a CDN

If your service is behind a CDN using a proxy mode (i.e. the traffic is routed through the CDN to Qovery), make sure to enable the option Domain behind a CDN and disable the option "Generate certificate" on the domain setup. Since the certificate of your domain is directly managed by the CDN, Qovery won't be able to do that for you and it will raise warnings on your application status.

CDN Proxy

If you are using Cloudflare to manage your CDN, we can also manage automatically your custom domain configuration via a wildcard domain setup for the whole cluster. Check our documentation here

Change the auto assigned sub-domain

You can specify a different sub-domain for your application as long as it belongs to the assigned cluster domain (see Qovery provided domains). @@ -63,7 +62,7 @@ - + @@ -81,7 +80,7 @@ - + diff --git a/docs/using-qovery/configuration/cloud-service-provider/index.html b/docs/using-qovery/configuration/cloud-service-provider/index.html index 2886b56e77..dd56c885d1 100644 --- a/docs/using-qovery/configuration/cloud-service-provider/index.html +++ b/docs/using-qovery/configuration/cloud-service-provider/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/configuration/cluster-advanced-settings/index.html b/docs/using-qovery/configuration/cluster-advanced-settings/index.html index 2c3a9de0ce..b9c0b390da 100644 --- a/docs/using-qovery/configuration/cluster-advanced-settings/index.html +++ b/docs/using-qovery/configuration/cluster-advanced-settings/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/configuration/clusters/index.html b/docs/using-qovery/configuration/clusters/index.html index 5315d9db95..bc952e6d2b 100644 --- a/docs/using-qovery/configuration/clusters/index.html +++ b/docs/using-qovery/configuration/clusters/index.html @@ -26,7 +26,7 @@ - + @@ -62,7 +62,7 @@ - + diff --git a/docs/using-qovery/configuration/cronjob/index.html b/docs/using-qovery/configuration/cronjob/index.html index c748fb3dd5..28690adbd9 100644 --- a/docs/using-qovery/configuration/cronjob/index.html +++ b/docs/using-qovery/configuration/cronjob/index.html @@ -26,7 +26,7 @@ - + @@ -59,7 +59,7 @@ - + diff --git a/docs/using-qovery/configuration/database/index.html b/docs/using-qovery/configuration/database/index.html index 070b9925e8..0ffb8a228b 100644 --- a/docs/using-qovery/configuration/database/index.html +++ b/docs/using-qovery/configuration/database/index.html @@ -26,7 +26,7 @@ - + @@ -58,7 +58,7 @@ - + diff --git a/docs/using-qovery/configuration/database/mongodb/index.html b/docs/using-qovery/configuration/database/mongodb/index.html index a2b17ddee4..9cc0e47309 100644 --- a/docs/using-qovery/configuration/database/mongodb/index.html +++ b/docs/using-qovery/configuration/database/mongodb/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/configuration/database/mysql/index.html b/docs/using-qovery/configuration/database/mysql/index.html index fc5e62c70c..7a8e4f1add 100644 --- a/docs/using-qovery/configuration/database/mysql/index.html +++ b/docs/using-qovery/configuration/database/mysql/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/configuration/database/postgresql/index.html b/docs/using-qovery/configuration/database/postgresql/index.html index ac66669a24..515cdc5658 100644 --- a/docs/using-qovery/configuration/database/postgresql/index.html +++ b/docs/using-qovery/configuration/database/postgresql/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/configuration/database/redis/index.html b/docs/using-qovery/configuration/database/redis/index.html index 79800711fd..7967bf3bbd 100644 --- a/docs/using-qovery/configuration/database/redis/index.html +++ b/docs/using-qovery/configuration/database/redis/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/configuration/deployment-rule/index.html b/docs/using-qovery/configuration/deployment-rule/index.html index 015318e4f1..e0d61676ec 100644 --- a/docs/using-qovery/configuration/deployment-rule/index.html +++ b/docs/using-qovery/configuration/deployment-rule/index.html @@ -26,7 +26,7 @@ - + @@ -63,7 +63,7 @@ - + diff --git a/docs/using-qovery/configuration/environment-variable/index.html b/docs/using-qovery/configuration/environment-variable/index.html index fd2e1eca1c..1cb3dbda70 100644 --- a/docs/using-qovery/configuration/environment-variable/index.html +++ b/docs/using-qovery/configuration/environment-variable/index.html @@ -26,7 +26,7 @@ - + @@ -67,7 +67,7 @@ - + diff --git a/docs/using-qovery/configuration/environment/index.html b/docs/using-qovery/configuration/environment/index.html index 670e38f585..b78d3c8a44 100644 --- a/docs/using-qovery/configuration/environment/index.html +++ b/docs/using-qovery/configuration/environment/index.html @@ -26,7 +26,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/docs/using-qovery/configuration/helm/index.html b/docs/using-qovery/configuration/helm/index.html index 29b2eb3143..3e06c5003d 100644 --- a/docs/using-qovery/configuration/helm/index.html +++ b/docs/using-qovery/configuration/helm/index.html @@ -26,7 +26,7 @@ - + @@ -61,7 +61,7 @@ - + diff --git a/docs/using-qovery/configuration/index.html b/docs/using-qovery/configuration/index.html index b3aca3a5b0..72b831d8fe 100644 --- a/docs/using-qovery/configuration/index.html +++ b/docs/using-qovery/configuration/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/configuration/lifecycle-job/index.html b/docs/using-qovery/configuration/lifecycle-job/index.html index 983a9d06df..8becd2541f 100644 --- a/docs/using-qovery/configuration/lifecycle-job/index.html +++ b/docs/using-qovery/configuration/lifecycle-job/index.html @@ -26,7 +26,7 @@ - + @@ -61,7 +61,7 @@ - + diff --git a/docs/using-qovery/configuration/object-storage/index.html b/docs/using-qovery/configuration/object-storage/index.html index 7ab59a3bcd..e5d4c293c8 100644 --- a/docs/using-qovery/configuration/object-storage/index.html +++ b/docs/using-qovery/configuration/object-storage/index.html @@ -26,7 +26,7 @@ - + @@ -66,7 +66,7 @@ - + diff --git a/docs/using-qovery/configuration/organization/api-token/index.html b/docs/using-qovery/configuration/organization/api-token/index.html index e07ad8b53a..19b377d94e 100644 --- a/docs/using-qovery/configuration/organization/api-token/index.html +++ b/docs/using-qovery/configuration/organization/api-token/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/configuration/organization/container-registry/index.html b/docs/using-qovery/configuration/organization/container-registry/index.html index 8a63f0ab28..1006ca4b70 100644 --- a/docs/using-qovery/configuration/organization/container-registry/index.html +++ b/docs/using-qovery/configuration/organization/container-registry/index.html @@ -26,7 +26,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/docs/using-qovery/configuration/organization/git-repository-access/index.html b/docs/using-qovery/configuration/organization/git-repository-access/index.html index 9a46a20371..db3633609f 100644 --- a/docs/using-qovery/configuration/organization/git-repository-access/index.html +++ b/docs/using-qovery/configuration/organization/git-repository-access/index.html @@ -26,7 +26,7 @@ - + @@ -60,7 +60,7 @@ - + diff --git a/docs/using-qovery/configuration/organization/helm-repository/index.html b/docs/using-qovery/configuration/organization/helm-repository/index.html index 3dd20ae764..78452d9f5f 100644 --- a/docs/using-qovery/configuration/organization/helm-repository/index.html +++ b/docs/using-qovery/configuration/organization/helm-repository/index.html @@ -26,7 +26,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/docs/using-qovery/configuration/organization/index.html b/docs/using-qovery/configuration/organization/index.html index ec105baf83..f6441f62eb 100644 --- a/docs/using-qovery/configuration/organization/index.html +++ b/docs/using-qovery/configuration/organization/index.html @@ -26,7 +26,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/docs/using-qovery/configuration/organization/labels-annotations/index.html b/docs/using-qovery/configuration/organization/labels-annotations/index.html index b24c91b285..f566cd8fff 100644 --- a/docs/using-qovery/configuration/organization/labels-annotations/index.html +++ b/docs/using-qovery/configuration/organization/labels-annotations/index.html @@ -26,7 +26,7 @@ - + @@ -61,7 +61,7 @@ - + diff --git a/docs/using-qovery/configuration/organization/members-rbac/index.html b/docs/using-qovery/configuration/organization/members-rbac/index.html index a960a45abb..f360c79180 100644 --- a/docs/using-qovery/configuration/organization/members-rbac/index.html +++ b/docs/using-qovery/configuration/organization/members-rbac/index.html @@ -26,7 +26,7 @@ - + @@ -58,7 +58,7 @@ - + diff --git a/docs/using-qovery/configuration/project/index.html b/docs/using-qovery/configuration/project/index.html index 5add80de58..ba037bcf3f 100644 --- a/docs/using-qovery/configuration/project/index.html +++ b/docs/using-qovery/configuration/project/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/configuration/provider/index.html b/docs/using-qovery/configuration/provider/index.html index 24ffa3ba0c..43383c0a11 100644 --- a/docs/using-qovery/configuration/provider/index.html +++ b/docs/using-qovery/configuration/provider/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/configuration/service-health-checks/index.html b/docs/using-qovery/configuration/service-health-checks/index.html index 6346d5243f..b2f8512a92 100644 --- a/docs/using-qovery/configuration/service-health-checks/index.html +++ b/docs/using-qovery/configuration/service-health-checks/index.html @@ -26,7 +26,7 @@ - + @@ -59,7 +59,7 @@ - + diff --git a/docs/using-qovery/configuration/user-account/index.html b/docs/using-qovery/configuration/user-account/index.html index 4dd37048b0..64b836506d 100644 --- a/docs/using-qovery/configuration/user-account/index.html +++ b/docs/using-qovery/configuration/user-account/index.html @@ -26,7 +26,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/docs/using-qovery/deployment/deploying-with-auto-deploy/index.html b/docs/using-qovery/deployment/deploying-with-auto-deploy/index.html index 5b3201bac3..7bdca6c125 100644 --- a/docs/using-qovery/deployment/deploying-with-auto-deploy/index.html +++ b/docs/using-qovery/deployment/deploying-with-auto-deploy/index.html @@ -26,7 +26,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/docs/using-qovery/deployment/deploying-with-ci-cd/index.html b/docs/using-qovery/deployment/deploying-with-ci-cd/index.html index b7094bf132..2cc98ff4b6 100644 --- a/docs/using-qovery/deployment/deploying-with-ci-cd/index.html +++ b/docs/using-qovery/deployment/deploying-with-ci-cd/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/deployment/deployment-actions/index.html b/docs/using-qovery/deployment/deployment-actions/index.html index 21478e2157..b7896083b8 100644 --- a/docs/using-qovery/deployment/deployment-actions/index.html +++ b/docs/using-qovery/deployment/deployment-actions/index.html @@ -26,7 +26,7 @@ - + @@ -61,7 +61,7 @@ - + diff --git a/docs/using-qovery/deployment/deployment-history/index.html b/docs/using-qovery/deployment/deployment-history/index.html index c1df943550..b2964d97c5 100644 --- a/docs/using-qovery/deployment/deployment-history/index.html +++ b/docs/using-qovery/deployment/deployment-history/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/deployment/deployment-pipeline/index.html b/docs/using-qovery/deployment/deployment-pipeline/index.html index f49b663309..e45c709722 100644 --- a/docs/using-qovery/deployment/deployment-pipeline/index.html +++ b/docs/using-qovery/deployment/deployment-pipeline/index.html @@ -26,7 +26,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/docs/using-qovery/deployment/deployment-strategies/index.html b/docs/using-qovery/deployment/deployment-strategies/index.html index f073907fc4..a45ed5bdab 100644 --- a/docs/using-qovery/deployment/deployment-strategies/index.html +++ b/docs/using-qovery/deployment/deployment-strategies/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/deployment/image-mirroring/index.html b/docs/using-qovery/deployment/image-mirroring/index.html index ca8d59f648..0476a9b547 100644 --- a/docs/using-qovery/deployment/image-mirroring/index.html +++ b/docs/using-qovery/deployment/image-mirroring/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/deployment/index.html b/docs/using-qovery/deployment/index.html index 5fb4e9c9cc..b4eada2912 100644 --- a/docs/using-qovery/deployment/index.html +++ b/docs/using-qovery/deployment/index.html @@ -26,7 +26,7 @@ - + @@ -58,7 +58,7 @@ - + diff --git a/docs/using-qovery/deployment/logs/index.html b/docs/using-qovery/deployment/logs/index.html index bc1b2c9592..a555ffd736 100644 --- a/docs/using-qovery/deployment/logs/index.html +++ b/docs/using-qovery/deployment/logs/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/deployment/running-and-deployment-statuses/index.html b/docs/using-qovery/deployment/running-and-deployment-statuses/index.html index 4d1335acaa..6d6de7683f 100644 --- a/docs/using-qovery/deployment/running-and-deployment-statuses/index.html +++ b/docs/using-qovery/deployment/running-and-deployment-statuses/index.html @@ -26,7 +26,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/docs/using-qovery/index.html b/docs/using-qovery/index.html index a55b00467e..1845c88d16 100644 --- a/docs/using-qovery/index.html +++ b/docs/using-qovery/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/api-integration/index.html b/docs/using-qovery/integration/api-integration/index.html index d92d1c15db..1252c91516 100644 --- a/docs/using-qovery/integration/api-integration/index.html +++ b/docs/using-qovery/integration/api-integration/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/container-registry/index.html b/docs/using-qovery/integration/container-registry/index.html index d665d58f88..de3767acb6 100644 --- a/docs/using-qovery/integration/container-registry/index.html +++ b/docs/using-qovery/integration/container-registry/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/continuous-integration/circle-ci/index.html b/docs/using-qovery/integration/continuous-integration/circle-ci/index.html index 00248a31bd..5339887fa8 100644 --- a/docs/using-qovery/integration/continuous-integration/circle-ci/index.html +++ b/docs/using-qovery/integration/continuous-integration/circle-ci/index.html @@ -26,7 +26,7 @@ - + @@ -58,7 +58,7 @@ - + diff --git a/docs/using-qovery/integration/continuous-integration/github-actions/index.html b/docs/using-qovery/integration/continuous-integration/github-actions/index.html index 971cbb35ec..df5a19d467 100644 --- a/docs/using-qovery/integration/continuous-integration/github-actions/index.html +++ b/docs/using-qovery/integration/continuous-integration/github-actions/index.html @@ -26,7 +26,7 @@ - + @@ -66,7 +66,7 @@ - + diff --git a/docs/using-qovery/integration/continuous-integration/gitlab-ci/index.html b/docs/using-qovery/integration/continuous-integration/gitlab-ci/index.html index c1419ded6b..f3e071ab15 100644 --- a/docs/using-qovery/integration/continuous-integration/gitlab-ci/index.html +++ b/docs/using-qovery/integration/continuous-integration/gitlab-ci/index.html @@ -26,7 +26,7 @@ - + @@ -61,7 +61,7 @@ - + diff --git a/docs/using-qovery/integration/continuous-integration/index.html b/docs/using-qovery/integration/continuous-integration/index.html index cc01b290df..8de0dfce90 100644 --- a/docs/using-qovery/integration/continuous-integration/index.html +++ b/docs/using-qovery/integration/continuous-integration/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/continuous-integration/jenkins/index.html b/docs/using-qovery/integration/continuous-integration/jenkins/index.html index 6a39003841..66d4784380 100644 --- a/docs/using-qovery/integration/continuous-integration/jenkins/index.html +++ b/docs/using-qovery/integration/continuous-integration/jenkins/index.html @@ -26,7 +26,7 @@ - + @@ -58,7 +58,7 @@ - + diff --git a/docs/using-qovery/integration/git-repository/index.html b/docs/using-qovery/integration/git-repository/index.html index 17952f3b72..2685699ba5 100644 --- a/docs/using-qovery/integration/git-repository/index.html +++ b/docs/using-qovery/integration/git-repository/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/helm-repository/index.html b/docs/using-qovery/integration/helm-repository/index.html index a740c085c5..d19452d772 100644 --- a/docs/using-qovery/integration/helm-repository/index.html +++ b/docs/using-qovery/integration/helm-repository/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/iac/cloudformation/index.html b/docs/using-qovery/integration/iac/cloudformation/index.html index 501b75b6a6..d28ca48177 100644 --- a/docs/using-qovery/integration/iac/cloudformation/index.html +++ b/docs/using-qovery/integration/iac/cloudformation/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/iac/index.html b/docs/using-qovery/integration/iac/index.html index 278e1c7cf7..e23a789b1a 100644 --- a/docs/using-qovery/integration/iac/index.html +++ b/docs/using-qovery/integration/iac/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/iac/other/index.html b/docs/using-qovery/integration/iac/other/index.html index bc95879354..436d606c67 100644 --- a/docs/using-qovery/integration/iac/other/index.html +++ b/docs/using-qovery/integration/iac/other/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/iac/terraform/index.html b/docs/using-qovery/integration/iac/terraform/index.html index 4f203c5039..cd32cd130f 100644 --- a/docs/using-qovery/integration/iac/terraform/index.html +++ b/docs/using-qovery/integration/iac/terraform/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/index.html b/docs/using-qovery/integration/index.html index 334d4352b7..2e2b9d12f8 100644 --- a/docs/using-qovery/integration/index.html +++ b/docs/using-qovery/integration/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/monitoring/datadog/index.html b/docs/using-qovery/integration/monitoring/datadog/index.html index db5ef1ee15..a256325837 100644 --- a/docs/using-qovery/integration/monitoring/datadog/index.html +++ b/docs/using-qovery/integration/monitoring/datadog/index.html @@ -26,7 +26,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/docs/using-qovery/integration/monitoring/index.html b/docs/using-qovery/integration/monitoring/index.html index 3db343c11a..8e22be38f1 100644 --- a/docs/using-qovery/integration/monitoring/index.html +++ b/docs/using-qovery/integration/monitoring/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/monitoring/new-relic/index.html b/docs/using-qovery/integration/monitoring/new-relic/index.html index ce7998e6ea..b394a6ceaa 100644 --- a/docs/using-qovery/integration/monitoring/new-relic/index.html +++ b/docs/using-qovery/integration/monitoring/new-relic/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/secret-manager/aws-secrets-manager/index.html b/docs/using-qovery/integration/secret-manager/aws-secrets-manager/index.html index 3e904a961a..391309c117 100644 --- a/docs/using-qovery/integration/secret-manager/aws-secrets-manager/index.html +++ b/docs/using-qovery/integration/secret-manager/aws-secrets-manager/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/secret-manager/doppler/index.html b/docs/using-qovery/integration/secret-manager/doppler/index.html index a9e1d3a10b..ce6d7e627e 100644 --- a/docs/using-qovery/integration/secret-manager/doppler/index.html +++ b/docs/using-qovery/integration/secret-manager/doppler/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/secret-manager/index.html b/docs/using-qovery/integration/secret-manager/index.html index f3700e9b19..782804f9d8 100644 --- a/docs/using-qovery/integration/secret-manager/index.html +++ b/docs/using-qovery/integration/secret-manager/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/slack/index.html b/docs/using-qovery/integration/slack/index.html index d2e020ba01..151f20439e 100644 --- a/docs/using-qovery/integration/slack/index.html +++ b/docs/using-qovery/integration/slack/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/terraform-provider/index.html b/docs/using-qovery/integration/terraform-provider/index.html index 895b3ebb93..ecc8933af8 100644 --- a/docs/using-qovery/integration/terraform-provider/index.html +++ b/docs/using-qovery/integration/terraform-provider/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/integration/webhook/index.html b/docs/using-qovery/integration/webhook/index.html index 9a2b1d9649..8062f8b7c0 100644 --- a/docs/using-qovery/integration/webhook/index.html +++ b/docs/using-qovery/integration/webhook/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/interface/cli/index.html b/docs/using-qovery/interface/cli/index.html index 9983abdde6..fc3b29ca45 100644 --- a/docs/using-qovery/interface/cli/index.html +++ b/docs/using-qovery/interface/cli/index.html @@ -26,7 +26,7 @@ - + @@ -89,7 +89,7 @@ - + diff --git a/docs/using-qovery/interface/index.html b/docs/using-qovery/interface/index.html index e1d6a70c80..9a9d9f64e6 100644 --- a/docs/using-qovery/interface/index.html +++ b/docs/using-qovery/interface/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/interface/rest-api/index.html b/docs/using-qovery/interface/rest-api/index.html index b76b429c5f..33babda9d9 100644 --- a/docs/using-qovery/interface/rest-api/index.html +++ b/docs/using-qovery/interface/rest-api/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/interface/terraform-interface/index.html b/docs/using-qovery/interface/terraform-interface/index.html index 8d2e109dee..99093c22e3 100644 --- a/docs/using-qovery/interface/terraform-interface/index.html +++ b/docs/using-qovery/interface/terraform-interface/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/interface/web-interface/index.html b/docs/using-qovery/interface/web-interface/index.html index aee8d478c6..f3d501e788 100644 --- a/docs/using-qovery/interface/web-interface/index.html +++ b/docs/using-qovery/interface/web-interface/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/maintenance/index.html b/docs/using-qovery/maintenance/index.html index 90715a3681..46e1ccf7f3 100644 --- a/docs/using-qovery/maintenance/index.html +++ b/docs/using-qovery/maintenance/index.html @@ -26,7 +26,7 @@ - + @@ -71,7 +71,7 @@ - + diff --git a/docs/using-qovery/troubleshoot/cluster-troubleshoot/index.html b/docs/using-qovery/troubleshoot/cluster-troubleshoot/index.html index 0c7c3fd8b4..0eb0bdea48 100644 --- a/docs/using-qovery/troubleshoot/cluster-troubleshoot/index.html +++ b/docs/using-qovery/troubleshoot/cluster-troubleshoot/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/troubleshoot/index.html b/docs/using-qovery/troubleshoot/index.html index 616340162a..6fc2674946 100644 --- a/docs/using-qovery/troubleshoot/index.html +++ b/docs/using-qovery/troubleshoot/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/docs/using-qovery/troubleshoot/service-deployment-troubleshoot/index.html b/docs/using-qovery/troubleshoot/service-deployment-troubleshoot/index.html index 5040b1717d..90e7a7b19f 100644 --- a/docs/using-qovery/troubleshoot/service-deployment-troubleshoot/index.html +++ b/docs/using-qovery/troubleshoot/service-deployment-troubleshoot/index.html @@ -26,7 +26,7 @@ - + @@ -59,7 +59,7 @@ - + diff --git a/docs/using-qovery/troubleshoot/service-run-troubleshoot/index.html b/docs/using-qovery/troubleshoot/service-run-troubleshoot/index.html index ad5acb767d..c122778e50 100644 --- a/docs/using-qovery/troubleshoot/service-run-troubleshoot/index.html +++ b/docs/using-qovery/troubleshoot/service-run-troubleshoot/index.html @@ -26,7 +26,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/guides/advanced/continuous-integration/index.html b/guides/advanced/continuous-integration/index.html index 5d651de512..9d0f3b59e0 100644 --- a/guides/advanced/continuous-integration/index.html +++ b/guides/advanced/continuous-integration/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/advanced/costs-control/index.html b/guides/advanced/costs-control/index.html index aed46bf20d..d4d28b1025 100644 --- a/guides/advanced/costs-control/index.html +++ b/guides/advanced/costs-control/index.html @@ -26,7 +26,7 @@ - + @@ -51,7 +51,7 @@ - + diff --git a/guides/advanced/deploy-api-gateway/index.html b/guides/advanced/deploy-api-gateway/index.html index 2045410fd7..adc426c8b3 100644 --- a/guides/advanced/deploy-api-gateway/index.html +++ b/guides/advanced/deploy-api-gateway/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/advanced/deploy-aws-services/index.html b/guides/advanced/deploy-aws-services/index.html index 5269bf75dd..ae728fb690 100644 --- a/guides/advanced/deploy-aws-services/index.html +++ b/guides/advanced/deploy-aws-services/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/advanced/deploy-daemonset-with-karpenter/index.html b/guides/advanced/deploy-daemonset-with-karpenter/index.html index b52ca65dcb..4339094e6a 100644 --- a/guides/advanced/deploy-daemonset-with-karpenter/index.html +++ b/guides/advanced/deploy-daemonset-with-karpenter/index.html @@ -26,7 +26,7 @@ - + @@ -49,7 +49,7 @@ - + diff --git a/guides/advanced/deploy-external-services/index.html b/guides/advanced/deploy-external-services/index.html index 03d05137e9..089e9e4207 100644 --- a/guides/advanced/deploy-external-services/index.html +++ b/guides/advanced/deploy-external-services/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/advanced/deploy-frontend/index.html b/guides/advanced/deploy-frontend/index.html index 63b471c646..f2c5f5cdf1 100644 --- a/guides/advanced/deploy-frontend/index.html +++ b/guides/advanced/deploy-frontend/index.html @@ -26,7 +26,7 @@ - + @@ -53,7 +53,7 @@ - + diff --git a/guides/advanced/helm-chart/index.html b/guides/advanced/helm-chart/index.html index cdd78a9c6f..a81c0491c0 100644 --- a/guides/advanced/helm-chart/index.html +++ b/guides/advanced/helm-chart/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/advanced/index.html b/guides/advanced/index.html index 84968db0c5..29974ca2ac 100644 --- a/guides/advanced/index.html +++ b/guides/advanced/index.html @@ -26,7 +26,7 @@ - + @@ -83,7 +83,7 @@ - + diff --git a/guides/advanced/microservices/index.html b/guides/advanced/microservices/index.html index 9b2c97e485..66480e5e23 100644 --- a/guides/advanced/microservices/index.html +++ b/guides/advanced/microservices/index.html @@ -26,7 +26,7 @@ - + @@ -58,7 +58,7 @@ - + diff --git a/guides/advanced/migration/index.html b/guides/advanced/migration/index.html index 495a7646ca..15646cc380 100644 --- a/guides/advanced/migration/index.html +++ b/guides/advanced/migration/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/advanced/monitoring/index.html b/guides/advanced/monitoring/index.html index 686d49e9e6..e33a28b69c 100644 --- a/guides/advanced/monitoring/index.html +++ b/guides/advanced/monitoring/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/advanced/monorepository/index.html b/guides/advanced/monorepository/index.html index 213cb1ff46..a33106b8fa 100644 --- a/guides/advanced/monorepository/index.html +++ b/guides/advanced/monorepository/index.html @@ -26,7 +26,7 @@ - + @@ -51,7 +51,7 @@ - + diff --git a/guides/advanced/production/index.html b/guides/advanced/production/index.html index 3c1eac8d3f..f43372a24f 100644 --- a/guides/advanced/production/index.html +++ b/guides/advanced/production/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/advanced/seed-database/index.html b/guides/advanced/seed-database/index.html index c63f1f58c0..27a10860a5 100644 --- a/guides/advanced/seed-database/index.html +++ b/guides/advanced/seed-database/index.html @@ -26,7 +26,7 @@ - + @@ -51,7 +51,7 @@ - + diff --git a/guides/advanced/terraform/index.html b/guides/advanced/terraform/index.html index 5176af41df..c73200dc0c 100644 --- a/guides/advanced/terraform/index.html +++ b/guides/advanced/terraform/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/advanced/upgrading-rds-instance/index.html b/guides/advanced/upgrading-rds-instance/index.html index 0454d83ef9..05fe6642b4 100644 --- a/guides/advanced/upgrading-rds-instance/index.html +++ b/guides/advanced/upgrading-rds-instance/index.html @@ -26,7 +26,7 @@ - + @@ -49,7 +49,7 @@ - + diff --git a/guides/advanced/use-preview-environments/index.html b/guides/advanced/use-preview-environments/index.html index 3c8868a6e6..7d50c33845 100644 --- a/guides/advanced/use-preview-environments/index.html +++ b/guides/advanced/use-preview-environments/index.html @@ -26,7 +26,7 @@ - + @@ -52,7 +52,7 @@ - + diff --git a/guides/getting-started/create-a-database/index.html b/guides/getting-started/create-a-database/index.html index ac8c7952ec..f5a159a294 100644 --- a/guides/getting-started/create-a-database/index.html +++ b/guides/getting-started/create-a-database/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/guides/getting-started/debugging/index.html b/guides/getting-started/debugging/index.html index 357dd3b5bb..d97e7ad37a 100644 --- a/guides/getting-started/debugging/index.html +++ b/guides/getting-started/debugging/index.html @@ -26,7 +26,7 @@ - + @@ -52,7 +52,7 @@ - + diff --git a/guides/getting-started/deploy-your-first-application/index.html b/guides/getting-started/deploy-your-first-application/index.html index 0560851fa2..488b0e7d93 100644 --- a/guides/getting-started/deploy-your-first-application/index.html +++ b/guides/getting-started/deploy-your-first-application/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/getting-started/index.html b/guides/getting-started/index.html index 88d380499e..bc42fbf461 100644 --- a/guides/getting-started/index.html +++ b/guides/getting-started/index.html @@ -26,7 +26,7 @@ - + @@ -59,7 +59,7 @@ - + diff --git a/guides/getting-started/managing-environment-variables/index.html b/guides/getting-started/managing-environment-variables/index.html index 552b23120e..37b75dab29 100644 --- a/guides/getting-started/managing-environment-variables/index.html +++ b/guides/getting-started/managing-environment-variables/index.html @@ -26,7 +26,7 @@ - + @@ -60,7 +60,7 @@ - + diff --git a/guides/getting-started/setting-custom-domain/index.html b/guides/getting-started/setting-custom-domain/index.html index f86a052395..c8a849a035 100644 --- a/guides/getting-started/setting-custom-domain/index.html +++ b/guides/getting-started/setting-custom-domain/index.html @@ -26,7 +26,7 @@ - + @@ -52,7 +52,7 @@ - + diff --git a/guides/index.html b/guides/index.html index d46bcccc4c..d13edda99b 100644 --- a/guides/index.html +++ b/guides/index.html @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ - + @@ -142,7 +142,7 @@ - + @@ -189,7 +189,7 @@ - + @@ -293,7 +293,7 @@ - + @@ -305,7 +305,7 @@ - + diff --git a/guides/installation-guide/guide-amazon-web-services/index.html b/guides/installation-guide/guide-amazon-web-services/index.html index 2cb89cbce8..280814e206 100644 --- a/guides/installation-guide/guide-amazon-web-services/index.html +++ b/guides/installation-guide/guide-amazon-web-services/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/installation-guide/guide-google-cloud-platform/index.html b/guides/installation-guide/guide-google-cloud-platform/index.html index 473d1bee12..f7b474868e 100644 --- a/guides/installation-guide/guide-google-cloud-platform/index.html +++ b/guides/installation-guide/guide-google-cloud-platform/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/installation-guide/guide-kubernetes/index.html b/guides/installation-guide/guide-kubernetes/index.html index a2391bed94..bf9def0519 100644 --- a/guides/installation-guide/guide-kubernetes/index.html +++ b/guides/installation-guide/guide-kubernetes/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/installation-guide/guide-microsoft-azure/index.html b/guides/installation-guide/guide-microsoft-azure/index.html index f956981d10..3dd53dc66c 100644 --- a/guides/installation-guide/guide-microsoft-azure/index.html +++ b/guides/installation-guide/guide-microsoft-azure/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/installation-guide/guide-scaleway/index.html b/guides/installation-guide/guide-scaleway/index.html index 2881e9e949..a03608f644 100644 --- a/guides/installation-guide/guide-scaleway/index.html +++ b/guides/installation-guide/guide-scaleway/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/installation-guide/index.html b/guides/installation-guide/index.html index d2f6d50480..cdf82d31bf 100644 --- a/guides/installation-guide/index.html +++ b/guides/installation-guide/index.html @@ -26,7 +26,7 @@ - + @@ -59,7 +59,7 @@ - + diff --git a/guides/tags/database-postgresql/index.html b/guides/tags/database-postgresql/index.html index 7681b89deb..296d06f662 100644 --- a/guides/tags/database-postgresql/index.html +++ b/guides/tags/database-postgresql/index.html @@ -26,7 +26,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/guides/tags/framework-rails/index.html b/guides/tags/framework-rails/index.html index 5228f91e3e..b3fa8b435b 100644 --- a/guides/tags/framework-rails/index.html +++ b/guides/tags/framework-rails/index.html @@ -26,7 +26,7 @@ - + @@ -51,7 +51,7 @@ - + diff --git a/guides/tags/index.html b/guides/tags/index.html index 51e8b6e1a6..3d0ec52262 100644 --- a/guides/tags/index.html +++ b/guides/tags/index.html @@ -26,7 +26,7 @@ - + @@ -49,7 +49,7 @@ - + diff --git a/guides/tags/installation-guide-aws/index.html b/guides/tags/installation-guide-aws/index.html index 514c3af5bc..a5d22c59bb 100644 --- a/guides/tags/installation-guide-aws/index.html +++ b/guides/tags/installation-guide-aws/index.html @@ -26,7 +26,7 @@ - + @@ -58,7 +58,7 @@ - + @@ -77,7 +77,7 @@ - + @@ -109,7 +109,7 @@ - + diff --git a/guides/tags/installation-guide-azure/index.html b/guides/tags/installation-guide-azure/index.html index c78b572261..a557b74449 100644 --- a/guides/tags/installation-guide-azure/index.html +++ b/guides/tags/installation-guide-azure/index.html @@ -26,7 +26,7 @@ - + @@ -51,7 +51,7 @@ - + diff --git a/guides/tags/installation-guide-gcp/index.html b/guides/tags/installation-guide-gcp/index.html index 26602d6369..c882c22e8b 100644 --- a/guides/tags/installation-guide-gcp/index.html +++ b/guides/tags/installation-guide-gcp/index.html @@ -26,7 +26,7 @@ - + @@ -51,7 +51,7 @@ - + diff --git a/guides/tags/installation-guide-kubernetes/index.html b/guides/tags/installation-guide-kubernetes/index.html index 02c1cffb61..e16e83042b 100644 --- a/guides/tags/installation-guide-kubernetes/index.html +++ b/guides/tags/installation-guide-kubernetes/index.html @@ -26,7 +26,7 @@ - + @@ -51,7 +51,7 @@ - + diff --git a/guides/tags/installation-guide-scaleway/index.html b/guides/tags/installation-guide-scaleway/index.html index c818512f5b..adf99658b2 100644 --- a/guides/tags/installation-guide-scaleway/index.html +++ b/guides/tags/installation-guide-scaleway/index.html @@ -26,7 +26,7 @@ - + @@ -51,7 +51,7 @@ - + diff --git a/guides/tags/language-javascript/index.html b/guides/tags/language-javascript/index.html index 9c29e32832..76dff9f10b 100644 --- a/guides/tags/language-javascript/index.html +++ b/guides/tags/language-javascript/index.html @@ -26,7 +26,7 @@ - + @@ -53,7 +53,7 @@ - + diff --git a/guides/tags/language-kotlin/index.html b/guides/tags/language-kotlin/index.html index d0d43506a7..18e1bd0a16 100644 --- a/guides/tags/language-kotlin/index.html +++ b/guides/tags/language-kotlin/index.html @@ -26,7 +26,7 @@ - + @@ -53,7 +53,7 @@ - + diff --git a/guides/tags/language-ruby/index.html b/guides/tags/language-ruby/index.html index f936787388..4a291feb75 100644 --- a/guides/tags/language-ruby/index.html +++ b/guides/tags/language-ruby/index.html @@ -26,7 +26,7 @@ - + @@ -51,7 +51,7 @@ - + diff --git a/guides/tags/language-rust/index.html b/guides/tags/language-rust/index.html index d6483c72b0..0c8ada52e1 100644 --- a/guides/tags/language-rust/index.html +++ b/guides/tags/language-rust/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/guides/tags/technology-docker/index.html b/guides/tags/technology-docker/index.html index a396c1bc8e..fa6420f5f6 100644 --- a/guides/tags/technology-docker/index.html +++ b/guides/tags/technology-docker/index.html @@ -26,7 +26,7 @@ - + @@ -38,7 +38,7 @@ - + @@ -51,7 +51,7 @@ - + @@ -63,7 +63,7 @@ - + diff --git a/guides/tags/technology-github/index.html b/guides/tags/technology-github/index.html index a0dc39353e..2e3ccb3553 100644 --- a/guides/tags/technology-github/index.html +++ b/guides/tags/technology-github/index.html @@ -26,7 +26,7 @@ - + @@ -51,7 +51,7 @@ - + diff --git a/guides/tags/technology-helm/index.html b/guides/tags/technology-helm/index.html index 434f89923d..e707aba5df 100644 --- a/guides/tags/technology-helm/index.html +++ b/guides/tags/technology-helm/index.html @@ -26,7 +26,7 @@ - + @@ -51,7 +51,7 @@ - + diff --git a/guides/tags/technology-qovery/index.html b/guides/tags/technology-qovery/index.html index cb3c5e8ad8..eaa655c1e2 100644 --- a/guides/tags/technology-qovery/index.html +++ b/guides/tags/technology-qovery/index.html @@ -26,7 +26,7 @@ - + @@ -137,7 +137,7 @@ - + diff --git a/guides/tags/technology-terraform/index.html b/guides/tags/technology-terraform/index.html index ba9f6b96b3..f2b04d2259 100644 --- a/guides/tags/technology-terraform/index.html +++ b/guides/tags/technology-terraform/index.html @@ -26,7 +26,7 @@ - + @@ -51,7 +51,7 @@ - + diff --git a/guides/tags/type-guide/index.html b/guides/tags/type-guide/index.html index 5790bb6fa0..11142c725c 100644 --- a/guides/tags/type-guide/index.html +++ b/guides/tags/type-guide/index.html @@ -26,7 +26,7 @@ - + @@ -101,7 +101,7 @@ - + diff --git a/guides/tags/type-tutorial/index.html b/guides/tags/type-tutorial/index.html index eb8ac91db3..3184478a7c 100644 --- a/guides/tags/type-tutorial/index.html +++ b/guides/tags/type-tutorial/index.html @@ -26,7 +26,7 @@ - + @@ -96,7 +96,7 @@ - + @@ -106,7 +106,7 @@ - + @@ -137,7 +137,7 @@ - + @@ -207,7 +207,7 @@ - + @@ -217,7 +217,7 @@ - + diff --git a/guides/tutorial/aws-sqs-lambda-with-qovery/index.html b/guides/tutorial/aws-sqs-lambda-with-qovery/index.html index 8eba3cd382..cccc522de2 100644 --- a/guides/tutorial/aws-sqs-lambda-with-qovery/index.html +++ b/guides/tutorial/aws-sqs-lambda-with-qovery/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/tutorial/aws-vpc-peering-with-qovery/index.html b/guides/tutorial/aws-vpc-peering-with-qovery/index.html index 23d28f4613..002a727b2f 100644 --- a/guides/tutorial/aws-vpc-peering-with-qovery/index.html +++ b/guides/tutorial/aws-vpc-peering-with-qovery/index.html @@ -26,7 +26,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/guides/tutorial/blazingly-fast-preview-environments-for-nextjs-nodejs-and-mongodb-on-aws/index.html b/guides/tutorial/blazingly-fast-preview-environments-for-nextjs-nodejs-and-mongodb-on-aws/index.html index df0cfd0718..60ac7e289f 100644 --- a/guides/tutorial/blazingly-fast-preview-environments-for-nextjs-nodejs-and-mongodb-on-aws/index.html +++ b/guides/tutorial/blazingly-fast-preview-environments-for-nextjs-nodejs-and-mongodb-on-aws/index.html @@ -26,7 +26,7 @@ - + @@ -59,7 +59,7 @@ - + diff --git a/guides/tutorial/build-e2e-testing-ephemeral-environments/index.html b/guides/tutorial/build-e2e-testing-ephemeral-environments/index.html index e3cdadff48..a404e5ade2 100644 --- a/guides/tutorial/build-e2e-testing-ephemeral-environments/index.html +++ b/guides/tutorial/build-e2e-testing-ephemeral-environments/index.html @@ -26,7 +26,7 @@ - + @@ -81,7 +81,7 @@ - + diff --git a/guides/tutorial/cloudwatch-integration/index.html b/guides/tutorial/cloudwatch-integration/index.html index 0b9c0a2585..62213cf32d 100644 --- a/guides/tutorial/cloudwatch-integration/index.html +++ b/guides/tutorial/cloudwatch-integration/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/guides/tutorial/create-a-blazingly-fast-api-in-rust-part-1/index.html b/guides/tutorial/create-a-blazingly-fast-api-in-rust-part-1/index.html index 9581ba966a..8906341452 100644 --- a/guides/tutorial/create-a-blazingly-fast-api-in-rust-part-1/index.html +++ b/guides/tutorial/create-a-blazingly-fast-api-in-rust-part-1/index.html @@ -26,7 +26,7 @@ - + @@ -69,7 +69,7 @@ - + diff --git a/guides/tutorial/create-a-playground-environment-on-aws/index.html b/guides/tutorial/create-a-playground-environment-on-aws/index.html index 73a1e81052..e3285bbd21 100644 --- a/guides/tutorial/create-a-playground-environment-on-aws/index.html +++ b/guides/tutorial/create-a-playground-environment-on-aws/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/tutorial/create-your-staging-environment-from-your-production-environment-on-aws/index.html b/guides/tutorial/create-your-staging-environment-from-your-production-environment-on-aws/index.html index bbbd1333d5..112710735c 100644 --- a/guides/tutorial/create-your-staging-environment-from-your-production-environment-on-aws/index.html +++ b/guides/tutorial/create-your-staging-environment-from-your-production-environment-on-aws/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/tutorial/customizing-preview-url-with-qovery-cli/index.html b/guides/tutorial/customizing-preview-url-with-qovery-cli/index.html index df3d00b6f5..d728cb752c 100644 --- a/guides/tutorial/customizing-preview-url-with-qovery-cli/index.html +++ b/guides/tutorial/customizing-preview-url-with-qovery-cli/index.html @@ -26,7 +26,7 @@ - + @@ -51,7 +51,7 @@ - + diff --git a/guides/tutorial/data-seeding-in-postgres/index.html b/guides/tutorial/data-seeding-in-postgres/index.html index c6e9075873..56ba0398db 100644 --- a/guides/tutorial/data-seeding-in-postgres/index.html +++ b/guides/tutorial/data-seeding-in-postgres/index.html @@ -26,7 +26,7 @@ - + @@ -64,7 +64,7 @@ - + diff --git a/guides/tutorial/deploy-jupyterhub-qovery/index.html b/guides/tutorial/deploy-jupyterhub-qovery/index.html index 2ecb2c1181..5779bfc821 100644 --- a/guides/tutorial/deploy-jupyterhub-qovery/index.html +++ b/guides/tutorial/deploy-jupyterhub-qovery/index.html @@ -26,7 +26,7 @@ - + @@ -49,7 +49,7 @@ - + diff --git a/guides/tutorial/deploy-rails-with-postgresql-and-sidekiq/index.html b/guides/tutorial/deploy-rails-with-postgresql-and-sidekiq/index.html index 83f292374c..8a5b1da470 100644 --- a/guides/tutorial/deploy-rails-with-postgresql-and-sidekiq/index.html +++ b/guides/tutorial/deploy-rails-with-postgresql-and-sidekiq/index.html @@ -26,7 +26,7 @@ - + @@ -104,7 +104,7 @@ - + diff --git a/guides/tutorial/deploy-temporal-on-kubernetes/index.html b/guides/tutorial/deploy-temporal-on-kubernetes/index.html index 19cec28813..6f8be6b16d 100644 --- a/guides/tutorial/deploy-temporal-on-kubernetes/index.html +++ b/guides/tutorial/deploy-temporal-on-kubernetes/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/guides/tutorial/generate-qovery-api-client/index.html b/guides/tutorial/generate-qovery-api-client/index.html index b77e920c84..5cf8ab51cf 100644 --- a/guides/tutorial/generate-qovery-api-client/index.html +++ b/guides/tutorial/generate-qovery-api-client/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/guides/tutorial/getting-started-with-preview-environments-on-aws-for-beginners/index.html b/guides/tutorial/getting-started-with-preview-environments-on-aws-for-beginners/index.html index 2356d6ed99..bdb3bb4408 100644 --- a/guides/tutorial/getting-started-with-preview-environments-on-aws-for-beginners/index.html +++ b/guides/tutorial/getting-started-with-preview-environments-on-aws-for-beginners/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/tutorial/github-organization-repository-access/index.html b/guides/tutorial/github-organization-repository-access/index.html index 05c7e90456..160b80e7b8 100644 --- a/guides/tutorial/github-organization-repository-access/index.html +++ b/guides/tutorial/github-organization-repository-access/index.html @@ -26,7 +26,7 @@ - + @@ -51,7 +51,7 @@ - + diff --git a/guides/tutorial/gitops-with-qovery/index.html b/guides/tutorial/gitops-with-qovery/index.html index 3708cd9967..3a1da08b20 100644 --- a/guides/tutorial/gitops-with-qovery/index.html +++ b/guides/tutorial/gitops-with-qovery/index.html @@ -26,7 +26,7 @@ - + @@ -94,7 +94,7 @@ - + diff --git a/guides/tutorial/grafana-install/index.html b/guides/tutorial/grafana-install/index.html index a7d3b25566..553b067ef5 100644 --- a/guides/tutorial/grafana-install/index.html +++ b/guides/tutorial/grafana-install/index.html @@ -26,7 +26,7 @@ - + @@ -51,7 +51,7 @@ - + diff --git a/guides/tutorial/how-to-activate-sso-to-connect-to-your-eks-cluster/index.html b/guides/tutorial/how-to-activate-sso-to-connect-to-your-eks-cluster/index.html index 2cdb9ad184..e93b44bcf1 100644 --- a/guides/tutorial/how-to-activate-sso-to-connect-to-your-eks-cluster/index.html +++ b/guides/tutorial/how-to-activate-sso-to-connect-to-your-eks-cluster/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/guides/tutorial/how-to-build-a-cloud-version-of-your-open-source-software-part-1/index.html b/guides/tutorial/how-to-build-a-cloud-version-of-your-open-source-software-part-1/index.html index e5069e427c..6181cbede0 100644 --- a/guides/tutorial/how-to-build-a-cloud-version-of-your-open-source-software-part-1/index.html +++ b/guides/tutorial/how-to-build-a-cloud-version-of-your-open-source-software-part-1/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/tutorial/how-to-build-a-cloud-version-of-your-open-source-software-part-2/index.html b/guides/tutorial/how-to-build-a-cloud-version-of-your-open-source-software-part-2/index.html index 00bf4e82cd..9ce8dea98d 100644 --- a/guides/tutorial/how-to-build-a-cloud-version-of-your-open-source-software-part-2/index.html +++ b/guides/tutorial/how-to-build-a-cloud-version-of-your-open-source-software-part-2/index.html @@ -26,7 +26,7 @@ - + @@ -53,7 +53,7 @@ - + diff --git a/guides/tutorial/how-to-build-a-cloud-version-of-your-open-source-software-part-3/index.html b/guides/tutorial/how-to-build-a-cloud-version-of-your-open-source-software-part-3/index.html index 9d9d953519..7e5676f430 100644 --- a/guides/tutorial/how-to-build-a-cloud-version-of-your-open-source-software-part-3/index.html +++ b/guides/tutorial/how-to-build-a-cloud-version-of-your-open-source-software-part-3/index.html @@ -26,7 +26,7 @@ - + @@ -67,7 +67,7 @@ - + diff --git a/guides/tutorial/how-to-connect-to-a-managed-mongodb-instance-on-aws/index.html b/guides/tutorial/how-to-connect-to-a-managed-mongodb-instance-on-aws/index.html index 79fdad20a2..70824c5e25 100644 --- a/guides/tutorial/how-to-connect-to-a-managed-mongodb-instance-on-aws/index.html +++ b/guides/tutorial/how-to-connect-to-a-managed-mongodb-instance-on-aws/index.html @@ -26,7 +26,7 @@ - + @@ -53,7 +53,7 @@ - + diff --git a/guides/tutorial/how-to-connect-to-your-eks-cluster-with-kubectl/index.html b/guides/tutorial/how-to-connect-to-your-eks-cluster-with-kubectl/index.html index 01a5fedb76..269575944e 100644 --- a/guides/tutorial/how-to-connect-to-your-eks-cluster-with-kubectl/index.html +++ b/guides/tutorial/how-to-connect-to-your-eks-cluster-with-kubectl/index.html @@ -26,7 +26,7 @@ - + @@ -53,7 +53,7 @@ - + diff --git a/guides/tutorial/how-to-create-an-rds-instance-through-aws-console/index.html b/guides/tutorial/how-to-create-an-rds-instance-through-aws-console/index.html index e3c5f33288..478d133f10 100644 --- a/guides/tutorial/how-to-create-an-rds-instance-through-aws-console/index.html +++ b/guides/tutorial/how-to-create-an-rds-instance-through-aws-console/index.html @@ -26,7 +26,7 @@ - + @@ -52,7 +52,7 @@ - + diff --git a/guides/tutorial/how-to-deploy-a-rust-rest-api-application-on-aws-with-ease/index.html b/guides/tutorial/how-to-deploy-a-rust-rest-api-application-on-aws-with-ease/index.html index 2702e721a1..c690de585d 100644 --- a/guides/tutorial/how-to-deploy-a-rust-rest-api-application-on-aws-with-ease/index.html +++ b/guides/tutorial/how-to-deploy-a-rust-rest-api-application-on-aws-with-ease/index.html @@ -26,7 +26,7 @@ - + @@ -75,7 +75,7 @@ - + diff --git a/guides/tutorial/how-to-deploy-your-application-on-aws-in-30-minutes/index.html b/guides/tutorial/how-to-deploy-your-application-on-aws-in-30-minutes/index.html index 470ba428ed..873c8cb1e8 100644 --- a/guides/tutorial/how-to-deploy-your-application-on-aws-in-30-minutes/index.html +++ b/guides/tutorial/how-to-deploy-your-application-on-aws-in-30-minutes/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/tutorial/how-to-integrate-qovery-with-github-actions/index.html b/guides/tutorial/how-to-integrate-qovery-with-github-actions/index.html index 3fd6c22689..8841953ff1 100644 --- a/guides/tutorial/how-to-integrate-qovery-with-github-actions/index.html +++ b/guides/tutorial/how-to-integrate-qovery-with-github-actions/index.html @@ -26,7 +26,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/guides/tutorial/how-to-run-commands-at-application-startup/index.html b/guides/tutorial/how-to-run-commands-at-application-startup/index.html index cd73b0f166..998e06f222 100644 --- a/guides/tutorial/how-to-run-commands-at-application-startup/index.html +++ b/guides/tutorial/how-to-run-commands-at-application-startup/index.html @@ -26,7 +26,7 @@ - + @@ -59,7 +59,7 @@ - + diff --git a/guides/tutorial/how-to-use-cloudfront-with-react-frontend-application-on-qovery/index.html b/guides/tutorial/how-to-use-cloudfront-with-react-frontend-application-on-qovery/index.html index f138ab6963..8a87490dfc 100644 --- a/guides/tutorial/how-to-use-cloudfront-with-react-frontend-application-on-qovery/index.html +++ b/guides/tutorial/how-to-use-cloudfront-with-react-frontend-application-on-qovery/index.html @@ -26,7 +26,7 @@ - + @@ -52,7 +52,7 @@ - + diff --git a/guides/tutorial/how-to-use-lifecycle-job-to-deploy-any-kind-of-resources/index.html b/guides/tutorial/how-to-use-lifecycle-job-to-deploy-any-kind-of-resources/index.html index b6a3f90296..845c313d56 100644 --- a/guides/tutorial/how-to-use-lifecycle-job-to-deploy-any-kind-of-resources/index.html +++ b/guides/tutorial/how-to-use-lifecycle-job-to-deploy-any-kind-of-resources/index.html @@ -26,7 +26,7 @@ - + @@ -51,7 +51,7 @@ - + diff --git a/guides/tutorial/how-to-write-a-dockerfile/index.html b/guides/tutorial/how-to-write-a-dockerfile/index.html index 2c31fec36a..a2e15e63d9 100644 --- a/guides/tutorial/how-to-write-a-dockerfile/index.html +++ b/guides/tutorial/how-to-write-a-dockerfile/index.html @@ -26,7 +26,7 @@ - + @@ -38,18 +38,18 @@ - +

-

How to write a Dockerfile

How to write your first Dockerfile in order to deploy your application with Qovery

With Qovery, there are two ways to build and deploy your application:

  1. Without a Dockerfile in your repository: your application is built with Buildpacks
  2. With a Dockerfile: sometimes Buildpacks won't fit your specific setup, and you'll have to write your Dockerfile.

In this article, we'll see, step by step, how to quickly write a proper Dockerfile for any application you would like to deploy.


My Sweet Dockerfile

If you read this, you probably don't know why Docker is used and what is the purpose of a Dockerfile.

Docker is a container engine, building and using images to deploy applications in containers. It looks like virtualization, and each container could be compared to a virtual machine with the minimal setup to run an application.

The Dockerfile is your image builder recipe. When Docker uses it, it will follow all instructions to build your application and run it.

The first step is to create a file named Dockerfile at your project root level so Qovery would be able to find and use it.

Also, to avoid unwanted files from your repository (images, .idea, DS_Store etc.), you need to add a .dockerignore. It will prevent heavy copy tasks of useless files, mostly your project dependencies and libraries you'll get back to with your package manager.

The .dockerignore file works like the .gitignore, so add all the path of the useless files and folders in it.

FROM

The first line you'll add in your Dockerfile is FROM.

It will pull an already existing image from Docker Hub. You should most of the time use an image that fits your application language (Node, Python, Java, etc.), but you can go a step backward and begin with a simple Linux image.

Your Dockerfile's first line should look like this:

FROM <image_name>:<image_version>

For example, with python:

FROM python:3

WORKDIR

Since most of the images are Linux-based, a good practice is to set up a directory you'll work in. That's the purpose of the WORKDIR line. It defines a directory and moves you in:

FROM <image_name>:<image_version>
WORKDIR /app

If you now work with a relative path (./), it will be in the app directory.

COPY

Now you have defined your base image and your working directory, it's time to add your code in. COPY works like cp linux command. First argument is the source and second one is the destination.

It's time to copy your source code in the image.

FROM <image_name>:<image_version>
WORKDIR /app
COPY . .

Here, the elements of your root folder from your current directory will be added inside the /app folder.

RUN

One does not simply get source code to run an application.

Most of the time, you have some stuff to do before an application execution like downloading/installing peer dependencies and build your application.

That's the purpose of RUN lines; it will execute a command and wait to finish the task to go forward.

FROM <image_name>:<image_version>
WORKDIR /app
COPY . .
RUN echo "Installing or doing stuff."
RUN <my_command>

You can set as many RUN lines as you need.

EXPOSE

If your app needs to be reached from outside the container, you have to open its listening port. EXPOSE is made for this.

FROM <image_name>:<image_version>
WORKDIR /app
COPY . .
RUN echo "Installing or doing stuff"
RUN <my_command>
EXPOSE <app_port>

CMD

Your application is now ready to run.

The last thing to do is to specify how to execute it. Add the CMD line with the same command with all the arguments you use locally to launch your application.

FROM <image_name>:<image_version>
WORKDIR /app
COPY . .
RUN echo "Installing or doing stuff"
RUN <my_command>
EXPOSE <app_port>
CMD [ "<command>", "<argument_1>", "<argument_2>" ]

Like a local usage, you can set as many arguments as needed.

Build your image

When Qovery uses your Dockerfile, it first builds it before running it.

If the build fails, Qovery won't be able to launch our application. To simplify debugging, you can build your image locally if you have Docker installed on your computer.

Open a terminal and set the path at the Dockerfile location, and use the command:

cd ~/my/folder/where/my/code/is
docker build .

It will build your image based on your Dockerfile. You'll see all the logs related to all lines you've added in the Dockerfile.

If something goes wrong, it will be printed onto the terminal, and you'll be able to debug it.

Test your image

If your image builds properly, you can now check how it will be handle by Qovery with the command:

qovery run

What's next?

If you follow this tutorial and everything works perfectly, it's time to deploy your app on Qovery. You will find all the things you need to know here.

Tutorial
+

How to write a Dockerfile

How to write your first Dockerfile in order to deploy your application with Qovery

In this article, we'll see, step by step, how to quickly write a proper Dockerfile for any application you would like to deploy.


My Sweet Dockerfile

If you read this, you probably don't know why Docker is used and what is the purpose of a Dockerfile.

Docker is a container engine, building and using images to deploy applications in containers. It looks like virtualization, and each container could be compared to a virtual machine with the minimal setup to run an application.

The Dockerfile is your image builder recipe. When Docker uses it, it will follow all instructions to build your application and run it.

The first step is to create a file named Dockerfile at your project root level so Qovery would be able to find and use it.

Also, to avoid unwanted files from your repository (images, .idea, DS_Store etc.), you need to add a .dockerignore. It will prevent heavy copy tasks of useless files, mostly your project dependencies and libraries you'll get back to with your package manager.

The .dockerignore file works like the .gitignore, so add all the path of the useless files and folders in it.

FROM

The first line you'll add in your Dockerfile is FROM.

It will pull an already existing image from Docker Hub. You should most of the time use an image that fits your application language (Node, Python, Java, etc.), but you can go a step backward and begin with a simple Linux image.

Your Dockerfile's first line should look like this:

FROM <image_name>:<image_version>

For example, with python:

FROM python:3

WORKDIR

Since most of the images are Linux-based, a good practice is to set up a directory you'll work in. That's the purpose of the WORKDIR line. It defines a directory and moves you in:

FROM <image_name>:<image_version>
WORKDIR /app

If you now work with a relative path (./), it will be in the app directory.

COPY

Now you have defined your base image and your working directory, it's time to add your code in. COPY works like cp linux command. First argument is the source and second one is the destination.

It's time to copy your source code in the image.

FROM <image_name>:<image_version>
WORKDIR /app
COPY . .

Here, the elements of your root folder from your current directory will be added inside the /app folder.

RUN

One does not simply get source code to run an application.

Most of the time, you have some stuff to do before an application execution like downloading/installing peer dependencies and build your application.

That's the purpose of RUN lines; it will execute a command and wait to finish the task to go forward.

FROM <image_name>:<image_version>
WORKDIR /app
COPY . .
RUN echo "Installing or doing stuff."
RUN <my_command>

You can set as many RUN lines as you need.

EXPOSE

If your app needs to be reached from outside the container, you have to open its listening port. EXPOSE is made for this.

FROM <image_name>:<image_version>
WORKDIR /app
COPY . .
RUN echo "Installing or doing stuff"
RUN <my_command>
EXPOSE <app_port>

CMD

Your application is now ready to run.

The last thing to do is to specify how to execute it. Add the CMD line with the same command with all the arguments you use locally to launch your application.

FROM <image_name>:<image_version>
WORKDIR /app
COPY . .
RUN echo "Installing or doing stuff"
RUN <my_command>
EXPOSE <app_port>
CMD [ "<command>", "<argument_1>", "<argument_2>" ]

Like a local usage, you can set as many arguments as needed.

Build your image

When Qovery uses your Dockerfile, it first builds it before running it.

If the build fails, Qovery won't be able to launch our application. To simplify debugging, you can build your image locally if you have Docker installed on your computer.

Open a terminal and set the path at the Dockerfile location, and use the command:

cd ~/my/folder/where/my/code/is
docker build .

It will build your image based on your Dockerfile. You'll see all the logs related to all lines you've added in the Dockerfile.

If something goes wrong, it will be printed onto the terminal, and you'll be able to debug it.

Test your image

If your image builds properly, you can now check how it will be handle by Qovery with the command:

qovery run

What's next?

If you follow this tutorial and everything works perfectly, it's time to deploy your app on Qovery. You will find all the things you need to know here.

Tutorial
- + @@ -61,7 +61,7 @@ - + diff --git a/guides/tutorial/import-your-environment-variables-with-the-qovery-cli/index.html b/guides/tutorial/import-your-environment-variables-with-the-qovery-cli/index.html index 68c91e4056..f2fe46afcc 100644 --- a/guides/tutorial/import-your-environment-variables-with-the-qovery-cli/index.html +++ b/guides/tutorial/import-your-environment-variables-with-the-qovery-cli/index.html @@ -26,7 +26,7 @@ - + @@ -54,7 +54,7 @@ - + diff --git a/guides/tutorial/index.html b/guides/tutorial/index.html index 7db54aeec0..82e53db1c6 100644 --- a/guides/tutorial/index.html +++ b/guides/tutorial/index.html @@ -26,7 +26,7 @@ - + @@ -94,7 +94,7 @@ - + @@ -104,7 +104,7 @@ - + @@ -135,7 +135,7 @@ - + @@ -203,7 +203,7 @@ - + @@ -213,7 +213,7 @@ - + diff --git a/guides/tutorial/kubernetes-observability-and-monitoring-with-datadog/index.html b/guides/tutorial/kubernetes-observability-and-monitoring-with-datadog/index.html index 29f16f52bd..0be02ccfa5 100644 --- a/guides/tutorial/kubernetes-observability-and-monitoring-with-datadog/index.html +++ b/guides/tutorial/kubernetes-observability-and-monitoring-with-datadog/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/tutorial/managing-env-variables-in-create-react-app/index.html b/guides/tutorial/managing-env-variables-in-create-react-app/index.html index bdc8d675df..20a84231af 100644 --- a/guides/tutorial/managing-env-variables-in-create-react-app/index.html +++ b/guides/tutorial/managing-env-variables-in-create-react-app/index.html @@ -26,7 +26,7 @@ - + @@ -59,7 +59,7 @@ - + diff --git a/guides/tutorial/migrate-your-application-from-heroku-to-aws/index.html b/guides/tutorial/migrate-your-application-from-heroku-to-aws/index.html index df9630c424..1562efa2c3 100644 --- a/guides/tutorial/migrate-your-application-from-heroku-to-aws/index.html +++ b/guides/tutorial/migrate-your-application-from-heroku-to-aws/index.html @@ -26,7 +26,7 @@ - + @@ -38,14 +38,19 @@ - +

Migrate your application from Heroku to AWS

Guide on how to migrate all your applications from Heroku to AWS with your databases

This guide describes how to migrate your application running on Heroku to AWS with Qovery. It covers all required steps you need to take to deploy your application on AWS and transfer your data from Heroku Postgres to the database managed by AWS via Qovery.

Please contact us via our forum if you experience any problem while migrating from Heroku to AWS with Qovery.

Migration Steps

  1. Use Buildpacks or Create your Dockerfile
  2. Create resources on Qovery
  3. Configure Environment Variables and Secrets
  4. Copy data from your Heroku databases to your AWS databases
  5. Deploy your apps
  6. FAQ by Heroku users

1. Create your Dockerfile or Use Buildpacks

Qovery supports two ways to build and run your application coming from Heroku:

  1. Buildpacks
  2. Docker

Both options build a container image that is runnable by a container engine (E.g. Docker). Qovery runs containers on Kubernetes.

Choose the option that better fits you:

Buildpacks automatically detects the language and the framework your application is using. Buildpacks builds and runs your app. Here is the list of supported languages and frameworks.

Limitations

Here are some limitations due to our Buildpacks implementation:

  • Qovery Buildpacks does not support Procfile with multiple commands at the moment.
  • Qovery does not support custom Buildpacks.

Those limitations will be solved in the coming months.

2. Create resources on Qovery

Application

Steps:

  1. Connect to the Qovery console.
  2. Create your Organization and your Project.
  3. Create an environment with the name production (it can be changed after).
  4. Create an application and give it a name (you can give the name of your repo if you have no idea)
  5. Select your app repository from your GitHub, GitLab or Bitbucket.
  6. Select the branch you want to deploy.
  7. Select the Build mode for Buildpacks or Dockerfile according to what you want.
  8. Specify the local listening port of your application.
  9. Click on "create"

Congrats! Your application is created 🎉

If you deploy an app from a mono-repository, we have a must-read guide for you here.

Database

Here are the steps to deploy your database:

Steps:

  1. Go to your production environment.
  2. Add your database by clicking on "Add" > "Database".
  3. Select the database (PostgreSQL, MySQL, MongoDB, Redis..) and the version you want to deploy.
  4. Select Managed or Container mode for your database.
  5. Select Public accessibility (set Private if you don't want to restore your data from an existing Heroku database).

Congrats! Your database is created as well 🎉

If you use MongoDB Atlas, or an existing database on AWS that you want to connect to your application deployed by Qovery. Check out our tutorial about VPC peering and how to securely connect to your existing database.

3. Configure your Environment Variables and Secrets

Qovery makes the difference between an environment variable and a secret. Basically, a Secret is similar to an Environment Variable but the value is encrypted and can't be revealed. Both are injected as environment variables during the build and the run of your applications. More info here

To extract your environment variables from Heroku, we recommend using the Heroku CLI and exporting all the environment variables and secrets in an .env (dot env) file. Qovery supports the import of a dot env file via the Qovery web interface and the Qovery CLI.

Export your environment variable via the Heroku CLI with the command:

# To install Heroku CLI: https://devcenter.heroku.com/articles/heroku-cli
heroku config
+
Stats
12 min read
Updated

This guide describes how to migrate your application running on Heroku to AWS with Qovery. It covers all required steps you need to take to deploy your application on AWS and transfer your data from Heroku Postgres to the database managed by AWS via Qovery.

We have created a new AI agent capable of migrating from Heroku to AWS, GCP, Scaleway or Azure in a few clicks. Check our announcement here.

Migration Steps

  1. Create your Dockerfile
  2. Create resources on Qovery
  3. Configure Environment Variables and Secrets
  4. Copy data from your Heroku databases to your AWS databases
  5. Deploy your apps
  6. FAQ by Heroku users

1. Create your Dockerfile

Qovery supports two ways to build and run your application coming from Heroku:

Are you familiar with Dockerfile? If not, I do recommend reading this article.

Here we will create our Dockerfiles to build and run our applications. Qovery will handle the build and the run of your applications, but need to have at least a Dockerfile to do it.

Find Dockerfile template

Pick one Dockerfile template according to the programming language or framework you are using for your app:

Here is the Dockerfile for your Rails application listening on the PORT 3000

Dockerfile
# syntax=docker/dockerfile:1
FROM ruby:2.7
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
WORKDIR /myapp
COPY Gemfile Gemfile
COPY Gemfile.lock Gemfile.lock
RUN bundle install
+
COPY . .
+
EXPOSE 3000
+
# Configure the main process to run when running the image
CMD ["rails", "server", "-b", "0.0.0.0", "-p", "3000"]
Dockerfile for Sidekiq

Here is the Dockerfile for your Rails app running as a worker mode with Sidekiq.

Dockerfile for Sidekiq
# syntax=docker/dockerfile:1
FROM ruby:2.7
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client # add mysql client if you need to
WORKDIR /myapp
COPY Gemfile Gemfile
COPY Gemfile.lock Gemfile.lock
RUN bundle install
+
COPY . .
+
CMD ["bundle", "exec", "sidekiq"]

Copy template

Copy your Dockerfile at the root of your project. By convention, you can name your file Dockerfile. If you already have a Dockerfile, feel free to name it Dockerfile.qovery. If you are using multiple Dockerfile for Qovery, feel free to give a name like Dockerfile-sidekiq.qovery.

For our example of migrating a Rails app and a Rails Sidekiq app, I will have at the root of my project a Dockerfile.qovery and a Dockerfile-sidekiq.qovery.

Test your Dockerfile

To test your Dockerfile we will locally our container. You just need to run the following commands:

docker build -f Dockerfile.qovery .

If everything goes well you should get the finale image ID at the end of the output.

[+] Building 19.0s (16/16) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 37B 0.0s
=> [internal] load .dockerignore 0.0s
...
=> [7/7] COPY . . 0.2s
=> exporting to image 0.0s
=> exporting layers 0.4s
=> writing image sha256:a0f90a6ec8bc4036a7b268479a0c0773ca324ba2de11fdef31309650743f4055 0.0s

To run your image you can run:

docker run a0f90a6ec8bc4036a7b268479a0c0773ca324ba2de11fdef31309650743f4055

If your app required a database to starts, then it can be normal that it fails to start. Otherwise, if your app is supposed to start and does not, then you will need to fix the issue and rebuild your app with docker build -f Dockerfile.qovery .

Any error while building your container image? 2 solutions:

  1. Read the error message and try to understand from where the problem is coming from. You can "Google" the error if it is not related to your code.
  2. Open a thread on our forum if you don't find the answer there, we will be happy to assist you.

Environment variables at the build time

Does your app use some environment variables at the build time? Then you will need to modify your Dockerfile to includes the environment variables. Let's imagine your app uses the environment variable CONTENT_API_KEY, then you will need to add the following instructions in your Dockerfile:

Dockerfile with environment variables
...
ARG CONTENT_API_KEY
ENV CONTENT_API_KEY $CONTENT_API_KEY
...

The value of the CONTENT_API_KEY environment variable will be taken from the specified environment variables in Qovery.

Add your Dockerfile to Git

Now, add your new Dockerfile to git with the following commands:

git add Dockerfile.qovery
git commit -m "Add Qovery Dockerfile"
git push origin

Loop

If you have multiple applications to deploy, create a Dockerfile for each of them.

2. Create resources on Qovery

Application

Steps:

  1. Connect to the Qovery console.
  2. Create your Organization and your Project.
  3. Create an environment with the name production (it can be changed after).
  4. Create an application and give it a name (you can give the name of your repo if you have no idea)
  5. Select your app repository from your GitHub, GitLab or Bitbucket.
  6. Select the branch you want to deploy.
  7. Specify the local listening port of your application.
  8. Click on "create"

Congrats! Your application is created 🎉

If you deploy an app from a mono-repository, we have a must-read guide for you here.

Database

Here are the steps to deploy your database:

Steps:

  1. Go to your production environment.
  2. Add your database by clicking on "Add" > "Database".
  3. Select the database (PostgreSQL, MySQL, MongoDB, Redis..) and the version you want to deploy.
  4. Select Managed or Container mode for your database.
  5. Select Public accessibility (set Private if you don't want to restore your data from an existing Heroku database).

Congrats! Your database is created as well 🎉

If you use MongoDB Atlas, or an existing database on AWS that you want to connect to your application deployed by Qovery. Check out our tutorial about VPC peering and how to securely connect to your existing database.

3. Configure your Environment Variables and Secrets

Qovery makes the difference between an environment variable and a secret. Basically, a Secret is similar to an Environment Variable but the value is encrypted and can't be revealed. Both are injected as environment variables during the build and the run of your applications. More info here

To extract your environment variables from Heroku, we recommend using the Heroku CLI and exporting all the environment variables and secrets in an .env (dot env) file. Qovery supports the import of a dot env file via the Qovery web interface and the Qovery CLI.

Export your environment variable via the Heroku CLI with the command:

# To install Heroku CLI: https://devcenter.heroku.com/articles/heroku-cli
heroku config
GREETINGS: hello world
STRIPE_API_KEY: xxx-yyy-zzz
IS_PRODUCTION: true

Then you can create your environment variables via the web interface (watch the video below)

Or via the Qovery CLI:

Import Heroku environment variables with the Qovery CLI
# auth yourself
qovery auth
# selection the app where you want to import your environment variables
qovery context set
# import your Heroku environment variables
heroku config --app <your_heroku_app_name> --json | \
qovery env parse --heroku-json > heroku.env && \
qovery env import heroku.env && \
rm heroku.env
@@ -55,7 +60,7 @@ - + @@ -67,7 +72,7 @@ - + diff --git a/guides/tutorial/monitor-and-reduce-kubernetes-spend-with-kubecost/index.html b/guides/tutorial/monitor-and-reduce-kubernetes-spend-with-kubecost/index.html index 84cf10a62d..4ab03ce1ae 100644 --- a/guides/tutorial/monitor-and-reduce-kubernetes-spend-with-kubecost/index.html +++ b/guides/tutorial/monitor-and-reduce-kubernetes-spend-with-kubecost/index.html @@ -26,7 +26,7 @@ - + @@ -49,7 +49,7 @@ - + diff --git a/guides/tutorial/setting-up-cloudflare-and-custom-domain-on-qovery/index.html b/guides/tutorial/setting-up-cloudflare-and-custom-domain-on-qovery/index.html index d68660752f..815decdef0 100644 --- a/guides/tutorial/setting-up-cloudflare-and-custom-domain-on-qovery/index.html +++ b/guides/tutorial/setting-up-cloudflare-and-custom-domain-on-qovery/index.html @@ -26,7 +26,7 @@ - + @@ -51,7 +51,7 @@ - + diff --git a/guides/tutorial/url-shortener-api-with-kotlin/index.html b/guides/tutorial/url-shortener-api-with-kotlin/index.html index c5e1de6d40..c45d22ddc8 100644 --- a/guides/tutorial/url-shortener-api-with-kotlin/index.html +++ b/guides/tutorial/url-shortener-api-with-kotlin/index.html @@ -26,7 +26,7 @@ - + @@ -82,7 +82,7 @@ - + diff --git a/guides/tutorial/use-an-api-gateway-in-front-of-multiple-services/index.html b/guides/tutorial/use-an-api-gateway-in-front-of-multiple-services/index.html index 0d4f6e23cd..a72f392f5c 100644 --- a/guides/tutorial/use-an-api-gateway-in-front-of-multiple-services/index.html +++ b/guides/tutorial/use-an-api-gateway-in-front-of-multiple-services/index.html @@ -26,7 +26,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/guides/tutorial/use-aws-iam-roles-with-qovery/index.html b/guides/tutorial/use-aws-iam-roles-with-qovery/index.html index 8b792c0729..e56a71c323 100644 --- a/guides/tutorial/use-aws-iam-roles-with-qovery/index.html +++ b/guides/tutorial/use-aws-iam-roles-with-qovery/index.html @@ -26,7 +26,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/guides/tutorial/working-with-git-submodules/index.html b/guides/tutorial/working-with-git-submodules/index.html index 562c69eda8..874258a722 100644 --- a/guides/tutorial/working-with-git-submodules/index.html +++ b/guides/tutorial/working-with-git-submodules/index.html @@ -26,7 +26,7 @@ - + @@ -53,7 +53,7 @@ - + diff --git a/index.html b/index.html index 009b39d1ed..89d8d19fa0 100644 --- a/index.html +++ b/index.html @@ -26,7 +26,7 @@ - + @@ -47,7 +47,7 @@ - + diff --git a/mailing_list/index.html b/mailing_list/index.html index 614c0b8dfb..fa25d4d5b9 100644 --- a/mailing_list/index.html +++ b/mailing_list/index.html @@ -22,7 +22,7 @@ - + @@ -37,7 +37,7 @@ - + diff --git a/runtime~main.f3be029e.js b/runtime~main.c4d3ba30.js similarity index 98% rename from runtime~main.f3be029e.js rename to runtime~main.c4d3ba30.js index 8c0f5a4c0d..8fa51294ce 100644 --- a/runtime~main.f3be029e.js +++ b/runtime~main.c4d3ba30.js @@ -1 +1 @@ -!function(e){function c(c){for(var f,a,r=c[0],n=c[1],o=c[2],u=0,i=[];ufunction MDXDefaultShortcode(props){console.warn("Component "+name+" was not imported, exported, or provided by MDXProvider as global scope");return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",props);};const layoutProps={rightToc};const MDXLayout="wrapper";function MDXContent({components,...props}){return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(MDXLayout,Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({},layoutProps,props,{components:components,mdxType:"MDXLayout"}),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"success",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`This guide also work for migrating your application from Heroku to GCP, Azure, Scaleway and `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/getting-started/install-qovery/"}),`all cloud provider`),` supported by Qovery.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`This guide describes how to migrate your application running on Heroku to AWS with Qovery. It covers all required steps you need to take to deploy your application on AWS and transfer your data from Heroku Postgres to the database managed by AWS via Qovery.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("blockquote",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{parentName:"blockquote"},`Please contact us via `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://discuss.qovery.com/"}),`our forum`),` if you experience any problem while migrating from Heroku to AWS with Qovery.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"],{name:"guide",mdxType:"Assumptions"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You are familiar with Heroku basics, have a Heroku account and access to Heroku CLI`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You have `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"https://start.qovery.com"}),`sign in on Qovery`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You have `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/guides/installation-guide/guide-amazon-web-services/"}),`set up your AWS account`),` with Qovery`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"migration-steps"},`Migration Steps`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#1-create-your-dockerfile-or-use-buildpacks"}),`Use Buildpacks or Create your Dockerfile`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#2-create-resources-on-qovery"}),`Create resources on Qovery`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#3-configure-your-environment-variables-and-secrets"}),`Configure Environment Variables and Secrets`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#4-copy-data-from-your-heroku-databases-to-your-aws-databases"}),`Copy data from your Heroku databases to your AWS databases`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#5-deploy-your-apps-"}),`Deploy your apps`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#faq-by-heroku-users"}),`FAQ by Heroku users`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"1-create-your-dockerfile-or-use-buildpacks"},`1. Create your Dockerfile or Use Buildpacks`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery supports two ways to build and run your application coming from Heroku:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Buildpacks`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Docker`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Both options build a container image that is runnable by a container engine (E.g. Docker). Qovery runs containers on Kubernetes.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Choose the option that better fits you:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_theme_Tabs__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{centered:true,className:"rounded",defaultValue:"buildpacks",placeholder:"Use Buildpacks or Create your Dockerfile",select:false,size:null,values:[{"group":"Platforms","label":"Use Buildpacks","value":"buildpacks"},{"group":"Platforms","label":"Create your Dockerfile","value":"dockerfile"}],mdxType:"Tabs"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_theme_TabItem__WEBPACK_IMPORTED_MODULE_4__[/* default */ "a"],{value:"dockerfile",mdxType:"TabItem"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("blockquote",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{parentName:"blockquote"},`Are you familiar with Dockerfile? If not, I do recommend reading `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/tutorial/how-to-write-a-dockerfile/"}),`this article`),`.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Here we will create our Dockerfiles to build and run our applications. Qovery will handle the build and the run of your applications, but need to have at least a Dockerfile to do it.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"choose-your-dockerfile-template"},`Choose your Dockerfile template`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`To get started,`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"find-dockerfile-template"},`Find Dockerfile template`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Pick one Dockerfile template according to the programming language or framework you are using for your app:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Your framework or language is missing? Open a thread on `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://discuss.qovery.com/"}),`our forum`),`, and we will provide you one.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_theme_Tabs__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{centered:false,className:"square",defaultValue:"rails",select:false,size:null,values:[{"group":"Files","label":"Rails","value":"rails"},{"group":"Files","label":"NodeJS","value":"nodejs"},{"group":"Files","label":"React","value":"react"},{"group":"Files","label":"VueJS","value":"vuejs"},{"group":"Files","label":"NextJS","value":"nextjs"},{"group":"Files","label":"Golang","value":"golang"},{"group":"Files","label":"Flask","value":"flask"},{"group":"Files","label":"Django","value":"django"},{"group":"Files","label":"Laravel","value":"laravel"},{"group":"Files","label":"Symfony","value":"symfony"},{"group":"Files","label":"Spring","value":"spring"},{"group":"Files","label":"Rust","value":"rust"}],mdxType:"Tabs"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_theme_TabItem__WEBPACK_IMPORTED_MODULE_4__[/* default */ "a"],{value:"rails",mdxType:"TabItem"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Here is the Dockerfile for your Rails application listening on the PORT 3000`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{"className":"language-shell","metastring":"title=\"Dockerfile\"","title":"\"Dockerfile\""}),`# syntax=docker/dockerfile:1 +const frontMatter={last_modified_on:'2024-09-18',$schema:'/.meta/.schemas/guides.json',title:'Migrate your application from Heroku to AWS',description:'Guide on how to migrate all your applications from Heroku to AWS with your databases',author_github:'https://github.com/evoxmusic',tags:['type: tutorial','installation_guide: aws'],hide_pagination:true};const metadata={"categories":[{"name":"tutorial","title":"Tutorial","description":"Additional step-by-step resources to leverage even more Qovery","permalink":"/guides/tutorial"}],"coverLabel":"Migrate your application from Heroku to AWS","description":"Guide on how to migrate all your applications from Heroku to AWS with your databases","permalink":"/guides/tutorial/migrate-your-application-from-heroku-to-aws","readingTime":"12 min read","source":"@site/guides/tutorial/migrate-your-application-from-heroku-to-aws.md","tags":[{"label":"type: tutorial","permalink":"/guides/tags/type-tutorial"},{"label":"installation_guide: aws","permalink":"/guides/tags/installation-guide-aws"}],"title":"Migrate your application from Heroku to AWS","truncated":false,"prevItem":{"title":"Microservices","permalink":"/guides/advanced/microservices"},"nextItem":{"title":"Migration","permalink":"/guides/advanced/migration"}};/* @jsx mdx */const rightToc=[{value:'Migration Steps',id:'migration-steps',children:[]},{value:'1. Create your Dockerfile',id:'1-create-your-dockerfile',children:[{value:'Test your Dockerfile',id:'test-your-dockerfile',children:[]},{value:'Environment variables at the build time',id:'environment-variables-at-the-build-time',children:[]},{value:'Add your Dockerfile to Git',id:'add-your-dockerfile-to-git',children:[]},{value:'Loop',id:'loop',children:[]}]},{value:'2. Create resources on Qovery',id:'2-create-resources-on-qovery',children:[{value:'Application',id:'application',children:[]},{value:'Database',id:'database',children:[]}]},{value:'3. Configure your Environment Variables and Secrets',id:'3-configure-your-environment-variables-and-secrets',children:[{value:'Connect your frontend app to your backend app',id:'connect-your-frontend-app-to-your-backend-app',children:[]},{value:'Connect your backend app to your database',id:'connect-your-backend-app-to-your-database',children:[]}]},{value:'4. Copy data from your Heroku databases to your AWS databases',id:'4-copy-data-from-your-heroku-databases-to-your-aws-databases',children:[]},{value:'5. Deploy your apps!',id:'5-deploy-your-apps',children:[]},{value:'FAQ by Heroku users',id:'faq-by-heroku-users',children:[{value:'How to create a custom domain?',id:'how-to-create-a-custom-domain',children:[]},{value:'How to monitor my apps?',id:'how-to-monitor-my-apps',children:[]},{value:'Do you have Heroku "Review App" equivalent?',id:'do-you-have-heroku-review-app-equivalent',children:[]},{value:'How to rollback?',id:'how-to-rollback',children:[]},{value:'How auto-scaling works?',id:'how-auto-scaling-works',children:[]},{value:'How to manage database migration?',id:'how-to-manage-database-migration',children:[]},{value:'Is it possible to get a shell / connect to my app?',id:'is-it-possible-to-get-a-shell--connect-to-my-app',children:[]},{value:'Can I use Terraform and Infrastructure as Code?',id:'can-i-use-terraform-and-infrastructure-as-code',children:[]},{value:'How can I connect my app to MongoDB Atlas?',id:'how-can-i-connect-my-app-to-mongodb-atlas',children:[]},{value:'How can I connect my app to an AWS service not managed by Qovery?',id:'how-can-i-connect-my-app-to-an-aws-service-not-managed-by-qovery',children:[]}]},{value:'Wrapping up',id:'wrapping-up',children:[]}];const makeShortcode=name=>function MDXDefaultShortcode(props){console.warn("Component "+name+" was not imported, exported, or provided by MDXProvider as global scope");return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",props);};const layoutProps={rightToc};const MDXLayout="wrapper";function MDXContent({components,...props}){return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(MDXLayout,Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({},layoutProps,props,{components:components,mdxType:"MDXLayout"}),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"success",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`This guide also work for migrating your application from Heroku to GCP, Azure, Scaleway and `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/getting-started/install-qovery/"}),`all cloud provider`),` supported by Qovery.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`This guide describes how to migrate your application running on Heroku to AWS with Qovery. It covers all required steps you need to take to deploy your application on AWS and transfer your data from Heroku Postgres to the database managed by AWS via Qovery.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("blockquote",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{parentName:"blockquote"},`We have created a new AI agent capable of migrating from Heroku to AWS, GCP, Scaleway or Azure in a few clicks. Check our `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://www.qovery.com/blog/open-source-devops-ai-agent--effortless-migration-from-heroku-to-aws/?utm_campaign=migration-ai-agent-email"}),`announcement here`),`.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"],{name:"guide",mdxType:"Assumptions"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You are familiar with Heroku basics, have a Heroku account and access to Heroku CLI`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You have `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"https://start.qovery.com"}),`sign in on Qovery`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You have `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/guides/installation-guide/guide-amazon-web-services/"}),`set up your AWS account`),` with Qovery`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"migration-steps"},`Migration Steps`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#1-create-your-dockerfile"}),`Create your Dockerfile`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#2-create-resources-on-qovery"}),`Create resources on Qovery`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#3-configure-your-environment-variables-and-secrets"}),`Configure Environment Variables and Secrets`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#4-copy-data-from-your-heroku-databases-to-your-aws-databases"}),`Copy data from your Heroku databases to your AWS databases`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#5-deploy-your-apps-"}),`Deploy your apps`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#faq-by-heroku-users"}),`FAQ by Heroku users`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"1-create-your-dockerfile"},`1. Create your Dockerfile`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery supports two ways to build and run your application coming from Heroku:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("blockquote",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{parentName:"blockquote"},`Are you familiar with Dockerfile? If not, I do recommend reading `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/tutorial/how-to-write-a-dockerfile/"}),`this article`),`.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Here we will create our Dockerfiles to build and run our applications. Qovery will handle the build and the run of your applications, but need to have at least a Dockerfile to do it.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"find-dockerfile-template"},`Find Dockerfile template`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Pick one Dockerfile template according to the programming language or framework you are using for your app:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Your framework or language is missing? Open a thread on `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://discuss.qovery.com/"}),`our forum`),`, and we will provide you one.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_theme_Tabs__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{centered:false,className:"square",defaultValue:"rails",select:false,size:null,values:[{"group":"Files","label":"Rails","value":"rails"},{"group":"Files","label":"NodeJS","value":"nodejs"},{"group":"Files","label":"React","value":"react"},{"group":"Files","label":"VueJS","value":"vuejs"},{"group":"Files","label":"NextJS","value":"nextjs"},{"group":"Files","label":"Golang","value":"golang"},{"group":"Files","label":"Flask","value":"flask"},{"group":"Files","label":"Django","value":"django"},{"group":"Files","label":"Laravel","value":"laravel"},{"group":"Files","label":"Symfony","value":"symfony"},{"group":"Files","label":"Spring","value":"spring"},{"group":"Files","label":"Rust","value":"rust"}],mdxType:"Tabs"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_theme_TabItem__WEBPACK_IMPORTED_MODULE_4__[/* default */ "a"],{value:"rails",mdxType:"TabItem"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Here is the Dockerfile for your Rails application listening on the PORT 3000`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{"className":"language-shell","metastring":"title=\"Dockerfile\"","title":"\"Dockerfile\""}),`# syntax=docker/dockerfile:1 FROM ruby:2.7 RUN apt-get update -qq && apt-get install -y nodejs postgresql-client WORKDIR /myapp @@ -46424,7 +46424,7 @@ ENV CONTENT_API_KEY $CONTENT_API_KEY `)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The value of the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`CONTENT_API_KEY`),` environment variable will be taken from the specified environment variables in Qovery.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"success",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery injects Environment Variables and Secrets at the build and run time of your app.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"add-your-dockerfile-to-git"},`Add your Dockerfile to Git`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Now, add your new Dockerfile to git with the following commands:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{"className":"language-shell"}),`git add Dockerfile.qovery git commit -m "Add Qovery Dockerfile" git push origin -`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"loop"},`Loop`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you have multiple applications to deploy, create a Dockerfile for each of them.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_theme_TabItem__WEBPACK_IMPORTED_MODULE_4__[/* default */ "a"],{value:"buildpacks",mdxType:"TabItem"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://buildpacks.io/"}),`Buildpacks`),` automatically detects the language and the framework your application is using. Buildpacks builds and runs your app. Here is the list of `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/application/#option-1-buildpacks"}),`supported languages and frameworks`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"warning",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`We do recommend using Docker to keep the full control of what's going on behind the scene. Buildpacks is a great technology but difficult to debug when something goes wrong. You can try deploying your apps on AWS with Qovery with Buildpacks, if you do not succeed, we do recommend switching for Docker.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"limitations"},`Limitations`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Here are some limitations due to our Buildpacks implementation:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Qovery Buildpacks does not support Procfile with multiple commands at the moment.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Qovery does not support custom Buildpacks.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Those limitations will be solved in the coming months.`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"2-create-resources-on-qovery"},`2. Create resources on Qovery`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"application"},`Application`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Are you a new Qovery user? Watch `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/getting-started/deploy-your-first-application/"}),`this tutorial`),` to learn how to deploy your first app.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",{class:"video-container"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("iframe",{src:"https://www.loom.com/embed/9246ae68c68f42debc3d5183d2b4f7f8",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:true,mozallowfullscreen:true,allowfullscreen:true}))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Steps:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Connect to the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"https://start.qovery.com"}),`Qovery console`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Create your `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/organization/"}),`Organization`),` and your `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/project/"}),`Project`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Create an environment with the name `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`production`),` (it can be changed after).`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Create an application and give it a name (you can give the name of your repo if you have no idea)`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select your app repository from your GitHub, GitLab or Bitbucket.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select the branch you want to deploy.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select the Build mode for `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`Buildpacks`),` or `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`Dockerfile`),` according to what you want.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Specify the local listening port of your application.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Click on "create"`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Congrats! Your application is created 🎉`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"warning",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Your application is created but not deployed yet! You can configure the vCPU, Memory, Environment Variables... before deploying it. If you want to deploy it before finishing the configuration you can click on "Actions" > "Deploy".`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you deploy an app from a mono-repository, we have a must-read guide for you `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/advanced/monorepository/"}),`here`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"database"},`Database`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Are you a new Qovery user? Watch `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/getting-started/create-a-database/"}),`this tutorial`),` to learn how to deploy your database.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Here are the steps to deploy your database:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"],{mdxType:"Assumptions"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You have created an application before`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",{class:"video-container"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("iframe",{src:"https://www.loom.com/embed/d7e10be0e5964f6799b158dc631bbbd1",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:true,mozallowfullscreen:true,allowfullscreen:true}))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Steps:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Go to your `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`production`),` environment.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Add your database by clicking on "Add" > "Database".`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select the database (PostgreSQL, MySQL, MongoDB, Redis..) and the version you want to deploy.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/database/#general"}),`Managed or Container mode`),` for your database.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`Public`),` accessibility (set `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`Private`),` if you don't want to restore your data from an existing Heroku database).`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Congrats! Your database is created as well 🎉`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you use MongoDB Atlas, or an existing database on AWS that you want to connect to your application deployed by Qovery. Check out `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/tutorial/aws-vpc-peering-with-qovery/"}),`our tutorial about VPC peering`),` and how to securely connect to your existing database.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"3-configure-your-environment-variables-and-secrets"},`3. Configure your Environment Variables and Secrets`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"success",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery supports Doppler integration - it's the easiest way to migrate your Environment Variables and Secrets from Heroku to Qovery. `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/integration/secret-manager/doppler/"}),`More info here`),`.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery makes the difference between an environment variable and a secret. Basically, a Secret is similar to an Environment Variable but the value is encrypted and can't be revealed. Both are injected as environment variables during the build and the run of your applications. `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/environment-variable/"}),`More info here`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`I recommend reading our `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/getting-started/managing-environment-variables/"}),`Getting Started with Environment Variables`),` guide.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`To extract your environment variables from Heroku, we recommend using the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://devcenter.heroku.com/articles/heroku-cli"}),`Heroku CLI`),` and exporting all the environment variables and secrets in an .env (dot env) file. Qovery supports the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/tutorial/import-your-environment-variables-with-the-qovery-cli/"}),`import of a dot env file`),` via the Qovery web interface and the Qovery CLI.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"warning",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you use Buildpacks for one of your app AND you have indicated a local listening port of your application, you will need to add an environment variable `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`PORT`),` with the value of your port to make your application starting properly. Otherwise, Qovery will fail to deploy your app!`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://devcenter.heroku.com/articles/config-vars#view-current-config-var-values"}),`Export your environment variable via the Heroku CLI`),` with the command:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{"className":"language-shell"}),`# To install Heroku CLI: https://devcenter.heroku.com/articles/heroku-cli +`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"loop"},`Loop`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you have multiple applications to deploy, create a Dockerfile for each of them.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"2-create-resources-on-qovery"},`2. Create resources on Qovery`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"application"},`Application`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Are you a new Qovery user? Watch `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/getting-started/deploy-your-first-application/"}),`this tutorial`),` to learn how to deploy your first app.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",{class:"video-container"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("iframe",{src:"https://www.loom.com/embed/9246ae68c68f42debc3d5183d2b4f7f8",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:true,mozallowfullscreen:true,allowfullscreen:true}))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Steps:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Connect to the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"https://start.qovery.com"}),`Qovery console`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Create your `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/organization/"}),`Organization`),` and your `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/project/"}),`Project`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Create an environment with the name `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`production`),` (it can be changed after).`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Create an application and give it a name (you can give the name of your repo if you have no idea)`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select your app repository from your GitHub, GitLab or Bitbucket.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select the branch you want to deploy.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Specify the local listening port of your application.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Click on "create"`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Congrats! Your application is created 🎉`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"warning",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Your application is created but not deployed yet! You can configure the vCPU, Memory, Environment Variables... before deploying it. If you want to deploy it before finishing the configuration you can click on "Actions" > "Deploy".`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you deploy an app from a mono-repository, we have a must-read guide for you `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/advanced/monorepository/"}),`here`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"database"},`Database`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Are you a new Qovery user? Watch `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/getting-started/create-a-database/"}),`this tutorial`),` to learn how to deploy your database.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Here are the steps to deploy your database:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"],{mdxType:"Assumptions"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You have created an application before`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",{class:"video-container"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("iframe",{src:"https://www.loom.com/embed/d7e10be0e5964f6799b158dc631bbbd1",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:true,mozallowfullscreen:true,allowfullscreen:true}))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Steps:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Go to your `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`production`),` environment.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Add your database by clicking on "Add" > "Database".`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select the database (PostgreSQL, MySQL, MongoDB, Redis..) and the version you want to deploy.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/database/#general"}),`Managed or Container mode`),` for your database.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`Public`),` accessibility (set `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`Private`),` if you don't want to restore your data from an existing Heroku database).`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Congrats! Your database is created as well 🎉`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you use MongoDB Atlas, or an existing database on AWS that you want to connect to your application deployed by Qovery. Check out `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/tutorial/aws-vpc-peering-with-qovery/"}),`our tutorial about VPC peering`),` and how to securely connect to your existing database.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"3-configure-your-environment-variables-and-secrets"},`3. Configure your Environment Variables and Secrets`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"success",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery supports Doppler integration - it's the easiest way to migrate your Environment Variables and Secrets from Heroku to Qovery. `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/integration/secret-manager/doppler/"}),`More info here`),`.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery makes the difference between an environment variable and a secret. Basically, a Secret is similar to an Environment Variable but the value is encrypted and can't be revealed. Both are injected as environment variables during the build and the run of your applications. `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/environment-variable/"}),`More info here`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`I recommend reading our `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/getting-started/managing-environment-variables/"}),`Getting Started with Environment Variables`),` guide.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`To extract your environment variables from Heroku, we recommend using the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://devcenter.heroku.com/articles/heroku-cli"}),`Heroku CLI`),` and exporting all the environment variables and secrets in an .env (dot env) file. Qovery supports the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/tutorial/import-your-environment-variables-with-the-qovery-cli/"}),`import of a dot env file`),` via the Qovery web interface and the Qovery CLI.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://devcenter.heroku.com/articles/config-vars#view-current-config-var-values"}),`Export your environment variable via the Heroku CLI`),` with the command:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{"className":"language-shell"}),`# To install Heroku CLI: https://devcenter.heroku.com/articles/heroku-cli heroku config GREETINGS: hello world @@ -52188,7 +52188,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _theme_TabItem__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5); /* harmony import */ var _theme_Tabs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9); /* harmony import */ var _site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(6); -const frontMatter={last_modified_on:'2024-08-12',$schema:'/.meta/.schemas/guides.json',title:'Migrate your application from Heroku to AWS',description:'Guide on how to migrate all your applications from Heroku to AWS with your databases',author_github:'https://github.com/evoxmusic',tags:['type: tutorial','installation_guide: aws'],hide_pagination:true};const metadata={"categories":[{"name":"tutorial","title":"Tutorial","description":"Additional step-by-step resources to leverage even more Qovery","permalink":"/guides/tutorial"}],"coverLabel":"Migrate your application from Heroku to AWS","description":"Guide on how to migrate all your applications from Heroku to AWS with your databases","permalink":"/guides/tutorial/migrate-your-application-from-heroku-to-aws","readingTime":"13 min read","source":"@site/guides/tutorial/migrate-your-application-from-heroku-to-aws.md","tags":[{"label":"type: tutorial","permalink":"/guides/tags/type-tutorial"},{"label":"installation_guide: aws","permalink":"/guides/tags/installation-guide-aws"}],"title":"Migrate your application from Heroku to AWS","truncated":false,"prevItem":{"title":"Microservices","permalink":"/guides/advanced/microservices"},"nextItem":{"title":"Migration","permalink":"/guides/advanced/migration"}};/* @jsx mdx */const rightToc=[{value:'Migration Steps',id:'migration-steps',children:[]},{value:'1. Create your Dockerfile or Use Buildpacks',id:'1-create-your-dockerfile-or-use-buildpacks',children:[{value:'Choose your Dockerfile template',id:'choose-your-dockerfile-template',children:[]},{value:'Test your Dockerfile',id:'test-your-dockerfile',children:[]},{value:'Environment variables at the build time',id:'environment-variables-at-the-build-time',children:[]},{value:'Add your Dockerfile to Git',id:'add-your-dockerfile-to-git',children:[]},{value:'Loop',id:'loop',children:[]},{value:'Limitations',id:'limitations',children:[]}]},{value:'2. Create resources on Qovery',id:'2-create-resources-on-qovery',children:[{value:'Application',id:'application',children:[]},{value:'Database',id:'database',children:[]}]},{value:'3. Configure your Environment Variables and Secrets',id:'3-configure-your-environment-variables-and-secrets',children:[{value:'Connect your frontend app to your backend app',id:'connect-your-frontend-app-to-your-backend-app',children:[]},{value:'Connect your backend app to your database',id:'connect-your-backend-app-to-your-database',children:[]}]},{value:'4. Copy data from your Heroku databases to your AWS databases',id:'4-copy-data-from-your-heroku-databases-to-your-aws-databases',children:[]},{value:'5. Deploy your apps!',id:'5-deploy-your-apps',children:[]},{value:'FAQ by Heroku users',id:'faq-by-heroku-users',children:[{value:'How to create a custom domain?',id:'how-to-create-a-custom-domain',children:[]},{value:'How to monitor my apps?',id:'how-to-monitor-my-apps',children:[]},{value:'Do you have Heroku "Review App" equivalent?',id:'do-you-have-heroku-review-app-equivalent',children:[]},{value:'How to rollback?',id:'how-to-rollback',children:[]},{value:'How auto-scaling works?',id:'how-auto-scaling-works',children:[]},{value:'How to manage database migration?',id:'how-to-manage-database-migration',children:[]},{value:'Is it possible to get a shell / connect to my app?',id:'is-it-possible-to-get-a-shell--connect-to-my-app',children:[]},{value:'Can I use Terraform and Infrastructure as Code?',id:'can-i-use-terraform-and-infrastructure-as-code',children:[]},{value:'How can I connect my app to MongoDB Atlas?',id:'how-can-i-connect-my-app-to-mongodb-atlas',children:[]},{value:'How can I connect my app to an AWS service not managed by Qovery?',id:'how-can-i-connect-my-app-to-an-aws-service-not-managed-by-qovery',children:[]}]},{value:'Wrapping up',id:'wrapping-up',children:[]}];const makeShortcode=name=>function MDXDefaultShortcode(props){console.warn("Component "+name+" was not imported, exported, or provided by MDXProvider as global scope");return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",props);};const layoutProps={rightToc};const MDXLayout="wrapper";function MDXContent({components,...props}){return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(MDXLayout,Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({},layoutProps,props,{components:components,mdxType:"MDXLayout"}),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"success",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`This guide also work for migrating your application from Heroku to GCP, Azure, Scaleway and `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/getting-started/install-qovery/"}),`all cloud provider`),` supported by Qovery.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`This guide describes how to migrate your application running on Heroku to AWS with Qovery. It covers all required steps you need to take to deploy your application on AWS and transfer your data from Heroku Postgres to the database managed by AWS via Qovery.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("blockquote",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{parentName:"blockquote"},`Please contact us via `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://discuss.qovery.com/"}),`our forum`),` if you experience any problem while migrating from Heroku to AWS with Qovery.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"],{name:"guide",mdxType:"Assumptions"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You are familiar with Heroku basics, have a Heroku account and access to Heroku CLI`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You have `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"https://start.qovery.com"}),`sign in on Qovery`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You have `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/guides/installation-guide/guide-amazon-web-services/"}),`set up your AWS account`),` with Qovery`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"migration-steps"},`Migration Steps`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#1-create-your-dockerfile-or-use-buildpacks"}),`Use Buildpacks or Create your Dockerfile`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#2-create-resources-on-qovery"}),`Create resources on Qovery`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#3-configure-your-environment-variables-and-secrets"}),`Configure Environment Variables and Secrets`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#4-copy-data-from-your-heroku-databases-to-your-aws-databases"}),`Copy data from your Heroku databases to your AWS databases`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#5-deploy-your-apps-"}),`Deploy your apps`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#faq-by-heroku-users"}),`FAQ by Heroku users`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"1-create-your-dockerfile-or-use-buildpacks"},`1. Create your Dockerfile or Use Buildpacks`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery supports two ways to build and run your application coming from Heroku:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Buildpacks`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Docker`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Both options build a container image that is runnable by a container engine (E.g. Docker). Qovery runs containers on Kubernetes.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Choose the option that better fits you:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_theme_Tabs__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{centered:true,className:"rounded",defaultValue:"buildpacks",placeholder:"Use Buildpacks or Create your Dockerfile",select:false,size:null,values:[{"group":"Platforms","label":"Use Buildpacks","value":"buildpacks"},{"group":"Platforms","label":"Create your Dockerfile","value":"dockerfile"}],mdxType:"Tabs"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_theme_TabItem__WEBPACK_IMPORTED_MODULE_4__[/* default */ "a"],{value:"dockerfile",mdxType:"TabItem"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("blockquote",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{parentName:"blockquote"},`Are you familiar with Dockerfile? If not, I do recommend reading `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/tutorial/how-to-write-a-dockerfile/"}),`this article`),`.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Here we will create our Dockerfiles to build and run our applications. Qovery will handle the build and the run of your applications, but need to have at least a Dockerfile to do it.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"choose-your-dockerfile-template"},`Choose your Dockerfile template`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`To get started,`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"find-dockerfile-template"},`Find Dockerfile template`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Pick one Dockerfile template according to the programming language or framework you are using for your app:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Your framework or language is missing? Open a thread on `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://discuss.qovery.com/"}),`our forum`),`, and we will provide you one.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_theme_Tabs__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{centered:false,className:"square",defaultValue:"rails",select:false,size:null,values:[{"group":"Files","label":"Rails","value":"rails"},{"group":"Files","label":"NodeJS","value":"nodejs"},{"group":"Files","label":"React","value":"react"},{"group":"Files","label":"VueJS","value":"vuejs"},{"group":"Files","label":"NextJS","value":"nextjs"},{"group":"Files","label":"Golang","value":"golang"},{"group":"Files","label":"Flask","value":"flask"},{"group":"Files","label":"Django","value":"django"},{"group":"Files","label":"Laravel","value":"laravel"},{"group":"Files","label":"Symfony","value":"symfony"},{"group":"Files","label":"Spring","value":"spring"},{"group":"Files","label":"Rust","value":"rust"}],mdxType:"Tabs"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_theme_TabItem__WEBPACK_IMPORTED_MODULE_4__[/* default */ "a"],{value:"rails",mdxType:"TabItem"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Here is the Dockerfile for your Rails application listening on the PORT 3000`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{"className":"language-shell","metastring":"title=\"Dockerfile\"","title":"\"Dockerfile\""}),`# syntax=docker/dockerfile:1 +const frontMatter={last_modified_on:'2024-09-18',$schema:'/.meta/.schemas/guides.json',title:'Migrate your application from Heroku to AWS',description:'Guide on how to migrate all your applications from Heroku to AWS with your databases',author_github:'https://github.com/evoxmusic',tags:['type: tutorial','installation_guide: aws'],hide_pagination:true};const metadata={"categories":[{"name":"tutorial","title":"Tutorial","description":"Additional step-by-step resources to leverage even more Qovery","permalink":"/guides/tutorial"}],"coverLabel":"Migrate your application from Heroku to AWS","description":"Guide on how to migrate all your applications from Heroku to AWS with your databases","permalink":"/guides/tutorial/migrate-your-application-from-heroku-to-aws","readingTime":"12 min read","source":"@site/guides/tutorial/migrate-your-application-from-heroku-to-aws.md","tags":[{"label":"type: tutorial","permalink":"/guides/tags/type-tutorial"},{"label":"installation_guide: aws","permalink":"/guides/tags/installation-guide-aws"}],"title":"Migrate your application from Heroku to AWS","truncated":false,"prevItem":{"title":"Microservices","permalink":"/guides/advanced/microservices"},"nextItem":{"title":"Migration","permalink":"/guides/advanced/migration"}};/* @jsx mdx */const rightToc=[{value:'Migration Steps',id:'migration-steps',children:[]},{value:'1. Create your Dockerfile',id:'1-create-your-dockerfile',children:[{value:'Test your Dockerfile',id:'test-your-dockerfile',children:[]},{value:'Environment variables at the build time',id:'environment-variables-at-the-build-time',children:[]},{value:'Add your Dockerfile to Git',id:'add-your-dockerfile-to-git',children:[]},{value:'Loop',id:'loop',children:[]}]},{value:'2. Create resources on Qovery',id:'2-create-resources-on-qovery',children:[{value:'Application',id:'application',children:[]},{value:'Database',id:'database',children:[]}]},{value:'3. Configure your Environment Variables and Secrets',id:'3-configure-your-environment-variables-and-secrets',children:[{value:'Connect your frontend app to your backend app',id:'connect-your-frontend-app-to-your-backend-app',children:[]},{value:'Connect your backend app to your database',id:'connect-your-backend-app-to-your-database',children:[]}]},{value:'4. Copy data from your Heroku databases to your AWS databases',id:'4-copy-data-from-your-heroku-databases-to-your-aws-databases',children:[]},{value:'5. Deploy your apps!',id:'5-deploy-your-apps',children:[]},{value:'FAQ by Heroku users',id:'faq-by-heroku-users',children:[{value:'How to create a custom domain?',id:'how-to-create-a-custom-domain',children:[]},{value:'How to monitor my apps?',id:'how-to-monitor-my-apps',children:[]},{value:'Do you have Heroku "Review App" equivalent?',id:'do-you-have-heroku-review-app-equivalent',children:[]},{value:'How to rollback?',id:'how-to-rollback',children:[]},{value:'How auto-scaling works?',id:'how-auto-scaling-works',children:[]},{value:'How to manage database migration?',id:'how-to-manage-database-migration',children:[]},{value:'Is it possible to get a shell / connect to my app?',id:'is-it-possible-to-get-a-shell--connect-to-my-app',children:[]},{value:'Can I use Terraform and Infrastructure as Code?',id:'can-i-use-terraform-and-infrastructure-as-code',children:[]},{value:'How can I connect my app to MongoDB Atlas?',id:'how-can-i-connect-my-app-to-mongodb-atlas',children:[]},{value:'How can I connect my app to an AWS service not managed by Qovery?',id:'how-can-i-connect-my-app-to-an-aws-service-not-managed-by-qovery',children:[]}]},{value:'Wrapping up',id:'wrapping-up',children:[]}];const makeShortcode=name=>function MDXDefaultShortcode(props){console.warn("Component "+name+" was not imported, exported, or provided by MDXProvider as global scope");return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",props);};const layoutProps={rightToc};const MDXLayout="wrapper";function MDXContent({components,...props}){return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(MDXLayout,Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({},layoutProps,props,{components:components,mdxType:"MDXLayout"}),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"success",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`This guide also work for migrating your application from Heroku to GCP, Azure, Scaleway and `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/getting-started/install-qovery/"}),`all cloud provider`),` supported by Qovery.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`This guide describes how to migrate your application running on Heroku to AWS with Qovery. It covers all required steps you need to take to deploy your application on AWS and transfer your data from Heroku Postgres to the database managed by AWS via Qovery.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("blockquote",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{parentName:"blockquote"},`We have created a new AI agent capable of migrating from Heroku to AWS, GCP, Scaleway or Azure in a few clicks. Check our `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://www.qovery.com/blog/open-source-devops-ai-agent--effortless-migration-from-heroku-to-aws/?utm_campaign=migration-ai-agent-email"}),`announcement here`),`.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"],{name:"guide",mdxType:"Assumptions"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You are familiar with Heroku basics, have a Heroku account and access to Heroku CLI`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You have `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"https://start.qovery.com"}),`sign in on Qovery`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You have `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/guides/installation-guide/guide-amazon-web-services/"}),`set up your AWS account`),` with Qovery`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"migration-steps"},`Migration Steps`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#1-create-your-dockerfile"}),`Create your Dockerfile`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#2-create-resources-on-qovery"}),`Create resources on Qovery`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#3-configure-your-environment-variables-and-secrets"}),`Configure Environment Variables and Secrets`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#4-copy-data-from-your-heroku-databases-to-your-aws-databases"}),`Copy data from your Heroku databases to your AWS databases`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#5-deploy-your-apps-"}),`Deploy your apps`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#faq-by-heroku-users"}),`FAQ by Heroku users`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"1-create-your-dockerfile"},`1. Create your Dockerfile`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery supports two ways to build and run your application coming from Heroku:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("blockquote",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{parentName:"blockquote"},`Are you familiar with Dockerfile? If not, I do recommend reading `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/tutorial/how-to-write-a-dockerfile/"}),`this article`),`.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Here we will create our Dockerfiles to build and run our applications. Qovery will handle the build and the run of your applications, but need to have at least a Dockerfile to do it.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"find-dockerfile-template"},`Find Dockerfile template`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Pick one Dockerfile template according to the programming language or framework you are using for your app:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Your framework or language is missing? Open a thread on `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://discuss.qovery.com/"}),`our forum`),`, and we will provide you one.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_theme_Tabs__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{centered:false,className:"square",defaultValue:"rails",select:false,size:null,values:[{"group":"Files","label":"Rails","value":"rails"},{"group":"Files","label":"NodeJS","value":"nodejs"},{"group":"Files","label":"React","value":"react"},{"group":"Files","label":"VueJS","value":"vuejs"},{"group":"Files","label":"NextJS","value":"nextjs"},{"group":"Files","label":"Golang","value":"golang"},{"group":"Files","label":"Flask","value":"flask"},{"group":"Files","label":"Django","value":"django"},{"group":"Files","label":"Laravel","value":"laravel"},{"group":"Files","label":"Symfony","value":"symfony"},{"group":"Files","label":"Spring","value":"spring"},{"group":"Files","label":"Rust","value":"rust"}],mdxType:"Tabs"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_theme_TabItem__WEBPACK_IMPORTED_MODULE_4__[/* default */ "a"],{value:"rails",mdxType:"TabItem"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Here is the Dockerfile for your Rails application listening on the PORT 3000`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{"className":"language-shell","metastring":"title=\"Dockerfile\"","title":"\"Dockerfile\""}),`# syntax=docker/dockerfile:1 FROM ruby:2.7 RUN apt-get update -qq && apt-get install -y nodejs postgresql-client WORKDIR /myapp @@ -52264,7 +52264,7 @@ ENV CONTENT_API_KEY $CONTENT_API_KEY `)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The value of the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`CONTENT_API_KEY`),` environment variable will be taken from the specified environment variables in Qovery.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"success",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery injects Environment Variables and Secrets at the build and run time of your app.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"add-your-dockerfile-to-git"},`Add your Dockerfile to Git`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Now, add your new Dockerfile to git with the following commands:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{"className":"language-shell"}),`git add Dockerfile.qovery git commit -m "Add Qovery Dockerfile" git push origin -`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"loop"},`Loop`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you have multiple applications to deploy, create a Dockerfile for each of them.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_theme_TabItem__WEBPACK_IMPORTED_MODULE_4__[/* default */ "a"],{value:"buildpacks",mdxType:"TabItem"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://buildpacks.io/"}),`Buildpacks`),` automatically detects the language and the framework your application is using. Buildpacks builds and runs your app. Here is the list of `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/application/#option-1-buildpacks"}),`supported languages and frameworks`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"warning",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`We do recommend using Docker to keep the full control of what's going on behind the scene. Buildpacks is a great technology but difficult to debug when something goes wrong. You can try deploying your apps on AWS with Qovery with Buildpacks, if you do not succeed, we do recommend switching for Docker.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"limitations"},`Limitations`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Here are some limitations due to our Buildpacks implementation:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Qovery Buildpacks does not support Procfile with multiple commands at the moment.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Qovery does not support custom Buildpacks.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Those limitations will be solved in the coming months.`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"2-create-resources-on-qovery"},`2. Create resources on Qovery`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"application"},`Application`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Are you a new Qovery user? Watch `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/getting-started/deploy-your-first-application/"}),`this tutorial`),` to learn how to deploy your first app.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",{class:"video-container"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("iframe",{src:"https://www.loom.com/embed/9246ae68c68f42debc3d5183d2b4f7f8",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:true,mozallowfullscreen:true,allowfullscreen:true}))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Steps:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Connect to the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"https://start.qovery.com"}),`Qovery console`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Create your `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/organization/"}),`Organization`),` and your `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/project/"}),`Project`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Create an environment with the name `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`production`),` (it can be changed after).`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Create an application and give it a name (you can give the name of your repo if you have no idea)`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select your app repository from your GitHub, GitLab or Bitbucket.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select the branch you want to deploy.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select the Build mode for `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`Buildpacks`),` or `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`Dockerfile`),` according to what you want.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Specify the local listening port of your application.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Click on "create"`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Congrats! Your application is created 🎉`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"warning",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Your application is created but not deployed yet! You can configure the vCPU, Memory, Environment Variables... before deploying it. If you want to deploy it before finishing the configuration you can click on "Actions" > "Deploy".`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you deploy an app from a mono-repository, we have a must-read guide for you `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/advanced/monorepository/"}),`here`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"database"},`Database`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Are you a new Qovery user? Watch `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/getting-started/create-a-database/"}),`this tutorial`),` to learn how to deploy your database.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Here are the steps to deploy your database:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"],{mdxType:"Assumptions"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You have created an application before`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",{class:"video-container"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("iframe",{src:"https://www.loom.com/embed/d7e10be0e5964f6799b158dc631bbbd1",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:true,mozallowfullscreen:true,allowfullscreen:true}))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Steps:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Go to your `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`production`),` environment.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Add your database by clicking on "Add" > "Database".`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select the database (PostgreSQL, MySQL, MongoDB, Redis..) and the version you want to deploy.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/database/#general"}),`Managed or Container mode`),` for your database.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`Public`),` accessibility (set `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`Private`),` if you don't want to restore your data from an existing Heroku database).`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Congrats! Your database is created as well 🎉`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you use MongoDB Atlas, or an existing database on AWS that you want to connect to your application deployed by Qovery. Check out `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/tutorial/aws-vpc-peering-with-qovery/"}),`our tutorial about VPC peering`),` and how to securely connect to your existing database.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"3-configure-your-environment-variables-and-secrets"},`3. Configure your Environment Variables and Secrets`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"success",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery supports Doppler integration - it's the easiest way to migrate your Environment Variables and Secrets from Heroku to Qovery. `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/integration/secret-manager/doppler/"}),`More info here`),`.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery makes the difference between an environment variable and a secret. Basically, a Secret is similar to an Environment Variable but the value is encrypted and can't be revealed. Both are injected as environment variables during the build and the run of your applications. `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/environment-variable/"}),`More info here`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`I recommend reading our `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/getting-started/managing-environment-variables/"}),`Getting Started with Environment Variables`),` guide.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`To extract your environment variables from Heroku, we recommend using the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://devcenter.heroku.com/articles/heroku-cli"}),`Heroku CLI`),` and exporting all the environment variables and secrets in an .env (dot env) file. Qovery supports the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/tutorial/import-your-environment-variables-with-the-qovery-cli/"}),`import of a dot env file`),` via the Qovery web interface and the Qovery CLI.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"warning",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you use Buildpacks for one of your app AND you have indicated a local listening port of your application, you will need to add an environment variable `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`PORT`),` with the value of your port to make your application starting properly. Otherwise, Qovery will fail to deploy your app!`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://devcenter.heroku.com/articles/config-vars#view-current-config-var-values"}),`Export your environment variable via the Heroku CLI`),` with the command:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{"className":"language-shell"}),`# To install Heroku CLI: https://devcenter.heroku.com/articles/heroku-cli +`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"loop"},`Loop`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you have multiple applications to deploy, create a Dockerfile for each of them.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"2-create-resources-on-qovery"},`2. Create resources on Qovery`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"application"},`Application`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Are you a new Qovery user? Watch `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/getting-started/deploy-your-first-application/"}),`this tutorial`),` to learn how to deploy your first app.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",{class:"video-container"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("iframe",{src:"https://www.loom.com/embed/9246ae68c68f42debc3d5183d2b4f7f8",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:true,mozallowfullscreen:true,allowfullscreen:true}))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Steps:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Connect to the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"https://start.qovery.com"}),`Qovery console`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Create your `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/organization/"}),`Organization`),` and your `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/project/"}),`Project`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Create an environment with the name `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`production`),` (it can be changed after).`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Create an application and give it a name (you can give the name of your repo if you have no idea)`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select your app repository from your GitHub, GitLab or Bitbucket.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select the branch you want to deploy.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Specify the local listening port of your application.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Click on "create"`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Congrats! Your application is created 🎉`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"warning",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Your application is created but not deployed yet! You can configure the vCPU, Memory, Environment Variables... before deploying it. If you want to deploy it before finishing the configuration you can click on "Actions" > "Deploy".`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you deploy an app from a mono-repository, we have a must-read guide for you `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/advanced/monorepository/"}),`here`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"database"},`Database`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Are you a new Qovery user? Watch `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/getting-started/create-a-database/"}),`this tutorial`),` to learn how to deploy your database.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Here are the steps to deploy your database:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"],{mdxType:"Assumptions"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You have created an application before`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",{class:"video-container"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("iframe",{src:"https://www.loom.com/embed/d7e10be0e5964f6799b158dc631bbbd1",width:"100%",height:"100%",frameborder:"0",webkitallowfullscreen:true,mozallowfullscreen:true,allowfullscreen:true}))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Steps:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Go to your `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`production`),` environment.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Add your database by clicking on "Add" > "Database".`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select the database (PostgreSQL, MySQL, MongoDB, Redis..) and the version you want to deploy.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/database/#general"}),`Managed or Container mode`),` for your database.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Select `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`Public`),` accessibility (set `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`Private`),` if you don't want to restore your data from an existing Heroku database).`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Congrats! Your database is created as well 🎉`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you use MongoDB Atlas, or an existing database on AWS that you want to connect to your application deployed by Qovery. Check out `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/tutorial/aws-vpc-peering-with-qovery/"}),`our tutorial about VPC peering`),` and how to securely connect to your existing database.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"3-configure-your-environment-variables-and-secrets"},`3. Configure your Environment Variables and Secrets`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"success",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery supports Doppler integration - it's the easiest way to migrate your Environment Variables and Secrets from Heroku to Qovery. `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/integration/secret-manager/doppler/"}),`More info here`),`.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery makes the difference between an environment variable and a secret. Basically, a Secret is similar to an Environment Variable but the value is encrypted and can't be revealed. Both are injected as environment variables during the build and the run of your applications. `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/environment-variable/"}),`More info here`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`I recommend reading our `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/getting-started/managing-environment-variables/"}),`Getting Started with Environment Variables`),` guide.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`To extract your environment variables from Heroku, we recommend using the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://devcenter.heroku.com/articles/heroku-cli"}),`Heroku CLI`),` and exporting all the environment variables and secrets in an .env (dot env) file. Qovery supports the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/tutorial/import-your-environment-variables-with-the-qovery-cli/"}),`import of a dot env file`),` via the Qovery web interface and the Qovery CLI.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://devcenter.heroku.com/articles/config-vars#view-current-config-var-values"}),`Export your environment variable via the Heroku CLI`),` with the command:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{"className":"language-shell"}),`# To install Heroku CLI: https://devcenter.heroku.com/articles/heroku-cli heroku config GREETINGS: hello world @@ -53257,11 +53257,10 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _site_src_components_Jump__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8); /* harmony import */ var _site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(3); /* harmony import */ var _site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(6); -const frontMatter={last_modified_on:'2024-08-27',title:'Application',description:'Learn how to configure your Application on Qovery'};const metadata={"id":"using-qovery/configuration/application","title":"Application","description":"Learn how to configure your Application on Qovery","source":"@site/docs/using-qovery/configuration/application.md","permalink":"/docs/using-qovery/configuration/application","sidebar":"docs","previous":{"title":"Environment","permalink":"/docs/using-qovery/configuration/environment"},"next":{"title":"Helm","permalink":"/docs/using-qovery/configuration/helm"}};/* @jsx mdx */const rightToc=[{value:'Deploying from a Git Repository',id:'deploying-from-a-git-repository',children:[]},{value:'Deploying from a Container Registry',id:'deploying-from-a-container-registry',children:[]},{value:'Create an Application',id:'create-an-application',children:[]},{value:'Deployment Management',id:'deployment-management',children:[]},{value:'Configuration',id:'configuration',children:[{value:'General',id:'general',children:[]},{value:'Resources',id:'resources',children:[]},{value:'Storage',id:'storage',children:[]},{value:'Ports',id:'ports',children:[]},{value:'Health Checks',id:'health-checks',children:[]},{value:'Deployment Restrictions',id:'deployment-restrictions',children:[]}]},{value:'Connecting from the internet',id:'connecting-from-the-internet',children:[{value:'Qovery provided domains',id:'qovery-provided-domains',children:[]},{value:'Custom domains',id:'custom-domains',children:[]}]},{value:'Connecting to a database',id:'connecting-to-a-database',children:[]},{value:'Connecting to another application',id:'connecting-to-another-application',children:[]},{value:'Environment Variable',id:'environment-variable',children:[]},{value:'Secrets',id:'secrets',children:[]},{value:'Logs',id:'logs',children:[]},{value:'SSH',id:'ssh',children:[]},{value:'Clone',id:'clone',children:[]},{value:'Advanced Settings',id:'advanced-settings',children:[]},{value:'Delete an Application',id:'delete-an-application',children:[]}];const makeShortcode=name=>function MDXDefaultShortcode(props){console.warn("Component "+name+" was not imported, exported, or provided by MDXProvider as global scope");return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",props);};const layoutProps={rightToc};const MDXLayout="wrapper";function MDXContent({components,...props}){return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(MDXLayout,Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({},layoutProps,props,{components:components,mdxType:"MDXLayout"}),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"],{name:"documentation",mdxType:"Assumptions"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`You have created an `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/environment/"}),`Environment`),`.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`An `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`application`),` is part of a `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/project/"}),`Project`),` within an `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/environment/"}),`Environment`),` and is a container unit. Multiple applications can be part of the same `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/environment/"}),`Environment`),`, be connected to a set of dependencies (databases and other services), and can communicate with other applications within the same Environment.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery allows you to create and deploy applications from two different sources: Git Repository or Container Registry`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"deploying-from-a-git-repository"},`Deploying from a Git Repository`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`In this configuration, Qovery will pull the code from the chosen repository, build the application and deploy it on your kubernetes cluster.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The list of Git repositories available during the setup is strictly tied to the permissions of your git account (by default Qovery can access all your repositories). If you want to restrict the Qovery access only to a few repositories, user the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/organization/git-repository-access/"}),`GitHub Qovery Application`),` (only for Github).`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"deploying-from-a-container-registry"},`Deploying from a Container Registry`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`In this configuration, Qovery will pull the chosen container registry an image you have pre-built and deploy it on your kubernetes cluster.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`To improve security and avoid deploying images from non-authorized registries, we have decided to restrict the list of Container Registry you can use during the setup process. Only an administrator with the right permissions can manage it from the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/organization/container-registry/"}),`Container Registry Management page`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Make sure that the image tag used are unique (do not use "latest", "dev", "master" etc..), see `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/deployment/image-mirroring/#why-unique-image-tags-are-necessary"}),`this section`),` for more information.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"create-an-application"},`Create an Application`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Steps__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{headingDepth:3,mdxType:"Steps"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Go into the chosen environment and press the "New Service" button and then the "Create application" button`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/creation_1.png",alt:"Creation"}))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Select the following fields:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Application Name: give a name to your application`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Application Source: Chose between Git Repository or Container Registry, depending on the source location of your application`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you want to deploy an application from a Git Repository you will have to select:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Git Repository: Select the git provider hosting your code (it can be hosted on GitHub, GitLab or Bitbucket). You can add a new git access by clicking on `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`New git access`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Branch: Select branch that Qovery should use to deploy your application`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Root Application Path: base folder in which the application resides in your repository`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Build Mode: choose between Docker or Buildpack. For more information, go to `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/application/#build-mode"}),`this section`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you want to deploy an application from a Container Registry you will have to select:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Registry: select the container registry storing the image of your application. You can add a new container registry by clicking on `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`New registry`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Image name: the name of the image to be deployed with this application (example: postgres)`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Image tag: the tag of the image to be deployed with this application (example: 1.0). `),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Image Entrypoint: the entrypoint to be used to launch your application (not mandatory)`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`CMD Arguments: the arguments to be passed to launch your application (not mandatory) separated with a space. Example: `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`rails -h 0.0.0.0 -p 8080 string "complex arg"`),`.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Make sure that the image tag used are unique (do not use "latest", "dev", "master" etc..), see `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/deployment/image-mirroring/#why-unique-image-tags-are-necessary"}),`this section`),` for more information.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If the base image in your Dockerfile is from a private registry, you just have to add the access to this registry before creating your application. See `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/organization/container-registry/"}),`Container Registry Management page`),` for more information.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},` Auto Deploy `)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`See the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/deployment/deploying-with-auto-deploy/"}),`Deploying with auto-deploy feature`),` section.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},` Extra labels/annotations (optional)`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Add your extra annotation/label groups. See the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/organization/labels-annotations/"}),`Add annotation/label group`),` section for more information.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Within this section, you will need to define the resources to be assigned to your application at run time.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`vCPU: the vCPU assigned to each instance of your application. The default is 500m (0.5 vCPU).`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`RAM: the amount of RAM assigned to each instance of your application. The default is 512MB.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Number of instances (Application Auto-scaling): select the minimum and the maximum number of instances of your application that can run within your cluster. The number of instances running at an insant t is automatically managed by Kubernetes (Application auto-scaling) and it is based on real-time CPU consumption. When your app goes above 60% of CPU consumption for 5 minutes, your app will be auto-scaled and more instances will be added. It is transparent. +const frontMatter={last_modified_on:'2024-09-18',title:'Application',description:'Learn how to configure your Application on Qovery'};const metadata={"id":"using-qovery/configuration/application","title":"Application","description":"Learn how to configure your Application on Qovery","source":"@site/docs/using-qovery/configuration/application.md","permalink":"/docs/using-qovery/configuration/application","sidebar":"docs","previous":{"title":"Environment","permalink":"/docs/using-qovery/configuration/environment"},"next":{"title":"Helm","permalink":"/docs/using-qovery/configuration/helm"}};/* @jsx mdx */const rightToc=[{value:'Deploying from a Git Repository',id:'deploying-from-a-git-repository',children:[]},{value:'Deploying from a Container Registry',id:'deploying-from-a-container-registry',children:[]},{value:'Create an Application',id:'create-an-application',children:[]},{value:'Deployment Management',id:'deployment-management',children:[]},{value:'Configuration',id:'configuration',children:[{value:'General',id:'general',children:[]},{value:'Resources',id:'resources',children:[]},{value:'Storage',id:'storage',children:[]},{value:'Ports',id:'ports',children:[]},{value:'Health Checks',id:'health-checks',children:[]},{value:'Deployment Restrictions',id:'deployment-restrictions',children:[]}]},{value:'Connecting from the internet',id:'connecting-from-the-internet',children:[{value:'Qovery provided domains',id:'qovery-provided-domains',children:[]},{value:'Custom domains',id:'custom-domains',children:[]}]},{value:'Connecting to a database',id:'connecting-to-a-database',children:[]},{value:'Connecting to another application',id:'connecting-to-another-application',children:[]},{value:'Environment Variable',id:'environment-variable',children:[]},{value:'Secrets',id:'secrets',children:[]},{value:'Logs',id:'logs',children:[]},{value:'SSH',id:'ssh',children:[]},{value:'Clone',id:'clone',children:[]},{value:'Advanced Settings',id:'advanced-settings',children:[]},{value:'Delete an Application',id:'delete-an-application',children:[]}];const makeShortcode=name=>function MDXDefaultShortcode(props){console.warn("Component "+name+" was not imported, exported, or provided by MDXProvider as global scope");return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",props);};const layoutProps={rightToc};const MDXLayout="wrapper";function MDXContent({components,...props}){return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(MDXLayout,Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({},layoutProps,props,{components:components,mdxType:"MDXLayout"}),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"],{name:"documentation",mdxType:"Assumptions"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`You have created an `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/environment/"}),`Environment`),`.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`An `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`application`),` is part of a `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/project/"}),`Project`),` within an `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/environment/"}),`Environment`),` and is a container unit. Multiple applications can be part of the same `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/environment/"}),`Environment`),`, be connected to a set of dependencies (databases and other services), and can communicate with other applications within the same Environment.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery allows you to create and deploy applications from two different sources: Git Repository or Container Registry`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"deploying-from-a-git-repository"},`Deploying from a Git Repository`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`In this configuration, Qovery will pull the code from the chosen repository, build the application and deploy it on your kubernetes cluster.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The list of Git repositories available during the setup is strictly tied to the permissions of your git account (by default Qovery can access all your repositories). If you want to restrict the Qovery access only to a few repositories, user the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/organization/git-repository-access/"}),`GitHub Qovery Application`),` (only for Github).`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"deploying-from-a-container-registry"},`Deploying from a Container Registry`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`In this configuration, Qovery will pull the chosen container registry an image you have pre-built and deploy it on your kubernetes cluster.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`To improve security and avoid deploying images from non-authorized registries, we have decided to restrict the list of Container Registry you can use during the setup process. Only an administrator with the right permissions can manage it from the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/organization/container-registry/"}),`Container Registry Management page`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Make sure that the image tag used are unique (do not use "latest", "dev", "master" etc..), see `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/deployment/image-mirroring/#why-unique-image-tags-are-necessary"}),`this section`),` for more information.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"create-an-application"},`Create an Application`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Steps__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"],{headingDepth:3,mdxType:"Steps"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Go into the chosen environment and press the "New Service" button and then the "Create application" button`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/creation_1.png",alt:"Creation"}))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Select the following fields:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Application Name: give a name to your application`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Application Source: Chose between Git Repository or Container Registry, depending on the source location of your application`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you want to deploy an application from a Git Repository you will have to select:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Git Repository: Select the git provider hosting your code (it can be hosted on GitHub, GitLab or Bitbucket). You can add a new git access by clicking on `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`New git access`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Branch: Select branch that Qovery should use to deploy your application`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Root Application Path: base folder in which the application resides in your repository`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Build and deploy: configure your Dockerfile location. For more information, go to `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/application/#build-and-deploy"}),`this section`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you want to deploy an application from a Container Registry you will have to select:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Registry: select the container registry storing the image of your application. You can add a new container registry by clicking on `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`New registry`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Image name: the name of the image to be deployed with this application (example: postgres)`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Image tag: the tag of the image to be deployed with this application (example: 1.0). `),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Image Entrypoint: the entrypoint to be used to launch your application (not mandatory)`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`CMD Arguments: the arguments to be passed to launch your application (not mandatory) separated with a space. Example: `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`rails -h 0.0.0.0 -p 8080 string "complex arg"`),`.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Make sure that the image tag used are unique (do not use "latest", "dev", "master" etc..), see `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/deployment/image-mirroring/#why-unique-image-tags-are-necessary"}),`this section`),` for more information.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If the base image in your Dockerfile is from a private registry, you just have to add the access to this registry before creating your application. See `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/organization/container-registry/"}),`Container Registry Management page`),` for more information.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},` Auto Deploy `)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`See the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/deployment/deploying-with-auto-deploy/"}),`Deploying with auto-deploy feature`),` section.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},` Extra labels/annotations (optional)`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Add your extra annotation/label groups. See the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/organization/labels-annotations/"}),`Add annotation/label group`),` section for more information.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Within this section, you will need to define the resources to be assigned to your application at run time.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`vCPU: the vCPU assigned to each instance of your application. The default is 500m (0.5 vCPU).`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`RAM: the amount of RAM assigned to each instance of your application. The default is 512MB.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Number of instances (Application Auto-scaling): select the minimum and the maximum number of instances of your application that can run within your cluster. The number of instances running at an insant t is automatically managed by Kubernetes (Application auto-scaling) and it is based on real-time CPU consumption. When your app goes above 60% of CPU consumption for 5 minutes, your app will be auto-scaled and more instances will be added. It is transparent. Qovery runs your application on Kubernetes and relies on `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"https://github.com/kubernetes-sigs/metrics-server"}),`metrics-server`),` service to auto-scale your app.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Please note that in this section you configure the CPU/RAM allocated by the cluster for your application and that cannot consume more than this value. Even if the application is underused and consume less resources, the cluster will still reserve the selected amount of CPU/RAM.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/application_creation_resources.png",alt:"Resources"}))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`You can now define one or more ports for your Application. Most of the application needs to be accessed by other services inside or outside your environment over different L7/L4 protocols. Today Qovery supports the following protocols:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`HTTPS (Select this protocol if you need to run Websockets)`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`gRPC`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`TCP`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`UDP`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`By default ports are accessible only from inside your environment. You can also expose them publicly, making them accessible over the public network via a dedicated public domain that will be assigned to your application by Qovery during the deployment (See the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"#qovery-provided-domains"}),`Qovery Provided Domains section`),`). Note that HTTPS/gRPC ports are always exposed over the port 443.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/application_creation_port.png",alt:"Application Ports"})),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`Important Informations`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Most of the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/service-health-checks/"}),`Kubernetes Health Checks`),` are based on the port declared in this section. Make sure you declare the right port and that you configure the health checks properly.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Connections on public ports are automatically closed after 60 seconds. If you want to implement long living connection (like for websockets) please make sure to use the rigth ingress timeouts in the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/advanced-settings/#network-settings"}),`advanced settings section`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Exposing publicly TCP/UDP ports requires to create a dedicated load balancer and it takes a few minutes before having it ready (~15 minutes). Note also that this has a direct impact on your cloud provider bill.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You can configure your application to use the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"li"},`PORT`),` environment variable by adding the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"li"},`PORT`),` on your application env variables page.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`A Note on Listening IPs: It is best for your application to listen on `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`0.0.0.0:$PORT`),`. While most things work with `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`127.0.0.1`),` and `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`localhost`),`, some do not (NodeJS for example)`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`(Optional) If a port has been defined for your application, you can define the health check probes to run in order to verify the state of your application`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`To know more about how to configure your Liveness and Readiness probes, have a look at `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/application-health-checks/"}),`the health-checks section`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Define any input variable required by your application to run. Any declared variable will be injected as environment variables based on the selected scope (project, environment, service) -Any additional environment variable can be added later from the environment variable section`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/job/variables.png",alt:"Input Variables"}))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`You will find a recap of your application setup and you can now decide to:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Go back to one of the previous steps and change your application settings`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Create your application without deploying it`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Create and deploy your application`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/application_creation_recap.png",alt:"Application"}))))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"deployment-management"},`Deployment Management`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Have a look at the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/deployment/"}),`Deployment Management`),` section for more information.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"configuration"},`Configuration`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Once created, you can access the configuration of an application at any time via the Settings tab available on the application section`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/settings.png",alt:"Application Settings"})),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`You can find below the description of each of the tabs available in this section`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"general"},`General`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`General settings section allows you to set up your application name and the source code location (git repository or image registry) .`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"git-repository"},`Git Repository`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If your application is built and deployed from a git repository, within this section you can:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Modify the git provider where your code is stored (it can be hosted on GitHub, GitLab or Bitbucket).`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Modify the branch that Qovery should use for deploying your application`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Modify `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`Root Application Path`),` - base folder in which the application resides in your repository`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/app-general-git.png",alt:"General Settings Git"})),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery supports mono repositories. `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/advanced/monorepository/"}),`See our advanced guide for more details.`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"warning",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If your repository contains private submodules using SSH protocol, you will need to add a secret beginning with GIT`,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("em",{parentName:"p"},`SSH_KEY`),`, containing a private SSH key with access rights to your sumbodules repositories.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Secret names examples:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`GIT_SSH_KEY_GITHUB`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`GIT_SSH_KEY_GITLAB`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`GIT_SSH_KEY_MYAPP`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"container-registry"},`Container Registry`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If your application is deployed from an image registry, within this section you can modify:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Registry: select the container registry storing the image of your application. Note: only pre-configured registry are available in this list, check the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/organization/container-registry/"}),`Container Registry Management page`),` for more information.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Image name: the name of the image to be deployed with this application (example: postgres)`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Image tag: the tag of the image to be deployed with this application (example: 1.0).`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Image Entrypoint: the entrypoint to be used to launch your applicaiton (not mandatory)`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`CMD Arguments: the arguments to be passed to launch your applicaiton (not mandatory). We expect the format to be an array. Example `,`["rails", "-h", "0.0.0.0", "-p", "8080", "string"]`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Make sure that the image tag used are unique (do not use "latest", "dev", "master" etc..), see `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/deployment/image-mirroring/#why-unique-image-tags-are-necessary"}),`this section`),` for more information.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/app-general-registry.png",alt:"General Settings Git"})),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"build-mode"},`Build Mode`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`This option is available only if you have selected "Git Repository" as source`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"option-1-buildpacks"},`Option 1: Buildpacks`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`To simplify the application build for the developer, Qovery supports `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://buildpacks.io"}),`Buildpacks`),` out of the box. Buildpacks determine the build process for an app and which assets and runtimes should be made available to your code at runtime. If your complex apps are running multiple languages, you can also use multiple buildpacks within a single app. -Meaning, as a developer, you don't need to write a `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`Dockerfile`),` to build and run your app. Qovery Buildpacks takes care of everything for you.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`Supported languages`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("table",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("thead",{parentName:"table"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("tr",{parentName:"thead"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("th",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`language`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("th",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`version`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("tbody",{parentName:"table"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("tr",{parentName:"tbody"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`Node.JS`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`any`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("tr",{parentName:"tbody"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`Clojure`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`any`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("tr",{parentName:"tbody"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`Python`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`any`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("tr",{parentName:"tbody"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`Java`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`any`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("tr",{parentName:"tbody"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`Gradle`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`any`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("tr",{parentName:"tbody"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`JVM`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`any`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("tr",{parentName:"tbody"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`Grails`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`any`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("tr",{parentName:"tbody"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`Scala`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`any`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("tr",{parentName:"tbody"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`Play`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`any`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("tr",{parentName:"tbody"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`PHP`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`any`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("tr",{parentName:"tbody"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`Go`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`any`)))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`You don't find a cool language? `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://roadmap.qovery.com/roadmap"}),`Suggest us to support it`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"option-2-dockerfile"},`Option 2: Dockerfile`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If your job is built via the Qovery CI (Source="Git Repository"), this section allows you to define the Dockerfile location. `),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you don't have one, you can use the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`docker init`),` command to generate one for your application (check the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://docs.docker.com/reference/cli/docker/init/"}),`documentation here`),`). After creating a Dockerfile, specify the location of your Dockerfile in `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`Dockefile path`),` field.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"auto-deploy"},`Auto Deploy`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`See the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/deployment/deploying-with-auto-deploy/"}),`Deploying with auto-deploy feature`),` section.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"extra-labelsannotations"},`Extra labels/annotations`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Add your extra annotation/label groups. See the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/organization/labels-annotations/"}),`Add annotation/label group`),` section for more information.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"resources"},`Resources`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/app-13.png",alt:"CPU"})),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"cpu"},`CPU`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`To configure the number of CPUs that your app needs, adjust the setting in the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`Resources`),` section of the application configuration.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Default is 500m (0.5 vCPU). `)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Please note that in this section you configure the CPU allocated by the cluster for your application and that cannot consume more than this value. Even if the application is underused and consumes fewer resources, the cluster will still reserve the selected amount of CPU.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"ram"},`RAM`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`To configure the amount of RAM that your app needs, adjust the setting in `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`Resources`),` section of the application configuration.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Default is 512MB.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Please note that in this section you configure the CPU allocated by the cluster for your application and that cannot consume more than this value. Even if the application is underused and consume less resources, the cluster will still reserve the selected amount of CPU. If your application requires more RAM than requested, it will be killed by the kubernetes scheduler.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"auto-scaling"},`Auto-scaling`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Application auto-scaling is based on real-time CPU consumption. When your app goes above 60% of CPU consumption for 15 seconds, your app will be auto-scaled and more instances will be added. It is transparent. The downscale will happen if the CPU consumption is lower than 60% for at least 5 minutes. +Any additional environment variable can be added later from the environment variable section`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/job/variables.png",alt:"Input Variables"}))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`You will find a recap of your application setup and you can now decide to:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Go back to one of the previous steps and change your application settings`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Create your application without deploying it`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Create and deploy your application`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/application_creation_recap.png",alt:"Application"}))))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"deployment-management"},`Deployment Management`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Have a look at the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/deployment/"}),`Deployment Management`),` section for more information.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"configuration"},`Configuration`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Once created, you can access the configuration of an application at any time via the Settings tab available on the application section`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/settings.png",alt:"Application Settings"})),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`You can find below the description of each of the tabs available in this section`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"general"},`General`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`General settings section allows you to set up your application name and the source code location (git repository or image registry) .`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"git-repository"},`Git Repository`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If your application is built and deployed from a git repository, within this section you can:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Modify the git provider where your code is stored (it can be hosted on GitHub, GitLab or Bitbucket).`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Modify the branch that Qovery should use for deploying your application`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Modify `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`Root Application Path`),` - base folder in which the application resides in your repository`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/app-general-git.png",alt:"General Settings Git"})),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery supports mono repositories. `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/advanced/monorepository/"}),`See our advanced guide for more details.`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"warning",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If your repository contains private submodules using SSH protocol, you will need to add a secret beginning with GIT`,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("em",{parentName:"p"},`SSH_KEY`),`, containing a private SSH key with access rights to your sumbodules repositories.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Secret names examples:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`GIT_SSH_KEY_GITHUB`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`GIT_SSH_KEY_GITLAB`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`GIT_SSH_KEY_MYAPP`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"container-registry"},`Container Registry`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If your application is deployed from an image registry, within this section you can modify:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Registry: select the container registry storing the image of your application. Note: only pre-configured registry are available in this list, check the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/organization/container-registry/"}),`Container Registry Management page`),` for more information.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Image name: the name of the image to be deployed with this application (example: postgres)`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Image tag: the tag of the image to be deployed with this application (example: 1.0).`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Image Entrypoint: the entrypoint to be used to launch your applicaiton (not mandatory)`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`CMD Arguments: the arguments to be passed to launch your applicaiton (not mandatory). We expect the format to be an array. Example `,`["rails", "-h", "0.0.0.0", "-p", "8080", "string"]`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Make sure that the image tag used are unique (do not use "latest", "dev", "master" etc..), see `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/deployment/image-mirroring/#why-unique-image-tags-are-necessary"}),`this section`),` for more information.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/app-general-registry.png",alt:"General Settings Git"})),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"build-and-deploy"},`Build and Deploy`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If your job is built via the Qovery CI (Source="Git Repository"), this section allows you to define the Dockerfile location. `),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you don't have one, you can use the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`docker init`),` command to generate one for your application (check the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://docs.docker.com/reference/cli/docker/init/"}),`documentation here`),`). After creating a Dockerfile, specify the location of your Dockerfile in `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`Dockefile path`),` field.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"auto-deploy"},`Auto Deploy`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`See the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/deployment/deploying-with-auto-deploy/"}),`Deploying with auto-deploy feature`),` section.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"extra-labelsannotations"},`Extra labels/annotations`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Add your extra annotation/label groups. See the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/organization/labels-annotations/"}),`Add annotation/label group`),` section for more information.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"resources"},`Resources`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/app-13.png",alt:"CPU"})),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"cpu"},`CPU`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`To configure the number of CPUs that your app needs, adjust the setting in the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`Resources`),` section of the application configuration.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Default is 500m (0.5 vCPU). `)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Please note that in this section you configure the CPU allocated by the cluster for your application and that cannot consume more than this value. Even if the application is underused and consumes fewer resources, the cluster will still reserve the selected amount of CPU.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"ram"},`RAM`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`To configure the amount of RAM that your app needs, adjust the setting in `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`Resources`),` section of the application configuration.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Default is 512MB.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Please note that in this section you configure the CPU allocated by the cluster for your application and that cannot consume more than this value. Even if the application is underused and consume less resources, the cluster will still reserve the selected amount of CPU. If your application requires more RAM than requested, it will be killed by the kubernetes scheduler.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"auto-scaling"},`Auto-scaling`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Application auto-scaling is based on real-time CPU consumption. When your app goes above 60% of CPU consumption for 15 seconds, your app will be auto-scaled and more instances will be added. It is transparent. The downscale will happen if the CPU consumption is lower than 60% for at least 5 minutes. You can adjust the minimum and maximum of instances you need in your application settings. Qovery runs your application on Kubernetes and relies on `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://github.com/kubernetes-sigs/metrics-server"}),`metrics-server`),` service to auto-scale your app.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"storage"},`Storage`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"block-storage"},`Block Storage`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The default filesystem for applications running on Qovery is ephemeral. Application data isn’t persisted across deploys and restarts, which works just fine for most apps because they use managed databases to persist data.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`However, many applications need persistent disk storage that isn’t ephemeral. These include:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Blogging platforms and CMSs like WordPress, Ghost, and Strapi.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Collaboration apps like Mattermost, GitLab, and Discourse.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`This is where Qovery block Storage comes in. Qovery applications can use storage to store data that persists across deploys and restarts, making it easy to deploy stateful applications.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"warning",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`For most use cases, it is better to use `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/object-storage/"}),`Object Storage`),` instead of Block Storage.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h6",{"id":"use-cases"},`Use cases`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h6",{"id":"-good-use-cases"},`✅ Good use cases`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`For I/O intensive applications (E.g. database)`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`To store temporary files`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h6",{"id":"-bad-use-cases"},`❌ Bad use cases`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`To store file > 1 TB`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`To expose files from an application (E.g. images)`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h5",{"id":"types-of-block-storage"},`Types of Block Storage`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Qovery Storage supports:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("table",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("thead",{parentName:"table"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("tr",{parentName:"thead"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("th",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`Type`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("th",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`Max IOPS`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("th",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`Max Throughput`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("th",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`Min Size`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("th",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`Max Size`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("th",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`Use cases`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("tbody",{parentName:"table"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("tr",{parentName:"tbody"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`fast_ssd`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`64000`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`1GB/s`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`5GB`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`10GB `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"td"},`Community`),` / 1TB paid plans`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("td",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"tr"},{"align":null}),`Critical business applications that require sustained IOPS like databases`)))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h5",{"id":"configuration-1"},`Configuration`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`You can set up your Block Storage in `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`Storage`),` section of your application configuration.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/app-7.png",alt:"Application Storage"})),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Storage can be added only if the application has never been deployed before AND if it runs only with one instance (check the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/application/#resources"}),`Resources section`),`)`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"ports"},`Ports`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Within this section you can define the port exposed by your application to the other services or even over the internet. You can edit the existing ports or declare new ones by specifying:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Application port: this is the port exposed internally by your application for the other services. `),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Protocol: you can select the protocol used by your application : HTTP (for both standard HTTP or websocket communications), gRPC, TCP, UDP.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Publicly exposed: it allows you to expose over the public network your service. A public domain will be assigned to your application during the deployment (see `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#connecting-from-the-internet"}),`Connecting from the internet section`),`)`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`If Publicly Exposed is selected:`,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",{parentName:"li"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`External port: it is the port that can be used to access this service over the internet (when exposed publicly). Note that for HTTP and gRPC the port is set by default to 443.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Port Name: it is the name assigned to the port. When multiple ports are exposed publicly, its value is used to route the traffic to the right port based on the called subdomain (which will contain the port name value). Since each port is exposed on the port 443, having a different subdomain is the only way to have multiple ports exposed over the internet. If not set, the default value is `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`p`),` (see `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#qovery-provided-domains"}),`Qovery Provided Domain section`),` for more information)`)))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/app-15.png",alt:"Application Ports"})),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"important-informations"},`Important Informations`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Most of the Kubernetes Health Checks]`,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/service-health-checks/"}),`docs.using-qovery.configuration.service-health-checks`),` are based on the port declared in this section. Make sure you declare the right port and that you configure the health checks properly.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Connections on public ports are automatically closed after 60 seconds. If you want to implement long living connection (like for websockets) please make sure to use the rigth ingress timeouts in the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"/docs/using-qovery/configuration/advanced-settings/#network-settings"}),`advanced settings section`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`Exposing publicly TCP/UDP ports requires to create a dedicated load balancer and it takes a few minutes before having it ready (~15 minutes). Note also that this has a direct impact on your cloud provider bill.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You can configure your application to use the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"li"},`PORT`),` environment variable by adding the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"li"},`PORT`),` on your application env variables page.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`A Note on Listening IPs: It's best for your application to listen on `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`0.0.0.0:$PORT`),`. While most things work with `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`127.0.0.1`),` and `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`localhost`),`, some do not (NodeJS for example)`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"health-checks"},`Health Checks`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`To know more about how to configure your Liveness and Readiness probes, have a look at `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/application-health-checks/"}),`the health-checks section`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"deployment-restrictions"},`Deployment Restrictions`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`This section allows to specify which changes on your repository should trigger an auto-deploy (if enabled). To know more about how to configure your Deployment Restrictions, have a look at the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/deployment/deploying-with-auto-deploy/#filtering-commits-triggering-the-auto-deploy"}),`deployment restrictions section`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"connecting-from-the-internet"},`Connecting from the internet`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Your application can be reached from the internet by publicly exposing at least one of its ports (See the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"#ports"}),`Ports`),` section to know more). Once this is done, Qovery will generate and assign a domain to your application (See `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"#qovery-provided-domains"}),`this section`),` to know more). You can customize the domain assigned to your application via the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`Domain`),` section in the settings (see `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"#custom-domains"}),`this section`),` to know more).`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"qovery-provided-domains"},`Qovery provided domains`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`For each port publicly exposed, a domain is automatically assigned by Qovery to your application. Qovery will manage for you the networking and the TLS configuration for these domains. `),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Example: `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`p80-zdf72de72-z709e1a88-gtw.za8ad0657.bool.sh`),` or `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`-p80-zdf72de72-z709e1a88-gtw.za8ad0657.bool.sh`),` for helm services.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Note:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`each service deployed on the same cluster will have the same root domain assigned (example: `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`za8ad0657.bool.sh`),`)`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`the first characters of the domain (before the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`-`),`) is based on the portName given to the port associated with this domain (See the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#ports"}),`port section`),`)`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`a default domain (without the portName) is assigned to the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`default port`),`(See the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#ports"}),`port section`),`). Example `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`zdf72de72-z709e1a88-gtw.za8ad0657.bool.sh`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`Special Case - Preview Environment`),` For each port exposed publicly, an additional domain will be created with the following pattern `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`portName-prId-srvName-envSourceName.cluster_domain`),`:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`portName: is the port name, as explained above`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`prID: is the id of the PR that has generated the preview environment`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`srvName: is the name of the service`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`envSourceName: is the name of the blueprint environment that has created the current preview environment`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`domain example: `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`p80-123-frontend-blueprint.za8ad0657.bool.sh`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"custom-domains"},`Custom domains`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you prefer to assign your own domain to the application, you can customize it from the "Domain" section within the application settings.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`You can customize the domain of your application in different ways, depending on what you want to achieve:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You want to use your own domain for your application`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You want to modify the subdomain assigned to your application by Qovery (i.e. change `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`p80-zdf72de72-z709e1a88-gtw.za8ad0657.bool.sh`),` into `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"li"},`my-app-domain.za8ad0657.bool.sh`),`). See `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"#qovery-provided-domains"}),`this section`),` to know more about these domains.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`In both cases, you can assign the new custom domain by pressing the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`Add Domain`),` button.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/app-16.png",alt:"Application Domains"})),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`This configuration will be `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`automatically removed`),` on every cloned environment or preview environment in order to avoid domain collision.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`For each custom domain, a green checkmark will appear if the domain is correctly configured. You can perform another check by clicking on the checkmark. If you're behind a CDN, we will only check if your custom domain resolves to an IP address.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/domain_check.png",alt:"Check Domains"})),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If there's an issue with a domain, a global error message will be displayed, and you can view the error details by hovering over the red cross. After correcting your configuration, you can perform another check by clicking on the red cross.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/domain_check_error.png",alt:"Check Domains"})),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"configuring-your-own-domain"},`Configuring your own domain`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Once the domain is added within the Qovery console (Example: mydomain.com), you need to configure within your DNS two `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`CNAME`),` records pointing to the domain provided by Qovery, as shown in the UI (example: mydomain.com CNAME za7cc1b71-z4b8474b3-gtw.zc531a994.rustrocks.cloud and *.mydomain.com CNAME za7cc1b71-z4b8474b3-gtw.zc531a994.rustrocks.cloud). `),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Having a wildcard domain entry (example: *.mydomain.com) configured on your DNS will avoid you to modify the Qovery setup every time you want to add a new subdomain. If `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`wildcard`),` is not supported by your DNS provider, you will have to configure each subdomain manually.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If a service needs to expose more than one port publicly, you can define a dedicated subdomain to redirect the traffic on the right port by setting the “Port Name” value within the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"#ports"}),`port settings`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`After re-deploying the service, Qovery will automatically handle the TLS/SSL certificate creation and renewal for the configured domain.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/custom-domain.png",alt:"Custom Domain"})),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Alert__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{type:"info",mdxType:"Alert"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/guides/getting-started/setting-custom-domain/"}),`We prepared a guide and video tutorial that explains how to set up your custom domain.`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},` Special case - domain behind a CDN `)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If your service is behind a CDN using a `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`proxy mode`),` (i.e. the traffic is routed through the CDN to Qovery), make sure to enable the option `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("inlineCode",{parentName:"p"},`Domain behind a CDN`),` and disable the option "Generate certificate" on the domain setup. Since the certificate of your domain is directly managed by the CDN, Qovery won't be able to do that for you and it will raise warnings on your application status.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",{align:"center"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("img",{src:"/img/configuration/application/cdn-proxy.png",alt:"CDN Proxy"})),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you are using Cloudflare to manage your CDN, we can also manage automatically your custom domain configuration via a wildcard domain setup for the whole cluster. Check our `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"/docs/using-qovery/configuration/clusters/#use-custom-domain-and-wildcard-tls-for-the-whole-cluster-beta"}),`documentation here`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h4",{"id":"change-the-auto-assigned-sub-domain"},`Change the auto assigned sub-domain`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`You can specify a different sub-domain for your application as long as it belongs to the assigned cluster domain (see `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"#qovery-provided-domains"}),`Qovery provided domains`),`). @@ -54668,7 +54667,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3); /* harmony import */ var _site_src_components_Jump__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8); /* harmony import */ var _site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(6); -const frontMatter={last_modified_on:'2022-05-04',$schema:'/.meta/.schemas/guides.json',title:'How to write a Dockerfile',description:'How to write your first Dockerfile in order to deploy your application with Qovery',author_github:'https://github.com/MacLikorne',tags:['type: tutorial','technology: docker'],hide_pagination:true};const metadata={"categories":[{"name":"tutorial","title":"Tutorial","description":"Additional step-by-step resources to leverage even more Qovery","permalink":"/guides/tutorial"}],"coverLabel":"How to write a Dockerfile","description":"How to write your first Dockerfile in order to deploy your application with Qovery","permalink":"/guides/tutorial/how-to-write-a-dockerfile","readingTime":"5 min read","source":"@site/guides/tutorial/how-to-write-a-dockerfile.md","tags":[{"label":"type: tutorial","permalink":"/guides/tags/type-tutorial"},{"label":"technology: docker","permalink":"/guides/tags/technology-docker"}],"title":"How to write a Dockerfile","truncated":false,"prevItem":{"title":"How To Use Lifecycle Job To Deploy Any Kind Of Resources","permalink":"/guides/tutorial/how-to-use-lifecycle-job-to-deploy-any-kind-of-resources"},"nextItem":{"title":"Import your environment variables with the Qovery CLI","permalink":"/guides/tutorial/import-your-environment-variables-with-the-qovery-cli"}};/* @jsx mdx */const rightToc=[{value:'My Sweet Dockerfile',id:'my-sweet-dockerfile',children:[{value:'FROM',id:'from',children:[]},{value:'WORKDIR',id:'workdir',children:[]},{value:'COPY',id:'copy',children:[]},{value:'RUN',id:'run',children:[]},{value:'EXPOSE',id:'expose',children:[]},{value:'CMD',id:'cmd',children:[]},{value:'Build your image',id:'build-your-image',children:[]},{value:'Test your image',id:'test-your-image',children:[]}]},{value:'What's next?',id:'whats-next',children:[]}];const makeShortcode=name=>function MDXDefaultShortcode(props){console.warn("Component "+name+" was not imported, exported, or provided by MDXProvider as global scope");return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",props);};const layoutProps={rightToc};const MDXLayout="wrapper";function MDXContent({components,...props}){return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(MDXLayout,Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({},layoutProps,props,{components:components,mdxType:"MDXLayout"}),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`With Qovery, there are two ways to build and deploy your application:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Without a Dockerfile in your repository: your application is built with `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"https://docs.qovery.com/docs/using-qovery/configuration/application/#option-1-buildpacks"}),`Buildpacks`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`With a Dockerfile: sometimes Buildpacks won't fit your specific setup, and you'll have to write your Dockerfile.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`In this article, we'll see, step by step, how to quickly write a proper Dockerfile for any application you would like to deploy.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{name:"guide",mdxType:"Assumptions"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You have installed the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"https://docs.qovery.com/docs/using-qovery/interface/cli/"}),`Qovery CLI`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You host your code on Github`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("hr",null),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"my-sweet-dockerfile"},`My Sweet Dockerfile`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you read this, you probably don't know why Docker is used and what is the purpose of a Dockerfile.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Docker is a container engine, building and using images to deploy applications in containers. It looks like virtualization, and each container could be compared to a virtual machine with the minimal setup to run an application.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The Dockerfile is your image builder recipe. When Docker uses it, it will follow all instructions to `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`build your application and run it`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The first step is to create a file named `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`Dockerfile`),` at your project root level so Qovery would be able to find and use it.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Also, to avoid unwanted files from your repository (images, .idea, DS_Store etc.), you need to add a `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`.dockerignore`),`. It will prevent heavy copy tasks of useless files, mostly your project dependencies and libraries you'll get back to with your package manager.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`.dockerignore`),` file works like the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`.gitignore`),`, so add all the path of the useless files and folders in it.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"from"},`FROM`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The first line you'll add in your Dockerfile is `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`FROM`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`It will pull an already existing image from `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://hub.docker.com/"}),`Docker Hub`),`. You should most of the time use an image that fits your application language (Node, Python, Java, etc.), but you can go a step backward and begin with a simple Linux image.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Your Dockerfile's first line should look like this:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{}),`FROM : +const frontMatter={last_modified_on:'2024-09-18',$schema:'/.meta/.schemas/guides.json',title:'How to write a Dockerfile',description:'How to write your first Dockerfile in order to deploy your application with Qovery',author_github:'https://github.com/MacLikorne',tags:['type: tutorial','technology: docker'],hide_pagination:true};const metadata={"categories":[{"name":"tutorial","title":"Tutorial","description":"Additional step-by-step resources to leverage even more Qovery","permalink":"/guides/tutorial"}],"coverLabel":"How to write a Dockerfile","description":"How to write your first Dockerfile in order to deploy your application with Qovery","permalink":"/guides/tutorial/how-to-write-a-dockerfile","readingTime":"5 min read","source":"@site/guides/tutorial/how-to-write-a-dockerfile.md","tags":[{"label":"type: tutorial","permalink":"/guides/tags/type-tutorial"},{"label":"technology: docker","permalink":"/guides/tags/technology-docker"}],"title":"How to write a Dockerfile","truncated":false,"prevItem":{"title":"How To Use Lifecycle Job To Deploy Any Kind Of Resources","permalink":"/guides/tutorial/how-to-use-lifecycle-job-to-deploy-any-kind-of-resources"},"nextItem":{"title":"Import your environment variables with the Qovery CLI","permalink":"/guides/tutorial/import-your-environment-variables-with-the-qovery-cli"}};/* @jsx mdx */const rightToc=[{value:'My Sweet Dockerfile',id:'my-sweet-dockerfile',children:[{value:'FROM',id:'from',children:[]},{value:'WORKDIR',id:'workdir',children:[]},{value:'COPY',id:'copy',children:[]},{value:'RUN',id:'run',children:[]},{value:'EXPOSE',id:'expose',children:[]},{value:'CMD',id:'cmd',children:[]},{value:'Build your image',id:'build-your-image',children:[]},{value:'Test your image',id:'test-your-image',children:[]}]},{value:'What's next?',id:'whats-next',children:[]}];const makeShortcode=name=>function MDXDefaultShortcode(props){console.warn("Component "+name+" was not imported, exported, or provided by MDXProvider as global scope");return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",props);};const layoutProps={rightToc};const MDXLayout="wrapper";function MDXContent({components,...props}){return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(MDXLayout,Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({},layoutProps,props,{components:components,mdxType:"MDXLayout"}),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`In this article, we'll see, step by step, how to quickly write a proper Dockerfile for any application you would like to deploy.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{name:"guide",mdxType:"Assumptions"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You have installed the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"https://docs.qovery.com/docs/using-qovery/interface/cli/"}),`Qovery CLI`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You host your code on Github`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("hr",null),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"my-sweet-dockerfile"},`My Sweet Dockerfile`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you read this, you probably don't know why Docker is used and what is the purpose of a Dockerfile.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Docker is a container engine, building and using images to deploy applications in containers. It looks like virtualization, and each container could be compared to a virtual machine with the minimal setup to run an application.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The Dockerfile is your image builder recipe. When Docker uses it, it will follow all instructions to `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`build your application and run it`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The first step is to create a file named `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`Dockerfile`),` at your project root level so Qovery would be able to find and use it.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Also, to avoid unwanted files from your repository (images, .idea, DS_Store etc.), you need to add a `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`.dockerignore`),`. It will prevent heavy copy tasks of useless files, mostly your project dependencies and libraries you'll get back to with your package manager.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`.dockerignore`),` file works like the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`.gitignore`),`, so add all the path of the useless files and folders in it.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"from"},`FROM`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The first line you'll add in your Dockerfile is `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`FROM`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`It will pull an already existing image from `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://hub.docker.com/"}),`Docker Hub`),`. You should most of the time use an image that fits your application language (Node, Python, Java, etc.), but you can go a step backward and begin with a simple Linux image.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Your Dockerfile's first line should look like this:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{}),`FROM : `)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`For example, with `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://hub.docker.com/_/python"}),`python`),`:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{}),`FROM python:3 `)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"workdir"},`WORKDIR`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Since most of the images are Linux-based, a good practice is to set up a directory you'll work in. That's the purpose of the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`WORKDIR`),` line. It defines a directory and moves you in:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{}),`FROM : WORKDIR /app @@ -56534,7 +56533,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _site_src_components_Alert__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3); /* harmony import */ var _site_src_components_Jump__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8); /* harmony import */ var _site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(6); -const frontMatter={last_modified_on:'2022-05-04',$schema:'/.meta/.schemas/guides.json',title:'How to write a Dockerfile',description:'How to write your first Dockerfile in order to deploy your application with Qovery',author_github:'https://github.com/MacLikorne',tags:['type: tutorial','technology: docker'],hide_pagination:true};const metadata={"categories":[{"name":"tutorial","title":"Tutorial","description":"Additional step-by-step resources to leverage even more Qovery","permalink":"/guides/tutorial"}],"coverLabel":"How to write a Dockerfile","description":"How to write your first Dockerfile in order to deploy your application with Qovery","permalink":"/guides/tutorial/how-to-write-a-dockerfile","readingTime":"5 min read","source":"@site/guides/tutorial/how-to-write-a-dockerfile.md","tags":[{"label":"type: tutorial","permalink":"/guides/tags/type-tutorial"},{"label":"technology: docker","permalink":"/guides/tags/technology-docker"}],"title":"How to write a Dockerfile","truncated":false,"prevItem":{"title":"How To Use Lifecycle Job To Deploy Any Kind Of Resources","permalink":"/guides/tutorial/how-to-use-lifecycle-job-to-deploy-any-kind-of-resources"},"nextItem":{"title":"Import your environment variables with the Qovery CLI","permalink":"/guides/tutorial/import-your-environment-variables-with-the-qovery-cli"}};/* @jsx mdx */const rightToc=[{value:'My Sweet Dockerfile',id:'my-sweet-dockerfile',children:[{value:'FROM',id:'from',children:[]},{value:'WORKDIR',id:'workdir',children:[]},{value:'COPY',id:'copy',children:[]},{value:'RUN',id:'run',children:[]},{value:'EXPOSE',id:'expose',children:[]},{value:'CMD',id:'cmd',children:[]},{value:'Build your image',id:'build-your-image',children:[]},{value:'Test your image',id:'test-your-image',children:[]}]},{value:'What's next?',id:'whats-next',children:[]}];const makeShortcode=name=>function MDXDefaultShortcode(props){console.warn("Component "+name+" was not imported, exported, or provided by MDXProvider as global scope");return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",props);};const layoutProps={rightToc};const MDXLayout="wrapper";function MDXContent({components,...props}){return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(MDXLayout,Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({},layoutProps,props,{components:components,mdxType:"MDXLayout"}),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`With Qovery, there are two ways to build and deploy your application:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ol",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`Without a Dockerfile in your repository: your application is built with `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"https://docs.qovery.com/docs/using-qovery/configuration/application/#option-1-buildpacks"}),`Buildpacks`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ol"},`With a Dockerfile: sometimes Buildpacks won't fit your specific setup, and you'll have to write your Dockerfile.`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`In this article, we'll see, step by step, how to quickly write a proper Dockerfile for any application you would like to deploy.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{name:"guide",mdxType:"Assumptions"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You have installed the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"https://docs.qovery.com/docs/using-qovery/interface/cli/"}),`Qovery CLI`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You host your code on Github`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("hr",null),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"my-sweet-dockerfile"},`My Sweet Dockerfile`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you read this, you probably don't know why Docker is used and what is the purpose of a Dockerfile.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Docker is a container engine, building and using images to deploy applications in containers. It looks like virtualization, and each container could be compared to a virtual machine with the minimal setup to run an application.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The Dockerfile is your image builder recipe. When Docker uses it, it will follow all instructions to `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`build your application and run it`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The first step is to create a file named `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`Dockerfile`),` at your project root level so Qovery would be able to find and use it.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Also, to avoid unwanted files from your repository (images, .idea, DS_Store etc.), you need to add a `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`.dockerignore`),`. It will prevent heavy copy tasks of useless files, mostly your project dependencies and libraries you'll get back to with your package manager.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`.dockerignore`),` file works like the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`.gitignore`),`, so add all the path of the useless files and folders in it.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"from"},`FROM`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The first line you'll add in your Dockerfile is `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`FROM`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`It will pull an already existing image from `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://hub.docker.com/"}),`Docker Hub`),`. You should most of the time use an image that fits your application language (Node, Python, Java, etc.), but you can go a step backward and begin with a simple Linux image.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Your Dockerfile's first line should look like this:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{}),`FROM : +const frontMatter={last_modified_on:'2024-09-18',$schema:'/.meta/.schemas/guides.json',title:'How to write a Dockerfile',description:'How to write your first Dockerfile in order to deploy your application with Qovery',author_github:'https://github.com/MacLikorne',tags:['type: tutorial','technology: docker'],hide_pagination:true};const metadata={"categories":[{"name":"tutorial","title":"Tutorial","description":"Additional step-by-step resources to leverage even more Qovery","permalink":"/guides/tutorial"}],"coverLabel":"How to write a Dockerfile","description":"How to write your first Dockerfile in order to deploy your application with Qovery","permalink":"/guides/tutorial/how-to-write-a-dockerfile","readingTime":"5 min read","source":"@site/guides/tutorial/how-to-write-a-dockerfile.md","tags":[{"label":"type: tutorial","permalink":"/guides/tags/type-tutorial"},{"label":"technology: docker","permalink":"/guides/tags/technology-docker"}],"title":"How to write a Dockerfile","truncated":false,"prevItem":{"title":"How To Use Lifecycle Job To Deploy Any Kind Of Resources","permalink":"/guides/tutorial/how-to-use-lifecycle-job-to-deploy-any-kind-of-resources"},"nextItem":{"title":"Import your environment variables with the Qovery CLI","permalink":"/guides/tutorial/import-your-environment-variables-with-the-qovery-cli"}};/* @jsx mdx */const rightToc=[{value:'My Sweet Dockerfile',id:'my-sweet-dockerfile',children:[{value:'FROM',id:'from',children:[]},{value:'WORKDIR',id:'workdir',children:[]},{value:'COPY',id:'copy',children:[]},{value:'RUN',id:'run',children:[]},{value:'EXPOSE',id:'expose',children:[]},{value:'CMD',id:'cmd',children:[]},{value:'Build your image',id:'build-your-image',children:[]},{value:'Test your image',id:'test-your-image',children:[]}]},{value:'What's next?',id:'whats-next',children:[]}];const makeShortcode=name=>function MDXDefaultShortcode(props){console.warn("Component "+name+" was not imported, exported, or provided by MDXProvider as global scope");return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("div",props);};const layoutProps={rightToc};const MDXLayout="wrapper";function MDXContent({components,...props}){return Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(MDXLayout,Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({},layoutProps,props,{components:components,mdxType:"MDXLayout"}),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`In this article, we'll see, step by step, how to quickly write a proper Dockerfile for any application you would like to deploy.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])(_site_src_components_Assumptions__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"],{name:"guide",mdxType:"Assumptions"},Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("ul",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You have installed the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"li"},{"href":"https://docs.qovery.com/docs/using-qovery/interface/cli/"}),`Qovery CLI`)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("li",{parentName:"ul"},`You host your code on Github`))),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("hr",null),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h2",{"id":"my-sweet-dockerfile"},`My Sweet Dockerfile`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`If you read this, you probably don't know why Docker is used and what is the purpose of a Dockerfile.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Docker is a container engine, building and using images to deploy applications in containers. It looks like virtualization, and each container could be compared to a virtual machine with the minimal setup to run an application.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The Dockerfile is your image builder recipe. When Docker uses it, it will follow all instructions to `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`build your application and run it`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The first step is to create a file named `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`Dockerfile`),` at your project root level so Qovery would be able to find and use it.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Also, to avoid unwanted files from your repository (images, .idea, DS_Store etc.), you need to add a `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`.dockerignore`),`. It will prevent heavy copy tasks of useless files, mostly your project dependencies and libraries you'll get back to with your package manager.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`.dockerignore`),` file works like the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`.gitignore`),`, so add all the path of the useless files and folders in it.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"from"},`FROM`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`The first line you'll add in your Dockerfile is `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`FROM`),`.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`It will pull an already existing image from `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://hub.docker.com/"}),`Docker Hub`),`. You should most of the time use an image that fits your application language (Node, Python, Java, etc.), but you can go a step backward and begin with a simple Linux image.`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Your Dockerfile's first line should look like this:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{}),`FROM : `)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`For example, with `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("a",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"p"},{"href":"https://hub.docker.com/_/python"}),`python`),`:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{}),`FROM python:3 `)),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("h3",{"id":"workdir"},`WORKDIR`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("p",null,`Since most of the images are Linux-based, a good practice is to set up a directory you'll work in. That's the purpose of the `,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("strong",{parentName:"p"},`WORKDIR`),` line. It defines a directory and moves you in:`),Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("pre",null,Object(_mdx_js_react__WEBPACK_IMPORTED_MODULE_2__[/* mdx */ "b"])("code",Object(_home_runner_work_documentation_documentation_website_node_modules_babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])({parentName:"pre"},{}),`FROM : WORKDIR /app