├── .github └── workflows │ └── website-publish.yml ├── .gitignore ├── README.md ├── docs ├── app-configuration.md ├── app-scaling-and-cluster.md ├── backup-and-restore.md ├── best-practices.md ├── captain-definition-file.md ├── cdd-migration.md ├── certbot-config.md ├── ci-cd-integration.md ├── ci-cd-integration │ ├── deploy-from-github.md │ └── deploy-from-gitlab.md ├── cli-commands.md ├── complete-webapp-tutorial.md ├── database-connection.md ├── deployment-methods.md ├── disk-cleanup.md ├── docker-compose.md ├── firewall.md ├── get-started.md ├── nginx-customization.md ├── one-click-apps.md ├── persistent-apps.md ├── play-with-docker.md ├── pre-deploy-script.md ├── recipe-deploy-create-react-app.md ├── resource-monitoring.md ├── run-locally.md ├── sample-apps.md ├── server-purchase │ ├── digitalocean.md │ └── openstack.md ├── service-update-override.md ├── stateless-with-persistent-data.md ├── support.md ├── theme-customization.md ├── troubleshooting-pro.md ├── troubleshooting.md └── zero-downtime.md ├── graphics ├── caprover-logo │ ├── image823-6.jpg │ ├── image823-6.png │ ├── logo2-lrg.png │ └── text-libel-suit.regular.png ├── captain-architecture.png ├── captain-architecture.svg ├── captain-in-one-picture.png ├── captain-in-one-picture.svg ├── logo.svg ├── screenshots-video-small.gif ├── screenshots-video-small.png ├── screenshots-video.gif ├── screenshots.gif ├── screenshots │ ├── Screenshot from 2019-01-29 20-41-11.png │ ├── Screenshot from 2019-01-29 20-41-33.png │ ├── Screenshot from 2019-01-29 20-42-08.png │ ├── Screenshot from 2019-01-29 20-42-20.png │ └── Screenshot from 2019-01-29 20-42-31.png ├── twitter-cover.png ├── twitter.png ├── twitter.pxd ├── twitter_cover-2.png └── twitter_cover.png └── website ├── CNAME ├── build_dir ├── core └── Footer.js ├── i18n └── en.json ├── package-lock.json ├── package.json ├── pages ├── email-sub.html ├── en │ ├── help.js │ └── index.js └── googlea598efcb1b249f09.html ├── publish-from-actions.sh ├── publish_to_github_pages.js ├── sidebars.json ├── siteConfig.js └── static ├── css └── custom.css └── img ├── captain-architecture.png ├── captain-in-one-picture.png ├── do-btn-blue.svg ├── docs ├── app-deploy.png ├── app-http.png ├── app-vars.png ├── deploy-from-github │ ├── adding-a-secret.png │ ├── create-a-new-app.png │ ├── create-github-secrets.png │ └── enable-app-token.png ├── gmail-1.png ├── gmail-2.png ├── label-path.png ├── nextcloud-deploy-manually.png ├── one-click.gif └── path-binding.png ├── favicon.ico ├── favicon └── favicon.ico ├── icon ├── customize.png ├── dev.png ├── money.png ├── server.png ├── setup.png └── time.png ├── logo-padded-250px.png ├── logo-padded.png ├── logo.png ├── netdata.gif ├── pwd-caprover.gif ├── screenshot.png ├── screenshots-video.gif └── themes.gif /.github/workflows/website-publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish website 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v1 12 | - uses: actions/setup-node@v1 13 | with: 14 | node-version: 10 15 | - run: cd website && ls -la && npm i && npm run clean-build && ./publish-from-actions.sh 16 | env: 17 | GITHUB_PERSONAL_TOKEN: ${{secrets.GITHUB_PERSONAL_TOKEN}} 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | 3 | website/.idea 4 | website/translated_docs 5 | website/build/ 6 | website/node_modules 7 | website/i18n/* 8 | !website/i18n/en.json 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CapRover Website 2 | Website and Docs for CapRover. 3 | 4 | ### Development 5 | 6 | ``` 7 | cd website 8 | npm i 9 | npm start 10 | ``` 11 | 12 | ### Adding New Docs 13 | 14 | Add the new MarkDown file in `/docs` directory. Add the listing to `/website/sidebars.json`. Then run `yarn start` to see the result. 15 | 16 | 17 | ### Build 18 | 19 | Simply run `yarn build` and all data will be converted into static html files inside `website/build` directory. 20 | -------------------------------------------------------------------------------- /docs/app-configuration.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: app-configuration 3 | title: App Configuration 4 | sidebar_label: App Configuration 5 | --- 6 | 7 |
8 | 9 | ## HTTP Settings 10 | 11 | This is where all HTTP related stuff sits. If your app is not an HTTP app, you can simply check "Do not expose as web app". This is used for anything that is not a webapp, like a database such as MongoDB or MySQL. 12 | 13 | ![httpsettings](/img/docs/app-http.png) 14 | 15 | By default, any webapp that you deploy gets a Captain domain assigned to it in this format: `appname.root.domain.com`. However, you have the option to add as many domains as you want to this app. For example, you can add `www.myawesomeapp.com` and `myawesomeapp.com`. 16 | 17 | There are also some advanced options such as Edit Default Nginx config and Container HTTP Port which you usually do not need to edit. 18 | 19 | #### Enabling HTTPS 20 | 21 | CapRover has built-in support for Let's Encrypt and it enables you to easily put your websites behind secure HTTPS without being concerned with the cost of SSL certificates (Let's Encrypt is free) and without any hassle of setting up configs and renewing certificates. 22 | 23 | To enable HTTPS for any domain, just click on enable HTTPS! It takes a few seconds and it's done! 24 | 25 | After enabling HTTPS, you can optionally, although very recommended, enforce HTTPS for all requests, i.e. denying plain insecure HTTP connections and redirect them to HTTPS. 26 | 27 | 28 | ## App Config 29 | 30 | This is where you can set runtime configuration and settings. 31 | 32 | ![appconfig](/img/docs/app-vars.png) 33 | 34 | ### Environment Variables 35 | 36 | One of the most basic configuration that you can set for your app is environment variables. These variables are usually used to pass in data that does not live in the code. Examples, include API key for a 3rd party service, database connection URI and etc. 37 | 38 | You can simply set the environmental variables on the dashboard and use them dynamically in your code, e.g., `process.env.VAR_NAME_HERE` for NodeJS, or `$_ENV["VAR_NAME_HERE"]` in PHP. 39 | 40 | If you'd like to access these variables during build time, you can use ARG command to your Dockerfile. 41 | 42 | ``` 43 | FROM imagename.... 44 | ARG VAR_NAME_HERE=${VAR_NAME_HERE} 45 | ENV VAR_NAME_HERE=${VAR_NAME_HERE} 46 | 47 | ## At this point, "VAR_NAME_HERE" is available as an env var during your build, 48 | ## you can do something like this: 49 | ## RUN echo $VAR_NAME_HERE 50 | ``` 51 | 52 | As well as the variables you set yourself, CapRover will also set a `CAPROVER_GIT_COMMIT_SHA` environment variable to the full git commit SHA that is being deployed. This is only available during the Docker build and is not available inside your app by default. If you want to use it inside your app then you can use something like the following: 53 | 54 | ``` 55 | FROM imagename.... 56 | ARG CAPROVER_GIT_COMMIT_SHA=${CAPROVER_GIT_COMMIT_SHA} 57 | ENV CAPROVER_GIT_COMMIT_SHA=${CAPROVER_GIT_COMMIT_SHA} 58 | ``` 59 | 60 | ### Port Mapping 61 | 62 | CapRover allows you to map ports from a container to the host. You should use this feature if you want a specific port of your apps/containers to be publicly accessible. The most common use case is when you want to **connect to a database container from your local machine**. 63 | 64 | Note that even if you don't set any port mapping, all ports are accessible from other containers on the same Captain cluster. Therefore, you should only use this option if you want the port to be publicly accessible. Make sure to have the port open, see [firewall settings](firewall.md). 65 | 66 | For example, if you want your NodeJS app to access your MongoDB database, and you do not need to access your MongoDB from your laptop, you don't need Port Mapping. Instead, you can use the fully qualified name for the MongoDB instance which is `srv-captain--mongodb-app-name` (replace `mongodb-app-name` with the app name you used). 67 | 68 | ### Persistent Directories 69 | 70 | Only used for [persistent apps](persistent-apps.md). 71 | 72 | ### Node ID 73 | 74 | Only used for [persistent apps](persistent-apps.md). Persistent apps need to be locked down to a particular node (if you have a cluster of servers). NodeId defines what node this app should be locked down to. 75 | 76 | ### Service Tags 77 | 78 | _available as of 1.11_ 79 | 80 | You can mark caprover services with special tags. This allows you to better group and view your apps in the table. 81 | 82 | ### Instance Count 83 | 84 | How many instances of this app should run at the same time. You may run as many instances as you'd like. However, you are limited by your hardware. If you increase this number and you don't have enough RAM or Disk space, your system may crash. It is advised to consider performance implications before increasing this number. 85 | 86 | ### Predeploy Function 87 | 88 | This is a [very dangerous and advanced option](pre-deploy-script.md). Do not use it unless you really know what you are doing. 89 | -------------------------------------------------------------------------------- /docs/app-scaling-and-cluster.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: app-scaling-and-cluster 3 | title: App Scaling & Cluster 4 | sidebar_label: App Scaling & Cluster 5 | --- 6 | 7 |
8 | 9 | CapRover offers you multiple ways to scale up your app, running it on multiple processes to take advantage of all the resources on your server. 10 | 11 | ## Run Multiple Instances of App: 12 | 13 | Your Pizza app is doing great and you are getting thousands of hits on your website. Having one instance of your app is not good enough. Your latency has gone up. Next thing you want is to consider to run multiple instances of your app on your Captain. You can do this from the Apps section of Captain web. Let's say you change your instance count to 3. Captain creates 3 instances of your app running at the same time. If any of them dies (crashes), it automatically spins off a new one! You always have 3 instances of your Pizza app running! The best part? Captain automatically spreads the requests between different instances of your app. 14 | 15 | ## Run Multiple Servers: 16 | 17 | Wow! Your Pizza app is really popular! You have 3 instances of your app running on the same server, RAM and CPU are almost maxed out. You need to get a second server. How do you connect the servers? Captain does that for you ;-) You simply get a server with Docker installed on it, similar to what you did for the original Captain server. Make sure your shiny new server can be accessed via SSH from the original Captain server (e.g. by copying the Captain's ssh public key to your secondary server). 18 | 19 | CapRover uses [Docker Swarm](https://docs.docker.com/engine/swarm/) under the hood. It provides an option to use CapRover UI to set up a cluster of nodes. Alternatively, you can use plain Docker Swarm commands `docker swarm join...` commands to set up your cluster. There is absolutely no difference between the two methods. The first method uses UI and the second method uses command line. 20 | 21 | At this point, you have to enter the following information: 22 | 23 | - CapRover IP Address (as seen by remote): this is the IP address of your original server 24 | - New node IP Address (as seen by Captain): this is the IP address of your second server 25 | - Private SSH key for `root` user: this is the SSH key from your CapRover server that will be used to SSH to your second server. On Linux, it's on `/home/yourusername/.ssh/id_rsa` 26 | - Node type: this describes what the role of the new server is. Use `worker` if you're new to Docker, for more details, read https://docs.docker.com/engine/swarm/how-swarm-mode-works/nodes/ 27 | 28 | Now, go to the "Cluster" section of Captain, enter the values into fields of the "Nodes" area and click on Join Cluster. Done! You now have a real cluster of your own! You can now change the instance count to 6, and Captain will spin up some instances on the other server for you, also automatically load balances the request and creates new instances if one machine dies. 29 | 30 | The leader node is a manager who's been elected as Leader. This is the node where Captain and main services such as nginx and Certbot (Let's Encrypt) will be running on. All your apps automatically get distributed to nodes by docker swarm. 31 | 32 | Note that only apps without "Persistent Data" can be scaled across nodes. Apps that have "Persistent Data" enabled will only run on 1 node. 33 | 34 | ### Default Push Registry: 35 | 36 | Default Push Docker Registry is a Docker Registry where your apps will be stored in as soon as you deploy them to server. 37 | 38 | For cluster mode (more than one server) you will need to have a default push Docker Registry. 39 | 40 | ### Setup Docker Registry: 41 | 42 | Docker Registry is simply the repository that different nodes in a cluster can access to download your app and run it. If only have one server (no cluster), there is pretty much no benefit to setting up Docker Registry. 43 | 44 | On the other hand, Docker Registry needs to be set up and ready for clusters. To setup Registry, simply go to your Captain web dashboard, select Cluster from the menu, and follow the instructions. You will be given two options: 45 | 46 | - Docker Registry managed by Captain. 47 | - Docker Registry managed by a 3rd party provider. 48 | 49 | For most cases, a Registry managed by Captain should be good enough. Note that before switching to cluster from a single node, if you have any existing app, you will have to setup Registry and re-deploy all your existing app to make sure they are pushed to the registry and are available to all nodes, not just the main leader node. 50 | 51 | ### More than one Registry: 52 | 53 | You can be connected to more than one registry at a time. For example, you may be connect to a private Docker Registry on AWS and a private Docker Registry on DockerHub because some of your apps (images) are stored in your AWS private registry, some are on DockerHub. 54 | 55 | Having said that, you can only have one default push registry. This is the registry where images will be pushed to once they are built on the server. 56 | 57 | ### Disabling Registry: 58 | 59 | At any point in time, you have the option to: 60 | 61 | - Disable Registry 62 | - Delete Registry Auth Details 63 | 64 | However, note that if you have a cluster (more than one server), if you remove your docker registry your apps may misbehave. 65 | 66 | ### Add a Private Docker Registry: 67 | 68 | If you need to pull images from a private docker registry such as ghcr.io or dockerhub etc, you will need to provide CapRover with your credentials so that it can pull images. For example for ghcr.io you'll need the following: 69 | 70 | - Username: `` 71 | - Password: [a personal token that you create](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) - make sure it has access to read packages at least. 72 | - Domain: `ghcr.io` 73 | - Image Prefix: `` (MUST BE lowercase) 74 | 75 | If Docker images are stored as `your-username/your-image` then use your github username as the image prefix. Otherwise, if you have an organization in github where your images are stored as `my-org/my-image`, use `my-org` as your image prefix. 76 | 77 | You can setup your credentials under the **Cluster** menu. If you only intend to pull images, make sure to disable **Pushing New Images** 78 | -------------------------------------------------------------------------------- /docs/backup-and-restore.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: backup-and-restore 3 | title: Backup & Restore 4 | sidebar_label: Backup & Restore 5 | --- 6 | 7 | ### Backup & Restore 8 | 9 | _This feature was added in v1.3.0._ 10 | 11 | _Backup/Restore feature is still in experimental stage. More changes to come in the future._ 12 | 13 | Backup/restoration is a complicated process and requires understanding of how different components work in CapRover instance. If you plan to use this feature, make sure you read this document thoroughly, and practice with a test server and learn the process before actually using this feature in production. 14 | 15 | **TDLR;** Normal backup/restore works for everything except images and volumes. For images, you have to use a Docker Registry (has pros and cons), for volumes, you have to use a custom solution (has pros and cons). 16 | 17 | ### Backup Process 18 | 19 | On your working CapRover instance, open the web dashboard, navigate to settings page, and click on "Create Backup" button. After a few seconds download will start. Keep the tar file and you will use this when restoring the CapRover instance. 20 | 21 | #### Automating backup process 22 | 23 | You can create a simple bash script for automated backups: 24 | 25 | ```bash 26 | API_TOKEN=$(curl $CAPROVER_URL/api/v2/login \ 27 | -H 'x-namespace: captain' \ 28 | -H 'content-type: application/json;charset=UTF-8' \ 29 | --data-raw "{\"password\":\"$CAPROVER_PASSWORD\"}" \ 30 | --compressed --silent | jq -r ".data.token") 31 | 32 | DOWNLOAD_TOKEN=$(curl $CAPROVER_URL/api/v2/user/system/createbackup \ 33 | -H "x-captain-auth: $API_TOKEN" \ 34 | -H 'x-namespace: captain' \ 35 | --data-raw '{"postDownloadFileName":"backup.tar"}' \ 36 | --compressed --silent | jq -r ".data.downloadToken") 37 | 38 | if [ ${#DOWNLOAD_TOKEN} -le 10 ]; then 39 | echo "DOWNLOAD_TOKEN must be at least 10 char long" 40 | exit 1 41 | fi 42 | 43 | wget "$CAPROVER_URL/api/v2/downloads/?namespace=captain&downloadToken=$DOWNLOAD_TOKEN" -O backup.tar 44 | ``` 45 | 46 | ### Restoration Process 47 | 48 | This process is very similar to fresh installation of CapRover, except a few differences. Follow the steps for Prerequisites from [Get Started](get-started.md), and make sure you have Docker installed on a server. 49 | 50 | _DO NOT_ run the installation command `docker run -p 80:80 -p 443:443.....`. Instead do the following steps: 51 | 52 | _(replace 123.123.123.123 with your server IP in instructions below)_ 53 | 54 | 1. Create an empty `/captain` directory on your server by running
`ssh root@123.123.123.123 mkdir /captain` 55 | 2. Rename your desired backup file to `backup.tar` on your desktop. 56 | 3. Copy `backup.tar` to server:
`scp ./backup.tar root@123.123.123.123:/captain/` 57 | 4. Install CapRover: 58 | 59 | ```bash 60 | docker run -p 80:80 -p 443:443 -p 3000:3000 -e ACCEPTED_TERMS=true -v /var/run/docker.sock:/var/run/docker.sock -v /captain:/captain caprover/caprover 61 | ``` 62 | 63 | CapRover will automatically detect your `backup.tar`, extract it and restores all your configs and settings. 64 | 65 | 5. You need to configure your DNS such that `*.youroldroot.domain.com` points to the new server IP. 66 | 67 | ### Keeping Old Server 68 | 69 | In some cases, you still have the previous server running, and you just want to create a clone of your server. Since you want your old server to keep running, you shouldn't change your DNS for the old domain. Instead, you want to assign a new one. In this case: 70 | 71 | 1. Create a new wildcard entry in your DNS `*.yournewroot.domain.com` and point it to the new server 72 | 2. On your desktop machine, create a temporary entry in your `etc/hosts` file and add this line 73 | 74 | ``` 75 | NEW-SERVER-IP-ADDRESS captain.oldroot.domain.com 76 | ``` 77 | 78 | NOTE that you cannot use wild card in hosts file, just add the domain for the dashboard so you can access it temporarily. 79 | 80 | 3. go to `captain.oldroot.domain.com` in your browser and login to the dashboard. 81 | 82 | NOTE that you might see an SSL error, you can click on advance and ignore. This is fine as your SSL certification might have been expired. It will get renewed once you set everything up and restart CapRover. 83 | 84 | 4. After logging in to the dashboard, go ahead and change your root domain to `yournewroot.domain.com` on the dashboard. 85 | 86 | 5. Re-enable SSL certifications and Force HTTPS for your dashboard and other apps if you want. 87 | 88 | 6. Edit your `etc/hosts` and remove the line you added in step 2. 89 | 90 | ### What is Restored? 91 | 92 | CapRover backup process backs up everything in your `/captain/data/` directory. This includes your app settings, configurations, SSL certificates and etc. What it does not include are: **Container Images** and **Persistent Directories** 93 | 94 | 1. **Container Images:** After restoring an instance of CapRover, you will notice that your app configurations are set, however, all your apps are reverted to the default state of "Your App Will Be Here!". You do need to redeploy all your apps. The good things about this approach is that your `backup.tar` file is really small and manageable. The cons of this approach, of course, is having to perform a re-deploy for all your apps. If you really want the images to be saved in a backup, you need to use a [Docker Registry](#d-r). 95 | 2. **Persistent Directories:** Some apps, like databases, have a persistent directory. Since each database has its own backup mechanism. It is recommended to use the proper method of backup for your specific database, like `mongodump` for MongoDB or `mysqldump` for MySQL and etc. This is the best approach for databases as it does not cause a down time. The other approach is to create a snapshot of volumes. This approach is generic and works on pretty much everything. For example, you can use this [3rd Party Project](https://github.com/loomchild/volume-backup). However, before running this, to avoid data corruption, you need to make sure that your containers are stopped `docker service ls --format {{.Name}} | while read in; do docker service scale "$in"=0; done` and then take a snapshot then resume all services `docker service ls --format {{.Name}} | while read in; do docker service scale "$in"=1; done`. In near future, CapRover will have a built-in solution like this. 96 | Other useful tools for backing up your persistent directories are: 97 | 98 | - https://github.com/futurice/docker-volume-backup 99 | - https://github.com/loomchild/volume-backup 100 | - https://github.com/blacklabelops/volumerize 101 | - https://github.com/schickling/dockerfiles/tree/master/postgres-backup-s3 102 | - https://github.com/schickling/dockerfiles/tree/master/mysql-backup-s3 103 | 104 |
105 | Docker Registry 106 | 107 | 108 | ### Docker Registry Instructions 109 | 110 | As noted above, container images are not part of the backup. To ensure that your apps do not require a re-deploy after the restoration process, you need to make sure that you're using a Docker Registry. A Docker Registry is a place where images for your apps will be stored. 111 | 112 | #### 3rd Party Registry 113 | 114 | If you set the "default push registry" in your CapRover dashboard under Cluster section, every image will get pushed to the registry once it's built on the server. This is the best option as it's a separate entity and you are not responsible for keeping your images. Once you restore your CapRover instance, everything just works like a charm! 115 | 116 | #### Self Hosted Registry 117 | 118 | If you set the "default push registry" to CapRover self-hosted registry, your app will work out of the box after the restoration process. However, on the negative side, your `backup.tar` will be very big. This file will include all images that are built on your server. 119 | 120 | If you had previously set the self-hosted registry, but you changed your mind and disabled the self-hosted registry to switched to a 3rd party registry, your backup files will still be big as the files are still sitting on your host system. If you want to purge all images stored in your registry, delete the registry directory `rm -rf /captain/data/registry` 121 | 122 |
123 | 124 |
125 | Multi-Node setup 126 | 127 | 128 | ### Multi Nodes 129 | 130 | What happens when you have a cluster? Backup and restoration process is pretty much the same as single node, except during the restoration, the first run exits after it detects that you're trying to restore a cluster. Your are asked to edit a file and add IP addresses of new nodes. 131 | 132 | For example, previously you had 2 nodes: 133 | 134 | - 222.222.222.10 (Main node) 135 | - 222.222.222.11 136 | 137 | For restoration you have prepared 2 nodes: 138 | 139 | - 222.222.222.20 (Main node) 140 | - 222.222.222.21 141 | 142 | You run the restoration script on `222.222.222.20` and the script exits asking you to enter the information for the second node. You edit the restoration instructions file and enter `222.222.222.21` as the new IP for the old IP of `222.222.222.11`. 143 | 144 | Next, you need to copy your private key (usually named `id_rsa`) to your server. For example, on linux: 145 | 146 | ```bash 147 | scp /home/myuser/.ssh/id_rsa root@123.123.123.123:/captain/ 148 | ``` 149 | 150 | _Make sure to delete this file from the server once the restoration process is finished_ 151 | 152 | Now re-run the restoration script (the same one that exited and asked for more info). Now this process goes through and your nodes will be restored, apps will be adjusted to move to the new nodes. For example if previously, you had a persistent app locked on the second node, it'll be locked to the second node in the restored instance as well. 153 | 154 | Volume restoration for the cluster is a bit more complicated. But if you are using a cluster, you probably know what you are doing :-) 155 | 156 |
157 | -------------------------------------------------------------------------------- /docs/best-practices.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: best-practices 3 | title: Best Practices 4 | sidebar_label: Best Practices 5 | --- 6 | 7 | CapRover is designed to be easy to use and intuitive. Having said that, there are a few tips and tricks that can help you get the most out of CapRover. 8 | 9 | ### Hidden Root Domain 10 | 11 | It's always a good practice to hide your tech stack from the potential attacker. To be extra secure, you can hide your root domain two levels deeper than your wildcard DNS settings. For example on your DNS panel you set 12 | 13 | ```bash 14 | A RECORD: 15 | 16 | *.server.domain.com >>>> 123.123.123.123 17 | ``` 18 | 19 | Then when setting up CapRover, instead of entering `server.domain.com`, enter `something.server.domain.com`. This way, you can access the dashboard via `captain.something.server.domain.com` and not `captain.server.domain.com`. You can then set your app's domain to `myapp.server.domain.com` under the app's HTTP settings to hide your root domain. 20 | 21 | Keep in mind this is not a shield that protects you from everything. It's just a security measure that makes it harder, and nearly impractical for some brute force attackers to attack your CapRover infrastructure. 22 | 23 | ### Custom Default Password 24 | 25 | CapRover uses `captain42` as its default password. This is usually safe as you can change your password by running `caprover serversetup` from your local machine right after the server installation is finished. However, this leaves a small window of 30 seconds or so for the attacker to change your password before you. This is very unlikely, but it's possible for this attack to happen. The attacker needs to know the exact attack window on a particular machine. Anyways, to mitigate this risk, simply choose a custom initial password when installing CapRover by adding `DEFAULT_PASSWORD` env var to the installation script. For example, the script below changes the default password from `captain42` to `myinitialpassword` 26 | 27 | ```bash 28 | docker run -e ACCEPTED_TERMS=true -e DEFAULT_PASSWORD='myinitialpassword' -p 80:80 -p 443:443 -p 3000:3000 -v /var/run/docker.sock:/var/run/docker.sock -v /captain:/captain caprover/caprover 29 | ``` 30 | 31 | ### Enforce HTTPS 32 | 33 | It is highly recommended that one of the first things you do is to enable HTTPS and enable "Enforce HTTPS" for your CapRover dashboard. After you've done all these, you should change your password. Note that if you are using `caprover serversetup` wizard, you will be doing this process automatically, no need to change your password after the setup. 34 | 35 | ### Use Service Accounts for Git 36 | 37 | One of the most popular features of CapRover is the automatic deployment from source control (GitHub, BitBucket, GitLab and etc...). For this approach to work with a private repository, you have to enter your username/password and they will be kept as encrypted content on your server. It is always a good practice to create a service account (bot account) on GitHub and etc, and give that account specific permission (read only) to certain repositories only. Such that if that account was compromised, your main owner account remains intact and you can remove the compromised account from the repo. 38 | 39 | ### Out of Memory when Building 40 | 41 | When you build on a paid service such as Heroku, your build process happens on a machine with high CPU and RAM. When you use CapRover, your build is done on the same machine that serves your app. This is not a problem until your app gets too big and the build process requires too much RAM. In that case, your build process might crash! See [**this**](https://github.com/caprover/caprover/issues/315) for example. There are multiple solutions: 42 | 43 | 1- Add swap space to the web server, explained [**here**](https://www.digitalocean.com/community/tutorials/how-to-add-swap-space-on-ubuntu-16-04). 44 | 45 | 2- Build on your local machine. For example, this process is explained in detail [**here**](recipe-deploy-create-react-app.md) for Create React App. 46 | 47 | 3- However, **the best solution** is to use a separate build system. You can see the guide [**here**](ci-cd-integration.md) 48 | 49 | ### Customize the NGINX Config for new apps 50 | 51 | Moved to https://caprover.com/docs/nginx-customization.html#customize-and-override-the-nginx-config-for-all-apps 52 | 53 | This section is kept here to avoid link breaking. 54 | -------------------------------------------------------------------------------- /docs/captain-definition-file.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: captain-definition-file 3 | title: Captain Definition File 4 | sidebar_label: Captain Definition File 5 | --- 6 | 7 |
8 | ## Basics 9 | One of the key components of CapRover is the `captain-definition` file that sits at the root of your project. In case of NodeJS app, it sits next to package.json, or next to index.php in case of PHP, or requirements.txt for Python app. It's a simple JSON like this: 10 | 11 | 12 | ``` 13 | { 14 | "schemaVersion": 2, 15 | "templateId": "node/8.7.0" 16 | } 17 | ``` 18 | 19 | `schemaVersion` is always 2. And `templateId` is the piece which defines the foundation you need in order to run your app. It is in `LANGUAGE/VERSION` format. LANGUAGE can be one of these: `node`, `php`, `python-django`, `ruby-rack`. And VERSION is the version of the language you want to use - see [below](#versions-for-templateid). 20 | 21 | Note that although the `templateId` can be one of the 4 most popular web app languages: NodeJS, PHP and Python/Django, Ruby/Rack, you are NOT LIMITED to these predefined languages! With CapRover, you have the ability to define your own Dockerfile. With a customized Dockerfile, you can deploy any laguage, Go, Java, .NET, you name it! Dockerfiles are quite easy to write. For example, the two captain-definition files below generate the exact same result. 22 | 23 | #### Simple version 24 | 25 | ``` 26 | { 27 | "schemaVersion": 2, 28 | "templateId": "node/8.7.0" 29 | } 30 | ``` 31 | 32 | 33 | #### Advanced Version 34 | 35 | ``` 36 | { 37 | "schemaVersion": 2, 38 | "dockerfileLines": [ 39 | "FROM node:8.7.0-alpine", 40 | "RUN mkdir -p /usr/src/app", 41 | "WORKDIR /usr/src/app", 42 | "COPY ./package.json /usr/src/app/", 43 | "RUN npm install && npm cache clean --force", 44 | "COPY ./ /usr/src/app", 45 | "ENV NODE_ENV production", 46 | "ENV PORT 80", 47 | "EXPOSE 80", 48 | "CMD [ \"npm\", \"start\" ]" 49 | ] 50 | } 51 | ``` 52 | ## Use Dockerfile in captain-definition: 53 | 54 | Note that the simple version of `captain-definition` with `templateId` is good as a starting point. But as your project gets more complex you may want to perform more complicated tasks with your base image, such as installing PHP extensions, installing `uWSGI`, installing particular version of `curl` and etc. In these cases, you can leverage the Dockerfile. Using custom Dockerfile allows you to build a very customized base image. If you're not familiar with Docker, you can simply use google to find something that's similar to your requirement and tweak it. Finally, if you're stuck, don't be shy to ask a question on our Slack channel, or StackOverflow. 55 | 56 | 57 | To use a Dockerfile that's in your repository, you can simply reference it in the captain-definition file: 58 | 59 | ``` 60 | { 61 | "schemaVersion": 2, 62 | "dockerfilePath": "./Dockerfile" 63 | } 64 | ``` 65 | 66 | Dockerfiles are so simple and easy to read. Even if you don't know anything about Docker, you can get an idea what this does. Some examples of advanced methods: [PHP Composer](https://github.com/githubsaturn/captainduckduck/issues/94) and [Meteor](https://github.com/githubsaturn/meteor-captainduckduck/blob/master/captain-definition) 67 | 68 | Using this approach (pure Dockerfile) you can deploy Ruby, Java, Scala, literally anything! If you need more details on dockerfile, please see [Dockerfile Help](https://docs.docker.com/engine/reference/builder) and [Best Practices](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices). 69 | 70 | ## Use Image Name 71 | 72 | If you are an advanced Docker user, you may know that there are plenty of pre-built applications sitting on DockerHub. You can deploy these images using captain-definition. For example to deploy https://hub.docker.com/r/nginxdemos/hello/, you use: 73 | 74 | ``` 75 | { 76 | "schemaVersion": 2, 77 | "imageName": "nginxdemos/hello" 78 | } 79 | ``` 80 | 81 | Tip: You can simply copy and paste the captain-definition file above on CapRover web dashboard under the deploy tab. 82 | 83 | 84 | ## Monorepo: 85 | You can use one git repo to deploy multiple different apps. For example, you may have a frontend and backend app in one repository. In this case, you can define multiple `captain-definition` files and have them deploying separate apps, for example, a directory structure, like this: 86 | ``` 87 | /project 88 | /frontend 89 | /src/index.js 90 | package.json 91 | /backend 92 | /src/index.js 93 | package.json 94 | captain-definition-backend 95 | captain-definition-frontend 96 | ``` 97 | With this content: 98 | `captain-definition-backend` 99 | ``` 100 | { 101 | "schemaVersion": 2, 102 | "dockerfileLines": [ 103 | "FROM node:12-alpine", 104 | "RUN mkdir -p /usr/src/app", 105 | "COPY ./backend /usr/src/app", 106 | "RUN npm install && npm cache clean --force", 107 | "CMD [ \"npm\", \"start\" ]" 108 | ] 109 | } 110 | ``` 111 | You can alternatively point to a Dockerfile. Note that the build context will be always the root of your project, so in the Dockerfile, you'll have to point to that specific directory, for example, `COPY ./backend /usr/src/app` 112 | 113 | Next, you need to instruct your CapRover to use the correct `captain-definition` for each app. Navigate to your app, go to DEPLOYMENT tab, and edit your captain-definition path to `./captain-definition-backend` 114 | 115 | ## Versions for templateId: 116 | NOTE: Versions get pulled from official repositories at runtime, therefore you do not need to update your Captain in order to use a new version of NodeJS. For example, see [here](https://hub.docker.com/_/node/). 117 | 118 | **IMPORTANT:** Versions mentioned below are for **reference only**. For example, at the time that this document was generated Node 10 was not available, but it is available now. Therefore, you can use `node/10` or `node/10.15` or `node/10.15.0` as your templateId despite the fact that it is not mentioned below. 119 | 120 | 121 | ```bash 122 | node/ 123 | carbon, 8, 8.9, 8.9.4, boron, 6, 6.12, 6.12.3, 9, 9.3, 9.3.0, 8.9.3, 9.2, 9.2.1, argon, 4, 4.8, 4.8.7, 6.12.2, 8.9.2, 6.12.1, 4.8.6, 6.12.0, 8.9.1, 9.2.0, 9.1, 9.1.0, 8.9.0, 9.0, 9.0.0, 4.8.5, 6.11, 6.11.5, 8.8, 8.8.1, 8.8.0, 8.7, 8.7.0, 6.11.4, 8.6, 8.6.0, 8.5, 8.5.0, 4.8.4, 6.11.3, 6.11.2, 7, 7.10, 7.10.1, 8.4, 8.4.0, 8.3, 8.3.0, 8.2, 8.2.1, 6.11.1, 8.2.0, 8.1, 8.1.4, 4.8.3, 6.11.0, 8.1.3, 8.1.2, 8.1.1, 8.1.0, 8.0, 8.0.0, 6.10, 6.10.3, 7.10.0, 4.8.2, 6.10.2, 7.9, 7.9.0, 7.8, 7.8.0, 4.8.1, 6.10.1, 7.7, 7.7.4, 4.8.0, 6.10.0, 7.7.3, 7.7.2, 7.7.1, 7.7.0, 7.6, 7.6.0, 4.7, 4.7.3, 6.9, 6.9.5, 7.5, 7.5.0, 4.7.2, 6.9.4, 7.4, 7.4.0, 4.7.1, 6.9.3, 7.3, 7.3.0, 6.9.2, 4.7.0, 7.2.1, 7.2, 4.6, 4.6.2, 7.2.0, 6.9.1, 7.1, 7.1.0 124 | ``` 125 | 126 | ```bash 127 | php/ 128 | 7, 7.2, 7.2.1, 7.0, 7.0.26, 7.1, 7.1.12, 5, 5.6, 5.6.32, 7.2.0, rc, 7.2-rc, 7.2.0RC6, 7.0.25, 7.1.11, 7.2.0RC5, 7.2.0RC4, 5.6.31, 7.0.24, 7.1.10, 7.2.0RC3, 7.1.9, 7.0.23, 7.2.0RC2, 7.2.0RC1, 7.0.22, 7.1.8, 7.2.0beta3, 7.2.0beta2, 7.1.7, 7.2.0beta1, 7.0.21, 7.2.0alpha3, 5.6.30, 7.0.20, 7.1.6, 7.1.5, 7.0.19, 7.0.18, 7.1.4, 7.0.17, 7.1.3, 7.0.16, 7.1.2, 7.1.1, 7.0.15, 5.6.29, 7.0.14, 7.1.0, 5.6.28, 7.0.13, 7.1-rc, 7.1.0RC6, 7.1.0RC5, 7.0.12, 5.6.27, 7.1.0RC4, 7.1.0RC3, 5.6.26, 7.0.11, 7.1.0RC2, 5.6.25, 7.0.10, 7.1.0RC1, 5.6.24, 7.0.9, 5.5.38, 5.5, 5.5.37, 5.6.23, 7.0.8, 5.5.36, 5.6.22, 7.0.7, 7.0.6, 5.6.21, 5.5.35, 7.0.5, 5.6.20, 5.5.34, 7.0.4, 5.6.19, 5.5.33, 7.0.3, 5.6.18, 5.5.32, 7.0.2, 5.6.17, 5.5.31, 7.0.1, 5.6.16, 5.5.30, 7.0.0, 5.4, 5.4.45, 7.0.0RC8, 5.6.15, 7.0.0RC7, 7.0.0RC6, 7.0.0RC5, 5.6.14, 7.0.0RC4, 7.0.0RC3, 5.6.13, 5.5.29, 7.0.0RC2, 7.0.0RC1, 7.0.0beta3, 5.6.12, 5.5.28, 5.4.44, 7.0.0beta2, 5.6.11, 5.5.27, 5.4.43, 7.0.0beta1, 5.5.21, 5.5.19, 5.5.16, 5.4.40, 5.4.41, 5.4.39, 5.5.17, 5.6.3, 5.6.0, 5.6.8, 5.6.4, 5.4.42, 5.5.20, 5.4.38, 5.5.22, 5.6.5, 5.6.2, 5.4.35, 5.4.36, 5.4.33, 5.3.29, 5.3, 5.5.26, 5.5.18, 5.4.32, 5.4.37, 5.6.1, 5.6.6, 5.6.9, 5.6.10, 5.4.34, 5.6.7, 5.5.24, 5.5.23, 5.5.25 129 | ``` 130 | 131 | ```bash 132 | python-django/ 133 | 2, 2.7, 2.7.14, 3, 3.6, 3.6.4, 3.6.3, rc, 3.7-rc, 3.7.0a3, 3.7.0a2, 3.7.0a1, 2.7.13, 3.6.2, 3.6-rc, 3.6.2rc2, 3.6.1, 3.6.2rc1 134 | ``` 135 | 136 | ```bash 137 | ruby-rack/ 138 | 2.4, 2.4.3, 2, 2.5, 2.5.0, rc, 2.5-rc, 2.5.0-rc1, 2.4.2, 2.5.0-preview1 139 | ``` 140 | -------------------------------------------------------------------------------- /docs/cdd-migration.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: cdd-migration 3 | title: CaptainDuckDuck Upgrade 4 | sidebar_label: CaptainDuckDuck Upgrade 5 | --- 6 | 7 | Note: This section is only intended if you want to upgrade your CaptainDuckDuck server to CapRover. 8 | 9 | ### Migration Script 10 | 11 | Simply run [this script](https://raw.githubusercontent.com/caprover/caprover/master/dev-scripts/migrate-from-cdd.sh) to upgrade your CaptainDuckDuck server to CapRover. It automatically creates a backup of your config directory `/captain` in case something goes wrong. 12 | 13 | 14 | To migrate, you can simply run the following lines: 15 | 16 | ``` 17 | wget https://raw.githubusercontent.com/caprover/caprover/master/dev-scripts/migrate-from-cdd.sh 18 | 19 | chmod +x migrate-from-cdd.sh 20 | 21 | ./migrate-from-cdd.sh 22 | ``` 23 | 24 | 25 | ### Tips for Migration: 26 | 27 | Make sure you have enough disk space. CapRover image is around 400MB and the script automatically backs up the config directory. 28 | 29 | #### Without Self-hosted Registry 30 | You are most probably fine if you have around 1.5GB of free space on your server. 31 | 32 | #### With Self-hosted Registry 33 | Self-hosted Registry can consume many many GB of disk space. Since Migration Script automatically creates a backup for your config directory, you may have problems during upgrade. 34 | 35 | To save space, if you had Self-hosted Registry enabled, you have two options: 36 | - you can manually edit the migration script and remove the backup line (`tar -cvf /captain-bk-$(date +%Y_%m_%d_%H_%M_%S).tar /captain`), 37 | - or, you can remove all the content of registry by running `rm -rf /captain/registry/*` as it consumes a lot of disk space. Note that if you perform this action, you have to redeploy your apps in order for other nodes to be able to access it. If you only have one node, no extra action is needed. 38 | 39 | 40 | ### Breaking Changes from CaptainDuckDuck to CapRover: 41 | - `schemaVersion` for captain-definition file is changed to `2`. 42 | - If you previously had to edit the custom port to something other than 80 for your specific app, you no longer need to edit NGINX config, you can simply set the container port to any port from the UI. 43 | - If you previously used a customized dockerfileLines, you have prefixed all `ADD` and `COPY` statements with `./src`. This is no longer needed with CapRover. For example, you previously had 44 | ```bash 45 | COPY ./src/package.json /usr/app/ 46 | ``` 47 | 48 | With CapRover you should change this to 49 | 50 | ```bash 51 | COPY ./package.json /usr/app/ 52 | ``` -------------------------------------------------------------------------------- /docs/certbot-config.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: certbot-config 3 | title: Certbot Overrides 4 | sidebar_label: Certbot Overrides 5 | --- 6 | 7 | 8 | ### NOTE: 9 | Most (almost all) users do not need to modify Certbot configs. CapRover automatically manages it for you. You should skip this page! 10 | 11 |
12 | 13 | ## Customize Certbot command to use DNS-01 challenge 14 | 15 | As of CapRover 1.12.0, you're able to customize the command that Certbot uses to generate SSL certificates. By default, CapRover uses the following command: 16 | ```bash 17 | certbot certonly --webroot -w ${webroot} -d ${domainName} 18 | ``` 19 | which works via HTTP-01 challenge. In this mode, Certbot will verify the ownership of your domain by sending a request to `http:///.well-known/acme-challenge/` where the content of is generated by Certbot. 20 | 21 | This challenge works fine for most users, but you can optionally use a different challenge if you want to. You can do so by overriding the Certbot's certificate generation command. 22 | 23 | ### 1) Certbot Docker image 24 | The default Certbot Docker image does not include the [3rd party plugins](https://hub.docker.com/r/certbot/certbot). You need to build a custom image: 25 | 26 | For example, for Cloudflare: 27 | ```Dockerfile 28 | # Change this to any other base image listed here: https://hub.docker.com/r/certbot/certbot 29 | ## Make sure to use the same version that CapRover uses by default (`certbotImageName` in [CaptainConstant](https://github.com/caprover/caprover/blob/master/src/utils/CaptainConstants.ts#L58)) 30 | BASE_IMAGE="certbot/dns-cloudflare:v2.11.0" 31 | 32 | TEMP_DOCKERFILE=$(mktemp) 33 | cat > $TEMP_DOCKERFILE < 89 |
90 |
91 | 92 | ## Configure Certbot to use a new ACME Server 93 | 94 | ### 1) Create config file 95 | 96 | Normally, the directory `/captain/data/letsencrypt/etc` should contain the volume used by Certbot, 97 | to configure Certbot, add a `cli.ini` file in this directory: 98 | ``` 99 | $ cd /captain/data/letsencrypt/etc/ 100 | $ nano cli.ini 101 | ``` 102 | 103 | ### 2) Configure the values 104 | 105 | We will take as an example ZeroSSL's ACME server to guide you over the steps needed to make Certbot work correctly with it, 106 | 107 | first (at least for ZeroSSL, you need to get EAB credentials which are [here](https://app.zerossl.com/developer)) we add our email and we tell Certbot to accept the TOS of the service: 108 | ``` 109 | email = foo@example.com 110 | agree-tos = true 111 | ``` 112 | 113 | then we add the server (and if needed the EAB credentials): 114 | ``` 115 | server = https://acme.zerossl.com/v2/DV90 # (change it with your ACME server) 116 | eab-kid = some-short-string 117 | eab-hmac-key = a-big-key 118 | ``` 119 | 120 | ### 3) Restart Certbot 121 | 122 | Then to apply our changes we need to update Certbot's service: 123 | ``` 124 | $ docker service update captain-certbot 125 | ``` 126 | 127 | And you're done ! 128 | 129 | ### 4) CAA Record 130 | 131 | Remember to add a CAA record in your DNS to avoid any problem when generating SSL certs 132 | 133 | for example, ZeroSSL need you to have: 134 | ``` 135 | . 3600 IN CAA 0 issue "sectigo.com" 136 | . 3600 IN CAA 0 issuewild "sectigo.com" 137 | ``` 138 | -------------------------------------------------------------------------------- /docs/ci-cd-integration.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: ci-cd-integration 3 | title: CI/CD Integration 4 | sidebar_label: Intro 5 | --- 6 | 7 | While CapRover is capable of building your source code and converting it to a Docker image very easily, often you realize that the build process is very heavy. In fact, in many cases, it's heavier than the load on your app itself. This may result in a server crash when you're trying to build your source code on your own server. The best way to avoid these heavy loads is to build your Docker image elsewhere and just deploy the built artifact to your CapRover server. 8 | 9 | There are many easy CI/CD platforms that offer generous free minutes for your builds, for example GitHub and GitLab both offer free minutes for private repositories and unlimited free minutes for public repositories. 10 | 11 | Read more about [Github integration](ci-cd-integration/deploy-from-github.md) and [Gitlab integration](ci-cd-integration/deploy-from-gitlab.md) next! -------------------------------------------------------------------------------- /docs/ci-cd-integration/deploy-from-github.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: deploy-from-github 3 | title: Build, Test and Deploy from GitHub 4 | sidebar_label: Deploy from GitHub 5 | --- 6 | 7 | ## Deploying directly from Github 8 | 9 | This example showcases a Vue 3 app with a PHP backend that can be built, tested and deployed directly from Github to CapRover using the CapRover community-maintained [GitHub Action](https://github.com/caprover/deploy-from-github). Feel free to clone an example project from https://github.com/PremoWeb/SDK-Foundation-Vue to try things out or build your next awesome app. 10 | 11 | ### Create a new App 12 | 13 | The name you choose here will become the APP_NAME secret. 14 | 15 | ![Create a new app](/img/docs/deploy-from-github/create-a-new-app.png "Create a new app") 16 | 17 | ### Enable App Token 18 | 19 | Find the "Deployment" tab for your new app, click Enable App Token and copy this token. This is your APP_TOKEN secret. 20 | 21 | ![Create a new app](/img/docs/deploy-from-github/enable-app-token.png "Enable App Token") 22 | 23 | ### Add the Github Secrets 24 | 25 | ![Add the Github Secrets](/img/docs/deploy-from-github/create-github-secrets.png "Add your Github Secrets") 26 | 27 |
28 | 29 | ![Creating a secret](/img/docs/deploy-from-github/adding-a-secret.png "Creating a secret") 30 | 31 | _Repeat the process for your APP_TOKEN and CAPROVER_SERVER secrets._ 32 | 33 | NOTE: CapRover server must be in the format of "https://captain.apps.your-domain.com". You can set CAPROVER_SERVER as a Global Secret for all your private and/or public projects. 34 | 35 |
36 | 37 | ### Add files to project 38 | 39 | You will need at minimum, two files to deploy to CapRover using this method. 40 | 41 | The first file will be your `captain-definition` file used by CapRover when deploying your app. The other file is a workflow yaml file that Github Actions will use to process your project prior to deployment. 42 | 43 | Contents of our new Workflow file to be saved at `.github/workflows/deploy.yml`: 44 | 45 | ``` 46 | name: Build & Deploy 47 | 48 | on: 49 | push: 50 | branches: [ "main" ] 51 | 52 | pull_request: 53 | branches: [ "main" ] 54 | 55 | jobs: 56 | build-and-deploy: 57 | runs-on: ubuntu-latest 58 | 59 | strategy: 60 | matrix: 61 | node-version: [18.x] 62 | 63 | steps: 64 | - name: Check out repository 65 | uses: actions/checkout@v4 66 | - name: Use Node.js ${{ matrix.node-version }} 67 | uses: actions/setup-node@v3 68 | with: 69 | node-version: ${{ matrix.node-version }} 70 | cache: "npm" 71 | - run: npm ci 72 | - run: npm run build --if-present 73 | - run: npm run test --if-present 74 | 75 | - uses: a7ul/tar-action@v1.1.0 76 | with: 77 | command: c 78 | cwd: "./" 79 | files: | 80 | backend/ 81 | frontend/dist/ 82 | captain-definition 83 | outPath: deploy.tar 84 | 85 | - name: Deploy App to CapRover 86 | uses: caprover/deploy-from-github@v1.0.1 87 | with: 88 | server: '${{ secrets.CAPROVER_SERVER }}' 89 | app: '${{ secrets.APP_NAME }}' 90 | token: '${{ secrets.APP_TOKEN }}' 91 | ``` 92 | 93 | A quick breakdown of what you are seeing above: 94 | 95 | The first step is to check out and build the Vue 3 frontend part of the app using NPM. The output of the build will be located in frontend/dist/. If present, the app would have also been tested prior to the second step. 96 | 97 | The second step copies the `backend/`, `frontend/dist/` directories and the `captain-definition` file into a deploy.tar file. 98 | 99 | The last step will send the tarball file to CapRover so that CapRover can begin to deploy your app. 100 | 101 | ### Commit changes to your code to deploy! 102 | 103 | When you commit files to your project's repo on the "main" branch, Github Actions will kick off the processing of your Workflow file and upon completion, you'll see your app deployed to Caprover within just a few seconds! Any errors seen by Github will automatically fire an email letting you know. No emails means a successful deployment! 104 | 105 |
106 | 107 | ### Alternative method (more efficient) 108 | 109 | Alternatively, you can even build the Docker image on Github and just deploy the built artifact to your CapRover instance. This will help as it does not consume RAM and CPU from your CapRover instance to build your image. 110 | 111 | In order to achieve this we will need to take the following steps to build the Docker image using GitHub Actions, store it using GitHub Packages, and then deploy it to CapRover. 112 | 113 | #### Create a GitHub Personal Access Token 114 | 115 | You will need to create a GitHub Personal Access Token with **write permission for packages**. 116 | 117 | GitHub has a great guide on creating a personal access token if you have not before. Here is the link: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token 118 | 119 | #### Create a New App 120 | 121 | If you do not have an app already on CapRover, create one using the instructions [here](#create-a-new-app) 122 | 123 | If you do already have an app on CapRover you can skip this step. 124 | 125 | #### Enable App Token 126 | 127 | If you do not already have an app token for your app, create one using the instructions [here](#enable-app-token) 128 | 129 | If you do have an app token, keep it handy as we will need it in the next step. 130 | 131 | #### Add The GitHub Secrets 132 | 133 | You will need to add the following information into GitHub Secrets: 134 | 135 | - App Name: Name of the app in CapRover 136 | - App Token: App token we got in the previous step 137 | - CapRover Server URL: URL of your CapRover Server 138 | - GitHub Token: GitHub Personal Access Token you created in previous step 139 | 140 | You can add GitHub Secrets using the instructions [here](#add-the-github-secrets) 141 | 142 | #### Add a private Docker Registry to CapRover 143 | 144 | In order to pull the image from GitHub Packages, you will need to add a private Docker registry to CapRover. If you haven't done this before, you can do this by following the instructions [here](https://caprover.com/docs/app-scaling-and-cluster.html#add-a-private-docker-registry) 145 | 146 | Use these values: 147 | 148 | - Username: `` 149 | - Password: `` 150 | - Domain: `ghcr.io` (no www, no http) 151 | - Image Prefix: `` (if you're pulling images from an org different than your username) 152 | 153 | > If your image prefix is your github username, your prefix MUST BE lowercase 154 | 155 | #### Create the GitHub Action 156 | 157 | GitHub Actions is the CI/CD pipeline built into GitHub. If you are unfamiliar with it, it would be beneficial to learn the basics by reviewing GitHub's Understanding GitHub Actions Docs: https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions 158 | 159 | Here is an example GitHub Action that builds a docker container on each push to a pull request and deploys it to the CapRover server (good example for a development environment set up) 160 | 161 | ``` 162 | name: Build and Deploy Docker Image 163 | 164 | on: [pull_request] 165 | 166 | jobs: 167 | build_and_deploy: 168 | runs-on: ubuntu-latest 169 | 170 | steps: 171 | - name: Check out repository 172 | uses: actions/checkout@v4 173 | 174 | - name: Set up Docker Buildx 175 | uses: docker/setup-buildx-action@v3 176 | 177 | - name: Login to Container Registry 178 | uses: docker/login-action@v3 179 | with: 180 | registry: ghcr.io 181 | username: ${{ github.repository_owner }} 182 | password: ${{ secrets.GITHUB_TOKEN }} 183 | 184 | - name: Preset Image Name 185 | run: echo "IMAGE_URL=$(echo ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:$(echo ${{ github.sha }} | cut -c1-7) | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV 186 | 187 | - name: Build and push Docker Image 188 | uses: docker/build-push-action@v5 189 | with: 190 | context: . 191 | file: ./Dockerfile 192 | push: true 193 | tags: ${{ env.IMAGE_URL }} 194 | 195 | - name: Deploy Image to CapRrover 196 | uses: caprover/deploy-from-github@v1.1.2 197 | with: 198 | server: "${{ secrets.CAPROVER_SERVER }}" 199 | app: "${{ secrets.APP_NAME }}" 200 | token: "${{ secrets.APP_TOKEN }}" 201 | image: ${{ env.IMAGE_URL }} 202 | ``` 203 | 204 | Here is a quick explanation of what each step in the action does: 205 | 206 | 1. **Check out repository**: This step uses the action `actions/checkout@v2`, which is a predefined GitHub Action that allows the workflow to access the contents of the repository. The checkout action will clone the repository onto the runner (the virtual environment that GitHub Actions uses to execute workflows), so all the subsequent steps in the workflow can operate on it. 207 | 2. **Set up Docker Buildx**: This step uses the action `docker/setup-buildx-action@v1`, which is a Docker action to set up Docker Buildx. This allows for more advanced container building capabilities. 208 | 3. **Login to Container Registry**: This step uses `docker/login-action@v2` to log into the GitHub Container Registry (ghcr.io) using the repository owner's username and a GitHub Token (GITHUB_TOKEN). This token must have been previously stored in the repository's secrets. 209 | 4. **Preset Image Name**: This is a shell command that constructs the URL for the Docker image. It uses the GitHub repository owner, the repository name, and the SHA of the current commit (truncated to the first 7 characters) to construct a URL, converting all upper-case characters to lower-case, and then writes this URL into the `GITHUB_ENV` so it can be used by subsequent steps as an environment variable. 210 | 5. **Build and push Docker Image**: This step uses `docker/build-push-action@v4` to build the Docker image using the Dockerfile in the repository and pushes it to the GitHub Container Registry at the URL that was set in the previous step. The `context: .` setting indicates that the build context is the current directory (i.e., the root of the repository). 211 | 6. **Deploy Image to CapRover**: This step uses `caprover/deploy-from-github@v1.1.2` action to deploy the Docker image that was just built and pushed to CapRover. The details of the CapRover server, the application name, and an access token are provided from the repository's secrets. The Docker image URL is taken from the environment variable set earlier. 212 | 213 | #### Deploy! 214 | 215 | After these changes are implemented commit + push them to your repo and watch the magic happen 🪄 216 | 217 | ### Need help? 218 | 219 | Commercial and community support is available. Please visit the [Help and Support](/docs/support.html "Help and Support") page for details. 220 | -------------------------------------------------------------------------------- /docs/ci-cd-integration/deploy-from-gitlab.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: deploy-from-gitlab 3 | title: Deploying from Gitlab 4 | sidebar_label: Deploy from GitLab 5 | --- 6 | 7 | 8 | 9 | In this tutorial, we'll go over the deployment via GitLab. Having said that, GitHub is very similar. If you have any issues along the way, let us know! 10 | 11 | 12 | ### 1- Create GitLab Repository 13 | 14 | If you don't have a GitLab account, create an account. 15 | - Click on "New Project" to create a new repository 16 | - Click on "Create blank project" 17 | - Name your project and finish your project creation 18 | 19 | 20 | 21 | ### 2- Add Sample Source Code 22 | 23 | For this tutorial we'll work with a very easy sample source code containing one file 24 | 25 | `index.php` 26 | ```php 27 | 28 | ``` 29 | 30 | Add, commit and push this file to your repository on GitLab. You should be seeing this file on the web UI of GitLab. 31 | 32 | 33 | 34 | ### 3- Dockerfile 35 | 36 | In order to build on a 3rd party build system, you need to have a Dockerfile. If you're using a CapRover templateId, you can use the ready to go [Dockerfiles that are in CapRover repository](https://github.com/caprover/caprover/tree/ff3d124f967ee06732c13774e9e633d33b0982c4/dockerfiles). 37 | 38 | In this tutorial, we'll use the PHP Dockerfile: 39 | 40 | `Dockerfile` 41 | ```Dockerfile 42 | FROM php:7.3-apache 43 | COPY ./ /var/www/html/ 44 | ``` 45 | 46 | **IMPORTANT** Make sure your `Dockerfile` is spelled exactly as this. 47 | 48 | Add, commit and push this file. 49 | 50 | 51 | 52 | ### 4- Create an Access Token for CapRover 53 | 54 | CapRover needs to pull the built images from GitLab, so we need to create an access token. Navigate to https://gitlab.com/-/profile/personal_access_tokens and create a token. 55 | 56 | Make sure to assign `read_registry` and `write_registry` permissions for this token. 57 | 58 | One you created the token move to the next step: 59 | 60 | 61 | 62 | ### 5- Add Token to CapRover 63 | 64 | Login to your CapRover web dashboard, under `Cluster` click on `Add Remote Registry`. Then enter these fields: 65 | 66 | - Username: `your gitlab username` 67 | - Password: `your gitlab Token [From the previous step]` 68 | - Domain: `registry.gitlab.com` 69 | - Image Prefix: `again, your gitlab username` 70 | 71 | NOTE: Image Prefix depends on how you structure your project in Gitlab. If you are using a group for your repository, your image prefix should be your group. 72 | In general, image prefix is the part between the domain and image name. For example, `my-group-project` is the Image Prefix for this project: 73 | ``` 74 | registry.gitlab.com/my-group-project/test:latest 75 | ``` 76 | 77 | Save your registry. 78 | 79 | 80 | 81 | ### 6- Disable Default Push 82 | 83 | Now that you added a registry, CapRover by default wants to push the built artifact to your registry. You do not need this for this tutorial, and it might make your deployments to fail. So go ahead and disable `Default Push` 84 | 85 | 86 | 87 | ### 7- Create a CapRover App 88 | 89 | On CapRover dashboard and create an app, we call it `my-test-gitlab-deploy` 90 | 91 | 92 | 93 | ### 8- Create CI/CD Variables 94 | 95 | Next, go to your project page on GitLab, navigate to `Settings > CI/CD`. Then, under `Variables` add the following variables: 96 | - `Key` : `CAPROVER_URL` , `Value` : `https://captain.root.domain.com [replace it with your domain]` 97 | - `Key` : `CAPROVER_PASSWORD` , `Value` : `mYpAsSwOrD [replace it with your password]` 98 | - `Key` : `CAPROVER_APP` , `Value` : `my-test-gitlab-deploy [replace it with your app name]` 99 | 100 | Add all these 3 variables. For best security make sure they are they are protected. It's okay if they are not masked, they won't appear in logs. 101 | 102 | 103 | 104 | ### 9- GitLab CI File 105 | 106 | So far, we have two files in our directory `index.php` and `Dockerfile`. Now let's add GitLab's specific build instructions: 107 | 108 | **IMPORTANT** Make sure your `.gitlab-ci.yml` is spelled exactly as this. It starts with a dot. 109 | 110 | 111 | `.gitlab-ci.yml` 112 | ```yaml 113 | build-docker-master: 114 | image: docker:19.03.1 115 | stage: build 116 | services: 117 | - docker:19.03.1-dind 118 | before_script: 119 | - export DOCKER_REGISTRY_USER=$CI_REGISTRY_USER # built-in GitLab Registry User 120 | - export DOCKER_REGISTRY_PASSWORD=$CI_REGISTRY_PASSWORD # built-in GitLab Registry Password 121 | - export DOCKER_REGISTRY_URL=$CI_REGISTRY # built-in GitLab Registry URL 122 | - export COMMIT_HASH=$CI_COMMIT_SHA # Your current commit sha 123 | - export IMAGE_NAME_WITH_REGISTRY_PREFIX=$CI_REGISTRY_IMAGE # Your repository prefixed with GitLab Registry URL 124 | - docker login -u "$DOCKER_REGISTRY_USER" -p "$DOCKER_REGISTRY_PASSWORD" $DOCKER_REGISTRY_URL # Instructs GitLab to login to its registry 125 | 126 | script: 127 | - echo "Building..." # MAKE SURE NO SPACE ON EITHER SIDE OF = IN THE FOLLOWING LINE 128 | - export CONTAINER_FULL_IMAGE_NAME_WITH_TAG=$IMAGE_NAME_WITH_REGISTRY_PREFIX/my-build-image:$COMMIT_HASH 129 | - docker build -f ./Dockerfile --pull -t built-image-name . 130 | - docker tag built-image-name "$CONTAINER_FULL_IMAGE_NAME_WITH_TAG" 131 | - docker push "$CONTAINER_FULL_IMAGE_NAME_WITH_TAG" 132 | - echo $CONTAINER_FULL_IMAGE_NAME_WITH_TAG 133 | - echo "Deploying on CapRover..." 134 | - docker run caprover/cli-caprover:v2.1.1 caprover deploy --caproverUrl $CAPROVER_URL --caproverPassword $CAPROVER_PASSWORD --caproverApp $CAPROVER_APP --imageName $CONTAINER_FULL_IMAGE_NAME_WITH_TAG 135 | only: 136 | - master 137 | ``` 138 | 139 | This is quite self-explanatory. **The best part is that you don't have to make any changes to this file!** It is the same file for all of your repositories regardless of their language or where you deploy them! 140 | 141 | The only 3 values that are different for this file, are the 3 `CAPROVER_***` values that you set in the previous step. 142 | 143 | 144 | Commit and push this file to your GitLab repository. By now, your GitLab repository must have at least these 3 files 145 | ```bash 146 | index.php 147 | Dockerfile 148 | .gitlab-ci.yml 149 | ``` 150 | 151 | Wait a little bit until your build is finished and deployed automatically! After a few minutes you can see your deployed app on CapRover!!! 152 | 153 | #### Note on using `--imageName` with a private registry 154 | 155 | If you encounter the following error when running `caprover deploy --imageName`, you may need to authenticate your Captain instance with your registry, as being logged in locally doesn't mean that CapRover can access the image. 156 | 157 | ``` 158 | Deploy failed! 159 | Error: (HTTP code 404) unexpected - pull access denied for user_name/repo_name, repository does not exist or may require 'docker login': denied: requested access to the resource is denied 160 | ``` 161 | 162 | **Log in to your private Docker repository on CapRover**: 163 | 164 | - Navigate to CLUSTER 165 | - Click on ADD REMOTE REGISTRY 166 | - Enter your data and save your registry 167 | - Now you can use `caprover deploy --imageName` with your private image registry. 168 | 169 | 170 | #### App Tokens 171 | 172 | When you use CI/CD, it may be more desirable to avoid storing your password. Instead, you can create app specific tokens to deployment of each app. 173 | 174 | ``` 175 | caprover deploy --appToken --caproverUrl https://captain.domain.com --imageName YOUR_IMAGE_NAME --appName YOUR_APP_NAME 176 | ``` 177 | 178 | Usually it is more secure to save token in an environment variable, CLI will load it from `CAPROVER_APP_TOKEN` variable. 179 | 180 | This functionality is available from CapRover 1.10 backend and CapRover CLI version of 2.2.0! 181 | 182 | 183 | 184 | #### Alternative Method 185 | 186 | Alternatively, you can use a webhook instead of `docker run caprover/cli-caprover:v2.1.1 caprover deploy....`. This method is a bit more complex. 187 | 188 | The following is NOT A WORKING example. Instead, it's just a hint on what steps are needed for the webhook method to work. 189 | 190 | ```bash 191 | - echo "Deploying on CapRover..." 192 | - export DEPLOY_BRANCH=deploy-caprover 193 | - cd ~ 194 | - git clone your-repo 195 | - cd your-repo 196 | - git checkout $DEPLOY_BRANCH || git checkout -b $DEPLOY_BRANCH 197 | - git rm -rf . 198 | - git clean -fdx . 199 | - echo "{\"schemaVersion\":2,\"imageName\":\"$CONTAINER_FULL_IMAGE_NAME_WITH_TAG\"}" > captain-definition 200 | - git add . 201 | - git commit -m "Deploy $CONTAINER_FULL_IMAGE_NAME_WITH_TAG" 202 | - git push --set-upstream origin $DEPLOY_BRANCH 203 | - curl -X POST https://captain.rootdomain.com/your-webhook 204 | ``` 205 | -------------------------------------------------------------------------------- /docs/cli-commands.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: cli-commands 3 | title: CLI Commands 4 | sidebar_label: CLI Commands 5 | --- 6 | 7 |
8 | 9 | You can use this CLI tool to deploy your apps. Before anything, install the CLI tool using npm: 10 | ``` 11 | npm install -g caprover 12 | ``` 13 | 14 | ### Server Setup 15 | 16 | The very first thing you need to do is to setup your Captain server. You can either do this by visiting `HTTP://IP_ADDRESS_OF_SERVER:3000` in your browser, or the recommended way which is the command line tool. Simple run 17 | ``` 18 | caprover serversetup 19 | ``` 20 | 21 | Follow the steps as instructed, enter IP address of server. Enter the root domain to be used with this Captain instance. If you don't know what Captain root domain is, please visit www.caprover.com for documentation. This is a very crucial step. After that, you'll be asked to enter your email address. This should be a valid email address as it will be used in your SSL certificate. After HTTPS is enabled, you'll be asked to change your password. And... Your are done! Go to Deploy section below to read more about app deployment. 22 | 23 | 24 | ### Login 25 | 26 | *If you've done the "Server Setup" process through the command line. You can skip "Login" step because "server setup" automatically logs you in as the last step of setup.* 27 | 28 | The very first thing you need to do is to login to your Captain server. It is recommended that at this point you have already set up your HTTPS. Login over insecure, plain HTTP is not recommended. 29 | 30 | To log in to server, simply run the following line and answer the questions. 31 | 32 | ```bash 33 | caprover login 34 | ``` 35 | 36 | If operation finishes successfully, you will be prompted with a success message. 37 | 38 | NOTE: You can be logged in to several Captain servers at the same time. This is particularly useful if you have separate staging and production servers. 39 | 40 | ### Deploy 41 | 42 | In order to deploy your application, you first need to create a captain-definition file and place it in the root of your project folder. In case of a nodejs application, this would sit in the same folder as your package.json. 43 | 44 | A simple captain-definition file for a nodejs application is: 45 | 46 | ``` 47 | { 48 | "schemaVersion": 2, 49 | "templateId": "node/8.7.0" 50 | } 51 | ``` 52 | 53 | See [Captain Definition File](captain-definition-file.md) for more details on the Captain Definition file. 54 | 55 | After making sure that this file exists, run the following command and answer the questions given: 56 | 57 | ```bash 58 | caprover deploy 59 | ``` 60 | 61 | You will then see your application being uploaded and, after that, your application getting built. Note that the build process can take several minutes, so please be patient! 62 | 63 | To use the previously-entered values for the current directory, without being asked again, use the `-d` option: 64 | 65 | ```bash 66 | caprover deploy -d 67 | ``` 68 | 69 | Alternatively, you can use the stateless mode and supply the CapRover server information inline: 70 | ```bash 71 | caprover deploy -h https://captain.root.domain.com -p password -b branchName -a app-name 72 | ``` 73 | 74 | This can be useful if you want to integrate CI/CD pipeline. 75 | 76 | #### Options: 77 | Those params are available: 78 | - `-d, --default`: Uses previously entered values for the current directory. Other options are not considered. 79 | - `-c, --configFile `: Specifies a configuration file to use for deployment settings. 80 | - `-u, --caproverUrl `: Sets the CapRover machine URL to which the deployment will be made. This URL is typically in the format [http[s]://][captain.].your-captain-root.domain. 81 | - `-p, --caproverPassword `: The password for the CapRover machine. This option is prompted when a URL is provided and an app token is not used. 82 | - `-n, --caproverName `: The name of the CapRover machine you wish to deploy to. This can be selected from a list of logged-in machines. 83 | - `-a, --caproverApp `: Specifies the application name on the CapRover machine to which you are deploying. This is selected from a list of available applications on the machine. 84 | - `-b, --branch `: Specifies the Git branch to be deployed. Note that uncommitted and git-ignored files will not be included. 85 | - `-t, --tarFile `: Specifies the path to a tar file which must include a captain-definition file for deployment. 86 | - `-i, --imageName `: Specifies a Docker image to be deployed. The image must exist on the server or be accessible through public or private repositories that CapRover can access. 87 | - `--appToken `: An optional token for app-level authentication, if required. 88 | 89 | 90 | ### List logged in servers 91 | 92 | To see a list of servers you are currently logged in to, run the following line: 93 | 94 | ```bash 95 | caprover list 96 | ``` 97 | 98 | ### Logout 99 | 100 | Run the following command: 101 | 102 | ```bash 103 | caprover logout 104 | ``` 105 | -------------------------------------------------------------------------------- /docs/complete-webapp-tutorial.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: complete-webapp-tutorial 3 | title: Complete Webapp Tutorial 4 | sidebar_label: Complete Webapp Tutorial 5 | --- 6 | 7 | 8 |
9 | 10 | This is a quick general tutorial to help you understand how you should architecture an app that has multiple components. 11 | 12 | Let's say we want to make a webapp version of [HOTDOG or NOT HOTDOG](https://www.theverge.com/2017/6/26/15876006/hot-dog-app-android-silicon-valley)! 13 | 14 | 15 | 16 | ## App Description 17 | Assume we want to create a webapp that shows a list of photos with a line describing whether the image is a hotdog or not hotdog, something like this: 18 | 19 | - Tags: Hotdog, Upload date: 2017-11-12 20 | - Tags: NOT Hotdog, Upload date: 2017-07-08 21 | - Tags: Hotdog, Upload date: 2017-07-07 22 | - .... 23 | 24 | Anyone can upload images and our very smart Artificial Intelligence tags that image with HOTDOG or NOT-HOTDOG, then we save that image on the server and we also save upload date and tags in the database. 25 | 26 | ## App Architecture 27 | To make this app, let's assume we decided to have the following components: 28 | - NodeJS WebApp: (including static assets, frontend app, and API) 29 | - PHP Image Upload app - where we can make a POST request to save a photo on disk 30 | - MongoDB where we can store upload information (tags, upload date and etc) 31 | - PYTHON An Image Recognition service where we can make a POST request to know whether the image is a HOTDOG or NOT HOTDOG 32 | 33 | ``` 34 | +---------------------+ 35 | | | 36 | | NodeJS Webapp | 37 | | | 38 | +---------------+------------+--------+-----------------+ 39 | | | | 40 | | | | 41 | | | | 42 | | | | 43 | | | | 44 | +-------v-----------+ +----------v----------+ +-----------v---+ 45 | | | | | | | 46 | | PHP File Uploader | | Python ImageDetector| | MongoDB | 47 | | | | | | | 48 | +-------------------+ +---------------------+ +---------------+ 49 | 50 | ``` 51 | 52 | ## Persistence or Not 53 | CapRover allows you to indicate whether your app/database/service has persistence data or not. Apps with persistence can have "persistent directories". These directories will be preserved if your app crashes and Captain starts a new instance of that app. All other directories will get wiped and reset to their default state if the application crashes and Captain starts a new instance of the app. In our example: 54 | - WebApp: DOES NOT have/need any persistence. 55 | - Image Upload App: Needs a persistent directory where images get saved on disk (for example, `/uploaded_files`) 56 | - MongoDB. Of course, this needs persistency (where we store information), we don't want to lose the database, just because our MongoDB crashed or our server got restarted. 57 | - PYTHON Image Recognition app. This one does not need to save any data on disk. It simply receives an image, does some image processing and let the client know whether the image was HOTDOG or NOT HOTDOG 58 | 59 | ## Creating Services: 60 | - NodeJS Web app: after you write this app, you simply create a webapp and name it `my-webapp` on Captain, you DO NOT check the persistency checkbox and you deploy your app. 61 | - Image Upload app: similar to webapp described above, but we'll check the persistence checkbox when creating the app. Name this app `image-uploader`. After that, we go to app details page and add a persistent directory, the path of the directory is where your app stores images. This depends on your app, in our example, let's assume it is `/uploaded_files` 62 | - MongoDB: we'll use the one-click app installer to create an instance of MongoDB. We'll name this container `my-mongodb`. When the container (database) is created, you can go to the details page and you'll see that Captain automatically assigned some persistent directories to this container. This is where MongoDB saves its data. 63 | - Python Image Recognition app: Again, create a new app on Captain. We do not need to set persistence for this app as it does not save any information on the disk. Let's name this app `image-processor`. 64 | 65 | 66 | ## Internal Access 67 | In order for your web-app to work. It needs to be able to talk to MongoDB instance, image uploader, and image processor. You can simply add a `srv-captain--` prefix to the name of the container if you want to access it from another container. For example in order to connect to your MongoDB instance which we name `my-mongodb`, you can add the following line to your NodeJS application (using mongoose library) 68 | ``` 69 | mongoose.connect("mongodb://srv-captain--my-mongodb/mydatabase", { useMongoClient: true }); 70 | ``` 71 | Of course, you can add username and password to the URI, see [here for example](https://stackoverflow.com/questions/7486623/mongodb-password-with-in-it). 72 | 73 | This is the same for other services; if you want to upload an image to your image uploader service you can just access it via `http://srv-captain--imageuploader` 74 | -------------------------------------------------------------------------------- /docs/database-connection.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: database-connection 3 | title: Database Connection 4 | sidebar_label: Database Connection 5 | --- 6 | 7 |
8 | 9 | All the databases that you deploy as a [one-click app](one-click-apps) are deployed as Docker containers. The name of each container is prefixed with `srv-captain--` in order to avoid clashing with other containers that might be running on the same host. All containers can talk to each other via Docker overlay network. The network architecture is something like this: 10 | 11 | 12 | ```bash 13 | Outside World 14 | + 15 | | 16 | +---------+---+---+-----------------------------+ 17 | | | | | 18 | | | NGINX | | 19 | | | | | 20 | | +--+-------+---+ | 21 | | | | | 22 | | | | | 23 | | +---v--+ +-----v+ +-----------+ | 24 | | | App1 | | App2 +------> Database1 | | 25 | | +------+ +------+ +-----------+ | 26 | | | 27 | +-----------------------------------------------+ 28 | ``` 29 | 30 | 31 | ### Internal Connections 32 | 33 | The simplest type of connection is when you want to connect to `Database1` from `App2` in the diagram above. In this case, you can just connect to `srv-captain--database1` and specify the port. There is NO NEED for port mapping or extra config. Your code look like something like this: 34 | 35 | ``` 36 | databaseEngine.connect( 37 | { 38 | host: srv-captain--database1, 39 | port: 5000 40 | } 41 | ) 42 | ``` 43 | 44 | 45 | ### External Connections 46 | 47 | **IMPORTANT** if you're having issues with external connection, it's likely that you're an incorrect config. CapRover is battle tested and guaranteed to work. See a number of common mistakes [here](https://github.com/caprover/caprover/issues/364) 48 | 49 | Sometimes, you need to connect to a database from the outside world. In this case you have two options: 50 | 51 | 1) Port Forwarding 52 | This is the simplest solution. You simply navigate to App Config page on CapRover and map a arbitrary host port to the database port. For example, the default MySql port is `3306`, you can map port `12345` of the host to port `3306` of the container, and then, from your local machine, do something like this: 53 | 54 | ``` 55 | databaseEngine.connect( 56 | { 57 | host: , 58 | port: 12345 59 | } 60 | ) 61 | ``` 62 | 63 | Make sure you allow the host port on your firewall. Otherwise you won't be able to connect to your database. 64 | 65 | 66 | 2) SSH Tunneling 67 | This method is more advanced. In order to do this, you first need to deploy an SSH one click app. You can select this from the official one click apps list on your CapRover instance. Make sure to choose a long and secure password. During setup, you will also be asked to provide a port to map this SSH image. By default it uses port `4646`. Make sure this port is allowed to pass through your firewall. Once this new image is deployed, you can now from your local machine run the following command: 68 | ``` 69 | ssh -L 8181:srv-captain--mysql:3306 root@ -p 4646 70 | ``` 71 | 72 | This will map your local port of `8181` to MySQL Container's port `3306`. Now, from your local machine, you can run something like this: 73 | ``` 74 | databaseEngine.connect( 75 | { 76 | host: localhost, 77 | port: 8181 78 | } 79 | ) 80 | ``` 81 | **IMPORTANT:** Note that you are not able to SSH Tunnel to your database from the regular SSH on server. You **must** create an SSH container. SSH on the host is not able to talk to the container. 82 | 83 | ```bash 84 | 85 | HOST SYSTEM 86 | +-----------------------------------------------------------------+ 87 | | +-------------------+ | 88 | | | | | 89 | | | SSHD ON HOST | | 90 | | +-------------------+ | 91 | | | 92 | | | 93 | | DOCKER OVERLAY NETWORK (isolated environment) | 94 | | +-------------------------------------------------------------+ | 95 | | | | | 96 | | | +----------------+ +--------------------+ | | 97 | | | | | | | | | 98 | | | | SSH Container | | Database Container | | | 99 | | | | +-------->+ | | | 100 | | | +-----^----------+ +--------------------+ | | 101 | | | | | | 102 | | +-------------------------------------------------------------+ | 103 | | | | 104 | +-----------------------------------------------------------------+ 105 | | 106 | | 107 | | 108 | +-----------+ 109 | | YOU | 110 | +-----------+ 111 | ``` 112 | -------------------------------------------------------------------------------- /docs/deployment-methods.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: deployment-methods 3 | title: Deployment Methods 4 | sidebar_label: Deployment Methods 5 | --- 6 | 7 |
8 | Regardless of your deployment method, make sure that you have a 'captain-definition' file in your project. See docs on [Captain Definition](captain-definition-file.md) for more details. 9 | 10 | ## Deploy via CLI 11 | Simply run `caprover deploy` in your git repo and follow the steps. This is the best method as it's the only method that reports potential build failures to you. Read more about it here: 12 | [Get Started - Step 5](get-started.md#step-5-deploy-the-test-app). 13 | 14 | ## Deploy via Web Dashboard 15 | Convert the content of your project into a tarball (`.tar`), go to your Captain web dashboard and upload the tar file. This deployment method is typically used for testing purposes only. 16 | 17 | For captain-definition files that do not require any source code, like [this](/docs/captain-definition-file.html#use-image-name), you can simply copy and paste the captain-definition content on web dashboard. 18 | 19 | ![deployapp](/img/docs/app-deploy.png) 20 | 21 | ## One Click Rollback 22 | 23 | Let's say you deployed a new version of your app. But you realize that it's buggy. You don't have time to go back, revert your changes or fix the bug, what would you do? Simple! Just go to deployment tab and click on the revert icon next to the version that you want to revert to. CapRover automatically starts a new build and deploy that version! Note that this **DOES NOT** revert changes that you made to Environment Variables, and other app configs such as persistent directories and etc. It just reverts your image (deployed source code). 24 | 25 | ## Automatic Deploy using Github, Bitbucket and etc. 26 | This method is perhaps the most convenient one. This method automatically triggers a build with a `captain-definiton` file when you push your repo to a specific branch (like `master` or `staging` or `release` or etc). To setup this, go to your apps settings and enter the repo information: 27 | - repo: This is the main HTTPS address of repo, in case of github, it is in `github.com/someone/something` format. Make sure it does NOT include `https://` prefix and `.git` suffix. 28 | - branch: The branch you want to be tracked, for example `master` or `staging` or `release`... 29 | - github/bitbucket username(email address): This is username that will be used when Captain downloads the repo. 30 | - github/bitbucket password: You can enter any non-empty text, like `123456`, for public projects. 31 | - Or, instead of username/password, use SSH Key: Make sure to use PEM format as other formats may not work. Use the following command if unsure: 32 | ``` 33 | ssh-keygen -m PEM -t ed25519 -C "yourname@example.com" -f ./deploykey -q -N "" 34 | ``` 35 | 36 | After you enter this information, save your configuration. And go to your apps page again. Now, you'll see a new field call webhook. Simply copy this webhook to your github/bitbucket repo webhooks (see below). Captain listens to POST requests on this link and triggers a build. 37 | 38 | #### Github 39 | Create a webhook here: 40 | - Project > Settings > Add Webhook > URL: Captain Webhook from your apps page, Content Type: `application/json`, 41 | Secret: , Just the `push` event. 42 | Furthermore add the contents of your generated public key to your repositories deploy keys. 43 | 44 | WARNING: Github has recently introduced a bug where the webhooks are trimmed at 255 characters, please see this issue: https://github.com/caprover/caprover/issues/2079 45 | 46 | #### Bitbucket 47 | Webhooks can be added here: 48 | - Project > Settings > Webhooks > Add Webhook > Title: Captain Server, URL: Captain Webhook from your apps page. 49 | 50 | #### GitLab and Others 51 | Webhooks can be added in a similar fashion. As long as the webhook fires a POST request, CapRover is able to pick it up and starts a build from the latest commit on the specified branch. 52 | -------------------------------------------------------------------------------- /docs/disk-cleanup.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: disk-cleanup 3 | title: Disk Clean-Up 4 | sidebar_label: Disk Clean-Up 5 | --- 6 | 7 |
8 | 9 | Docker uses the disk in different ways: 10 | 11 | ## Docker Images 12 | Saving your images: images are compressed files with your built source-code that you deployed to the server. Every time you deploy a new version of your code, Docker builds a new image for the new version and keeps the old image by default. If you want to clean up all "unused" images on your server, run 13 | ``` 14 | docker container prune --force 15 | docker image prune --all 16 | ``` 17 | 18 | Important Note: Use this approach only if you have a Docker registry set up (local or remote). This is due to an existing bug in Docker, see [here](https://github.com/caprover/caprover/issues/180) for more details on the problem and also see the related [Docker Issue](https://github.com/moby/moby/issues/36295) 19 | 20 | ## Docker Volumes 21 | Volumes, aka "Persistent Directories". When you create an app with persistent data, like a database, you will assign it a persistent directory. When you change the persistent directory, or when you delete your app, you don't need the volumes anymore. Cleaning up orphaned volumes are tricky. If you have a useful volume for an app that is "currently" crashing and not-running, that volume is considered as "orphaned" by Docker :( So, to safely clean up orphaned volumes, first, check to see if all your services are running by: 22 | ``` 23 | docker service ls 24 | ``` 25 | Under REPLICAS, you should see `1/1`, `2/2` and etc. If you see a service that is not running, then do not proceed! Otherwise, go head and clean-up orphaned volumes by: 26 | ``` 27 | docker volume prune 28 | ``` 29 | 30 | Alternatively, you can first list all volumes, and delete only the ones that you don't want: 31 | ``` 32 | docker volume ls # lists all volumes 33 | docker volume rm volume-name-goes-here # removes a specific volume 34 | ``` 35 | -------------------------------------------------------------------------------- /docs/docker-compose.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: docker-compose 3 | title: Docker Compose 4 | sidebar_label: Docker Compose 5 | --- 6 | 7 | 8 | ## What is Docker Compose? 9 | 10 | For Docker newbies, lots of examples that you find on the internet are Docker Compose. For example, this is a simple Docker Compose for WordPress: 11 | 12 | ```yaml 13 | version: '3.3' 14 | 15 | services: 16 | db: 17 | image: mysql:5.7 18 | volumes: 19 | - db-data:/var/lib/mysql 20 | restart: always 21 | environment: 22 | MYSQL_ROOT_PASSWORD: somewordpress 23 | MYSQL_DATABASE: wordpress 24 | MYSQL_USER: wordpress 25 | MYSQL_PASSWORD: wordpress 26 | 27 | wordpress: 28 | depends_on: 29 | - db 30 | image: wordpress:latest 31 | ports: 32 | - "8000:80" 33 | restart: always 34 | environment: 35 | WORDPRESS_DB_HOST: db:3306 36 | WORDPRESS_DB_USER: wordpress 37 | WORDPRESS_DB_PASSWORD: wordpress 38 | WORDPRESS_DB_NAME: wordpress 39 | volumes: 40 | db-data: {} 41 | ``` 42 | 43 | It is pretty self-explanatory. It defines one or multiple services (apps) and their configurations such as persistent volumes, mapped ports, environment variable and etc. Docker compose is a really easy and readable way to define a set of apps that need to be working together. Usually to run a docker compose file, you need to run something like: 44 | ``` 45 | docker-compose -f my-docker-compose.yml up 46 | ``` 47 | 48 | 49 | ## Relationship to CapRover - Bad 50 | 51 | CapRover is just a thin layer around Docker. It uses docker to build and run your applications. It does all of these through [Docker API](https://docs.docker.com/engine/api/v1.40). 52 | 53 | Although Docker Compose a feature in Docker CLI, it is NOT available in Docker API. This means CapRover cannot handle docker compose files. 54 | 55 | 56 | ## Relationship to CapRover - Good 57 | 58 | Having said that, CapRover has a built in system to parse out docker-compose (partially) and converts it to pieces that Docker API understands. In fact, this is exactly how CapRover one click apps work. One click apps, are just templatized variant of Docker Compose files. For example, this is the one click app for wordpress: 59 | 60 | ```yaml 61 | captainVersion: 4 62 | services: 63 | $$cap_appname-db: 64 | image: $$cap_db_type:$$cap_database_version 65 | volumes: 66 | - $$cap_appname-db-data:/var/lib/mysql 67 | restart: always 68 | environment: 69 | MYSQL_ROOT_PASSWORD: $$cap_db_pass 70 | MYSQL_DATABASE: wordpress 71 | MYSQL_USER: $$cap_db_user 72 | MYSQL_PASSWORD: $$cap_db_pass 73 | caproverExtra: 74 | notExposeAsWebApp: 'true' 75 | $$cap_appname-wordpress: 76 | depends_on: 77 | - $$cap_appname-db 78 | image: wordpress:$$cap_wp_version 79 | volumes: 80 | - $$cap_appname-wp-data:/var/www/html 81 | restart: always 82 | environment: 83 | WORDPRESS_DB_HOST: srv-captain--$$cap_appname-db:3306 84 | WORDPRESS_DB_USER: $$cap_db_user 85 | WORDPRESS_DB_PASSWORD: $$cap_db_pass 86 | caproverOneClickApp: 87 | variables: 88 | - id: $$cap_db_user 89 | label: Database user 90 | defaultValue: wordpressuser 91 | validRegex: /^([a-zA-Z0-9])+$/ 92 | - id: $$cap_db_pass 93 | label: Database password 94 | description: '' 95 | validRegex: /.{1,}/ 96 | - id: $$cap_wp_version 97 | label: WordPress Version 98 | defaultValue: '4.9' 99 | description: Check out their Docker page for the valid tags https://hub.docker.com/r/library/wordpress/tags/ 100 | validRegex: /^([^\s^\/])+$/ 101 | - id: $$cap_db_type 102 | label: Database Type 103 | defaultValue: mysql 104 | description: You can either choose mariadb or mysql, you need to change the version according to which DB is selected. It is case sensitive. 105 | validRegex: /^(mysql|mariadb)$/ 106 | - id: $$cap_database_version 107 | label: Database Version, default is MySQL 108 | defaultValue: '5.7' 109 | description: Check out the Docker pages for the valid tags https://hub.docker.com/r/library/mysql/tags/ or https://hub.docker.com/_/mariadb?tab=tags 110 | validRegex: /^([^\s^\/])+$/ 111 | instructions: 112 | start: >- 113 | WordPress is an online, open source website creation tool written in PHP. But in non-geek speak, it’s probably the easiest and most powerful blogging and website content management system (or CMS) in existence today. 114 | Enter your WordPress Configuration parameters and click on next. A MySQL (database) and a WordPress container will be created for you. The process will take about a minute for the process to finish. 115 | end: > 116 | Wordpress is deployed and available as $$cap_appname-wordpress . 117 | IMPORTANT: It will take up to 2 minutes for WordPress to be ready. Before that, you might see a 502 error page. 118 | displayName: WordPress 119 | isOfficial: true 120 | description: WordPress is a content management system based on PHP and MySQL that is usually used with the MySQL or MariaDB database 121 | documentation: Taken from https://docs.docker.com/compose/wordpress/. Port mapping removed from WP as it is no longer needed 122 | ``` 123 | 124 | As you can see, the top part is very similar a Docker Compose! 125 | 126 | 127 | ## How to Run Docker Compose on CapRover 128 | 129 | 130 | Note that, as mentioned above, the built-in parser does not support all fields that are available in docker compose. Specifically, it only supports: `image`, `environment`, `ports`, `volumes`, `depends_on`, and `hostname`, other parameters are currently being ignored by CapRover. 131 | 132 | Assuming that your Docker Compose doesn't have any of these parameters, or they are not crucial for your application, you can simply run Docker Compose by 133 | 134 | 1) Navigate to Apps 135 | 136 | 2) Click on "One Click Apps/Databases" 137 | 138 | 3) Navigate to the very bottom of the list, and click on the last item, called `>> TEMPLATE <<` 139 | 140 | 4) Copy the following section to the box: 141 | 142 | 143 | ```yaml 144 | captainVersion: 4 145 | caproverOneClickApp: 146 | instructions: 147 | start: Just a plain Docker Compose. 148 | end: Docker Compose is deployed. 149 | ######## 150 | ``` 151 | 152 | 5) After `########`, copy the entire content of your Docker Compose. Keep in mind that your services will get prefixed with `srv-captain--` when deployed via CapRover. Hence make changes if needed. For example, the complete wordpress docker compose will look like this in CapRover 153 | 154 | 155 | ```yaml 156 | captainVersion: 4 157 | caproverOneClickApp: 158 | instructions: 159 | start: Just a plain Docker Compose. 160 | end: Docker Compose is deployed. 161 | ######## 162 | version: '3.3' 163 | 164 | services: 165 | db: 166 | image: mysql:5.7 167 | volumes: 168 | - db-data:/var/lib/mysql 169 | restart: always 170 | environment: 171 | MYSQL_ROOT_PASSWORD: somewordpress 172 | MYSQL_DATABASE: wordpress 173 | MYSQL_USER: wordpress 174 | MYSQL_PASSWORD: wordpress 175 | 176 | wordpress: 177 | depends_on: 178 | - db 179 | image: wordpress:latest 180 | ports: 181 | - "8000:80" 182 | restart: always 183 | environment: 184 | WORDPRESS_DB_HOST: srv-captain--db:3306 ## NOTICE it is changed to "srv-captain--db" from "db" 185 | WORDPRESS_DB_USER: wordpress 186 | WORDPRESS_DB_PASSWORD: wordpress 187 | WORDPRESS_DB_NAME: wordpress 188 | volumes: 189 | db-data: {} 190 | ``` 191 | 192 | ## Service with CAP_ADD Flag 193 | 194 | If you are working on a container like OpenVPN, they often require special cap_add docker flag. You can add them like this: 195 | 196 | ```yaml 197 | captainVersion: 4 198 | services: 199 | openvpn: 200 | caproverExtra: 201 | containerHttpPort: 943 202 | image: linuxserver/openvpn-as:2.9.0-5c5bd120-Ubuntu18-ls124 203 | environment: 204 | PUID: 1000 205 | PGID: 1000 206 | TZ: UTC 207 | INTERFACE: "" 208 | volumes: 209 | - openvpn:/config 210 | ports: 211 | - 9443:9443 212 | - 1194:1194 213 | cap_add: 214 | - NET_ADMIN 215 | caproverOneClickApp: 216 | displayName: OpenVPN Access Server 217 | isOfficial: false 218 | description: Full featured secure network tunneling VPN software. 219 | documentation: https://openvpn.net/index.php/access-server/overview.html 220 | instructions: 221 | start: Just a openvpn Docker Compose with cap_add. 222 | end: Docker Compose is deployed. 223 | ``` 224 | 225 | 226 | ## Alternative Approach 227 | 228 | If you can't make it work with a one click app template, there is another option! You can simply run pure docker compose by download the compose file and run `docker compose up`. But before that just add `captain-overlay-network` to your web application section of your docker compose yaml file: 229 | ``` 230 | web-app: 231 | image: ..... 232 | container_name: ...... 233 | networks: 234 | - captain-overlay-network 235 | 236 | networks: 237 | captain-overlay-network: 238 | external: true 239 | ``` 240 | 241 | Now instead of potential port mapping that you might have, like `8080:80`, you can just create a CapRover "Nginx Reverse Proxy" app and use your container name as the upstream proxy, like `http://web-app` and done! 242 | 243 | -------------------------------------------------------------------------------- /docs/firewall.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: firewall 3 | title: Firewall & Port Forwarding 4 | sidebar_label: Firewall & Port Forwarding 5 | --- 6 | 7 |
8 | 9 | 10 | Captain uses: 11 | - 80 TCP for regular HTTP connections 12 | - 443 TCP/UDP for secure HTTPS and HTTP/3 connections 13 | - 3000 TCP for initial Captain Installation (can be blocked once Captain is attached to a domain) 14 | - 7946 TCP/UDP for Container Network Discovery 15 | - 4789 TCP/UDP for Container Overlay Network 16 | - 2377 TCP/UDP for Docker swarm API 17 | - 996 TCP for secure HTTPS connections specific to Docker Registry 18 | 19 | In case of an ubuntu server, run 20 | 21 | ``` 22 | ufw allow 80,443,3000,996,7946,4789,2377/tcp; ufw allow 7946,4789,2377,443/udp; 23 | ``` 24 | 25 | 26 | Note that for a more secure installation you can only expose 80/443/3000 to the world, the rest of the ports are only used in a cluster, and it would suffice to make them open to the other nodes in the cluster. 27 | If you have a single instance, just run: 28 | 29 | ``` 30 | ufw allow 80,443,3000 31 | ``` 32 | 33 | 34 | Also, if you are using Port Mapping to allow external connections, for example from your laptop to a MySQL instance on Captain, you will have to add the corresponding port to the exclusion as well. 35 | 36 | 37 | NOTE: 38 | Docker bypasses ufw for mapped ports. If you have manually added a mapped port for any of your apps deployed under CapRover, ufw does not necessarily block the ports. See the [relevant information here]( 39 | https://askubuntu.com/questions/652556/uncomplicated-firewall-ufw-is-not-blocking-anything-when-using-docker) 40 | 41 | -------------------------------------------------------------------------------- /docs/get-started.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: get-started 3 | title: Getting Started 4 | sidebar_label: Getting Started 5 | --- 6 | 7 | ## Simple Setup 8 | 9 | The recommended method to install CapRover is via DigitalOcean one-click app. CapRover is available as a One-Click app in DigitalOcean marketplace. 10 | 11 | Note that if you are a new DigitalOcean user, you will receive **\$100 Free Credit** once you sign up for the first two months. This is enough for two months of multiple servers! 12 | 13 | If you use this method, you can skip **Prerequisites** section and step 1 of **CapRover Setup** below! 14 | 15 |
16 | 17 | 18 | CreateDroplet 19 | 20 | 21 |
22 | 23 | ## Prerequisites 24 | 25 | ### A) Domain Name 26 | 27 | During installation, you'll be asked to point a wildcard DNS entry to your CapRover IP Address. This will cost you as low as \$2 a year (or [even less](https://www.reddit.com/r/selfhosted/comments/sp8etq/comment/hwdgztx/?utm_source=reddit&utm_medium=web2x&context=3)!) 28 | 29 | Note that you can use CapRover without a domain too. But you won't be able to setup HTTPS. 30 | 31 | ### B) Server 32 | 33 | #### B1) Public IP 34 | 35 | _Side note: You can [install CapRover locally](run-locally.md) on your laptop on a private network which is behind NAT (your router). But if you want to enable HTTPS and/or access the apps from outside of your private network, it requires some special setup, like port forwarding._ 36 | 37 | In standard installation, CapRover has to be installed on a machine with a public IP address. If you need help with Public IP, see [Server & Public IP address](server-purchase/digitalocean.md). This will cost you as low as $5 a month. If you use the DigitalOcean referral code, you'll get $100 credit - two months worth of free server: https://m.do.co/c/6410aa23d3f3 38 | 39 | #### B2) Server Specs 40 | 41 | _**CPU Architecture**:_ CapRover source code is compatible with any CPU architecture and the Docker build available on Docker Hub is built for AMD64 (X86), ARM64, and ARMV7 CPUs. 42 | 43 | _**Recommended Stack**:_ CapRover is tested on Ubuntu 22.04 and Docker 19.03. If you're using CapRover on a different OS, you might want to look at [Docker Docs](https://docs.docker.com/engine/userguide/storagedriver/selectadriver/#supported-storage-drivers-per-linux-distribution). 44 | 45 | _**Ubuntu 24.04**:_ This version [has been tested](https://github.com/caprover/caprover/issues/2244) by multiple people and there seems to be no known issues with this version. 46 | 47 | _**Minimum RAM**:_ Note that the build process sometimes consumes too much RAM, and 512MB RAM might not be enough (see [this issue](https://github.com/caprover/caprover/issues/28)). Most providers offer a minimum of 1GB RAM on \$5 instance including DigitalOcean, Vultr, Scaleway, Linode, SSD Nodes and etc. 48 | 49 | #### B3) Docker 50 | 51 | Your server must have Docker installed on it. If you get your server from DigitalOcean, you can select a server with CapRover one-click app and everything will be installed for you automatically. Otherwise, you can install Docker CE by following [this instruction](https://docs.docker.com/engine/installation). Note that your Docker version needs to be, at least, version 25.x+. 52 | 53 | **AVOID snap installation** [snap installation of Docker is buggy](https://github.com/caprover/caprover/issues/501#issuecomment-554764942). Use the official installation instructions for Docker. 54 | 55 | #### B4) Configure Firewall 56 | 57 | Some server providers have strict firewall settings. To disable firewall on Ubuntu: 58 | 59 | ```bash 60 | ufw allow 80,443,3000,996,7946,4789,2377/tcp; ufw allow 7946,4789,2377/udp; 61 | ``` 62 | 63 | See [firewall settings](firewall.md) if you need more details. 64 | 65 |
66 |
67 | 68 | # CapRover Setup 69 | 70 | ## Step 1: CapRover Installation 71 | 72 | Just run the following line, sit back and enjoy! 73 | 74 | ```bash 75 | docker run -p 80:80 -p 443:443 -p 3000:3000 -e ACCEPTED_TERMS=true -v /var/run/docker.sock:/var/run/docker.sock -v /captain:/captain caprover/caprover 76 | ``` 77 | 78 | NOTE: do not change the port mappings. CapRover only works on the specified ports. 79 | 80 | You will see a bunch of outputs on your screen. Once the CapRover is initialized, you can visit `http://[IP_OF_YOUR_SERVER]:3000` in your browser and login to CapRover using the default password `captain42`. You can change your password later. **However, do not make any changes in the dashboard**. We'll use the command line tool to setup the server (recommended). 81 | 82 | ## Step 2: Connect Root Domain 83 | 84 | Let's say you own `mydomain.com`. You can set `*.something.mydomain.com` as an `A-record` in your DNS settings to point to the IP address of the server where you installed CapRover. Note that it can take several hours for this change to take into effect. It will show up like this in your DNS configs: 85 | 86 | - **TYPE**: A record 87 | - **HOST**: `*.something` 88 | - **POINTS TO**: (IP Address of your server) 89 | - **TTL**: (doesn't really matter) 90 | 91 | To confirm, go to https://mxtoolbox.com/DNSLookup.aspx and enter `randomthing123.something.mydomain.com` and check if IP address resolves to the IP you set in your DNS. Note that `randomthing123` is needed because you set a wildcard entry in your DNS by setting `*.something` as your host, not `something`. 92 | 93 | > **NOTE**: CapRover requires A Record to be pointing to CapRover's IP Address. If you use proxy services, such as Cloudflare, you may face difficulties. CapRover does not officially support such use cases. 94 | 95 | ## Step 3: Configure and initialize CapRover 96 | 97 | ### With CLI (recommended) 98 | 99 | Assuming you have npm installed on your local machine (e.g., your laptop), simply run (add `sudo` if needed): 100 | 101 | ```bash 102 | npm install -g caprover 103 | ``` 104 | 105 | Then, run 106 | 107 | ```bash 108 | caprover serversetup 109 | ``` 110 | 111 | Follow the steps and login to your CapRover instance. When prompted to enter the root domain, enter `something.mydomain.com` assuming that you set `*.something.mydomain.com` to point to your IP address in step #2. Now you can access your CapRover from `captain.something.mydomain.com`. You can read more about hiding the root domain [here](./best-practices.md#hidden-root-domain). 112 | 113 | > **NOTE**: **It will not be possible to carry through with the `caprover serversetup` if you've already forced https on your CapRover instance.** 114 | > In such case go straight to logging in with the `caprover login` command. To change the password go to the settings menu in the app. 115 | 116 | ### With the web interface (doesn't require npm) 117 | 118 | 1. Login to `http://[IP_OF_YOUR_SERVER]:3000` 119 | 2. Configure the root domain 120 | 3. Enable HTTPS, then force it 121 | 4. Once you are connected through HTTPS, change the default password (`captain42`) 122 | 123 | ## Step 4: (Optional) Set up Swap file 124 | 125 | In some cases you may run into problems due to not having enough physical RAM. 126 | For example, when building a Docker image, if it starts to take up too much memory, the build will fail. 127 | To work around these problems (without purchasing more RAM) you can set up a Swap file (which is used as virtual RAM), 128 | by following these instructions on [How To Create A Linux Swap File](https://linuxize.com/post/create-a-linux-swap-file/). 129 | 130 | ## Step 5: Deploy the Test App 131 | 132 | Go to the CapRover in your browser, from the left menu select Apps and create a new app. Name it `my-first-app`. Then, download any of the test apps here, unzip the content. and while inside the directory of the test app, run: 133 | 134 | ```bash 135 | /home/Desktop/captain-examples/captain-node$ caprover deploy 136 | ``` 137 | 138 | Follow the instructions, enter `my-first-app` when asked for app name. First time build takes about two minutes. After build is completed, visit `my-first-app.something.mydomain.com` where `something.mydomain.com` is your root domain. 139 | CONGRATS! Your app is live!! 140 | 141 | You can connect multiple custom domains (like `www.my-app.com`) to a single app and enable HTTPS and do much more in the app's settings page. 142 | 143 | Note that when you run `caprover deploy`, the current git commit will be sent over to your server. 144 | 145 | > **IMPORTANT**: Uncommitted files and files in `gitignore` WILL NOT be sent to the server. 146 | 147 | You can visit CapRover in the browser and set custom parameters for your app such as environment variables, and do much more! For more details regarding deployment, please see [CLI docs](cli-commands.md). For details on `captain-definition` file, see [Captain Definition File](captain-definition-file.md). 148 | -------------------------------------------------------------------------------- /docs/nginx-customization.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: nginx-customization 3 | title: NGINX Config 4 | sidebar_label: NGINX Config 5 | --- 6 | 7 | ## Config Customization 8 | 9 | Although CapRover automatically manages everything about routing HTTP requests to your apps, there might still be some special config values that you want to manually tweak. It can be special caching logic for a special file type or route, timeout customization, max body size and many more parameters that you can manually adjust via nginx. 10 | 11 | CapRover enables you to manually adjust these parameters via fully customized config files. There are three areas that you can adjust parameters: 12 | 13 | - NGINX Base Config File (`/etc/nginx/nginx.conf` inside container). This is the first file that NGINX will look at. It redirects nginx to look up other config files. You can manually tweak this file in web dashboard, settings. 14 | - CapRover Config File (`/etc/nginx/conf.d/captain-root.conf` inside container). This is the config file that you, the developer, will interact with when you visit `captain.root.domain.com`. Typically, you shouldn't need to modify this file. But if you need to, you can modify it in web dashboard > settings 15 | - Application Specific Config File (`/etc/nginx/conf.d/captain.conf` inside container). This is where you can change application-specific settings. Let's say, you have a video uploader app where you want to allow incoming body size to be 1GB. You can do so, by going to web dashboard > Apps > Apps Edit and manually change this parameter. Note that any change that you make is only applied to this specific app, all other apps will use the default config. This configuration template will be applied to ALL DOMAINS pointing to the app, i.e., Captain creates one server block for `my-app-name.captainroot.domain.com` and potentially another server block `www.myapp.com` and etc... 16 | 17 | Once you've changed the template, you can see the compiled version of your nginx configs at `/captain/generated/nginx` from within the `caprover/caprover` Docker image (`docker exec -it docker_container_id /bin/sh`) in order to verify whether the final compiled version is what you wanted by examining the files listed below. Note that you CANNOT MANUALLY modify these files as they will get overridden by Captain. If you want to make any change, you should always change the Nginx template in CapRover dashboard. 18 | 19 | - `/captain/generated/nginx/nginx.conf` – generated NGINX Base Config File 20 | - `/captain/generated/nginx/conf.d/captain-root.conf` – generated CapRover Config File 21 | - `/captain/generated/nginx/conf.d/captain.conf` – generated Application Specific Config File 22 | 23 | ## Custom Files and Directories 24 | 25 | On top of config customization, you might need to use some files in your nginx container, things such as custom SSL certs, specific static assets and etc. Since in CapRover instance, everything (including nginx) is sitting in a separate container, you'll need to map a directory from your host to the container. Captain already did that for you. The directory `/captain/data/nginx-shared` in your server is available in your nginx container as `/nginx-shared`. Let's say you place a custom SSL cert in that folder and call it `/captain/data/nginx-shared/custom-cert.pem`. In order to reference that file in your nginx config, you'll use `/nginx-shared/custom-cert.pem` 26 | 27 | 28 | ## Customize and override the NGINX Config for all apps 29 | 30 | NOTE: this will be available starting version 1.11 31 | 32 | To modify the default NGINX configuration for newly created apps to add in the IP whitelist and other NGIX config. 33 | 34 | 1- Obtain a copy of the `server-block-conf.ejs` template from the CapRover GitHub repository. [**here**](https://github.com/caprover/caprover/blob/master/template/server-block-conf.ejs) 35 | 36 | 2- Create the file `/captain/data/server-block-conf-override.ejs`, copy the contents of the template, and make the desired modifications. 37 | Assuming you start CapRover Docker with `-v /captain:/captain.` 38 | -------------------------------------------------------------------------------- /docs/one-click-apps.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: one-click-apps 3 | title: One-Click Apps 4 | sidebar_label: One-Click Apps 5 | --- 6 | 7 |
8 | 9 | CapRover has built-in support for several popular apps that can be deployed as is. These include WordPress, MySQL, MongoDB and many more. 10 | 11 | There is a repository of [One Click Apps on GitHub](https://github.com/caprover/one-click-apps) and it's continuously growing. 12 | 13 | ![OneClickAppsCapRover](/img/docs/one-click.gif) 14 | 15 |

16 | 17 | #### Databases and Database GUI 18 | - MongoDB 19 | - MongoExpress 20 | - MsSQL 21 | - MySQL 22 | - Redis 23 | - PhpMyAdmin 24 | - PostgreSQL 25 | - Adminer 26 | - Apache CouchDB 27 | - Gitea 28 | - ElasticSearch 29 | - And many more... 30 | #### Blogging and Content 31 | - WordPress 32 | - Ghost 33 | - Prisma 1 34 | - Strapi 35 | - Minio 36 | - And many more... 37 | #### Dev Tools 38 | - Jenkins 39 | - Drone.io 40 | - Hasura 41 | - Nexus3 42 | - Many more... 43 | #### Other Apps 44 | - Parse 45 | - NextCloud 46 | - Rainloop 47 | - Thumbor 48 | - OhMyForm 49 | - And many more... 50 | 51 | 52 | 53 |
54 | 55 | Thanks to [@8byr0](https://github.com/8byr0), we have a **community maintained** [directory of apps](https://wizardly-ptolemy-8fcac8.netlify.app/). You can view the source code [here](https://github.com/8byr0/caprover-sampleapps-browser). 56 | 57 | 58 | ## What about other apps? 59 | Just because an app or database is not available as a one click app, it doesn't mean that you can't deploy it. All you need to do is to search for the Docker image of the app that you're looking for. For example, before NextCloud was available as a one click app, you could still deploy it manually like this 60 | ![nextcloud](/img/docs/nextcloud-deploy-manually.png) 61 | 62 | 63 | With CapRover v1, it's even easier than the method explained above. Since `captain-definition` now supports `imageName`. You can copy and past this into the deploy section of an app that you create. No more `tar` file creation is needed when all you need is `imageName`: 64 | 65 | ``` 66 | { 67 | "schemaVersion": 2, 68 | "imageName": "nextcloud:12-rc" 69 | } 70 | ``` 71 | All the environment variables that you can set are listed on their DockerHub page: https://hub.docker.com/_/nextcloud/ 72 | 73 |
74 | 75 | ## Configuration Settings 76 | 77 | They all come with pre-configured settings, however, you'll be have the option to customize the settings. For example, MySQL database uses port 3306, but you can change this port to another port if it suits your needs. 78 | 79 | It is important to mention that some of these configuration parameters, might show up as environment variables in your app settings after you deploy the app, however, their values only being used in the installing phase. i.e., changing password of MySQL through changing the PASSWORD environment variable will not work. Instead, you should use MySQL commands to change the password. The PASSWORD environment variable is being used to set up the original password during the installation phase. 80 | 81 | ## Upgrading One Click apps 82 | 83 | So you deployed your one click app and sometime later a new version comes out and you want to update your app. The process is different for different apps: 84 | 85 | #### Simple Image Update 86 | Most good quality apps allow you to simply update the underlying image and that's it! This usually the case for most application. For example, if you have a MySQL 5.5 and you want to upgrade to 5.7, you can simply go to the "Deployment" tab, navigate to the bottom and under **Method 6: Deploy via ImageName** just type in mysql:5.7 and click deploy! 87 | 88 | The image names are usually in `imagename:version` format or `account/image:version` format. You can look at the image that have been deployed by CapRover under the deployment history. Also you can look at the new versions at DockerHub. For example, 89 | - `mysql` versions can be found from here: https://hub.docker.com/_/mysql?tab=tags 90 | - `portainer/portainer` versions can be found from here: https://hub.docker.com/r/portainer/portainer/tags 91 | 92 | Note that there are other use cases where CapRover modifies the original image to provide more functionality. For example, redis container is modified to provide [authentication option](https://github.com/caprover/one-click-apps/blob/af172b6680583487bdeacf230d7abaf9b57f4811/public/v4/apps/redis.yml#L10-L12). In this case, it's easier to simply delete your app and recreate it. If your app has persistent data, make sure NOT TO REMOVE the volume when deleting the app and make sure to recreate the app with the exact same name so that the exact same volume will be attached to the app. 93 | 94 | 95 | 96 | #### Other cases 97 | Some apps have a different way of upgrading, specifically if they have persistent code data. WordPress is a good example. To upgrade WordPress, all you need to do is to perform upgrade from within the wordpress website panel itself. Sometimes on top of that, you need to upgrade the underlying image, in that case, just follow the guide above. 98 | 99 | 100 | ## Connecting to Databases 101 | 102 | ### Connecting Within CapRover Cluster 103 | 104 | Note that since all these applications are Docker containers, you can have multiple MySQL databases on running on port 3306 without having any conflict. If you want to connect to two different MySQL databases, from a PHP app, where both PHP and MySQLs are under the same instance of CapRover, you can use `srv-captain--mysqlappname1:3306` and `srv-captain--mysqlappname2:3306`. 105 | 106 | 107 | ### Connecting Remotely 108 | 109 | However, if you want to connect to your database from a remote machine (e.g. your laptop) you need to map a container port to a server port. In that case, you have to map two different ports on the server, for example: 110 | - Port 1001 of the server goes to mysql-1 port 3306 111 | - Port 1002 of the server goes to mysql-2 port 3306 112 | 113 | Port mapping is needed if you want to connect to a database from a remote machine. You can read more about it [Captain Configuration - Port Mapping](app-configuration.md#port-mapping). 114 | 115 | After port mapping, you can enter these values for your Database Client: 116 | - Host: IP-ADDRESS-OF-SERVER 117 | - Port: MAPPED-PORT-ON-HOST 118 | 119 | 120 | For example, in the example explained above, `MAPPED-PORT-ON-HOST` is `1001` for `mysql-1` and `1002` for `mysql-2`. 121 | 122 | Assuming your server ip is `123.123.123.123` and your mapped port is `9999`: 123 | - For Mongo DB, you would use `mongodb://dbuser:dbpassword@123.123.123.123:9999/dbname` 124 | - For MySQL, you would use `HOST: 123.123.123.123`, `PORT: 9999` 125 | - and etc... 126 | 127 | **IMPORTANT:** After port mapping is done make sure to open the server port. For example, if you mapped port 4444 of your host (server) to port 3306 of your container, you need to run the following command: 128 | 129 | ``` 130 | ufw allow 4444 131 | ``` 132 | -------------------------------------------------------------------------------- /docs/persistent-apps.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: persistent-apps 3 | title: Persistent Apps 4 | sidebar_label: Persistent Apps 5 | --- 6 | 7 |
8 | 9 | ### Persistent or Not 10 | 11 | When you want to create an app you have the option of creating the app with "Persistent Data" or not. By default, you should always prefer no persistence. However, they are cases where you need to create an app with persistence. Also, if you have a massive amount of static data that you don't want to bundle with your repository and have it shipped to the server everytime you build, you can map a directory on the host to a directory inside the container and FTP to your server and move your files there. This is generally not needed unless the amount of static data that you need to send to your server is extremely large. 12 | 13 | #### Persistent Apps: 14 | These are the apps that have some data that need to survive restart, crash, container update and etc. Because these apps store data on disk, once they get created they get locked down on a specific server (if you have multiple servers). You can still change the constraint so that they will be moved to another machine, but if you do, they will lose anything that might have been stored on the current host. Examples that use persistent apps include: 15 | - Any database that stores data on disk has to have persistent data enabled. Otherwise all data will be lost when the container restarts (due to crash, host restart and etc...) 16 | - A photo upload app which does not use third party storages like Amazon S3 to store images. Instead, it locally stores uploaded images. 17 | - A webapp that needs to store some user uploaded files and plugins locally on disk (like WordPress) 18 | 19 | The main limitation of apps with Persistent Data is that they cannot be run as multiple instances. That's because they would access the same storage area and the data can be corrupted if multiple apps try to write on the same path. 20 | 21 | Note that even for Persistent Apps, NOT ALL DIRECTORIES will be treated as persistent directories. After you created the app as an app with persistent data, you'll have to define directories that you want to be persistent in the app details page on web dashboard. You can let CapRover manage the stored directories for you (use labels), or use a specific path on the host (server). 22 | 23 | ##### Using label 24 | In that case, they will be placed in `/var/lib/docker/volumes/YOUR_VOLUME_NAME/_data` on your server. The path inside the container is completely customizable. By default, the volume name will have `captain--` prepended to the field you enter (e.g. `my-volume` will become `captain--my-volume`) 25 | 26 | ##### Using specific path 27 | For example, you can map `/var/usr` on your server to `/my-host-usr-something` in your container (app). This way you can save a file in your container at `/my-host-usr-something/myfile.txt` and the file will be available on your server (host) at `/var/usr/myfile.txt`. **Note** that, if you choose to use this option (specifying a specific host path), you'll have to make sure that the path already exists in your host before assigning it. 28 | 29 | #### Removing Persistent Apps: 30 | Persistent directories need to be manually removed after you remove an app from Captain dashboard. This is to avoid accidental deletion of important data. To delete persistent directories, depending on the type of persistent directories, steps are different: 31 | - Volumes (persistent directories mapped to a label): 32 | ![Volumes](/img/docs/label-path.png) 33 | For this type, you need to run `docker volume ls` to see the names of the volumes, and then run `docker volume rm NAME_OF_VOLUME` to remove the volume 34 | - Mapped directories on host: these are directories from your server that are mapped to a directory in your container (app). To remove them, simply remove the directory from your server via `rm -rf /path/to/directory` 35 | ![mapped](/img/docs/path-binding.png) 36 | 37 | #### Non-Persistent Apps: 38 | Generally speaking, anything that does not directly store data on disk can be made non-persistent. You should always prefer to have non-persistent apps as they are much more flexible. Let's say you have multiple servers, if a server becomes unhealthly, all "non-persistent" apps on that server will automatically get moved to other servers whereas persistent apps are locked down to that server due to some data that they saved on that server. 39 | 40 | Also, multiple instances of non-persistent apps can be running at the same time without causing any issues as they live in isolated environment and each of them has their very own disk space. Note that non persistent apps can still write data on disk, things on temporary cache and etc, but that data will get deleted once the container restarts due to a crash, deploy, configuration update or host restart. Examples include: 41 | 42 | - A image processor which takes a photo and runs some logic to figure out what is in the picture. This is a good example of an app that can benefit from getting spawned as multiple instances as it's CPU heavy. 43 | - A TODO web app. Note that this app will definitely uses some sort of database which is persistent. But the webapp itself does not store anything directly on disk. 44 | - An image upload app that uses Amazon S3 as the storage engine rather than storing images locally on disk 45 | -------------------------------------------------------------------------------- /docs/play-with-docker.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: play-with-docker 3 | title: Play with CapRover 4 | sidebar_label: Play with CapRover 5 | --- 6 | 7 |
8 | 9 | ## View-only Demo 10 | 11 | If you only want to see the view-only demo, go to the [home page](/) and click on **Live Demo** 12 | 13 |
14 | 15 | ## Working Demo 16 | 17 | If you want to create a working instance of CapRover, you can use Play-with-Docker website. This is a website that allows you to create Virtual Servers in seconds and install Docker images on it. This is the best play ground for playing with CapRover. 18 | 19 | 20 | ![](/img/pwd-caprover.gif) 21 | 22 | 23 | Follow these steps: 24 | - Make sure you have an account on [Docker Hub](https://hub.docker.com/). If you don't, create one, it's 100% free. 25 | - Go to [play-with-docker.com](http://play-with-docker.com/) 26 | - Click on Start and log in using your Docker Hub username/password 27 | - Once your session started you will see a page with a timer 28 | - You can click on **+ADD NEW INSTANCE** on the left side menu bar and create a Virtual Server 29 | - Once your server is created, copy and paste this command: 30 | ```bash 31 | curl -L https://pwd.caprover.com | bash 32 | ``` 33 | 34 | - The installation process takes about 2 minutes and it's fully automated. 35 | - When the installation process finishes, you'll see a message like this: 36 | ``` 37 | =================================== 38 | =================================== 39 | **** Installation is done! ***** 40 | CapRover is available at http://captain.ip123456789123456.direct.labs.play-with-docker.com 41 | Default password is: captain42 42 | =================================== 43 | =================================== 44 | ``` 45 | 46 | Simply copy the URL and log into CapRover using `captain42` as your password! 47 | 48 | **IMPORTANT:** YOU CANNOT enable https using play-with-docker, but other features should work normally. 49 | -------------------------------------------------------------------------------- /docs/pre-deploy-script.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: pre-deploy-script 3 | title: Pre-deploy Script 4 | sidebar_label: Pre-deploy Script 5 | --- 6 | 7 |
8 | This is a very advanced operation and requires attention. Otherwise, it can break the deployment for your app. 9 | 10 | This script will run right before your container (i.e. app) gets updated due to a configuration change or app deploy. In this script, you can modify the Docker service object, invoke an HTTP call, and literally do anything. The template for this script is: 11 | ``` 12 | var preDeployFunction = function (captainAppObj, dockerUpdateObject) { 13 | return Promise.resolve() 14 | .then(function(){ 15 | 16 | // Do something in a Promise form 17 | 18 | // In the end, return the "possibly-modified" dockerUpdateObject 19 | return dockerUpdateObject; 20 | }); 21 | }; 22 | 23 | ``` 24 | 25 | Note that `captainAppObj`, is the app object as saved in `/captain/data/config-captain.json` file, and `dockerUpdateObject` is the service update object that is being passed to Docker to update the service (environment vars, image version and etc). This object is as per [Docker docs](https://docs.docker.com/engine/api/v1.30/#operation/ServiceUpdate). 26 | 27 | Since this script will be executed in CapRover process, you'll get access to all node dependecies that CapRover has, see [Caprover/caprover/package.json](https://github.com/caprover/caprover/blob/master/package.json). For example, the following script injects a UUID mapped to the deployed version to service label with every update: 28 | 29 | ``` 30 | var { v4: uuid } = require('uuid'); 31 | 32 | var preDeployFunction = function (captainAppObj, dockerUpdateObject) { 33 | return Promise.resolve() 34 | .then(function(){ 35 | 36 | dockerUpdateObject.TaskTemplate.ContainerSpec.Labels[uuid()] = 37 | captainAppObj.deployedVersion+ ''; 38 | return dockerUpdateObject; 39 | }); 40 | }; 41 | 42 | ``` 43 | 44 | Note that this pre-deploy script, particularly Docker service update object, is complicated. Hence, it is strongly recommended to use this pre-deploy method if you are an expert user. For example, note that how an empty string is being added to the deployed version in this line: 45 | 46 | ``` 47 | dockerUpdateObject.TaskTemplate.ContainerSpec.Labels[uuid()] = captainAppObj.deployedVersion+ ''; 48 | ``` 49 | 50 | Removing this simple hack, will throw an error when deploying apps. To see logs, you need to run `docker service logs captain-captain --follow`. Even the error from Docker is not very clear. All in all, this is an advanced feature and is not recommended for beginners and intermediate users. 51 | -------------------------------------------------------------------------------- /docs/recipe-deploy-create-react-app.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: recipe-deploy-create-react-app 3 | title: Static React App 4 | sidebar_label: Static React App 5 | --- 6 | 7 | 8 | ## Sample App 9 | 10 | See [sample apps directory](https://github.com/caprover/caprover/tree/master/captain-sample-apps) for a ready to deploy React App. While the example given in that directory is great, if your server doesn't have enough RAM and your package.json has too many dependencies, your build process may crash on your server when it runs out of memory. In that case, you can follow the steps give below to build your app on your own local machine (e.g., your laptop) and deploy the built code to the server. 11 | 12 | 13 | ## Build on Local Machine 14 | 15 | Here is a small step-by-step guide to deploy a `create-react-app` as a static site. 16 | Unlike the regular `caprover deploy` that would deploy source files on a `NodeJS` container then build your app and run a small node server to serve your files, this guide shows how you can build locally and deploy the static bundle in a simple static server container. 17 | 18 | The big advantage of this technique is that the build happens on your machine where you already have `node_modules` and probably more computing power than on your server. You also only upload minified files and not the entire codebase. Because of these, the deployment is way faster and less computing intensive for your server. 19 | 20 | While this guide uses `create-react-app` as an example, you can apply the same technique for any static project (VueJS, Parcel, Angular...). 21 | 22 | #### Build your app 23 | 24 | The first thing you have to do is to build your app for production. 25 | 26 | ```bash 27 | npm run build 28 | ``` 29 | 30 | #### Create `captain-definition` 31 | 32 | Then create a `captain-definition` at the root of your project: 33 | 34 | ```json 35 | { 36 | "schemaVersion": 2, 37 | "dockerfileLines": [ 38 | "FROM socialengine/nginx-spa:latest", 39 | "COPY ./build /app", 40 | "RUN chmod -R 777 /app" 41 | ] 42 | } 43 | ``` 44 | 45 | This `captain-definition` uses `socialengine/nginx-spa` which is a simple static ngninx server that handle `pushState` (every request is routed to `/index.html` so you can use frontend routing). 46 | 47 | **Note**: If your `build` output in a different folder than `build` you need to change the `COPY ./build /app` into `COPY ./[my-output-folder] /app` 48 | 49 | #### Create the `tar` file 50 | 51 | Now you need to create a `tar` file, usually you don't have to do this because `caprover deploy` create one from you git repository but here we don't want to put the content of our repository in the `tar` but only the static files and `captain-definition` file. 52 | 53 | ```bash 54 | tar -cvf ./deploy.tar --exclude='*.map' ./captain-definition ./build/* 55 | ``` 56 | 57 | **Note**: If your `build` output in a different folder than `build` you need to replace `./build/*` with `./[my-output-folder]/*` 58 | 59 | **Note**: We also exclude `.map` files because these are usually quite big and make the upload longer. If you want `.map` files in production just remove the `--exclude='*.map'`. 60 | 61 | **Tip**: Add `deploy.tar` to your `.gitignore` to avoid accidentally pushing it 😉 62 | 63 | #### Deploy with `caprover` 64 | 65 | Now all we have to do is to use the `caprover` CLI with a `-t` argument to use our own `tar` file instead of the one made from the git repo. 66 | 67 | ```bash 68 | caprover deploy -t ./deploy.tar 69 | ``` 70 | 71 | Then answer the questions as usual, wait for the upload and 🎉 72 | -------------------------------------------------------------------------------- /docs/resource-monitoring.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: resource-monitoring 3 | title: Resource Monitoring 4 | sidebar_label: Resource Monitoring 5 | --- 6 |
7 | 8 | You always want to see how your app is behaving. Is it eating up your memory or CPU? Or is your network connection slow? You can answer all these questions by visiting Captain Monitoring menu from the web dashboard. You can enable [NetData](https://github.com/netdata/netdata) which is a server monitoring tool and monitor your server. 9 | 10 | 11 | ![](/img/netdata.gif) 12 | -------------------------------------------------------------------------------- /docs/run-locally.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: run-locally 3 | title: Run Locally 4 | sidebar_label: Run Locally 5 | --- 6 | 7 |
8 | Note that this is an **advanced process**. Some of the concepts used in this section are not easy for the beginners. In order to run CapRover on your local machine (just for testing and development) you need Docker installed on your machine. 9 | 10 |
11 | 12 | > Note: If you prefer visual tutorials, please refer to this community created tutorial on YouTube: https://www.youtube.com/watch?v=J_6H11DrzXY 13 | 14 | As for the root domain, by default, CapRover uses `http://captain.captain.localhost`. On most systems, `captain.captain.localhost` automatically resolves to local ip address of the machine, i.e. 127.0.0.1 and therefore no additional work is needed. 15 | 16 | > However, if it doesn't do that automatically, you need to manually point `*.captain.localhost` to `127.0.0.1` or `192.168.1.2` (your local ip). **NOTE** that `etc/hosts` won't be enough as Captain needs a wildcard entry and `etc/hosts` does not allow wildcards, i.e. `*.something`. On ubuntu 16, `dnsmasq` (a local DNS server) is built-in. So, it's as simple as editing this file: `/etc/NetworkManager/dnsmasq.d/dnsmasq-localhost.conf` (create it if it does not exist) and adding this line to it: `address=/captain.localhost/192.168.1.2` where `192.168.1.2` is your local IP address. To make sure you have `dnsmasq`, you can run `which dnsmasq` on your terminal. If it's available, its path will be printed on the terminal, otherwise, there won't be anything printed on your terminal. 17 | > Note: For Ubuntu 18, read https://askubuntu.com/questions/1029882/how-can-i-set-up-local-wildcard-127-0-0-1-domain-resolution-on-18-04 18 | 19 | To verify that you have both prerequisites mentioned above: 20 | 21 | - Run `docker version` and make sure your version is at least the version mentioned in the [docs](get-started.md#c-install-docker-on-server-at-least-version-1706x) 22 | - Run `nslookup randomstring123.captain.localhost` and make sure it resolves to `127.0.0.1` or your local ip (something like `192.168.1.2`): 23 | 24 | ``` 25 | Server: 127.0.1.1 26 | Address: 127.0.1.1#53 27 | 28 | Name: randomstring123.captain.localhost 29 | Address: 192.168.1.2 30 | ``` 31 | 32 | ## Installation 33 | 34 | Once you have confirmed that you have the prereqs ready, you can go ahead and install Captain on your machine, similar to what you do on your server. Make sure you run as a user with sufficient permission, i.e. `sudo` on linux based systems. Just follow the steps outlined here: [Captain Installation](get-started#step-1-captain-installation), except for a few differences mentioned below. 35 | 36 | ### Differences: 37 | 38 | #### Main IP 39 | 40 | First of all, the installation command for local installation requires an extra parameter (`MAIN_NODE_IP_ADDRESS`) 41 | 42 | ```bash 43 | echo "{\"skipVerifyingDomains\":\"true\"}" > /captain/data/config-override.json 44 | docker run -e ACCEPTED_TERMS=true -e MAIN_NODE_IP_ADDRESS=127.0.0.1 -p 80:80 -p 443:443 -p 3000:3000 -v /var/run/docker.sock:/var/run/docker.sock -v /captain:/captain caprover/caprover 45 | ``` 46 | **NOTE:** if port 80 and 443 are currently occupied and you want to run CapRover behind a reverse proxy, [see here](https://github.com/caprover/caprover/issues/1166#issuecomment-2430704491). 47 | 48 | #### Setup 49 | 50 | Do not run `caprover serversetup`. Instead, go to http://captain.captain.localhost:3000 and manually set root domain to `captain.localhost`. DO NOT enable/force HTTPS. Obviously, you cannot enable HTTPS on your local domain (captain.localhost). 51 | 52 | Once you set your root domain as `captain.localhost`, use `caprover login` and enter `http://captain.captain.localhost` as your captain URL and `captain42` as your default password. 53 | 54 | > However, if you want to access your CapRover instance from another device on your LAN, you can set the root domain to `captain.LOCAL_IP.sslip.io` (for example `captain.192.168.1.2.sslip.io`). 55 | 56 | **NON-LINUX USERS** 57 | You need to add `/captain` to shared paths. 58 | To do so, click on the Docker icon -> Setting -> File Sharing and add `/captain` 59 | 60 | You are set! 61 | 62 | ## Install CapRover on a Private [local] Network 63 | 64 | This is handy when you want to install CapRover on your home network, for example on a Raspberry pi. 65 | 66 | Imagine you have this network: 67 | 68 | ``` 69 | ┌───────────────────────┐ 70 | │ Your Router │ 71 | │ │ 72 | │ public IP │ 73 | │ 11.22.33.44 │ your private network 74 | ├───────────────────────┴─────────────────────────────────────────────────────────────────────┐ 75 | │ │ 76 | │ ┌────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ 77 | │ │ │ │ │ │ │ │ 78 | │ │ PC1 │ │ PC2 │ │ PC3 │ │ 79 | │ │ │ │ │ │ │ │ 80 | │ │ 192.168.1.10 │ │ 192.168.1.11 │ │ 192.168.1.12 │ │ 81 | │ │ │ │ │ │ │ │ 82 | │ └────────────────┘ └──────────────────┘ └──────────────────┘ │ 83 | │ │ 84 | │ │ 85 | │ │ 86 | └─────────────────────────────────────────────────────────────────────────────────────────────┘ 87 | ``` 88 | 89 | You can install CapRover on PC3 by simply running this command: 90 | 91 | ```bash 92 | echo "{\"skipVerifyingDomains\":\"true\"}" > /captain/data/config-override.json 93 | docker run -e ACCEPTED_TERMS=true -e MAIN_NODE_IP_ADDRESS=192.168.1.12 -p 80:80 -p 443:443 -p 3000:3000 -v /var/run/docker.sock:/var/run/docker.sock -v /captain:/captain caprover/caprover 94 | ``` 95 | 96 | The only extra bit is this: ` -e MAIN_NODE_IP_ADDRESS=192.168.1.12` and also disabling domain verification on CapRover. 97 | 98 | At this point, you should be able to access your CapRover dashboard from PC1 and PC2 via `http://192.168.1.12:3000` on your browser. 99 | 100 | Still you aren't able to deploy apps, but the dashboard should be accessible. 101 | If the dashboard isn't accessible, you have an internal firewall that prevents PC1 from accessing PC3. 102 | 103 | If the dashboard is accessible, move on to the next stages. 104 | 105 | ### option 1 - only internal usecase: 106 | 107 | You can install CapRover on your internal network so that it's only accessible from your private network. If you want to do that, you have to assign `*.caproverinstance.local` or something similar in your local DNS server to point to `192.168.1.12`. If you don't have a local DNS server you cannot do this. 108 | 109 | Some local DNS servers, like PiHole, don't allow wildcard in the local DNS entries, in that case, you have to add `captain.caproverinstance.local` to point to the IP. and in the future, add your apps names one by one. It's tedious but doable. 110 | 111 | Now, go to the dashboard via `http://192.168.1.12:3000` and update the root domain to `caproverinstance.local`. 112 | 113 | At this point, you should be able to access the dashboard via `http://captain.caproverinstance.local` in your browser. 114 | If you are having problem here, it means your local DNS server isn't working as expected. You'll have to fix it. 115 | 116 | Note that you should not (cannot) enable HTTPS for internal domains. 117 | 118 | ### option 2 - make the instance accessible from the outside. 119 | 120 | requirement: your public IP address must be a static IP address. 121 | 122 | This is very similar to how you install CapRover on a publicly available VPS. All you need to do is to enable port forwarding on your router: 123 | 124 | ``` 125 | port 80 of router => port 80 of 192.168.1.12 126 | port 443 of router => port 80 of 192.168.1.12 127 | ``` 128 | 129 | Now use your regular DNS provider and map `*.domain.com` to the public IP address of your network. 130 | 131 | Now, like a normal installation, just login to `http://192.168.1.12:3000` and update the root domain to `domain.com` 132 | 133 | At this point, your instance should be accessible from `http://captain.domain.com`. You can enable HTTPS and deploy your apps. 134 | 135 | ## Troubleshooting: 136 | 137 | As mentioned above, running a local machine is an advanced task and might fail due to different reasons, depending on the error, your solution might be different. For example, if you get the following error: 138 | 139 | ``` 140 | Captain Starting ... 141 | Installing Captain Service ... 142 | December 18th 2017, 11:51:11.295 pm Starting swarm at 34.232.18.13:2377 143 | Installation failed. 144 | { Error: (HTTP code 400) bad parameter - must specify a listening address because the address to advertise is not recognized as a system address, and a system's IP address to use could not be uniquely identified 145 | at /usr/src/app/node_modules/docker-modem/lib/modem.js:254:17 146 | at process._tickCallback (internal/process/next_tick.js:180:9) 147 | reason: 'bad parameter', 148 | statusCode: 400, 149 | json: 150 | { message: 'must specify a listening address because the address to advertise is not recognized as a system address, and a system\'s IP address to use could not be uniquely identified' } } 151 | ``` 152 | 153 | You can try this: 154 | 155 | ```bash 156 | docker run -e ACCEPTED_TERMS=true -e "MAIN_NODE_IP_ADDRESS=192.168.1.2" -v /var/run/docker.sock:/var/run/docker.sock caprover/caprover 157 | ``` 158 | 159 | and replace `192.168.1.2` with your own local IP. 160 | -------------------------------------------------------------------------------- /docs/sample-apps.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: sample-apps 3 | title: Sample Apps 4 | sidebar_label: Sample Apps 5 | --- 6 | 7 |
8 | CapRover is built on top of Docker container. Therefore, pretty much all applications can be deployed on CapRover. As mentioned in `captain-definition` docs, there is a few simple versions of `captain-definition` for most popular web languages such as NodeJS, PHP, python and ruby. 9 | 10 | However, CapRover is not limited to these languages. For example, it can deploy a go app. You just need a Dockerfile for it. 11 | 12 | 13 | ### Ready to be Deployed! 14 | 15 | Inside CapRover repo, you can find a collection of different sample apps that are ready to be deployed! See: 16 | https://github.com/caprover/caprover/tree/master/captain-sample-apps 17 | 18 | There are: 19 | - ASP .NET 20 | - Go app 21 | - nginx advance app 22 | - Python 23 | - Ruby 24 | - Elixir/Phoenix/LiveView 25 | - NodeJS 26 | - React App 27 | - and etc... 28 | 29 | 30 | To deploy sample apps, you just need to: 31 | - Download the tar file of your choice. 32 | - Go to your CapRover web dashboard and create a test app. 33 | - Go to "Deployment" tab and upload the tar file! 34 | - Done!! 35 | 36 | Now you can unzip the tar content and see what's inside. This will give you an idea how different apps can be deployed using CapRover (Docker). 37 | 38 | 39 | ### Community Apps 40 | 41 | A collection of sample apps from the community. 42 | 43 | #### CapRover Django 44 | 45 | This project template aims to provide a more real-world Django template including: 46 | - PostgreSQL 47 | - Instructions for CapRover setup 48 | - Handling of Django settings 49 | 50 | View the code and documentation on [GitLab](https://gitlab.com/kamneros/caprover-django) 51 | 52 | Additionaly, you can find a step by step tutorial to deploy your Django App to CapRover [here](https://blog.kenshuri.com/posts/006_from_heroku_to_capRover.md). 53 | 54 | #### CapRover Laravel 55 | 56 | - [jackbrycesmith/laravel-caprover-template](https://github.com/jackbrycesmith/laravel-caprover-template) 57 | 58 | #### Elixir/Phoenix App Deploy 59 | Deploy an Elixir/Phoenix LiveView web app complete with diagnostic dashboard. 60 | 61 | - [Drag and Drop tarball](https://github.com/TehSnappy/phoenix_sample/releases/download/v1.0/phoenix_sample.tar) 62 | - [Link to application code](https://github.com/TehSnappy/phoenix_sample) 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /docs/server-purchase/digitalocean.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: digitalocean 3 | title: Setting CapRover Up With DigitalOcean 4 | sidebar_label: DigitalOcean 5 | --- 6 | 7 | 8 | If this is your first time setting up a server, DigitalOcean is probably the easiest solution for you. Plus, you can use this link and get $100 credit! 9 | https://m.do.co/c/6410aa23d3f3 10 | 11 | DigitalOcean calls their servers "Droplets". After signing up, go to the Droplets section and click on "Create Droplet". Under choose an image, click on One-Click Apps, and select Docker. This way, Docker comes pre-installed with your server. If you have an SSH key, enter your SSH key at the bottom of this Droplet Create page, if not, don't worry, it's just alternative password. Once your Droplet is created, you will get an email with IP address of your server, user and pass. If you know how to SSH, then great, SSH into your server. If not, again don't worry! DigitalOcean is really beginner friendly. Simply go to your Droplets section on your DigitalOcean account, click on the Droplet you created. From the menu on the left side, select ACCESS and launch console. Enter `root` when asked for login and enter the password which you received in email. If you didn't receive your password in email, click on Reset Root Password below Launch Console button. Note that you'll have to type your long password. The web interface that DigitalOcean gives you does not support Copy/Paste ctrl+c ctrl+v. 12 | 13 | At this point you are logged into your server and you can run captain installer as explained in Getting Started section. 14 | -------------------------------------------------------------------------------- /docs/server-purchase/openstack.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: openstack 3 | title: Setting CapRover Up With OpenStack 4 | sidebar_label: OpenStack 5 | --- 6 | 7 | ## Why OpenStack? 8 | 9 | OpenStack is the most popular alternative to proprietary infrastructure-as-a-service (IaaS) cloud standards. 10 | Both huge cloud providers like AWS and Azure as well as some smaller ones like Hetzner have their own distinct APIs, 11 | configurations, and naming conventions for deploying resources. 12 | OpenStack allows you to deploy the same way on any cloud that implements the OpenStack standard (or even roll your own), 13 | thereby escaping vendor lock-in. 14 | 15 | ## Set up an OpenStack provider 16 | 17 | A number of cloud providers support OpenStack, including Infomaniak, VEXXHOST, OVHcloud, SharkTech, and more. 18 | 19 | Out of the providers I've seen, Infomaniak has the best [documentation](https://docs.infomaniak.cloud/). 20 | 21 | You should follow your provider's instructions for getting the cloud.yaml file for connection the OpenStack CLI 22 | to the cloud project. 23 | 24 | Here's a brief summary of the steps for Infomaniak. 25 | See their [documentation](https://docs.infomaniak.cloud/documentation/00.getting-started/01.Create_new_project/) for more details, including screenshots. 26 | Steps for other providers should be similar. 27 | 28 | 1. Create a new project in your public cloud dashboard. Call the project something like `caprover-prod`. 29 | 2. When prompted, generate and set a password for the OpenStack user. 30 | 3. Go to "Manage users" for the project. Click the dropdown next to the only user (starting with PCU-...) and download 31 | the clouds.yaml file. 32 | 4. Move `clouds.yaml` to a location [where the OpenStack client will be able to find it](https://docs.openstack.org/python-openstackclient/latest/configuration/index.html), i.e. 33 | `.config/openstack/clouds.yaml` in your home directory. 34 | If you've already set up the file before, copy and append the configuration to your existing file. 35 | 5. Open up your `clouds.yaml` file and change the cloud name from `PCP-...` to something more human-readable like 36 | `infomaniak-prod`. This will let you keep adding to your file as you add more environments or even other OpenStack 37 | providers. 38 | 6. Also insert the password you've generated in step 2 into the file. 39 | 40 | ## Install the OpenStack CLI and validate the connection 41 | 1. Install the OpenStack command line client. 42 | The [official OpenStack instructions](https://docs.openstack.org/newton/user-guide/common/cli-install-openstack-command-line-clients.html) 43 | would have you install the client via `pip`, but it's a lot cleaner to use [pipx](https://pipx.pypa.io/stable/) 44 | instead to avoid polluting your global Python package space: 45 | ``` 46 | pip install pipx 47 | pipx install python-openstackclient 48 | pipx inject python-openstackclient python-heatclient 49 | ``` 50 | 2. Validate the connection with the command: 51 | ``` 52 | openstack --os-cloud mycloud project list 53 | ``` 54 | (Note: in this and following commands, replace `mycloud` with the actual name you've set up in clouds.yaml, 55 | such as `vexxhost-dev` or `infomaniak-prod`). 56 | This should display your default project name. 57 | 58 | ## Deploy the OpenStack Heat template file 59 | 60 | 1. You'll need to generate a key to be able to SSH into your CapRover server if needed. 61 | You can create the folder `~/.ssh/openstack` or store your key wherever you like. 62 | ``` 63 | openstack --os-cloud mycloud keypair create caprover > ~/.ssh/openstack/mycloud.priv 64 | chmod 600 ~/.ssh/openstack/mycloud.priv 65 | ``` 66 | 2. Many OpenStack providers supply a default set of VM images. 67 | Check available images with 68 | ``` 69 | openstack --os-cloud mycloud image list 70 | ``` 71 | It's recommended to grab the latest version of Ubuntu LTS. 72 | You can also upload your own image by following the instructions 73 | [here](https://docs.openstack.org/heat/latest/getting_started/create_a_stack.html#preparing-to-create-a-stack). 74 | 3. Check available flavors with 75 | ``` 76 | openstack --os-cloud mycloud flavor list 77 | ``` 78 | 3. Check available networks with 79 | ``` 80 | openstack --os-cloud mycloud network list 81 | ``` 82 | 4. Finally, put all the pieces together to deploy CapRover. Be sure to replace the placeholder values with your own. 83 | ``` 84 | openstack --os-cloud mycloud stack create -t https://raw.githubusercontent.com/caprover/caprover/master/dev-scripts/openstack/single-instance.yml --parameter image_id= --parameter instance_type= --parameter network= caprover 85 | ``` 86 | For example, the following works on Infomaniak: 87 | ``` 88 | openstack --os-cloud infomaniak-dev stack create -t https://raw.githubusercontent.com/caprover/caprover/master/se 89 | tup/openstack/single-instance.yml --parameter image_id="Ubuntu 22.04 LTS Jammy Jellyfish" --parameter instance_type=a1-ram2-disk20-perf1 --parameter network=ext-net1 caprover 90 | ``` 91 | 92 | ## Validate the deployment 93 | 1. Log in to your OpenStack dashboard web UI. 94 | 2. Open Instances. You should see the instance `caprover-caprover_manager-...`. Copy its IP address. 95 | 3. You should be able to see the CapRover dashboard in your browser at `:3000`. 96 | From this point you should be able to finish setting up CapRover using the instructions in 97 | [Getting Started](https://caprover.com/docs/get-started.html) 98 | 4. You can also SSH into the instance with the command: 99 | ``` 100 | ssh -i ~/.ssh/openstack/mycloud-prod.priv -o StrictHostKeyChecking=accept-new ubuntu@ 101 | ``` 102 | After you're in, you can browse the output of the installation process from the Heat template with the command 103 | `sudo less /var/log/cloud-init-output.log`. -------------------------------------------------------------------------------- /docs/service-update-override.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: service-update-override 3 | title: Service Update Override 4 | sidebar_label: Service Update Override 5 | --- 6 | 7 | **Available as of v1.8.0** 8 | 9 | Although [pre-deploy script](pre-deploy-script.md) provides a great power for customization of the service, sometimes, it has too much power for what you need to do. 10 | 11 | For example, Docker allows you to define read-only volumes, or UDP only port mapping, and many other customization flags through [docker update command](https://docs.docker.com/engine/reference/commandline/service_update/). Not all of these flags are ported over to CapRover as they are rarely used. Nevertheless, there are situations where you want to use some of these flags. For these cases, you can define a service override JSON or YAML content. 12 | 13 | Every time you deploy a new version, or you change a configuration parameter in the app, your service goes through an update process: 14 | 15 | 1. CapRover updates the fields that are explicitly set on CapRover UI (env vars, instance count and etc). 16 | 2. If "Service Update Override" is present, CapRover overrides the result from the previous step with the override content. 17 | 3. If "Pre-deploy script" is present, CapRover runs the pre-deploy script. 18 | 4. The result from the previous 3 steps is then passed to the Docker API so that Docker can update the service under the hood. 19 | 20 | ## Schema 21 | 22 | For the "Service Update Override", you can use both yaml and JSON. The schema needs to match [Service Update Object](https://docs.docker.com/engine/api/v1.40/#operation/ServiceUpdate) in Docker API. In YAML format, it'll be something like the following YAML. Note that this is just a partial example, there are many more customization parameter available. 23 | 24 | ```yaml 25 | TaskTemplate: 26 | ContainerSpec: 27 | Labels: 28 | some.label: some.value 29 | Image: busybox 30 | Command: 31 | - ./mycommand.sh 32 | Hostname: my.domain.com 33 | CapabilityAdd: 34 | - CAP_NET_ADMIN 35 | DNSConfig: 36 | Nameservers: 37 | - 8.8.8.8 38 | - 8.8.4.4 39 | Mounts: 40 | - Type: bind 41 | Source: /host/directory 42 | Target: /some/path/in/container 43 | ReadOnly: true 44 | Args: 45 | - top 46 | Resources: 47 | Limits: 48 | MemoryBytes: 104857600 49 | NanoCPUs: 2000000000 50 | Reservations: 51 | MemoryBytes: 104857600 52 | NanoCPUs: 2000000000 53 | RestartPolicy: 54 | Condition: any 55 | MaxAttempts: 0 56 | Placement: 57 | Constraints: 58 | - node.id==2ivku8v2gvtg4 59 | Networks: 60 | - Target: captain-overlay-network 61 | LogDriver: 62 | Name: json-file 63 | Options: 64 | max-size: 512m 65 | ForceUpdate: 0 66 | Mode: 67 | Replicated: 68 | Replicas: 1 69 | UpdateConfig: 70 | Parallelism: 2 71 | Delay: 1000000000 72 | FailureAction: pause 73 | Monitor: 15000000000 74 | MaxFailureRatio: 0.15 75 | Order: start-first 76 | RollbackConfig: 77 | Parallelism: 1 78 | Delay: 1000000000 79 | FailureAction: pause 80 | Monitor: 15000000000 81 | MaxFailureRatio: 0.15 82 | Order: start-first 83 | EndpointSpec: 84 | Mode: vip 85 | Ports: 86 | - Name: something 87 | Protocol: tcp 88 | TargetPort: 80 89 | PublishedPort: 8080 90 | PublishMode: host 91 | ``` 92 | 93 | 94 | ## Sample Use Cases 95 | 96 | One common use case is to limit the resource usage by a particular service. In that case, you can do something like: 97 | 98 | ``` 99 | TaskTemplate: 100 | Resources: 101 | Limits: 102 | MemoryBytes: 104857600 103 | NanoCPUs: 2000000000 104 | ``` 105 | 106 | This will impose a limit of 2 CPUs and 100MB RAM usage on your service. You can confirm this by running 107 | ``` 108 | docker service inspect srv-captain--your-app-name --pretty 109 | ``` 110 | 111 | Another use case is when you want to customize the command: 112 | ```yaml 113 | TaskTemplate: 114 | ContainerSpec: 115 | Command: "./mycommand.sh" 116 | ``` 117 | 118 | If your container need some CAP_ADD added to the docker service, you can go as follow: 119 | 120 | ```yaml 121 | TaskTemplate: 122 | ContainerSpec: 123 | CapabilityAdd: 124 | - CAP_SYS_ADMIN 125 | - CAP_NET_ADMIN 126 | ``` 127 | 128 | 129 | 130 | ## Revert to Default 131 | 132 | One important note is that CapRover does NOT modify any existing flags that it doesn't control. Flags that CapRover controls are: env vars, ports, image, and a few others. 133 | 134 | If you override a property that is not controlled by CapRover, like the CPU limit in above, even if you delete the override, the config won't be reverted. This is because it has already been set in Docker engine. 135 | 136 | So instead of removing the override, change the override to another value, and then remove it. For example, if you want to remove the limitation on CPU and RAM: 137 | - First, set it to a high value, for example, RAM to 50GB and CPU to 20 CPUs 138 | - Then, you can remove the override. 139 | 140 | 141 | Of course, alternatively, you can delete the service and create a new one. 142 | -------------------------------------------------------------------------------- /docs/stateless-with-persistent-data.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: stateless-with-persistent-data 3 | title: Stateless with Persistent data 4 | sidebar_label: Stateless with Persistent data 5 | --- 6 | 7 | 8 | **Before you start here, please read:** 9 | 10 | * [Persistent Apps](persistent-apps.md) 11 | 12 | 13 | This documentation will help you set-up a stateless app with persistant data. For example a website hosted with "**php:7.4-apache**" serving the "**uploads**" ( `/var/www/html/uploads` ) folder or any other folder you define from for example AWS or Wasabi S3, or any of the other [storage systems rclone supports](https://rclone.org/overview/). This makes it possible to have an otherwise pinned to node X app, to fail-over to a other node within the same Docker swarm. 14 | 15 | There are multiple docker volume plugins to allow this set-up, I [@Daniël](https://caprover.slack.com/archives/DLR2Q4TC1) and my colleague Floris started out with "**rexray/s3fs**" but switched over to "**sapk/plugin-rclone**" as it was more stable, and handled fail-overs from node X to Y better. 16 | 17 | --- 18 | 19 | **Important note:** The below steps are for intermediate and advanced (*linux*) users. 20 | 21 | --- 22 | 23 | #### Placeholder variables 24 | 25 | * `$volumename` can for example be `captain--yourappname-rclone` 26 | * `$remotename` can for example be `captain--yourappname` 27 | * `$remotename/path` can for example be `captain--yourappname/_data` 28 | * `$rcloneremotename` can for example be `wasabi-s3` 29 | 30 | --- 31 | 32 | ### 1) Preparing rclone 33 | 34 | You start by creating the `rclone.conf` file, this can be done on any (*local*) machine that has rclone installed. 35 | For the ease of this documentation we'll assume you have [rclone installed](https://rclone.org/install/) on the primary node of your Docker swarm. 36 | 37 | From this primary node, run "**[rclone config](https://rclone.org/commands/rclone_config/)**" to create the config file, when done run `rclone config file` to know where the config file is stored. 38 | When you're using 'root' as you're user it will be stored in `/root/.config/rclone/rclone.conf` which we will use as a reference for the further writing of this guide. 39 | 40 | The `rclone.conf` file will look like something like this: 41 | 42 | ``` 43 | [$rcloneremotename] 44 | type = s3 45 | provider = Wasabi 46 | access_key_id = YourAccessKey 47 | secret_access_key = YourSecretAccessKey 48 | region = eu-central-1 49 | endpoint = s3.eu-central-1.wasabisys.com 50 | env_auth = false 51 | upload_cutoff = 25M 52 | chunk_size = 5M 53 | disable_checksum = false 54 | upload_concurrency = 3 55 | ``` 56 | 57 | Make sure each swarm node has the `/root/.config/rclone/rclone.conf` file, with the exact same content, double check by using `md5sum /root/.config/rclone/rclone.conf` and compare the checksums. 58 | *Or at least make sure, if there are multiple configs avaiable, that the one you'll be using is the same* 59 | 60 | ### 2) Prepare your storage system 61 | 62 | Make sure that your S3 bucket (or the folder you'll be using on the storage system you've configured via `rclone config`) actually exists and that the name of the bucket / folder matches the name of `$remotename` 63 | 64 | ### 3) Preparing the docker rclone plugin 65 | 66 | On each swarm node install the docker volume plugin with the help of this command `docker plugin install sapk/plugin-rclone` 67 | 68 | Then execute this command on each node, the below one was specially for "**php:N.N-apache**" containers ( _for example php:7.4-apache_ ) 69 | 70 | ``` 71 | docker volume create --driver sapk/plugin-rclone --opt config="$(base64 /root/.config/rclone/rclone.conf)" --opt args="--uid 33 --gid 33 --allow-root --allow-other" --opt remote=$rcloneremotename:$remotename/path --name $volumename 72 | ``` 73 | 74 | If you have an S3 bucket, in which files get uploaded via either AWS / Wasabi web interface, or anything else such as SFTPGo mounted to the S3 bucket, then you'll need to tell rclone to refresh it's dir cache: 75 | 76 | ``` 77 | docker volume create --driver sapk/plugin-rclone --opt config="$(base64 /root/.config/rclone/rclone.conf)" --opt args="--uid 33 --gid 33 --allow-root --allow-other --dir-cache-time 5s" --opt remote=$rcloneremotename:$remotename/path --name $volumename 78 | ``` 79 | 80 | What happens is that "**[rclone mount](https://rclone.org/commands/rclone_mount/)**" mounts the volume on the Docker swarm node(s), though be aware that other flags/parameters can benefit or negatively impact your app experience so test them throughout. 81 | 82 | **The above UID and GID are matched to Apache2 and can differentiate with other apps.** 83 | 84 | ### 4) Preparing the app 85 | 86 | Then deploy a blank app with "**Has Persistent Data**" unchecked, and set-up it's parameters of you're liking under the "**HTTP Settings**", "**App Configs**" & "**Deployment**" tabs. 87 | 88 | In the "**App Configs**" in the "**Service Update Override**" section, place the following. 89 | Be aware that `/var/www/html/uploads` is a path / folder you should define yourself, but is used for referene here. 90 | 91 | Set the "**ReadOnly**" value to either `true` or `false` based on what is appropirate to you're app. 92 | If you're php app allows it's users to upload files, set it to `false`. 93 | 94 | ``` 95 | TaskTemplate: 96 | ContainerSpec: 97 | Mounts: [ 98 | { 99 | "Type": "volume", 100 | "Source": "$volumename", 101 | "Target": "/var/www/html/uploads", 102 | "ReadOnly": false 103 | } 104 | ] 105 | ``` 106 | 107 | This way the application running on "*php:7.4-apache*" can move from node1 to any other nodes that are properly configured. 108 | 109 | If you have a question, or run into issues, please get in contact via Slack in the General channel and if needed mention me [@Daniël](https://caprover.slack.com/archives/DLR2Q4TC1) and I or anyone else will try to help you out. 110 | -------------------------------------------------------------------------------- /docs/support.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: support 3 | title: Help and Support 4 | sidebar_label: Help and Support 5 | --- 6 | 7 |
8 | 9 | ### Where to Get Support? 10 | 11 | If you're reporting a bug, or you have a feature request, you can use GitHub issues: 12 | https://github.com/caprover/caprover/issues 13 | 14 | If you need some help with deployment and something does not quite work, message on [**Slack Chat**](https://join.slack.com/t/caprover/shared_invite/zt-2qlb28drp-RpxNfY3nUhroLuRJUUJzDA) or use [**GitHub Issues**](https://github.com/caprover/caprover/issues). 15 | 16 | ### Need Commercial Support? 17 | 18 | Feel free to send an email to `support at/caprover/dot/com` to get our rates. 19 | 20 | Alternatively, you can use the following third party entities for their paid service: 21 | 22 | ### Need Hourly Consultation? 23 | 24 | #### [PremoWeb Internet Services](https://premoweb.com) 25 | 26 |        Got a complicated application stack or many applications you'd like to move to Caprover? PremoWeb is a United States based business now offering application migration services for those who want to make the migration. Schedule a free consulation with owner Nick Maietta at 888-PREMOWEB (888-773-6693) or via email at `nick at/premoweb/dot/com`. You can also find Nick on the Slack Group. 27 | 28 | ### You!! 29 | 30 | Please feel free to [edit](https://github.com/caprover/caprover-website/edit/master/docs/support.md) add your name here if you're familiar with CapRover. 31 | 32 | ### Need Airtight System? 33 | 34 | CapRover uses many services for hosting code, building, health control, and running, such as GitHub, Google, Docker Hub and etc. It also hosts many 3rd party apps, either in form of plugins (such as NetData) or One-Click apps. These apps may use 3rd party services, i.e. their backend services. If you need to run CapRover in an airtight situation, for example an environment that doesn't have access to the internet, please contact us for private support `support at/caprover/dot/com`. 35 | -------------------------------------------------------------------------------- /docs/theme-customization.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: theme-customization 3 | title: Custom Themes 4 | sidebar_label: Custom Themes 5 | --- 6 | 7 | _As of version 1.13_ 8 | 9 | CapRover now offers theme customization to give you more control over the look and feel of your dashboard. Utilizing Ant Design for our front-end framework, you can tailor the UI to match your preferences. To get started, refer to the [Ant Design customization documentation](https://ant.design/docs/react/customize-theme) for detailed guidance. By tweaking variables such as primary color, border radius, and font size, you can create a personalized theme that reflects your brand or taste. Happy theming! 10 | 11 | ![](/img/themes.gif) 12 | 13 | **A few notes:** 14 | 15 | - Ant Design theme is a javascript object, not a stringified JSON. The keys do not have double quotes. 16 | - There are 3 variables that are passed to Ant Design theme: `isDarkMode`, `darkAlgorithm` and `defaultAlgorithm`. For example you can use `colorBg: isDarkMode?'#010101':'#ffffff'` 17 | 18 | ### Other customizations 19 | 20 | Other than Ant Design theme customizations, there are two other ways you can customize your dashboard: 21 | 22 | #### Embed elements into 23 | 24 | This is typically used to inject fonts. For example, the legacy theme, uses: 25 | 26 | ```html 27 | 31 | ``` 32 | 33 | To load Quicksand font as it's used in the customized Ant Design theme. But really, you can do anything with this box! 34 | 35 | You can insert custom JS that completely modifies the elements on the dashboard however you want. You can even insert Google analytics tags! 36 | 37 | #### CapRover extra configurations: 38 | 39 | There are some customizations that are not modifiable by Ant Design by default. Those customizations can be modified through CapRover extra configuration box. 40 | 41 | Currently, the only parameter here is the theme of side bar on the dashboard (light or dark), but there might be more in the future. 42 | 43 | ```js 44 | { 45 | siderTheme: "dark"; 46 | } 47 | ``` 48 | 49 | 50 | 51 | ### Submit your custom themes! 52 | 53 | If you have built a new fun theme, feel free to submit a pull request to include it in [our built-in themes](https://github.com/caprover/caprover/tree/master/template/themes) 54 | -------------------------------------------------------------------------------- /docs/troubleshooting-pro.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: troubleshooting-pro 3 | title: Troubleshooting CapRover Pro 4 | sidebar_label: Troubleshooting (Pro) 5 | --- 6 | 7 |
8 | 9 | This section is only applicable to CapRover Pro subscribers (paid plans). You can subscribe to paid plans and benefit from additional features such as build status notifications, security upgrades such as login alerts and two factor authentication. 10 | 11 | ## Reset OTP (two factor auth) 12 | 13 | You may need to reset the two factor authentication in rare cases such as: 14 | 15 | - When https://pro.caprover.com is down and you cannot access your instance 16 | - When you have lost access to the authenticator app 17 | 18 | In these cases, all you need to do is to simply clear the pro configs and temporarily downgrade your server to a non-paid version. You can do that by removing the `pro` content in `/captain/data/config-captain.json` 19 | 20 | The following helper script will do exactly that: 21 | 22 | ```bash 23 | docker service scale captain-captain=0 && \ 24 | docker run -it --rm -v /captain:/captain caprover/caprover /bin/sh -c "wget https://raw.githubusercontent.com/caprover/caprover/master/dev-scripts/clear-pro-config.js ; node clear-pro-config.js ;" && \ 25 | docker service scale captain-captain=1 && \ 26 | echo "OKAY" 27 | 28 | ``` 29 | 30 | **Update:** 31 | 32 | Starting v1.12.0, you can run the following script: 33 | 34 | ```bash 35 | docker exec -it $(docker ps --filter name=captain-captain -q) npm run disable-otp 36 | ``` 37 | 38 | ## Deploy with OTP enabled 39 | 40 | When you have OTP enabled, you cannot deploy using regular `caprover deploy` as it requires 2FA token (`enter OTP token as well`). Instead, you should use App Tokens: 41 | 42 | ```bash 43 | caprover deploy --caproverUrl https://captain.domain.com --appToken 123456123456123456 --appName my-app -b main 44 | ``` 45 | 46 | You can enable App Token from Deployment tab. Alternatively, you can use the following format (not recommended): 47 | 48 | ```bash 49 | CAPROVER_OTP_TOKEN=123456; caprover login 50 | 51 | ## or 52 | 53 | CAPROVER_OTP_TOKEN=123456; caprover deploy 54 | ``` 55 | 56 | ## Set specific email address for the alerts 57 | 58 | Changing notification emails is not currently a built in feature. However, one of the many reasons that Google was chosen to be our auth provider is that on Gmail you can easily set up filters and forward specific emails to a different email address. 59 | 60 | Just search for `from: alerts@mail.pro.caprover.com` and create a filter, then forward your results to another email address. 61 | 62 | ![gmail-instruction-1](/img/docs/gmail-1.png) 63 | ![gmail-instruction-2](/img/docs/gmail-2.png) 64 | 65 | ## Email support 66 | 67 | Our paid Pro plan includes a 24hr SLA email support. You can email us at `pro.support at/caprover/dot/com` to get support. Please be sure to use the same email that you've used for purchase. 68 | -------------------------------------------------------------------------------- /docs/zero-downtime.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: zero-downtime 3 | title: Zero Downtime Deployments 4 | sidebar_label: Zero Downtime 5 | --- 6 | 7 | #### Example: 8 | 9 | If you prefer to learn from an example, see [this github repository](https://github.com/caprover/zero-downtime-example). 10 | 11 | This repo contains an example app that takes 15sec to start up. But, when deploying this app on any CapRover instance, you will not see any 502 errors. 12 | 13 | Keep in mind that you need to ensure that, when creating an app, you **DO NOT** check the "persistent data" checkbox. 14 | 15 | ### Understanding the Challenge 16 | 17 | During the deployment process, when a new Docker image is being rolled out, there might be a temporary service disruption (502 error during deployment). This usually occurs because the new container can take some time (e.g., 30 seconds) to become fully operational. During this time, if the service receives traffic, Nginx might return a 502 Bad Gateway error, indicating that it cannot receive a response from the backend service. 18 | 19 | ### The Role of Docker Health Checks 20 | 21 | Docker health checks are a vital feature that helps mitigate deployment-induced downtime. They allow you to specify a command in a Dockerfile for periodically checking the health of a container. Docker then uses this information to manage the lifecycle of the container based on its state. 22 | 23 | ### Implementing Health Checks in CapRover 24 | 25 | To integrate health checks into your CapRover deployment process, follow these steps: 26 | 27 | **Step 1:** Define the Health Check in Your Dockerfile 28 | Modify your Dockerfile to include a `HEALTHCHECK` instruction. This instruction tells Docker how to test the container to check if it is still working. This can be a command that checks the internal state of the container or makes a request to a HTTP endpoint. 29 | 30 | ```dockerfile 31 | HEALTHCHECK --interval=30s --timeout=30s --retries=3 \ 32 | CMD curl -f http://127.0.0.1:3000/ || exit 1 33 | ``` 34 | 35 | In this example, curl will request the root URL of the container every 30 seconds. If curl exits with a non-zero status more than three times in a row (as defined by 36 | `--retries`), the container is considered unhealthy. 37 | 38 | **Step 2:** Deploy and Configure in CapRover 39 | Once your Dockerfile is updated, deploy your application via CapRover. The platform, which uses Docker Swarm, will recognize the health check instructions and manage the deployment accordingly. 40 | 41 | CapRover's default behavior, with Docker Swarm, will wait for the new container to pass its health check before routing traffic to it. This effectively avoids routing requests to containers that are not ready to handle them, thereby preventing 502 errors. 42 | 43 | ### When does it not work? 44 | 45 | If your app doesn't use a volume, CapRover uses `start-first` strategy when updating the containers. This means that the new version of your container will be up and running before the old one is killed. This should give you next-to-zero downtime. 46 | 47 | This strategy is intentionally not applied to apps with volumes attached to them. This is because if multiple instances of the same service are trying to access the same file, this will result in data corruption and failures. For apps with volumes (**persistent data**), CapRover user `stop-first` strategy. This means that the old container is stopped first, before the new container starts up. This results in some amount of downtime. 48 | 49 | If your app has persistent data, you can still force the `start-first` strategy, but keep in mind that if might cause data corruption as the old and new container might try to write the same file at the same time. If you still want to proceed with this, you can simply enter this in your [service override](service-update-override.md) 50 | 51 | ```yaml 52 | UpdateConfig: 53 | Parallelism: 2 54 | Delay: 1000000000 55 | FailureAction: pause 56 | Monitor: 15000000000 57 | MaxFailureRatio: 0.15 58 | Order: start-first 59 | ``` 60 | -------------------------------------------------------------------------------- /graphics/caprover-logo/image823-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/caprover-logo/image823-6.jpg -------------------------------------------------------------------------------- /graphics/caprover-logo/image823-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/caprover-logo/image823-6.png -------------------------------------------------------------------------------- /graphics/caprover-logo/logo2-lrg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/caprover-logo/logo2-lrg.png -------------------------------------------------------------------------------- /graphics/caprover-logo/text-libel-suit.regular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/caprover-logo/text-libel-suit.regular.png -------------------------------------------------------------------------------- /graphics/captain-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/captain-architecture.png -------------------------------------------------------------------------------- /graphics/captain-in-one-picture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/captain-in-one-picture.png -------------------------------------------------------------------------------- /graphics/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 39 | 41 | 42 | 44 | image/svg+xml 45 | 47 | 48 | 49 | 50 | 51 | 55 | 58 | 64 | 69 | 74 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /graphics/screenshots-video-small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/screenshots-video-small.gif -------------------------------------------------------------------------------- /graphics/screenshots-video-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/screenshots-video-small.png -------------------------------------------------------------------------------- /graphics/screenshots-video.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/screenshots-video.gif -------------------------------------------------------------------------------- /graphics/screenshots.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/screenshots.gif -------------------------------------------------------------------------------- /graphics/screenshots/Screenshot from 2019-01-29 20-41-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/screenshots/Screenshot from 2019-01-29 20-41-11.png -------------------------------------------------------------------------------- /graphics/screenshots/Screenshot from 2019-01-29 20-41-33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/screenshots/Screenshot from 2019-01-29 20-41-33.png -------------------------------------------------------------------------------- /graphics/screenshots/Screenshot from 2019-01-29 20-42-08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/screenshots/Screenshot from 2019-01-29 20-42-08.png -------------------------------------------------------------------------------- /graphics/screenshots/Screenshot from 2019-01-29 20-42-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/screenshots/Screenshot from 2019-01-29 20-42-20.png -------------------------------------------------------------------------------- /graphics/screenshots/Screenshot from 2019-01-29 20-42-31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/screenshots/Screenshot from 2019-01-29 20-42-31.png -------------------------------------------------------------------------------- /graphics/twitter-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/twitter-cover.png -------------------------------------------------------------------------------- /graphics/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/twitter.png -------------------------------------------------------------------------------- /graphics/twitter.pxd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/twitter.pxd -------------------------------------------------------------------------------- /graphics/twitter_cover-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/twitter_cover-2.png -------------------------------------------------------------------------------- /graphics/twitter_cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caprover/caprover-website/0116a10fe3d65a8a98bce5afddea0571b0fcf37c/graphics/twitter_cover.png -------------------------------------------------------------------------------- /website/CNAME: -------------------------------------------------------------------------------- 1 | caprover.com 2 | -------------------------------------------------------------------------------- /website/build_dir: -------------------------------------------------------------------------------- 1 | export BUILD_DIR="./build/CapRover" -------------------------------------------------------------------------------- /website/core/Footer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | const React = require('react'); 9 | 10 | class Footer extends React.Component { 11 | docUrl(doc) { 12 | const baseUrl = this.props.config.baseUrl; 13 | return baseUrl + 'docs/' + doc; 14 | } 15 | 16 | pageUrl(doc, language) { 17 | const baseUrl = this.props.config.baseUrl; 18 | return baseUrl + (language ? language + '/' : '') + doc; 19 | } 20 | 21 | render() { 22 | const currentYear = new Date().getFullYear(); 23 | return ( 24 | 78 | ); 79 | } 80 | } 81 | 82 | module.exports = Footer; 83 | -------------------------------------------------------------------------------- /website/i18n/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment": "This file is auto-generated by write-translations.js", 3 | "localized-strings": { 4 | "next": "Next", 5 | "previous": "Previous", 6 | "tagline": "Scalable, Free and Self-hosted PaaS!", 7 | "docs": { 8 | "app-configuration": { 9 | "title": "App Configuration", 10 | "sidebar_label": "App Configuration" 11 | }, 12 | "app-scaling-and-cluster": { 13 | "title": "App Scaling & Cluster", 14 | "sidebar_label": "App Scaling & Cluster" 15 | }, 16 | "backup-and-restore": { 17 | "title": "Backup & Restore", 18 | "sidebar_label": "Backup & Restore" 19 | }, 20 | "best-practices": { 21 | "title": "Best Practices", 22 | "sidebar_label": "Best Practices" 23 | }, 24 | "captain-definition-file": { 25 | "title": "Captain Definition File", 26 | "sidebar_label": "Captain Definition File" 27 | }, 28 | "cdd-migration": { 29 | "title": "CaptainDuckDuck Upgrade", 30 | "sidebar_label": "CaptainDuckDuck Upgrade" 31 | }, 32 | "certbot-config": { 33 | "title": "Certbot Overrides", 34 | "sidebar_label": "Certbot Overrides" 35 | }, 36 | "ci-cd-integration": { 37 | "title": "CI/CD Integration", 38 | "sidebar_label": "Intro" 39 | }, 40 | "ci-cd-integration/deploy-from-github": { 41 | "title": "Build, Test and Deploy from GitHub", 42 | "sidebar_label": "Deploy from GitHub" 43 | }, 44 | "ci-cd-integration/deploy-from-gitlab": { 45 | "title": "Deploying from Gitlab", 46 | "sidebar_label": "Deploy from GitLab" 47 | }, 48 | "cli-commands": { 49 | "title": "CLI Commands", 50 | "sidebar_label": "CLI Commands" 51 | }, 52 | "complete-webapp-tutorial": { 53 | "title": "Complete Webapp Tutorial", 54 | "sidebar_label": "Complete Webapp Tutorial" 55 | }, 56 | "database-connection": { 57 | "title": "Database Connection", 58 | "sidebar_label": "Database Connection" 59 | }, 60 | "deployment-methods": { 61 | "title": "Deployment Methods", 62 | "sidebar_label": "Deployment Methods" 63 | }, 64 | "disk-cleanup": { 65 | "title": "Disk Clean-Up", 66 | "sidebar_label": "Disk Clean-Up" 67 | }, 68 | "docker-compose": { 69 | "title": "Docker Compose", 70 | "sidebar_label": "Docker Compose" 71 | }, 72 | "firewall": { 73 | "title": "Firewall & Port Forwarding", 74 | "sidebar_label": "Firewall & Port Forwarding" 75 | }, 76 | "get-started": { 77 | "title": "Getting Started", 78 | "sidebar_label": "Getting Started" 79 | }, 80 | "nginx-customization": { 81 | "title": "NGINX Config", 82 | "sidebar_label": "NGINX Config" 83 | }, 84 | "one-click-apps": { 85 | "title": "One-Click Apps", 86 | "sidebar_label": "One-Click Apps" 87 | }, 88 | "persistent-apps": { 89 | "title": "Persistent Apps", 90 | "sidebar_label": "Persistent Apps" 91 | }, 92 | "play-with-docker": { 93 | "title": "Play with CapRover", 94 | "sidebar_label": "Play with CapRover" 95 | }, 96 | "pre-deploy-script": { 97 | "title": "Pre-deploy Script", 98 | "sidebar_label": "Pre-deploy Script" 99 | }, 100 | "recipe-deploy-create-react-app": { 101 | "title": "Static React App", 102 | "sidebar_label": "Static React App" 103 | }, 104 | "resource-monitoring": { 105 | "title": "Resource Monitoring", 106 | "sidebar_label": "Resource Monitoring" 107 | }, 108 | "run-locally": { 109 | "title": "Run Locally", 110 | "sidebar_label": "Run Locally" 111 | }, 112 | "sample-apps": { 113 | "title": "Sample Apps", 114 | "sidebar_label": "Sample Apps" 115 | }, 116 | "server-purchase/digitalocean": { 117 | "title": "Setting CapRover Up With DigitalOcean", 118 | "sidebar_label": "DigitalOcean" 119 | }, 120 | "server-purchase/openstack": { 121 | "title": "Setting CapRover Up With OpenStack", 122 | "sidebar_label": "OpenStack" 123 | }, 124 | "service-update-override": { 125 | "title": "Service Update Override", 126 | "sidebar_label": "Service Update Override" 127 | }, 128 | "stateless-with-persistent-data": { 129 | "title": "Stateless with Persistent data", 130 | "sidebar_label": "Stateless with Persistent data" 131 | }, 132 | "support": { 133 | "title": "Help and Support", 134 | "sidebar_label": "Help and Support" 135 | }, 136 | "theme-customization": { 137 | "title": "Custom Themes", 138 | "sidebar_label": "Custom Themes" 139 | }, 140 | "troubleshooting-pro": { 141 | "title": "Troubleshooting CapRover Pro", 142 | "sidebar_label": "Troubleshooting (Pro)" 143 | }, 144 | "troubleshooting": { 145 | "title": "Troubleshooting", 146 | "sidebar_label": "Troubleshooting" 147 | }, 148 | "zero-downtime": { 149 | "title": "Zero Downtime Deployments", 150 | "sidebar_label": "Zero Downtime" 151 | } 152 | }, 153 | "links": { 154 | "Docs": "Docs", 155 | "GitHub": "GitHub", 156 | "Slack Group": "Slack Group" 157 | }, 158 | "categories": { 159 | "Basics": "Basics", 160 | "Do More": "Do More", 161 | "Recipes and Tips": "Recipes and Tips", 162 | "Help": "Help" 163 | } 164 | }, 165 | "pages-strings": { 166 | "Help Translate|recruit community translators for your project": "Help Translate", 167 | "Edit this Doc|recruitment message asking to edit the doc source": "Edit", 168 | "Translate this Doc|recruitment message asking to translate the docs": "Translate" 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "examples": "docusaurus-examples", 4 | "start": "docusaurus-start", 5 | "build": "docusaurus-build", 6 | "publish-gh-pages": "docusaurus-publish", 7 | "publish": "rm -rf ./build && docusaurus-build && cp ./CNAME ./build/CapRover/ && node publish_to_github_pages.js", 8 | "clean-build": "rm -rf ./build && docusaurus-build && cp ./CNAME ./build/CapRover/ && echo 'Finished building'", 9 | "write-translations": "docusaurus-write-translations", 10 | "version": "docusaurus-version", 11 | "rename-version": "docusaurus-rename-version" 12 | }, 13 | "devDependencies": { 14 | "docusaurus": "^1.14.6", 15 | "gh-pages": "^3.1.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /website/pages/email-sub.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Email Subscription 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 26 |
27 |
31 |
32 | 33 | 34 |
35 | 41 | 43 | 44 | 45 |
46 | 47 |
48 | 49 | 50 |
51 | 56 |
57 |
58 | 60 |
61 |
62 |
63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /website/pages/en/help.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | const React = require('react'); 9 | 10 | const CompLibrary = require('../../core/CompLibrary.js'); 11 | const Container = CompLibrary.Container; 12 | const GridBlock = CompLibrary.GridBlock; 13 | 14 | const siteConfig = require(process.cwd() + '/siteConfig.js'); 15 | 16 | function docUrl(doc, language) { 17 | return siteConfig.baseUrl + 'docs/' + (language ? language + '/' : '') + doc; 18 | } 19 | 20 | class Help extends React.Component { 21 | render() { 22 | let language = this.props.language || ''; 23 | const supportLinks = [ 24 | { 25 | content: `Learn more using the [documentation on this site.](${docUrl( 26 | 'doc1.html', 27 | language 28 | )})`, 29 | title: 'Browse Docs', 30 | }, 31 | { 32 | content: 'Ask questions about the documentation and project', 33 | title: 'Join the community', 34 | }, 35 | { 36 | content: "Find out what's new with this project", 37 | title: 'Stay up to date', 38 | }, 39 | ]; 40 | 41 | return ( 42 |
43 | 44 |
45 |
46 |

Need help?

47 |
48 |

This project is maintained by a dedicated group of people.

49 | 50 |
51 |
52 |
53 | ); 54 | } 55 | } 56 | 57 | module.exports = Help; 58 | -------------------------------------------------------------------------------- /website/pages/googlea598efcb1b249f09.html: -------------------------------------------------------------------------------- 1 | google-site-verification: googlea598efcb1b249f09.html -------------------------------------------------------------------------------- /website/publish-from-actions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # FROM: https://raw.githubusercontent.com/maxheld83/ghpages/master/LICENSE 4 | # MIT License 5 | 6 | # Copyright (c) 2019 Maximilian Held 7 | 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | 15 | # The above copyright notice and this permission notice shall be included in all 16 | # copies or substantial portions of the Software. 17 | 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE. 25 | 26 | 27 | set -e 28 | 29 | source ./build_dir 30 | 31 | echo "#################################################" 32 | echo "Changing directory to 'BUILD_DIR' $BUILD_DIR ..." 33 | cd $BUILD_DIR 34 | 35 | echo "#################################################" 36 | echo "Now deploying to GitHub Pages..." 37 | REMOTE_REPO="https://${GITHUB_PERSONAL_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" && \ 38 | REPONAME="$(echo $GITHUB_REPOSITORY| cut -d'/' -f 2)" && \ 39 | OWNER="$(echo $GITHUB_REPOSITORY| cut -d'/' -f 1)" && \ 40 | GHIO="${OWNER}.github.io" && \ 41 | if [[ "$REPONAME" == "$GHIO" ]]; then 42 | REMOTE_BRANCH="master" 43 | else 44 | REMOTE_BRANCH="gh-pages" 45 | fi && \ 46 | git init && \ 47 | git config user.name "${GITHUB_ACTOR}" && \ 48 | git config user.email "${GITHUB_ACTOR}@users.noreply.github.com" && \ 49 | if [ -z "$(git status --porcelain)" ]; then 50 | echo "Nothing to commit" && \ 51 | exit 0 52 | fi && \ 53 | git add . && \ 54 | git commit -m 'Deploy to GitHub Pages' && \ 55 | echo "REMOTE_BRANCH: $REMOTE_BRANCH" && \ 56 | git push --force $REMOTE_REPO master:$REMOTE_BRANCH && \ 57 | rm -fr .git && \ 58 | cd $GITHUB_WORKSPACE && \ 59 | echo "Content of $BUILD_DIR has been deployed to GitHub Pages." 60 | -------------------------------------------------------------------------------- /website/publish_to_github_pages.js: -------------------------------------------------------------------------------- 1 | const ghpages = require('gh-pages'); 2 | const path = require('path'); 3 | const fs = require('fs-extra') 4 | 5 | 6 | ghpages.publish('build/CapRover', function (err) { 7 | if (err) 8 | console.log(err); 9 | else 10 | console.log('Built and deployed successfully'); 11 | }); 12 | -------------------------------------------------------------------------------- /website/sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "docs": { 3 | "Basics": [ 4 | "get-started", 5 | "cdd-migration", 6 | "captain-definition-file", 7 | "deployment-methods", 8 | "app-configuration", 9 | "persistent-apps", 10 | "cli-commands", 11 | "one-click-apps", 12 | "complete-webapp-tutorial" 13 | ], 14 | "Do More": [ 15 | "resource-monitoring", 16 | "nginx-customization", 17 | "service-update-override", 18 | "app-scaling-and-cluster", 19 | "pre-deploy-script", 20 | "play-with-docker", 21 | "run-locally", 22 | "certbot-config", 23 | "theme-customization" 24 | ], 25 | "Recipes and Tips": [ 26 | "sample-apps", 27 | "zero-downtime", 28 | "database-connection", 29 | "best-practices", 30 | "backup-and-restore", 31 | "recipe-deploy-create-react-app", 32 | "stateless-with-persistent-data", 33 | "docker-compose", 34 | { 35 | "type": "subcategory", 36 | "label": "CI/CD Integration", 37 | "ids": [ 38 | "ci-cd-integration", 39 | "ci-cd-integration/deploy-from-github", 40 | "ci-cd-integration/deploy-from-gitlab" 41 | ] 42 | } 43 | ], 44 | "Help": [ 45 | { 46 | "type": "subcategory", 47 | "label": "Server Purchase", 48 | "ids": ["server-purchase/digitalocean", "server-purchase/openstack"] 49 | }, 50 | "disk-cleanup", 51 | "firewall", 52 | "troubleshooting", 53 | "troubleshooting-pro", 54 | "support" 55 | ] 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /website/siteConfig.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | // See https://docusaurus.io/docs/site-config.html for all the possible 9 | // site configuration options. 10 | 11 | /* List of projects/orgs using your project for the users page */ 12 | const users = [ 13 | { 14 | caption: 'User1', 15 | // You will need to prepend the image path with your baseUrl 16 | // if it is not '/', like: '/test-site/img/logo.png'. 17 | image: '/img/logo.png', 18 | infoLink: 'https://www.facebook.com', 19 | pinned: true, 20 | }, 21 | ]; 22 | 23 | const siteConfig = { 24 | title: 'CapRover' /* title for your website */, 25 | tagline: 'Scalable, Free and Self-hosted PaaS!', 26 | cname: 'caprover.com', 27 | url: 'https://caprover.com' /* your website url */, 28 | baseUrl: '/' /* base url for your project */, 29 | // For github.io type URLs, you would set the url and baseUrl like: 30 | // url: 'https://facebook.github.io', 31 | // baseUrl: '/test-site/', 32 | 33 | // Used for publishing and more 34 | projectName: 'CapRover', 35 | organizationName: 'CapRover', 36 | // For top-level user or org sites, the organization is still the same. 37 | // e.g., for the https://JoelMarcey.github.io site, it would be set like... 38 | // organizationName: 'JoelMarcey' 39 | 40 | // For no header links in the top nav bar -> headerLinks: [], 41 | headerLinks: [ 42 | {doc: 'get-started', label: 'Docs'}, 43 | { 44 | href: 'https://github.com/caprover/caprover', 45 | label: 'GitHub', 46 | }, 47 | { 48 | href: 'https://join.slack.com/t/caprover/shared_invite/zt-2qlb28drp-RpxNfY3nUhroLuRJUUJzDA', 49 | label: 'Slack Group', 50 | }, 51 | ], 52 | 53 | editUrl: 'https://github.com/caprover/caprover-website/edit/master/docs/', 54 | 55 | gaTrackingId: 'UA-132762521-1', 56 | 57 | // If you have users set above, you add it here: 58 | users, 59 | 60 | /* path to images for header/footer */ 61 | headerIcon: 'img/logo.png', 62 | footerIcon: 'img/logo.png', 63 | favicon: 'img/favicon.ico', 64 | 65 | /* colors for website */ 66 | colors: { 67 | primaryColor: '#135c8c', 68 | secondaryColor: '#0e4468', 69 | }, 70 | 71 | /* custom fonts for website */ 72 | /*fonts: { 73 | myFont: [ 74 | "Times New Roman", 75 | "Serif" 76 | ], 77 | myOtherFont: [ 78 | "-apple-system", 79 | "system-ui" 80 | ] 81 | },*/ 82 | 83 | // This copyright info is used in /core/Footer.js and blog rss/atom feeds. 84 | copyright: 85 | 'Copyright © ' + 86 | new Date().getFullYear() + 87 | ' githubsaturn', 88 | 89 | highlight: { 90 | // Highlight.js theme to use for syntax highlighting in code blocks 91 | theme: 'default', 92 | }, 93 | 94 | // Add custom scripts here that would be placed in