How to Deploy a Custom Docker Application from a Git Repository with xCloud
Updated November 3, 2026 · 6 min read
You can deploy any app that ships a Docker Compose file straight from its Git repository. xCloud reads the compose file, finds the ports your app publishes, puts your domain in front of the right one, and runs the containers on your server.
This guide walks you through the whole process, from creating or picking an NGINX server to deploying your application and going live. For server sizes and prices, see the Docker container hosting page.
Step 1: Create or pick an NGINX server
You need an NGINX server; OpenLiteSpeed servers cannot run Docker. If you already have one, go to Step 2. To create one, click New Server on the dashboard and choose your provider. You can use an xCloud Managed Server or connect your own server.

Enter the Server Name, and optionally pick an App Type and Tags that help you find the server later. Under Choose Web Server, select NGINX. Docker is not a separate choice.

Fill in the rest of the form for your provider (server size, or IP address and SSH details for your own server), then create the server. A new server can take a few minutes to become ready.
xCloud installs Docker during your first container deploy, so you can skip this. To have Docker ready before that, open the server, go to Management → Settings, click Install a Service at the top of Server Utilities, then click Install next to Docker. See Enable Docker on an NGINX server for details.

Step 2: Start a new site on your server
Open your server from Servers and click New Site at the top right. The Add Your New Site Into panel opens with your server’s name.

Step 3: Open Deploy via Git and pick your repository
Click the Deploy via Git tab. Under Deploy Any App From Git, pick where your code lives:
- Public Repository: paste the repository URL (for example
https://github.com/your-account/your-app) into the search box and press Enter. - Private Repository: choose a connected Git account and search for the repository. No account connected yet? Click Connect a Git provider, or paste the repository’s SSH URL (
git@…) and xCloud shows a deploy key to add to the repository.

xCloud checks the repository and shows it under Paste your repository URL, with the branch it will deploy. To pick another one, click Change Repository.
Step 4: Choose Docker container
Above the repository, click Docker container. xCloud may suggest Native app for some repositories; Docker container runs your app from its compose file instead.

If Docker is not on the server yet, a note says it will be installed automatically during the first deployment. You don’t need to do anything.
Step 5: Set the compose file and scan its ports
If your repository also has a Dockerfile, xCloud shows Deploy with. Choose docker-compose.yml to follow this guide. The Dockerfile option is not covered here.
Under Configuration, check the Docker Compose file field. It holds the path of your compose file from the repository root, such as docker-compose.yml or docker/production/compose.yml. Correct it if your file lives somewhere else, then click Re-Scan.

xCloud reads the file and lists the ports your services publish in Primary port. Each entry shows the port, the service name and the port inside the container, for example 3000 — documenso (3000). Pick the port of the service your domain should open.
What you may see next:
- Several services publish ports: xCloud tells you so. Choose Use a live domain instead and map each extra service to its own domain or subdomain and port.
- No ports found: the message No exposed ports found in … appears with a Port (1024–65535) field. Enter the port your app is published on.
- A port is already used by another site on the server: the list marks it as in use, and you cannot pick it as the primary port.
Step 6: Set your domain
By default xCloud gives the site a Staging domain (no DNS), so you can test before you point a real domain at it. To go live on your own domain right away, click Use a live domain instead, enter the domain and follow the DNS steps on screen.
Step 7: Add your .env file
Open Environment & deploy script and tick Provide a .env file. Type your variables as KEY=value, one per line, or click Suggest from repo to have xCloud suggest variables from your repository. Check a suggestion before you use it.
If your compose file uses variables that have no value yet, xCloud adds them to the .env box with empty values and tells you how many it added. Fill in their values before you deploy.
Ports set in your .env file update on their own. Many apps let you choose their port in the .env file. When you finish editing the .env box and click anywhere outside it, xCloud scans the compose file again with your values. The note under the box says so: Ports set through .env variables, such as HOST_PORT, refresh automatically once you finish editing your .env.

After the scan, Primary port shows the port from your .env. For example, if your app’s port defaults to 3000 and you add PORT=8085 to your .env, the primary port changes from 3000 to 8085.

If you picked a primary port yourself, xCloud keeps your choice as long as the new scan still finds that port.
For developers: variable forms the scan understands
The port scan reads every variable form Docker Compose supports:
| In your compose file | What xCloud uses |
|---|---|
${VAR} |
The value of VAR from your .env. Unset means missing. |
${VAR:-default} |
VAR if it is set and not empty, else default. |
${VAR-default} |
VAR if it is set (even empty), else default. |
${VAR:?message} / ${VAR?message} |
VAR. If it is unset (or empty, for :?), xCloud reports it as missing and adds VAR= to your .env. |
${VAR:+alt} / ${VAR+alt} |
alt when VAR is set (and not empty, for :+), else nothing. |
$VAR inside ports: |
The value of VAR. Unset means missing. |
The example above uses the ${VAR:-default} form: the compose file publishes ${PORT:-3000}, so PORT=8085 in your .env sets the port to 8085.
Step 8: Check the deploy script and deploy
Under Deploy script, xCloud fills in the commands that pull, stop and start your containers, for example:
docker compose pull
docker compose down
docker compose --env-file .env up -d --build
xCloud adjusts these commands for you if your compose file is somewhere else or you skip the .env file.
Change them only if your app needs extra commands. A deploy script runs after every later deploy, so changing it needs the Manage Deploy Scripts permission. Without it, you see the standard script read-only with this message: This is the standard script for this setup. To change it, ask a team admin for the Manage Deploy Scripts permission. xCloud refuses any other script, but you can still deploy with the standard one. To grant the permission, see Who can change a deploy script.

For a repository from a connected Git account, tick Enable push-to-deploy (webhook) to redeploy each time you push to the branch.
Click Deploy. When the deployment finishes, click Visit Site next to the site name at the top of the site dashboard to open your app.
Troubleshooting
- A port is missing from Primary port. The variable that sets it has no value. Find its line in the .env box (it may be one xCloud added with an empty value), fill it in and click outside the box. Still missing? Click Re-Scan.
- The wrong file was scanned. Check the path in Docker Compose file, then click Re-Scan.
- The scan stops with “This action is unauthorized.” To scan a repository from the team’s connected Git account, you need the Manage integrations permission. Only a Team Admin can have it. Ask for it, or type your port in the Port (1024–65535) field.
- The deployment gets stuck, fails to clone, or won’t trigger on push. See Troubleshooting Git Deployments.
To deploy a Docker app without Git, see How to deploy Custom Docker with xCloud. To protect your app’s data, see Backup and restore Docker apps.
Frequently asked questions
Can I set my app’s port in the .env file instead of the compose file?
Yes. If your compose file reads its port from the .env file, add that port to your .env. When you click outside the .env box, xCloud scans the file again and the Primary port list shows the port you set.
Why is my port missing from the Primary port list?
The variable that sets the port has no value yet. Look in your .env for a line with the variable name and an empty value, fill it in, then click outside the .env box. If the port still does not show, click Re-Scan.
What happens if xCloud finds no ports in my compose file?
xCloud shows the message “No exposed ports found” and a Port field. Enter the port your app is published on, between 1024 and 65535.
Do I need to install Docker before I deploy?
No. If Docker is not on the server yet, xCloud installs it during your first deployment. You can also install it ahead of time from the server’s Management → Settings page.
If you run into any issues, feel free to reach out to our support team.