In this step you will install the Uffizzi GitHub App and grant Uffizzi access to the repositories you want to deploy. Login to Uffizzi, then navigate to Account > Settings > General, then select Configure next to the GitHub option.
12 |
13 |
14 |
15 |
You'll be asked to Install Uffizzi Cloud, then grant access to your repositories.
16 |
17 |
18 |
19 |
Similarly, you can manage the Uffizzi app installation from GitHub by navigating to Settings > Applications > Uffizzi Cloud > Configure
20 |
21 |
22 |
23 |
24 | If the Docker Compose template you created in Section 1 references images stored in a private container registry, add those credentials in this step, as indicated in the screenshot below:
25 |
26 | 2. Add application secrets
27 |
If your compose file includes [application secrets](https://docs.uffizzi.com/references/compose-spec/#secrets), such as database credentials, you can add them in the Uffizzi Dashboard. Navigate to your project, then select Specs > Secrets > NEW SECRET. This will open a modal, where you can input your secrets as NAME=VALUE pairs. Be sure to add one secret per line, separatedy by = with no white spaces.
28 |
29 |
30 |
31 |
32 |
33 |
Once the secrets are saved, you will not be able to view or edit their values. To make changes to a secret, first delete the old secret, then create a new one.
34 |
35 |
36 | 3. Link to your Docker Compose template
37 |
In this final step, we'll link to our Docker Compose template that's stored in our GitHub repository. To do this, navigate to your project, then select Specs > Compose > NEW COMPOSE. Next, select the repository, branch (typically this is the branch you open pull requests against), and name of the compose file. Finally, select VALIDATE & SAVE.
38 |
39 |
40 |
41 |
Note, if you did not add your secrets as described in the previous step, you will see a validation error with a link to add your secretes.
42 |
43 |
44 |
Once your compose file has been successfully added, you will see it in the Uffizzi Dashboard with a link to its source on GitHub. Any changes you make to this compose file on GitHub will be synced in the Uffizzi Dashboard.
45 |
46 |
47 |
48 |
49 | That's it! Uffizzi is now configured with your Docker Compose template. To test your setup, you can manually deploy your primary branch to an on-demand test environment using the **Test Compose** button in the Uffizzi Dashboard, or try opening a pull request on GitHub to deploy a feature branch.
50 |
51 | ## **Connect container registy credentials to Uffizzi**
52 |
53 | Follow this section if you're using an external container registry, such as GHCR, ECR, or Docker Hub, to store your built images (i.e. You are not relying on Uffizz CI to storage images for you).
54 |
55 | How you add container registry credentials to Uffizzi depends on your registry of choice.
56 |
57 | ### GitHub Container Registry (ghcr.io)
58 |
59 |
60 |
61 | ``` yaml
62 | secrets:
63 | personal-access-token: ${{ secrets.GHCR_ACCESS_TOKEN }}
64 | ```
65 |
66 | Once you've created a personal access token, you should add it in your Uffizzi Account Settings.
67 |
68 | Add GHCR personal access token in Account Settings
69 | Login to Uffizzi, then navigate to Account > Settings > Registries, then select Configure next to the GHCR option.
70 |
71 |
72 |
73 |
74 |
Enter your GitHub username and personal access token, then select Sign in to GitHub Container Registry.
75 |
76 |
77 | ### ECR, ACR, GCR, Docker Hub
78 | If you use Amazon ECR, Azure Container Registry (ACR), Google Container Registry (GCR), or Docker Hub, you should add your credentials as [GitHub repository secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository).
79 |
80 | See this AWS ECR example
81 |
If you use Amazon ECR, Azure Container Registry (ACR), Google Container Registry (GCR), or Docker Hub, you should add your credentials as GitHub repository secrets. In the highlighted example below, AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are used:
Now, we need to add these same credentials in the Uffizzi Dashboard. In Step 3 of 4 of the account setup guide, you are asked to connect to various external services, as shown below. Select the Sign in option for your registry provider(s) of choice, then enter your credentials. For example, to add AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, select Sign in to Amazon Elastic Container Registry.
120 |
121 |
122 |
After account setup, you can make changes to your credentials by selecting Menu (three horizontal lines) > Settings > Integrations > CONFIGURE/DISCONNECT.
123 |
124 |
125 |
126 |
127 | That's it! Your pipeline is now configured to use Uffizzi. To test your pipeline, try opening a new pull request.
128 |
129 | ## Suggested articles
130 |
131 | * [Configure password-protected environments](password-protected.md)
132 | * [`UFFIZZ_URL` environment variable](../references/uffizzi-environment-variables.md)
133 | * [Set up single sign-on (SSO)](single-sign-on.md)
134 |
--------------------------------------------------------------------------------
/docs/guides/container-registry-integrations.md:
--------------------------------------------------------------------------------
1 | # Authenticate with a container registry
2 |
3 | You can authenticate with the container registries you use in one of two ways, depending on which CI solution you choose:
4 |
5 | ## External CI
6 |
7 | If you're using an external CI provider, such as GitHub Actions, GitLab CI, or CircleCI, you must add registry credentials as secrets in your provider's interface.
8 |
9 | Uffizzi supports the following container registries:
10 | - Amazon ECR
11 | - Azure Container Registry (ACR)
12 | - Docker Hub
13 | - GitHub Container Registry (GHCR)
14 | - Google Container Registry (GCR)
15 | - Docker Registry (generic)
16 |
17 |
18 | See the following GitHub Actions example ([full example available here](https://github.com/UffizziCloud/example-voting-app/blob/8f78f9204c8869aca538cb929d49c5b1074da8ff/.github/workflows/uffizzi-previews.yml)) that passes a GitHub Container Registry access token to the [Uffizzi resuable workflow](https://github.com/marketplace/actions/preview-environments):
19 |
20 | === "GitHub Actions example"
21 | ``` yaml hl_lines="16"
22 | deploy-uffizzi-preview:
23 | name: Use Remote Workflow to Preview on Uffizzi
24 | needs: render-compose-file
25 | uses: UffizziCloud/preview-action/.github/workflows/reusable.yaml@v2.2.0
26 | if: ${{ github.event_name == 'pull_request' && github.event.action != 'closed' }}
27 | with:
28 | compose-file-cache-key: ${{ needs.render-compose-file.outputs.compose-file-cache-key }}
29 | compose-file-cache-path: docker-compose.rendered.yml
30 | username: adam+1@idyl.tech
31 | server: https://app.uffizzi.com
32 | project: my-application-c2e3
33 | secrets:
34 | password: ${{ secrets.UFFIZZI_PASSWORD }}
35 | url-username: admin
36 | url-password: ${{ secrets.URL_PASSWORD }}
37 | personal-access-token: ${{ secrets.GHCR_ACCESS_TOKEN }}
38 | permissions:
39 | contents: read
40 | pull-requests: write
41 | ```
42 |
43 |
44 | ## Uffizzi CI
45 | If you're using Uffizzi CI, you can choose to add your application components from source code or as pre-built images pulled from a container registry. This guide describes the process of configuring Uffizzi to to pull and deploy images from your container registry. If your container registry provider is not listed below, [let us know](mailto:support@uffizzi.com).
46 |
47 | ### Amazon ECR
48 |
49 | To configure Uffizzi to pull images from your Amazon ECR, it is recommended that you first create a dedicated IAM user for this purpose. After creating this IAM user, add its credentials in the Uffizzi Dashboard. Finally, configure webhooks to send notifications to Uffizzi when you push new images to ECR.
50 |
51 | Create IAM user to authorize Uffizzi to pull images from ECR
52 |
53 |
To fetch container images from your private ECR repositories, Uffizzi requires an API access key for an IAM User within your AWS Account. It's a best practice to grant this user only the permissions required. This section will walk you through creating a new IAM User, granting it strict permissions, and creating an API access key.
54 |
55 |
The easiest way to create this user is to use the AWS command-line interface (CLI). Make sure you have installed and configured the `aws` command on your workstation or container, including setting the default region to match your ECR repositories.
56 |
57 |
Create a new IAM User within your AWS Account. If you get an error that it already exists, that's fine.
58 |
59 | ```
60 | aws iam create-user --user-name uffizzi --output table
61 | ```
62 |
63 |
Attach an Amazon-managed policy to the new User. This grants permission only to list and read images.
When you configure ECR within Uffizzi in the next step, you'll need these values.
76 |
77 |
78 | Add IAM user credentials in the Uffizzi Dashboard
79 |
80 |
In the Uffizzi Dashboard (UI), navigate to Settings > Integrations. There you will see a list that includes container registries supported by Uffizzi. Select CONFIGURE next to the Amazon ECR option.
81 |
82 |
83 |
84 |
85 |
When prompted, sign in to ECR with your registry domain, access key ID, and your secret access key. Once authenticated, Uffizzi will now be able to pull images from your registry.
After configuring AWS ECR to pull images, you'll probably also want to enable Continuous Previews when you push a new container image. This requires configuring AWS EventBridge to send Uffizzi notifications via webhook HTTP requests. This section will walk you through configuring these webhooks.
94 |
95 |
The easiest way to configure these webhooks is to use the AWS CLI. Make sure you have installed and configured the aws command on your workstation or container, including setting the default region to match your ECR repositories.
96 |
97 |
Download the following shell script to configure these webhooks for you:
You should see output about the resource you've just created. If you see errors about resources already existing that's fine; that means someone else has already configured them.
111 |
112 |
You should also see the EventBridge Rule and other resources within the AWS Console:
113 |
114 |
115 |
116 |
117 | Removing webhook configuration
118 |
119 |
We've also provided a script to remove all of this configuration. Use this when you want to reconfigure the webhooks or when you no longer require automatic deployment to Uffizzi.
If no longer needed, you can then delete the IAM User. You must first delete all of the user's API Access Keys.
142 |
143 |
144 | ### Azure Container Registry (ACR)
145 |
146 | To configure Uffizzi to pull images from your ACR, it is recommended that you first create a dedicated service principal for this purpose, along with an Application and Subscription. After creating these resources, add the service principal's credentials in the Uffizzi Dashboard. Finally, configure webhooks to send notifications to Uffizzi when new images or tags are pushed to ACR.
147 |
148 | Create Azure service principal to authorize Uffizzi to pull images from ACR
149 |
150 |
Once you have an active Subscription and a Container Registry, you can use the create-for-rbac command to create a service principal and simultaneously grant it the ACRPull role:
This command will output a JSON object with some values you will need later: appId and password. See the Azure CLI documentation for details about this command.
161 |
162 |
163 | Add your Azure service principal in the Uffizzi Dashboard
164 |
To grant Uffizzi access to pull images from your ACR, you will need:
165 |
166 |
167 |
Your registry domain (registry-name.azurecr.io)
168 |
Application ID
169 |
Password
170 |
171 |
172 |
The Application ID and Password are provided in the output from the create-for-rbac command above, or they can be obtained within the Azure web portal.
173 |
174 |
Log in to the Uffizzi Dashboard (UI) and navigate to Settings > Integrations then select CONFIGURE next to the ACR option.
175 |
176 |
177 |
178 |
179 |
Enter your credentials when prompted, then click Sign in to Azure Container Registry. Uffizzi should now have access to pull images from your ACR.
If you've added images from ACR to a template or compose file, you'll probably also want to enable continuous previews when you push a new container image. This requires adding a webhook to send Uffizzi notifications. This section will walk you through configuring this webhook.
188 |
189 |
The easiest way to configure these webhooks is to use the Azure command-line interface (CLI). Make sure you have installed and configured the az command on your workstation or container.
190 |
191 |
First identify which ACR Registry you want to use for automatic deployments.
192 |
193 | ```
194 | az acr list --output table
195 | ```
196 |
197 |
Use the name of that registry when you add the webhook:
To stop sending notifications to Uffizzi, you can remove the webhook you configured above:
207 |
208 | ```
209 | az acr webhook delete --registry --name uffizzi
210 | ```
211 |
212 |
213 | ### GitHub Container Registry (GHCR)
214 |
215 | To configure Uffizzi to pull images from GHCR, you must first create an personal access token to provide to Uffizzi. Once authorized, Uffizzi will automatically configure webhooks on your registry to be notified when you push new images.
216 |
217 | Create a personal access token for GHCR
218 |
219 |
To create a GitHub personal access token follow these instructions. Your token needs read:packages scope.
220 |
221 |
222 |
223 | Authorize Uffizzi to pull container images from GHCR
224 |
225 |
Log in to the Uffizzi Dashboard and navigate to Settings > Integrations, then select CONFIGURE next to the GitHub Container Registry option.
226 |
227 |
228 |
229 |
Enter your GitHub username and the personal access token you created, then select Sign in to GitHub Container Registry. Uffizzi should now have access to pull images from your GHCR registry. Uffizzi will automatically configure a webhook to be notified when you push new images.
230 |
231 |
232 |
233 |
234 |
235 | Deleting the personal access token for GHCR
236 |
237 |
Log in to your GitHub account, then navigate to Settings > Developer settings > Personal access tokens. Then select Delete for the token you want to delete. This will revoke Uffizzi's access to your GHCR registry.
238 |
239 |
240 |
241 |
242 |
243 |
244 | ### Google Container Registry (GCR)
245 |
246 | To configure Uffizzi to pull images from your GCR, you need to add your GCR key file in the Uffizzi Dashboard (UI). Once added, configure a webhook to send notifications to Uffizzi when you push new images to GCR.
247 |
248 | Authorize Uffizzi to pull container images from GCR
249 |
250 |
To grant Uffizzi access to pull images from your GCR, you will need a JSON key file.
251 |
252 |
Log in to the Uffizzi Dashboard and navigate to Settings > Integrations, then select CONFIGURE next to the GCR option.
253 |
254 |
255 |
256 |
257 |
Upload or copy and paste your key file when prompted, then click Add GCR Key File. Uffizzi should now have access to pull images from your GCR.
If you've added images from GCR to a template or compose file, you'll probably also want to enable continuous previews when you push a new container image. This requires adding a webhook to send Uffizzi notifications. This section will walk you through configuring this webhook.
267 |
268 |
The easiest way to configure these webhooks is to use the Google Cloud command-line interface (CLI). Make sure you have installed and configured the gcloud command on your workstation or container.
If these commands fail, make sure you have enabled the Pub/Sub API for your Google Cloud Project. You may also need to specify --project if you have multiple Google Cloud Projects.
If this was your only Subscription to the GCR Topic, you could also delete that Topic.
297 |
298 |
If that was your only Topic, you could also disable the Pub/Sub API.
299 |
300 |
301 |
302 | ### Docker Hub
303 |
304 | To configure Uffizzi to pull images from your private Docker Hub registry, it is recommended that you first create an Access Token to provide to Uffizzi. Once authorized, Uffizzi will automatically configure webhooks on your registry to be notified when you push new images.
305 |
306 | Create an access token for Docker Hub
307 |
308 |
Log in to Docker Hub, then navigate to Account Settings > Security and select the New Access Token button. In the Access Token Description field, enter "uffizzi" or a similar description. For Access permissions choose Read-only, then select Generate to create your Access Token.
309 |
310 |
311 |
312 |
On the next screen, you should see your Accesss Token. Save this value, as you will need it in the next step.
Log in to the Uffizzi Dashboard and navigate to Settings > Integrations, then select CONFIGURE next to the Docker Hub option.
321 |
322 |
323 |
324 |
Enter your Docker ID and the access token you created, then select Sign in to Docker Hub. Uffizzi should now have access to pull images from your Docker Hub registry. Uffizzi will automatically configure a webhook to be notified when you push new images.
Log in to Docker Hub, then navigate to Account Settings > Security. Select the the checkbox next the access token you added in the Uffizzi Dashboard, then select Delete and Delete Forever to confirm.
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
--------------------------------------------------------------------------------
/docs/guides/demo-on-uffizzi.md:
--------------------------------------------------------------------------------
1 | # **Demo on Uffizzi** button
2 |
3 | Add the **Demo on Uffizzi** button to your repository's `README.md` to give visitors a fast way to interact with your application in a live demo environment. This button requires **no configuration** by your users, and it **does not** require them to have a Uffizzi account.
4 |
5 | 
6 |
7 | !!! Note
8 | The **Demo on Uffizzi** button is currently available only to Uffizzi [Open Source Plan](https://www.uffizzi.com/pricing) customers—i.e. it will not work on any arbitrary repo. Open source maintainers can [contact us on Slack](https://join.slack.com/t/uffizzi/shared_invite/zt-ffr4o3x0-J~0yVT6qgFV~wmGm19Ux9A) to configure this for their projects.
9 |
10 | ## How it works
11 |
12 | For qualifying projects, Uffizzi creates a public route of the the form `https://app.uffizzi.com/demo/github.com//`. When a user visits this endpoint (by clicking on the demo button), Uffizzi checks that a demo Compose file (`docker-compose.demo.uffizzi.yml`) is configured for the project. If it exists, Uffizzi will deploy this configuration to a demo environment.
13 |
14 | ```
15 | [](https://app.uffizzi.com/demo/github.com//)
16 | ```
17 |
18 |
19 |
--------------------------------------------------------------------------------
/docs/guides/docker-compose-template.md:
--------------------------------------------------------------------------------
1 | # Create a Docker Compose template
2 |
3 | In this section, we'll create a template using [Docker Compose](https://docs.docker.com/compose/compose-file/) that describes our application configuration. Uffizzi uses Docker Compose as its configuration format because it is relatively simple and widely used by developers.
4 |
5 | !!! note
6 | Uffizzi supports a subset of the [Compose specification](https://github.com/compose-spec/compose-spec/blob/master/spec.md). For a full list of supported keywords, see the [Uffizzi Compose file reference](../references/compose-spec.md).
7 |
8 | ## Configure your Compose to dynamically update image definitions
9 | The Uffizzi environment creation step typically executes at the end of a CI pipeline after a series of steps that are triggered by an event, such as a pull request or new commit. If you don't have an existing CI solution, Uffizzi CI can build your application from source and store your container images for you (Note: Your source code must be stored in a GitHub repository to use Uffizzi CI). Alternatively, if you're using an external CI service, such as GitHub Actions or CircleCI, you will need to tell Uffizzi where your images are stored and how to access them.
10 |
11 | Each time your CI pipeline builds and pushes new images, Uffizzi needs access to them. This means that we need to dynamically update our compose file `service` definitions with the new image names and tags each time our pipeline runs. To do this, we'll follow one of two methods, depending on which CI solution you choose:
12 |
13 | - **Uffizzi CI** - If you want to use Uffizzi CI, you can simply define a `build` context that points to your source code repository on GitHub and let Uffizzi handle building and tagging images and updating your Compose. See the [Uffizzi Compose file reference](../references/compose-spec.md#build) for `build` and `context` details.
14 |
15 | - **External CI** - If you're using an external CI provider such as GitHub Actions or GitLab CI, you can use variable substitution to pass the output from your CI build step, i.e. `image:tag`, to your Compose file `image` definition (See highlighted example below). This solution is discussed in detail in the [next section](integrate-with-ci.md).
16 |
17 | === "Uffizzi CI"
18 |
19 | ``` yaml hl_lines="3-5" title="docker-compose.uffizzi.yml"
20 | services:
21 | app:
22 | build:
23 | context: https://github.com/example/app
24 | dockerfile: Dockerfile
25 | environment:
26 | PGUSER: "postgres"
27 | PGPASSWORD: "postgres"
28 | deploy:
29 | resources:
30 | limits:
31 | memory: 250M
32 |
33 | db:
34 | image: postgres:9.6
35 | environment:
36 | POSTGRES_USER: "postgres"
37 | POSTGRES_PASSWORD: "postgres"
38 | ```
39 |
40 | === "External CI (e.g. GitHub Action)"
41 |
42 | ``` yaml hl_lines="3" title="docker-compose.uffizzi.yml"
43 | services:
44 | app:
45 | image: "${APP_IMAGE}" # Output of build step stored as environment variable
46 | environment:
47 | PGUSER: "${PGUSER}"
48 | PGPASSWORD: "${PGPASSWORD}"
49 | deploy:
50 | resources:
51 | limits:
52 | memory: 250M
53 |
54 | db:
55 | image: postgres:9.6
56 | environment:
57 | POSTGRES_USER: "${PGUSER}"
58 | POSTGRES_PASSWORD: "${PGPASSWORD}"
59 | ```
60 |
61 | ## Define an Ingress for your application
62 |
63 | Whether using Uffizzi CI or an external CI provider, Uffizzi needs to know which of your application services will receive incoming traffic. This "Ingress" is an HTTPS load balancer that will forward HTTP traffic to one of the defined `services`. Along with the service name, you must indicate on which port the target container is listening. The `ingress` must be defined within an `x-uffizzi` [extension field](https://docs.docker.com/compose/compose-file/compose-file-v3/#extension-fields) as shown in the example below:
64 |
65 | ``` yaml hl_lines="1-5" title="docker-compose.uffizzi.yml"
66 | # This block tells Uffizzi which service should receive HTTP traffic.
67 | x-uffizzi:
68 | ingress:
69 | service: app
70 | port: 80
71 |
72 | # My application
73 | services:
74 | app:
75 | image: "${APP_IMAGE}" # Output of build step stored as environment variable
76 | environment:
77 | PGUSER: "${PGUSER}"
78 | PGPASSWORD: "${PGPASSWORD}"
79 | deploy:
80 | resources:
81 | limits:
82 | memory: 250M
83 |
84 | db:
85 | image: postgres:9.6
86 | environment:
87 | POSTGRES_USER: "${PGUSER}"
88 | POSTGRES_PASSWORD: "${PGPASSWORD}"
89 | ```
90 |
91 |
92 | !!! Tip
93 | If you need to expose multiple public routes for your application, see this article [Exposing multiple routes](expose-multiple-routes.md).
94 |
95 | ## Add secrets in your CI platform (optional)
96 |
97 | You may also want to move sensitive information like credentials out of your Docker Compose file before commiting it to a remote repository. Most CI providers offer a way to store secrets and then reference them in the steps of your pipeline. To do this, we'll follow one of two methods, depending on which CI solution you choose:
98 |
99 | - **Uffizzi CI** - If you want to use Uffizzi CI, you can create read-only secrets in the Uffizzi Dashboard web interface (this process is described in detail in [Section 3](configure-credentials.md)), then reference them using the `external` keyword, as shown below. For details on `secrets` and `external` configuration options, see the [Uffizzi Compose file reference](../references/compose-spec.md#nested-secrets).
100 |
101 | - **External CI** - If you're using an external CI provider, you can store the secrets using your provider's interface and then reference them via variable substitution within an `environment` definition (See highlighted example below). This solution is discussed in detail in the [next section](integrate-with-ci.md).
102 |
103 | GitHub Actions example
104 |
In GitHub, navigate to your repository, then select Settings > Secrets > Actions > New repository secret. Alternatively, you can [use the GitHub CLI](https://cli.github.com/manual/gh_secret).
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 | === "Uffizzi CI"
113 |
114 | ``` yaml hl_lines="20-32" title="docker-compose.uffizzi.yml"
115 | # This block tells Uffizzi which service should receive HTTPS traffic
116 | x-uffizzi:
117 | ingress:
118 | service: app
119 | port: 80
120 |
121 | services:
122 | app:
123 | build:
124 | context: https://github.com/example/app
125 | dockerfile: Dockerfile
126 | secrets:
127 | - pg_user
128 | - pg_password
129 | deploy:
130 | resources:
131 | limits:
132 | memory: 250M
133 |
134 | db:
135 | image: postgres:9.6
136 | secrets:
137 | - pg_user
138 | - pg_password
139 |
140 | secrets:
141 | pg_user:
142 | external: true
143 | name: "POSTGRES_USER"
144 | pg_password:
145 | external: true
146 | name: "POSTGRES_PASSWORD"
147 | ```
148 |
149 | === "External CI (e.g. GitHub Actions)"
150 |
151 | ``` yaml hl_lines="20-22" title="docker-compose.uffizzi.yml"
152 | # This block tells Uffizzi which service should receive HTTPS traffic
153 | x-uffizzi:
154 | ingress:
155 | service: app
156 | port: 80
157 |
158 | services:
159 | app:
160 | image: "${APP_IMAGE}" # Output of build step stored as environment variable
161 | environment:
162 | PGUSER: "${PGUSER}"
163 | PGPASSWORD: "${PGPASSWORD}"
164 | deploy:
165 | resources:
166 | limits:
167 | memory: 250M
168 |
169 | db:
170 | image: postgres:9.6
171 | environment:
172 | POSTGRES_USER: "${PGUSER}"
173 | POSTGRES_PASSWORD: "${PGPASSWORD}"
174 | ```
175 |
176 | ## Commit your template to your repository
177 |
178 | Once you're finished creating your Docker Compose template, commit it to your repository and push.
179 |
180 | ## Next article
181 |
182 | [Integrate with your CI pipeline](integrate-with-ci.md)
183 |
--------------------------------------------------------------------------------
/docs/guides/environment-variables.md:
--------------------------------------------------------------------------------
1 | # Add environment variables
2 |
3 | Environment variables are name/value pairs that are dynamically loaded into your containers at runtime. They are often used to pass configuration details to your application. Using environment variables instead of hard-coded values lets you keep environment-specific details out of your source code.
4 |
5 | You will add secrets in one of two ways, depending on which CI solution you choose:
6 |
7 | ## External CI
8 |
9 | If you're using an external CI provider, such as GitHub Actions, GitLab CI, or CircleCI, environment variables should be stored via your provider's interface and referenced in your [Docker Compose template](docker-compose-template.md) using the [`environment`](../references/compose-spec.md#environment) element.
10 |
11 |
12 | !!! note
13 | Docker Compose element [`env_file`](../references/compose-spec.md#env_file) is not currently support for external CI providers.
14 |
15 | ## Uffizzi CI
16 |
17 | If you're using Uffizzi CI, you have two options for adding environment variables in your [Uffizzi Compose file](../references/compose-spec.md): `environment` or `env_file`.
18 |
19 | * Use [`environment`](../references/compose-spec.md#environment) if you have a small number of environment variables to add. You can list your variables in an `environment` block within the service definition. For example, the following `docker-compose.uffizzi.yml` snippet adds two environment variables, `FOO` and `BAR`, to the `myservice` container:
20 | ```yaml
21 | services:
22 | mysevice:
23 | image: example/myservice:latest
24 | environment:
25 | FOO: bar
26 | BAR: baz
27 | ```
28 |
29 | * Use [`env_file`](../references/compose-spec.md#env_file) if you have a large number of enviroment variables that would otherwise clutter up your compose file. You can store your variables in a file within your repository and use the `env_file` component to specify the path to this file. For example, the following `docker-compose.uffizzi.yml` snippet tells Uffizzi to read the contents of `envs/myconfigs.env` and add them to the container `myservice`:
30 | ```yaml
31 | services:
32 | mysevice:
33 | image: example/myservice:latest
34 | env_file: ./envs/myconfigs.env
35 | ```
36 |
--------------------------------------------------------------------------------
/docs/guides/expose-multiple-routes.md:
--------------------------------------------------------------------------------
1 | # Expose multiple routes for your application
2 |
3 | ## Understanding Uffizzi `ingress`
4 | For each ephemeral environment, Uffizzi provisions one _https_ load balancer to receive incoming traffic for your application. This "`ingress`" is defined in your Docker Compose file and requires a `service` and `port` definition, as shown in the example below.
5 |
6 | ``` yaml
7 | x-uffizzi:
8 | ingress:
9 | service: app
10 | port: 80
11 |
12 | services:
13 | app:
14 | ...
15 | ```
16 |
17 | ## Exposing multiple routes
18 |
19 | Uffizzi allows only one `service` to act as your `ingress`, but your application may have multiple services you want to expose. For example, you may want to serve your main application at `/` and a console at `/console`. To do this, you can add a new `nginx` service to your configuration to map requests for specific ports to their target containers. We'll first add an `nginx` service to the Docker Compose file, then configure it as the `ingress`. Finally, we'll define the routes in an `nginx.conf` file.
20 |
21 | ```yaml title="docker-compose.uffizzi.multiple-routes.yml"
22 | x-uffizzi:
23 | ingress:
24 | service: nginx
25 | port: 8081
26 |
27 | services:
28 | nginx:
29 | image: nginx:alpine
30 | ports:
31 | - "8081:8081"
32 | volumes:
33 | - ./uffizzi/nginx:/etc/nginx/conf.d/
34 |
35 | app:
36 | ports:
37 | - 3001:3001
38 |
39 | api:
40 | ports:
41 | - 7001:7001
42 | ```
43 |
44 |
45 |
46 | Now we will create a new file in our repository `/uffizzi/nginx/nginx.conf` that defines how our paths will be exposed. By default the official `nginx:latest` base image we used in our Docker Compose file will include all `/etc/nginx/conf.d/*.conf` files.
47 |
48 | Here we assume that `app` is listening for connections on `3001` and `3002` for the main applicaiton and console, respectively. If requests for port `:3001` are received, we tell `nginx` to forward those requests to `/`. If requests for port `3002` are received, we tell `nginx` to forward those requests to `/console`.
49 |
50 | ```json title="nginx.conf"
51 |
52 | http {
53 | server {
54 | listen 8081;
55 |
56 | location / {
57 | proxy_pass http://localhost:3001;
58 | }
59 |
60 | location /console/ {
61 | proxy_pass http://localhost:3002;
62 | }
63 | }
64 | }
65 | ```
66 |
--------------------------------------------------------------------------------
/docs/guides/github-environment.md:
--------------------------------------------------------------------------------
1 | # Create a GitHub Environment for your previews
2 | [GitHub Environments](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment) are a convenient way to collect all of your previews in a single view on GitHub. Specifically, GitHub Environments are the target of your workflows, so you can configure a "uffizzi" Environment to be the target of your ephemeral preview deployments. You'll also see these deployments appear in your Actions workflow graph.
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | ## Set up a "uffizzi" GitHub Environment
11 | If you're using the standard [Uffizzi reusable workflow](https://github.com/marketplace/actions/preview-environments) to create, update, and delete environments on pull request events, then you just need to create a GitHub Environment called "uffizzi" in your reposiory via the GitHub UI. The reusable workflow is pre-configured to populate this Environment with Uffizzi preview deployments. If you're not using the resuable workflow, you'll need to configue the `jobs..environment` key as described [here](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#using-an-environment).
12 |
13 | Login to GitHub, then navigate to your repository **Settings** > **Environments** and select **New environment**. For the Environmnet name enter "**uffizzi**". Note that if you name it something else, it won't work since the reusable workflow expects the enviroment to be named "uffizzi".
14 |
15 | That's it! You can now select the "uffizzi" Environment to see the new Deployments that are created every time your Uffizzi workflow runs.
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/docs/guides/logs.md:
--------------------------------------------------------------------------------
1 | # Check logs
2 |
3 | Three types of logs are available in Uffizzi: container logs, build logs and event logs.
4 |
5 | **Container logs** - Also known as runtime logs, container logs are output from the application itself, including its dependencies. Container logs capture stdout, allowing you to inspect the activity of your application. Anything you would typically see in a terminal running your app locally is shown here. If you have trouble getting your app running on Uffizzi or connecting to a database, container logs are often the best place to start troubleshooting.
6 |
7 | **Build logs** - When building your application from source (e.g. GitHub), Uffizzi displays logs from this process in the the Build Logs feed. If you have trouble getting your app to build on Uffizzi, build logs may provide you with enough information to troubleshoot your issue.
8 |
9 | To view either container logs or build logs, first navigate to the desired preview in the Uffizzi Dashboard, then select the container whose logs you want to view. You can toggle between the container and build logs in the left-hand menu:
10 |
11 | 
12 |
13 |
14 |
15 | **Event logs** - These are Kubernetes events that are provided by the Kubernetes API. Uffizzi displays these logs in the Event Log feed. To view event logs, first navigate to the desired preview in the Uffizzi Dashboard, then select the **Event Log** option from the left-hand menu:
16 |
17 | 
18 |
19 |
20 |
--------------------------------------------------------------------------------
/docs/guides/password-protected.md:
--------------------------------------------------------------------------------
1 | # Password-protected environments
2 |
3 | Uffizzi allows you to configure a username and password for your Preview Environments to limit who has access to them. This feature is enabled per project, so anyone navigating to the URL of any Preview Environment of that project, either via a web browser or with a command like `curl`, must enter valid credentials to gain access. To configure this feature, you must be an account [Owner](../topics/rbac.md#owner).
4 |
5 | Select your CI provider to begin set up:
6 |
7 | [Uffizzi CI ⬇](#configure-password-protection-for-uffizzi-ci)
8 | [GitHub Actions ⬇](#configure-password-protection-for-github-actions)
9 |
10 | ## Configure password protection for Uffizzi CI
11 | 1. In the Uffizzi Dashboard, navigate to your project, then select **Project Settings** > **Password protection** > **Edit** > **Enabled** (toggle).
12 | Click to expand
13 |
14 |
15 | 2. Enter a username and password, then select **Save**.
16 |
17 | Password protection will now be enabled for all environments belonging to this project, including any pre-existing environments. To access these Preview Environments, you can pass your credentials via the [web browser](#access-via-web-browser) or [`curl` command](#access-via-curl).
18 |
19 | ## Configure password protection for GitHub Actions
20 | 1. In the Uffizzi Dashboard, navigate to your project, then select **Project Settings** > **Password protection** > **Edit** > **Enabled** (toggle).
21 | Click to expand
22 |
23 |
24 | 2. Enter a username and password, then select **Save**.
25 | 3. Store credentials as GitHub Actions secrets.
26 |
27 | In GitHub, navigate to your repository. Then select **Settings** > **Secrets and variables** > **Actions** > **Secrets** (tab) > **New repository secret**. (_Be sure you add a new repository **secret** from the **Secrets** tab, not a new repository **variable** from the **Variables** tab_). Add a secret name and value, then select **Add secret**.
28 | Click to expand
29 |
30 |
31 |
32 | 4. Pass credentials as parameters in your preview job.
33 |
34 | If you are using the official Uffizzi [preview action](https://github.com/marketplace/actions/preview-environments) with the [reusable workflow](https://github.com/UffizziCloud/preview-action/blob/master/.github/workflows/reusable.yaml), you will also need to pass the environment username and password to the reusable workflow via [`url-username`](https://github.com/marketplace/actions/preview-environments#url-username-and-url-password) and [`url-password`](https://github.com/marketplace/actions/preview-environments#url-username-and-url-password) parameters. These credentials are used by the preview action (and Uffizzi) to perform health checks on your Preview Environments. You can see example usage [here](https://github.com/UffizziCloud/example-voting-app/blob/8f78f9204c8869aca538cb929d49c5b1074da8ff/.github/workflows/uffizzi-previews.yml#L179-L180).
35 |
36 | ``` yaml hl_lines="9 10" title="uffizzi-preview.yaml"
37 | deploy-uffizzi-preview:
38 | name: Use Remote Workflow to Preview on Uffizzi
39 | needs: render-compose-file
40 | uses: UffizziCloud/preview-action/.github/workflows/reusable.yaml@v2.2.0
41 | if: ${{ github.event_name == 'pull_request' && github.event.action != 'closed' }}
42 | with:
43 | ...
44 | secrets:
45 | url-username: ${{ secrets.URL_USERNAME }}
46 | url-password: ${{ secrets.URL_PASSWORD }}
47 | permissions:
48 | ...
49 | ```
50 |
51 | Password protection will now be enabled for all environments belonging to this project, including any pre-existing environments. To access these Preview Environments, you can pass your credentials via the [web browser](#access-via-web-browser) or [`curl` command](#access-via-curl).
52 |
53 | ## Access via web browser
54 | If you visit the preview URL in a browser, you can enter the environment username and password in the _http_ dialog window, as shown in the screenshot below. Select **Log in** to be redirected to the Preview Environment.
55 |
56 | 
57 | ## Access via `curl`
58 | You can access a password-protected environment via the `curl` command by passing the environment username and password as an argument. For example:
59 |
60 | ```
61 | curl -u "username:password" [PREVIEW_URL]
62 | ```
63 |
64 | !!! Note
65 | The official Uffizzi [preview action](https://github.com/marketplace/actions/preview-environments) uses the `curl` command to check for successful deployments of Preview Environments. You can see how the Uffizzi preview action performs this check [here](https://github.com/UffizziCloud/preview-action/blob/599ea1a94a5ee8bca85843f9ec40524778e14cfc/.github/workflows/reusable.yaml#L284-L287).
66 |
67 | ## Suggested articles
68 | * [Set up single sign-on (SSO)](single-sign-on.md)
69 | * [Configure role-based access (RBAC)](../topics/rbac.md)
70 | * [Check the logs](logs.md)
71 |
--------------------------------------------------------------------------------
/docs/guides/secrets.md:
--------------------------------------------------------------------------------
1 | # Secrets
2 |
3 | Secrets provide a mechanism for securely adding sensitive data, such as passwords, tokens, or keys, to the containers of a preview environment. Secrets are similar to environment variables, but they are intended for confidential data. Secrets are defined as name/value pairs and are injected at runtime.
4 |
5 | You can add secrets in one of two ways, depending on which CI solution you choose:
6 |
7 | ## External CI
8 |
9 | If you're using an external CI provider, such as GitHub Actions, GitLab CI, or CircleCI, secrets should be stored via your provider's interface and referenced in your compose file using the [`environment`](../references/compose-spec.md#environment) element with variable substitution.
10 |
11 | In the following example, `PG_USER` and `PG_PASSWORD` are stored using [GitHub Actions secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets) and referenced using variable substitution in a [Docker Compose template](docker-compose-template.md).
12 |
13 | See the [Uffizzi resuable workflow](https://github.com/marketplace/actions/preview-environments) for example usage.
14 |
15 | === "GitHub Actions"
16 |
17 | ``` yaml
18 | secrets:
19 | username: ${{ secrets.PG_USER }}
20 | password: ${{ secrets.PG_PASSWORD }}
21 | ```
22 |
23 | === "Docker Compose Template"
24 |
25 | ``` yaml
26 | services:
27 | postgres:
28 | image: postgres:9.6
29 | environment:
30 | POSTGRES_USER: "${PGUSER}"
31 | POSTGRES_PASSWORD: "${PGPASSWORD}"
32 | deploy:
33 | resources:
34 | limits:
35 | memory: 500M
36 | ```
37 |
38 | ## Uffizzi CI
39 |
40 | ### Add secrets in the Uffizzi Dashboard (app.uffizzi.com)
41 | If you're using Uffizzi CI, secrets can be added in the Uffizzi Dashboard (**Project** > **Project Settings** > **Secrets**). Once added, they cannot be viewed or edited. To update a Secret, you should delete the old Secret and create a new one. Secrets added in the **Project Settings** are available to all Preview environments in that project.
42 |
43 |
44 | 
45 |
46 | ### Add `secrets` element to your Docker Compose template
47 |
48 | In your Docker Compose, add the `secrets` and `external` elements as show in the example below. Be sure that your secrets are added in the Uffizzi Dashboard. If the external secret does not exist, you will see a secret-not-found error message in the Uffizzi Dashboard.
49 |
50 | - `external`: Indicates that the secret object (a name/value pair) is declared in the Uffizzi Dashboard (UI). Value must be `true`.
51 | - `name`: The name of the secret object in Uffizzi.
52 |
53 | In the following example, `POSTGRES_USER` and `POSTGRES_PASSWORD` are the names of secrets that have been added in the Uffizzi Dashboard. Their respective values are available to the `db` service once the stack is deployed.
54 |
55 | === "Uffizzi CI"
56 |
57 | ``` yaml
58 | services:
59 | db:
60 | image: postgres:9.6
61 | secrets:
62 | - pg_user
63 | - pg_password
64 |
65 | secrets:
66 | pg_user:
67 | external: true
68 | name: "POSTGRES_USER"
69 | pg_password:
70 | external: true
71 | name: "POSTGRES_PASSWORD"
72 | ```
73 |
--------------------------------------------------------------------------------
/docs/guides/set-up-your-account.md:
--------------------------------------------------------------------------------
1 | # Set up your account
2 |
3 | ## From GitHub Actions
4 | When you run a GitHub Actions workflow that calls the Uffizzi [preview action](https://github.com/marketplace/actions/preview-environments), a Uffizzi account will be automatically created from your GitHub username. This happens because Uffizzi receives a signed [OIDC token](../topics/oidc.md) from GitHub that verifies your identity. There is no need to create a Uffizzi account before running the workflow. Afterwards when you sign in to _uffizzi.com_, you will see that your account already exists.
5 |
6 | !!! Important
7 | When a preview workflow is first merged into your [default branch](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-branches-in-your-repository/changing-the-default-branch), the workflow run will fail. This is expected behavior since the preview workflow must be _initiated from the default branch_ of the base repository. That is, this workflow must first be merged into the default branch for subsequent workflow runs to succeed.
8 |
9 | ## From uffizzi.com
10 | You can alternatively go to [uffizzi.com](https://uffizzi.com) and use the **Sign up with GitHub** button to create an account with your GitHub login. When you do this, you will be redirected to the GitHub OAuth page, which includes a warning that Uffizzi may "Act on your behalf" (See screenshot below). Note that this is part of the standard permissions for GitHub OAuth. The warning is misleading because Uffizzi is only requesting read-only access to your email address and username at this step to set up your account.
11 |
12 |
13 |
14 | After selecting **Authorize Uffizzi Cloud**, you are asked to **Install & Authorize** the Uffizzi GitHub App, where you can see which permissions Uffizzi is requesting. Uffizzi requests only the minimum permissions it needs. The only way Uffizzi acts on your behalf is by commenting on PRs.
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/docs/guides/single-sign-on.md:
--------------------------------------------------------------------------------
1 | # Single sign-on (SSO)
2 |
3 | Single sign-on allows you to require that members of your organization sign in to the Uffizzi Dashboard via your Identity Provider. Uffizzi is compatible with any Identity Provider that supports both the SAML and OpenID Connect protocols. We currently have out-of-the-box support for the following SSO Identity Providers:
4 |
5 | * ADFS
6 | * Azure AD
7 | * Google SAML
8 | * Okta
9 | * OneLogin
10 | * OpenID
11 | * PingIdentity
12 | * SAML (generic)
13 | * VMWare
14 |
15 | ## Configure SSO
16 |
17 | Follow these steps to configure SSO on Uffizzi:
18 |
19 | 1. Create an account with email/password at [app.uffizzi.com](https://app.uffizzi.com/sign_in). By default, the user that creates an account will become an account [Admin](../rbac/#admin).
20 | 2. Once your account is created and you are logged in to the Uffizzi Dashboard, select the menu icon in the top left corner (the three horizontal lines). Then navigate to **Settings** -> **Single Sign-On (SSO)**.
21 | 3. In the text field provided, enter the domain associated with your organization's email addresses. For example if your email address format is name@acme.com, then enter *acme.com* in the domain field. Once you've entered your domain, select **ADD DOMAIN**.
22 | 4. Select **CONFIGURE SSO**. This will route you to a setup guide that includes configuration instructions specific to your Identity Provider. Once you complete the setup guide, you will be routed back to the Uffizzi Dashboard.
23 | 5. If your configuration was successful, you should see a confirmation message. If so, SSO is now configured for your account. Your teammates will now be required to sign in to the Uffizzi Dashboard with SSO. On the Uffizzi sign in page, they should select the **SIGN IN WITH SSO** option.
24 | 6. If there is a problem with your SSO connection, you can reset your configuration by selecting the **CONFIGURE SSO** button again and then selecting **Reset Connection** in the setup guide.
25 |
26 | ## Sign in with SSO
27 |
28 | Once configured, your team members must authenticate via [app.uffizzi.com](https://app.uffizzi.com/sign_in_sso) with the **Sign in with SSO** option. Our SSO implementation does not support signing in from your Identity Provider portal since IDP-initiated authentication is [vulnerable to man-in-the-middle attacks](https://workos.com/blog/sp-initiated-sso-vs-idp-authentication). We recommended that you disable the Uffizzi sign in option in your IdP's portal.
29 |
30 |
31 |
--------------------------------------------------------------------------------
/docs/guides/support-microservices-in-ephemeral-environments-with-nginx.md:
--------------------------------------------------------------------------------
1 | # Support microservices in ephemeral environments with Nginx
2 |
3 | **A guide on how you can support your microservices architecture on Uffizzi ephemeral environments through Nginx**
4 |
5 | By [Shruti Chaturvedi](https://github.com/ShrutiC-git)
6 |
7 | ## **Nginx with Uffizzi: What problems can it solve?**
8 |
9 | Uffizzi, being cloud-native, allows you to bring your microservices architecture into ephemeral environments. The services directive is used to start each of the microservices defined in the `docker-compose.uffizzi.yml` file in its own container. This allows you to develop and manage the microservices as containers, independently of each other, in your ephemeral environments independently of each other.
10 |
11 | The next component of the microservices architecture is networking. How you configure networking for your ephemeral environments depends on your application architecture. If you have multiple independent client-side and server-side services talking through HTTP/S, for example, an Angular frontend talking to Node backend, networking between these services can be achieved using Nginx as a reverse proxy. Some other cases where we’ve used Nginx to help projects onboard to ephemeral environments are:
12 |
13 | - More than one microservice exposed publicly: if your application has multiple public-facing services, you’ll need to put them behind Nginx (or an alternate reverse proxy such as Traefik). The reverse proxy will receive your traffic, and route requests for different services accordingly. Currently, Uffizzi does not support adding multiple "ingresses" (multiple entry ports) into your application. For example, if you have one service named personal-account, exposed publicly on port `3000`, and another service named team-account, exposed publicly on port `3001`, natively (without Nginx), you can expose either `3000` or `3001` on your ephemeral environment to receive external requests using the [ingress field in your compose file](../references/compose-spec/#ingress-required). With Nginx added, you can put both services behind Nginx, expose Nginx to receive HTTP/S traffic, and forward requests coming to Nginx to your services.
14 |
15 | - More than one port needs to be accessed publicly (primarily applicable for monoliths): if a service has more than one exposed port that needs to be accessed publicly, adding Nginx as a reverse proxy will help you achieve this elegantly.
16 |
17 | ## **Example Application**
18 | Let’s take a look at an example of configuring a microservices application with Nginx. This example is a simple voting app, where users can cast a vote for dogs or cats and see the results of the polling in real-time. You can follow the [example on GitHub](https://github.com/UffizziCloud/quickstart). The application has 5 different microservices:
19 |
20 | 1. **`voting-app` service**: client-side service in Python, that allows you to cast a vote. Writes to our Redis queue
21 |
22 | 2. **`redis` service** - Redis queue to collect new votes
23 |
24 | 3. **`worker` service** - .NET Core worker service to consume votes from the Redis queue and write to Postgres
25 |
26 | 4. **`db` service** - Postgres DB, backed by a Docker volume, to write and read the votes
27 |
28 | 5. **`result-app`** service - Node.js web app that reads data from the db service and displays the results in real-time.
29 |
30 | 
31 |
32 | In this example, we have two services exposed publicly: the `voting-app` service, which receives votes, and the `result-app` service, which displays the results back to the user. As mentioned before, currently, Uffizzi supports defining a single service in your ephemeral environment to receive external requests. However, adding Nginx into the environment will solve the problem.
33 |
34 | We will define Nginx as the ingress into the ephemeral environments to listen to incoming HTTP/S connections and route the request to one of the two exposed services based on the path requested.
35 |
36 | 
37 |
38 | To define an [`ingress`](../references/compose-spec.md#ingress-required), we need a `port` (the environment will be listening for traffic on this port) and a `service` (the requests coming to the port will be forwarded to this service). In our case, we will first create an `nginx` service in the compose file, and use this service as our `ingress`.
39 |
40 | ### **Step 1: Creating an Nginx container**
41 |
42 | Within your `docker-compose.uffizzi.yml` file, add a new service (within the services directive), we’ll name it `nginx`. Our `nginx` service will use the [official Nginx image from Docker Hub](https://hub.docker.com/_/nginx). If you want, you can also build a custom image based on Nginx’s official image. If you’re following the example on GitHub, please know that we have used a custom image for the nginx service (named `loadbalancer`) built on the official Nginx image.
43 |
44 | ``` yaml
45 | nginx:
46 | image: nginx:alpine
47 | deploy:
48 | resources:
49 | limits:
50 | memory: 125M
51 | ```
52 |
53 | ### **Step 2: Creating Nginx configuration file**
54 |
55 | Once you have the above service added, we will now configure routing rules for Nginx to forward requests to the `voting-app` service and `result-app` service.
56 |
57 | We will create a new configuration file called `nginx.conf` and define how Nginx should handle request routing. Please make sure this file is placed under a directory, and the total size of the directory is smaller than 1 MB compressed (the limit is not applicable if you’re using [Uffizzi CI](../references/uffizzi-ci.md)). If you’re having trouble configuring volumes, read our [troubleshooting guide](../troubleshooting/most-common-problems.md).
58 |
59 | There are 2 ways traffic will come into the example app:
60 |
61 | 1. Users interact with the voting-app service to cast their votes
62 | 2. Users interact with the result-app to see results
63 |
64 | We will, therefore, need to route requests from the `nginx` service to these two services. Our requirements for the `nginx` (`ingress`) service are:
65 |
66 | - Requests to the root of our app should take users to the `result-app` service, where they can see the votes that have been cast so far.
67 |
68 | - The `result-app` service should redirect users to the `vote-app` service, where they can cast their votes.
69 |
70 | - The `vote-app` service must respond to the redirect from `result-app` and allow users to cast their votes.
71 |
72 | Here is the `nginx.conf` file:
73 |
74 | ```
75 | server {
76 | listen 8080;
77 | server_name localhost;
78 | location / {
79 | proxy_pass http://localhost:8088/; # result-app addr
80 | }
81 | location /vote/ {
82 | proxy_pass http://localhost:8888/; # voting-app addr
83 | }
84 | }
85 | ```
86 |
87 | In the above `nginx.conf` file, we have defined Nginx to listen on port `8080`. The port you define here should not be in use by other services/containers. Requests received at the root (defined by `/`) will be sent from Nginx to the `result-app` service. Requests received at `/vote` will be sent to the `vote-app` service. This config file will allow the `nginx` container—when configured as `ingress` in the `docker-compose.uffizzi.yml`—to receive HTTPS traffic and forward HTTP to the defined upstream.
88 |
89 | ### **Step 3: Configuring the Nginx container**
90 |
91 | We’ll now further configure the Nginx container to mount this config file into the container. Make the following changes to the `nginx` service:
92 |
93 | ``` yaml
94 | nginx:
95 | image: nginx:alpine
96 | environment:
97 | VOTE_HOST: "localhost"
98 | VOTE_PORT: "8888"
99 | RESULT_HOST: "localhost"
100 | RESULT_PORT: "8088"
101 | volumes: ./nginx-uffizzi:/etc/nginx
102 | deploy:
103 | resources:
104 | limits:
105 | memory: 125M
106 | ```
107 |
108 | Take note of the `volumes` section. Currently, Uffizzi does not support mounting single files from the host to the container. We, therefore, placed the `nginx.conf` file into a directory called `nginx-uffizzi` and mount this directory to `/etc/nginx` in the container.
109 |
110 | According to the official docs from Nginx, for NGINX Open Source, where the config needs to be mounted will depend on the package system used to install NGINX and the operating system. It is typically one of `/usr/local/nginx/conf`, `/etc/nginx`, or `/usr/local/etc/nginx`. The `nginx.conf` is a highly configurable file that you can configure according to the needs of your app. However, instead of replacing the default `nginx.conf` altogether, we often recommend adding your configuration file(s) in the `/etc/nginx/conf.d/` directory, which Nginx will apply as additional configuration to the default `nginx.conf`. See [Nginx documentation](https://docs.nginx.com/nginx/admin-guide/basic-functionality/managing-configuration-files/) for details on how multiple configurations are applied.
111 |
112 | ### **Step 4: Adding nginx container as our entrypoint/ingress into the ephemeral environment**
113 |
114 | After fully configuring the nginx container, let’s add this as the ingress to receive traffic into Uffizzi ephemeral environments. At the top-level of your compose file, add the following:
115 |
116 | ``` yaml
117 | x-uffizzi:
118 | ingress:
119 | service: nginx
120 | port: 8080
121 | ```
122 |
123 | Your compose should look like this after adding the above snippet:
124 |
125 | ``` yaml
126 | x-uffizzi:
127 | ingress:
128 | service: nginx
129 | port: 8080
130 | services:
131 | nginx:
132 | image: nginx:alpine
133 | volumes: ./nginx-uffizzi:/etc/nginx
134 | deploy:
135 | resources:
136 | limits:
137 | memory: 125M
138 | other-services:
139 | image: service-image
140 | ```
141 |
142 | Voila! After making these changes, and opening a PR in your project, a new environment will spin up, receiving HTTPS traffic on the port you have defined (here `8080`). Adding a reverse proxy as ingress for your ephemeral environments is a really powerful way of bringing your microservices application to Uffizzi. Scenarios we discussed above, and more, can efficiently be solved by adding Nginx into your Uffizzi ephemeral environments. For more blogs on enhancing developer productivity with ephemeral environments, check out [our blog](https://www.uffizzi.com/blog). If you want ephemeral environments for your microservices, [get in touch with us](https://www.uffizzi.com/contact) and let us know how we can help!
143 |
144 |
145 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | # Uffizzi Overview
2 |
3 | ## What is Uffizzi?
4 | Uffizzi is a platform that enables teams to easily create and destroy on-demand cloud environments for development, QA, staging, and more. These "ephemeral environments" give teams a flexible way to scale their test infrastructure, while avoiding the bottleneck of a traditional shared test environment. With Uffizzi ephemeral environments, developers can test pre-release branches in clean, isolated environments that are not polluted by previous tests. Uffizzi ephemeral environments can also be used by product and sales teams to preview new features for clients and other stakeholders.
5 |
6 | Other common names for ephemeral environments are _preview environments_, _on-demand environments_, _scratch environments_, _environments-as-a-service (EaaS)_, _pull request environments_, and _continuous previews_.
7 |
8 | ## How it works
9 |
10 | When added to your git repository or continuous integration (CI) pipeline, Uffizzi works in the background each time a change is made to your code—for example, when a pull request (PR) or merge request (MR) is opened, closed, or updated. Additionally, you can create environments via the Uffizzi CLI from your local workstation, or by manually triggering a CI workflow.
11 |
12 | If initiated via PR, Uffizzi will post a comment to your PR issue with a secure _https_ link to your ephemeral environment. Or you can customize your workflows to send the URL to another service like Slack. In either case, your environment is continually refreshed when you push new commits, so anyone reviewing the environment will see the latest changes. Uffizzi also handles clean up, so your environments last only as long as you need them.
13 |
14 |
15 |
16 | ## Quicklinks
17 | | Topic | Description |
18 | |--------|---------------|
19 | | [Quickstart](quickstart.md) | How to install and get started with Uffizzi |
20 | | [Using Uffizzi](using-uffizzi.md) | Detailed integration guide that covers git and/or CI integration |
21 | | [CLI Reference](references/cli.md) | Command-line reference |
22 | | [Troubleshooting](troubleshooting/most-common-problems.md) | Most common problems and ways to solve them |
--------------------------------------------------------------------------------
/docs/install.md:
--------------------------------------------------------------------------------
1 | # Install the Uffizzi CLI
2 |
3 | This guide describes how to install the command-line interface (CLI) tool [`uffizzi`](https://github.com/UffizziCloud/uffizzi_cli), which will allow you to create and manage ephemeral environments on Uffizzi Cloud. If you're self-hosting Uffizzi, you should instead follow the [self-hosting installation guide](https://github.com/UffizziCloud/uffizzi/blob/develop/INSTALL.md).
4 |
5 | ## Homebrew Tap
6 |
7 | For macOS or Linux users, you can install the Uffizzi CLI via the [Homebrew](https://brew.sh/) tap:
8 |
9 | ``` bash
10 | brew tap uffizzicloud/tap
11 | brew install uffizzicloud/tap/uffizzi
12 | ```
13 |
14 | **Note**: Be sure to first run `brew tap` before running `brew install`.
15 |
16 | ## From the binrary releases
17 | The Uffizzi CLI is currently available as a binary for macOS and Linux. Windows users should use our official Docker container image, [available on Docker Hub](https://hub.docker.com/r/uffizzi/cli).
18 |
19 | === "Mac (AMD or ARM)"
20 |
21 | ``` bash
22 | curl -L -o uffizzi "https://github.com/UffizziCloud/uffizzi_cli/releases/latest/download/uffizzi-darwin" && sudo install -c -m 0755 uffizzi /usr/local/bin && rm -f uffizzi
23 | ```
24 |
25 | === "Linux (AMD or ARM)"
26 |
27 | ``` bash
28 | curl -L -o uffizzi "https://github.com/UffizziCloud/uffizzi_cli/releases/latest/download/uffizzi-linux" && sudo install -c -m 0755 uffizzi /usr/local/bin && rm -f uffizzi
29 | ```
30 |
31 | === "Windows / Docker"
32 |
33 | ``` bash
34 | docker run --interactive --rm --tty --entrypoint=sh uffizzi/cli
35 | ```
36 |
37 | Alternatively, you can download binaries directly from the [GitHub Releases](https://github.com/UffizziCloud/uffizzi_cli/releases) page, then add the location to your `PATH`.
38 |
39 | ## Configure the CLI
40 |
41 | Once you've downloaded and installed the Uffizzi CLI, run `uffizzi config` to set the Uffizzi API server you want to use. Accept the default value `app.uffizzi.com` (Uffizzi Cloud):
42 |
43 | ``` bash
44 | $ uffizzi config
45 | ...
46 | Server: (app.uffizzi.com)
47 | ```
48 |
49 |
50 | ## Login
51 |
52 | Login to Uffizzi Cloud or your installation of Uffizzi.
53 |
54 | ### Via GitHub or GitLab OAuth
55 |
56 | Once you've configured the Ufizzi CLI, you can login with your GitHub or GitLab credentials via `uffizzi login`. This command will open a browser window to https://app.uffizzi.com where you can sign up for a new account or sign in to an existing account.
57 |
58 | ``` bash
59 | uffizzi login
60 | ```
61 |
62 | Once you're logged in, return to the CLI. You'll need to select which GitHub/GitLab account you want to use as the default account context, for example, if you have both a personal and organizational account. You can change this setting later with the [`uffizzi config`](references/cli.md#config) command.
63 |
64 | ``` bash
65 | $ uffizzi login
66 | Select an account: (Press ↑/↓ arrow to move and Enter to select)
67 | ‣ Acme Corp
68 | jdoe
69 | ```
70 |
71 | For more information on Uffizzi's account model, see [Teams and Accounts on Uffizzi Cloud](topics/teams-and-accounts.md) and [Role-based Access Control](topics/rbac.md).
72 |
73 | ### Via Email/Password
74 |
75 | If you have an email and password login for Uffizzi, you can login via:
76 |
77 | ```
78 | uffizzi login --email --username --server
79 | ```
80 |
81 | ### Via Environment Variables
82 |
83 | Alternatively, for email/password accounts (i.e. not GitHub or GitLab OAuth), if you set environment varialbes `UFFIZZI_USER_EMAIL` and `UFFIZZI_USER_PASSWORD`, Uffizzi will log you in automatically when you run `uffizzi login`.
84 |
85 | ## Create a new project
86 |
87 | In Uffizzi, every environment must belong to a project. If this is your first time setting up Uffizzi, select **Create a new project**. Then enter a project name, slug, description.
88 |
89 | ``` bash
90 | $ uffizzi login
91 | ...
92 | > Create a new project
93 | ```
--------------------------------------------------------------------------------
/docs/quickstart-uffizzi-ci.md:
--------------------------------------------------------------------------------
1 | # Configure Uffizzi CI
2 |
3 | Uffizzi CI is an integrated build service provided by Uffizzi Cloud. Every time you push a new commit to your repository, Uffizzi CI receives a webhook and builds your application from source. Choose this solution if you don't already have a CI platform or don't want to use your existing solution to build preview images. [Learn more >](references/uffizzi-ci.md)
4 |
5 | ## Example Usage
6 |
7 | ### **1. Fork the `quickstart-uffizzi-ci` repository**
8 | Fork the [`quickstart-uffizzi-ci`](https://github.com/UffizziCloud/quickstart-uffizzi-ci) repository on GitHub. Be sure to uncheck the option **Copy the `main` branch only**. This ensures that the `try-uffizzi` branch will be included in your fork.
9 |
10 | Click to expand
11 |
12 |
13 |
14 | #### What's in this repository?
15 | This repository includes a sample voting application that consists of five microservies. Also included in the repository is a Docker Compose template ([`docker-compose.uffizzi.yml`](https://github.com/UffizziCloud/quickstart-uffizzi-ci/blob/main/docker-compose.uffizzi.yml)) that describes the application stack and includes information required by Uffizzi.
16 |
17 | At a minimum, this file must include the following object definitions:
18 |
19 | 1. **[`services`](references/compose-spec.md#services)** - The container service(s) that make up your application. See [Docker Compose for Uffizzi](references/compose-spec.md) for supported keywords.
20 | 2. **[`x-uffizzi`](references/compose-spec.md#x-uffizzi-extension-configuration-reference)** - This is a custom extension field required by Uffizzi.
21 |
22 | a. [`ingress`](references/compose-spec.md#ingress-required) - Tells Uffizzi which of your `services` should receive incoming _https_ traffic
23 | b. [`continuous_previews`](references/compose-spec.md#continuous_previews) - Required by Uffizzi CI. Set the following values to `true`:
24 |
25 | - `deploy_preview_when_pull_request_is_opened: true`
26 | - `delete_preview_when_pull_request_is_closed: true`
27 | - `share_to_github: true` - Toggles commenting on GitHub pull request issues
28 |
29 | Your Docker Compose template must be committed to the branch that you merge _into_, i.e. your target base branch (typically this is your default branch). It is recommended to commit your compose file to the root directory, although this is not required. Note that all paths specified in your `docker-compose.uffizzi.yml` file should be relative to this file location.
30 |
31 | !!! Note
32 | See the [Docker Compose for Uffizzi reference guide](references/compose-spec.md) for a comprehensive list of supported keywords.
33 |
34 | ### **2. Create a project at uffizzi.com**
35 |
36 | If you haven't already done so, [create a Uffizzi Cloud account](https://app.uffizzi.com/sign_up). Once logged in, follow these steps to create project:
37 |
38 | 1. Select **New project** > **Uffizzi CI** > **Configure GitHub**
39 | 2. Install Uffizzi Cloud on your GitHub account
40 | 3. Install & Authorize the Uffizzi GitHub App your repository
41 | 4. Select **Set up project** for your desired repository
42 | 5. Add your `docker-compose.uffizzi.yml` file in **Project** > **Settings** > **Compose**. Be sure to choose the branch that you merge into, i.e. your target base branch.
43 | 6. Save and validate your compose; resolve any errors
44 | 7. Check your configuration with a test deployment
45 |
46 | Click to expand (Screenshots)
47 |
1. Select New project > Uffizzi CI > Configure GitHub
48 |
49 |
2. Install Uffizzi Cloud on your GitHub account
50 |
51 |
3. Install & Authorize the Uffizzi GitHub App your repository
52 |
53 |
4. Select Set up project for the repository you just forked
54 |
55 |
5. Add your `docker-compose.uffizzi.yml` file in Project > Settings > Compose. Be sure to choose the branch that you merge into, i.e. your target base branch.
56 |
57 |
6. Save and validate your compose; resolve any errors
58 |
59 |
7. Check your configuration with a test deployment
60 |
61 |
62 |
63 | ### **3. Open a pull request for `try-uffizzi` branch against `main` in your fork**
64 |
65 | Be sure that you're opening a PR on the branches of _your fork_ (i.e. `your-account/main` ← `your-account/try-uffizzi`). If you try to open a PR for `UffizziCloud/main` ← `your-account/try-uffizzi`, a preview will not run in this example.
66 |
67 | That's it! This will kick off Uffizzi CI and post the Preview Environment URL as a comment to your PR issue.
68 |
--------------------------------------------------------------------------------
/docs/quickstart.md:
--------------------------------------------------------------------------------
1 | # Quickstart Guide
2 |
3 | This guide covers how you can quickly get started using Uffizi to create virtual clusters. If you want to create Docker Compose-based environments instead, start with [this guide](docker-compose-environment.md).
4 |
5 | !!! Important
6 | Uffizzi virtual clusters are currently in beta. Our team is actively working to improve reliability and developer experience. Please report any bugs to bugs@uffizzi.com
7 |
8 | ## Prerequisites
9 |
10 | The following prerequisites are required for this guide:
11 |
12 | 1. A GitHub or GitLab account for creating a Uffizzi Cloud login
13 | 2. Installing and configuring the Uffizzi client
14 | 3. Deciding which continuous integration tool to configure, if any
15 |
16 | ## Install Uffizzi
17 |
18 | Download a binary release of the Uffizzi client from the [official release page](https://github.com/UffizziCloud/uffizzi_cli/releases).
19 |
20 | For more details, see the [installation guide](install.md).
21 |
22 | ## Create an account
23 |
24 | For this quickstart guide, we'll be creating an account on Uffizzi Cloud using your GitHub or GitLab login. The following command will provide you with a link to sign up via a browser. If you've already created an account at [uffizzi.com](https://uffizzi.com), this command will let you login to your existing account:
25 |
26 | ``` bash
27 | uffizzi login
28 | ```
29 |
30 | !!! Note
31 | If you'd rather have an email/password based login on Uffizzi Cloud, [submit a request](mailto:accounts@uffizzi.com).
32 | If you're self-hosting Uffizzi, you should follow the [self-hosting guide](https://github.com/UffizziCloud/uffizzi/blob/develop/INSTALL.md) to create an account.
33 |
34 | ### Account setup
35 |
36 |
37 | 1. **Select an account** - In this step, you'll select your default account context. You can change this setting later with the [`uffizzi config`](references/cli.md#config) command.
38 |
39 | ```
40 | $ uffizzi login
41 | Select an account: (Press ↑/↓ arrow to move and Enter to select)
42 | ‣ Acme Corp
43 | jdoe
44 | ```
45 | !!! Note
46 | If you signed up with GitHub or GitLab, you'll see your personal account and any organizations or groups you belong to. Choose your organization/group account if you want to create ephemeral environments for your team applications. Otherwise, you can select your personal account to create clusters for personal projects. Note that Personal and Team accounts are billed separately. [Learn more >](topics/teams-and-accounts.md)
47 |
48 | 2. **Create a new project** - Select **Create a new project**. Enter a project name as "quickstart" or similar, then confirm the project slug. For project description, enter "Quickstart guide" or just leave it blank.
49 |
50 | ## Create a virtual cluster
51 |
52 | Let's create a [virtual Kubernetes cluster](topics/virtual-clusters.md) to which we'll apply manifests in the next steps.
53 |
54 | In the command below, replace `~/.kube/config` with the path to your kubeconfig file, if different. Uffizzi will merge with an existing kubeconfig at the location you specify. If you don't have a kubeconfig file, you can omit this option and Uffizzi will create a new kubeconfig file at `~/.kube/config`.
55 |
56 | ``` bash
57 | uffizzi cluster create --name quickstart --kubeconfig ~/.kube/config --update-current-context
58 | ```
59 |
60 | The last option `--update-current-context` is equivalent to `kubectl config use-context`. It tells Uffizzi to set the default cluster context to the one that was just created.
61 |
62 | To verify that the cluster was successfully created, run:
63 |
64 | ``` bash
65 | uffizzi cluster list
66 | ```
67 |
68 | ## Download an example application
69 |
70 | We'll be using an [example application](https://github.com/UffizziCloud/quickstart-k8s) to deploy onto our cluster. The following GitHub repository includes code for the applicaiton, along with Kubernetes manifests that describe its configuration.
71 |
72 | Clone the repository, then change to its directory:
73 |
74 | ``` bash
75 | git clone https://github.com/UffizziCloud/quickstart-k8s.git && \
76 | cd quickstart-k8s
77 | ```
78 |
79 | ## Apply the manifests to your cluster
80 |
81 | From the `quickstart-k8s/` directory, run the following `kubectl` command to apply the manifests from the `manifests/` directory to your cluster:
82 |
83 | ``` bash
84 | kubectl apply --kustomize .
85 | ```
86 |
87 | The above will create deployments, services, and ingresses for `vote` and `result` applications. The hostnames on the ingresses are assigned dynamically so that users don't have to create their own and spend time sorting out possible hostname conflict issues.
88 |
89 | If you query your created ingress with `kubectl get ingress -A`, you should see something like the following:
90 | ```
91 | NAME CLASS HOSTS ADDRESS PORTS AGE
92 | result uffizzi result-default-quickstart-cluster-320.uclusters.app.uffizzi.com 80, 443 14m
93 | vote uffizzi vote-default-quickstart-cluster-320.uclusters.app.uffizzi.com 80, 443 14m
94 | ```
95 |
96 | ## Understanding Ingress on Uffizzi
97 |
98 | There are two ingress options on Uffizzi: default and custom.
99 |
100 | ### Default IngressClass `uffizzi`
101 |
102 | The default IngressClass for any ingress created in a virtual cluster is `uffizzi`. The hostnames will be overriden to the format below :
103 |
104 | ```
105 | https://---.uclusters.app.uffizzi.com
106 | ```
107 |
108 | This allows users to quickly start testing their serivces and routing traffic from the outside world without having to configure hostnames manually or provisioning their own Ingress controller. Alternatively, you can define a custom IngressClass, as described below.
109 |
110 | ### Custom IngressClass
111 |
112 | You can bring your own IngressClass, and install the necessary controller on your virtual cluster. Custom IngressClasses on Uffizzi virtual clusters are configured just like they are for a standard Kubernetes cluster.
113 |
114 | Follow the official kubernetes documentation for understanding what an [IngressClass](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class) is and how you can back it up by deploying your own [Ingress controller of choice](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/).
115 |
116 | ## Verify everything works
117 |
118 | You can verify that everything is working by opening both the ingress URLs in your browser. You can vote for cats or dogs from the vote service, then see the voting results in the result service.
119 |
120 | ## Clean up
121 |
122 | Once your done with this environment, you can clean everything up—including all Kubernetes resources and data—by deleting the cluster:
123 |
124 | ```
125 | uffizzi cluster delete quickstart --delete-config
126 | ```
127 |
128 | The `--delete-config` flag tells Uffizzi to delete this cluster, user, and context for your kubeconfig file.
129 |
130 | ## What's next?
131 |
132 | See advanced usage examples, like how to add Uffizzi to a continuous integration (CI) pipeline like GitHub Actions or GitLab CI, so you can create ephemeral environments on every pull request or merge request.
133 |
134 | [Using Uffizzi →](using-uffizzi.md){ .md-button .md-button--primary }
135 |
136 |
137 |
--------------------------------------------------------------------------------
/docs/references/example-compose.md:
--------------------------------------------------------------------------------
1 | # Example Docker Compose files for Uffizzi
2 |
3 | ## **Monorepo example (using Uffizzi CI)**
4 | In this example, Uffizzi CI builds multiple serviecs that are all co-located in a single repository (i.e., a "monorepo")
5 |
6 | See the source code for this example here: https://github.com/UffizziCloud/example-voting-app-monorepo
7 |
8 | ```yaml title="docker-compose.uffizzi.monorepo.yml"
9 | # Uffizzi extension
10 | x-uffizzi:
11 | ingress:
12 | service: loadbalancer
13 | port: 8080
14 | continuous_preview:
15 | deploy_preview_when_pull_request_is_opened: true
16 | delete_preview_when_pull_request_is_closed: true
17 | share_to_github: true
18 |
19 | # Vote applicaiton
20 | services:
21 | redis:
22 | image: redis:latest
23 |
24 | postgres:
25 | image: postgres:9.6
26 | secrets:
27 | - pg_user
28 | - pg_password
29 |
30 | worker:
31 | build: ./worker # Assumes Dockerfile exists in this repo
32 | deploy:
33 | resources:
34 | limits:
35 | memory: 250M
36 |
37 | result:
38 | build: ./result
39 | context: Dockerfile # Or you can specify an alternate monorepo
40 | environment:
41 | PORT: 8088
42 |
43 | vote:
44 | build: ./vote
45 | deploy:
46 | resources:
47 | limits:
48 | memory: 250M
49 | environment:
50 | PORT: 8888
51 |
52 | loadbalancer:
53 | image: nginx:latest
54 | configs:
55 | - source: nginx-vote-conf
56 | target: /etc/nginx/conf.d/vote.conf
57 |
58 | # Loadbalancer configuration
59 | configs:
60 | nginx-vote-conf:
61 | file: ./vote.conf
62 |
63 | # Postgres credentials
64 | secrets:
65 | pg_user:
66 | external: true # indicates value is external to this repository
67 | name: "POSTGRES_USER" # i.e., value should be added in the Uffizzi Dashboard
68 | pg_password:
69 | external: true # indicates value is external to this repository
70 | name: "POSTGRES_PASSWORD" # i.e., value should be added in the Uffizzi Dashboard
71 | ```
72 |
73 | ## **Polyrepo example (using Uffizzi CI)**
74 | In this example, Uffizzi CI builds services from source that are stored in different repositories (i.e. a "polyrepo").
75 |
76 | See the source code for this example here: https://github.com/UffizziCloud/example-voting-worker/blob/main/docker-compose.uffizzi.yml
77 |
78 | ``` yaml title="docker-compose.uffizzi.2.yml"
79 | # Uffizzi extension
80 | x-uffizzi:
81 | ingress: # required
82 | service: loadbalancer
83 | port: 8080
84 | continuous_preview:
85 | deploy_preview_when_pull_request_is_opened: true
86 | delete_preview_when_pull_request_is_closed: true
87 | share_to_github: true
88 | # Vote applicaiton
89 | services:
90 | redis:
91 | image: redis:latest # Defaults registry is hub.docker.com
92 | postgres:
93 | image: postgres:9.6 # Defaults registry is hub.docker.com
94 | secrets:
95 | - pg_user
96 | - pg_password
97 | worker:
98 | build: . # defaults to ./Dockerfile
99 | deploy:
100 | resources:
101 | limits:
102 | memory: 250M
103 | result:
104 | build:
105 | context: https://github.com/UffizziCloud/example-voting-result#main
106 | dockerfile: Dockerfile
107 | environment:
108 | PORT: 8088
109 | vote:
110 | build:
111 | context: https://github.com/UffizziCloud/example-voting-vote # defaults to "Default branch" as set in GitHub (usually main/master)
112 | dockerfile: Dockerfile
113 | x-uffizzi-continuous-preview:
114 | deploy_preview_when_pull_request_is_opened: false
115 | deploy:
116 | resources:
117 | limits:
118 | memory: 250M
119 | environment:
120 | PORT: 8888
121 | loadbalancer:
122 | image: nginx:latest
123 | configs:
124 | - source: nginx-vote-conf
125 | target: /etc/nginx/conf.d/vote.conf
126 | # Loadbalancer configuration
127 | configs:
128 | nginx-vote-conf:
129 | file: ./vote.conf
130 | # Postgres credentials
131 | secrets:
132 | pg_user:
133 | external: true # indicates value is external to this repository
134 | name: "POSTGRES_USER" # i.e., value should be added in the Uffizzi Dashboard
135 | pg_password:
136 | external: true # indicates value is external to this repository
137 | name: "POSTGRES_PASSWORD" # i.e., value should be added in the Uffizzi Dashboard
138 | ```
139 |
140 | ## Expose multiple routes in an ephemeral environment
141 |
142 | Some applications may want to expose different services at different routes, for example, `/` and `/console`. To do this, we can use `nginx` to map requests for specific ports to their target containers. We'll first add an `nginx` service to our Docker Compose file, then define the routes in an `nginx.conf` file.
143 |
144 | ```yaml title="docker-compose.uffizzi.3.yml"
145 | x-uffizzi:
146 | ingress:
147 | service: nginx
148 | port: 8081
149 | continuous_previews:
150 | deploy_preview_when_pull_request_is_opened: true
151 | delete_preview_when_pull_request_is_closed: true
152 | share_to_github: true
153 |
154 | services:
155 | nginx:
156 | image: nginx:alpine
157 | restart: unless-stopped
158 | ports:
159 | - "8081:8081"
160 | volumes:
161 | - ./uffizzi/nginx:/etc/nginx/conf.d/
162 |
163 | app:
164 | depends_on:
165 | - "postgres"
166 | build:
167 | context: ./
168 | dockerfile: ./Dockerfile
169 | ports:
170 | - 3001:3001
171 |
172 | postgres:
173 | image: postgres:14-alpine
174 | user: postgres
175 | environment:
176 | POSTGRES_USER: "postgres"
177 | POSTGRES_PASSWORD: "postgres" # See https://docs.uffizzi.com/guides/secrets/#add-secrets-element-to-your-docker-compose-template
178 | deploy:
179 | resources:
180 | limits:
181 | memory: 500M
182 | ```
183 |
184 |
185 |
186 | Now we will create a new file in our repository `/uffizzi/nginx/nginx.conf` that defines how our paths will be exposed. By default the official `nginx:latest` base image we used in our Docker Compose file will include all `/etc/nginx/conf.d/*.conf` files.
187 |
188 | Now we will create a new file in our repository `/uffizzi/nginx/nginx.conf` that defines how our paths will be exposed.
189 |
190 | ```json title="nginx.conf"
191 |
192 | http {
193 | server {
194 | listen 8081;
195 |
196 | location / {
197 | proxy_pass http://localhost:3001;
198 | }
199 |
200 | location /console/ {
201 | proxy_pass http://localhost:3002;
202 | }
203 | }
204 | }
205 |
206 | ```
207 |
208 |
209 |
--------------------------------------------------------------------------------
/docs/references/uffizzi-ci.md:
--------------------------------------------------------------------------------
1 | # Uffizzi CI
2 | !!! Note
3 | If you use GitHub Actions, GitLab CI, or another CI provider, you do not need to use Uffizzi CI.
4 |
5 | ## What is Uffizzi CI?
6 | Uffizzi CI is an integrated build and deployment service provided by Uffizzi Cloud free of charge. Choose this solution if you don't already have a CI platform or don't want to use your existing solution to build preview images.
7 |
8 | Every time you push a new commit to your repository, Uffizzi CI receives a webhook and builds your application from source. This ensures that the latest changes are always included in your previews. To use Uffizzi CI, your code must be stored in a GitHub repository.
9 |
10 | ## Setting up Uffizzi CI
11 | To set up Uffizzi CI, you'll first need to create a project in the Uffizzi Dashboard, then install and authorize the Uffizzi GitHub App. Once you've done that, you'll connect a [Compose file](../references/compose-spec.md) in your project settings.
12 |
13 | ### **1. Create a Uffizzi CI project**
14 |
15 | If you haven't already done so, create a Uffizzi CI project. Login to the [Uffizzi Dashboard](https://app.uffizzi.com/sign_in), then navigate to **Account** > **Projects**. Select **New project** > **Uffizzi CI** > **Configure GitHub**
16 | Click to expand (Screenshots)
17 |
18 |
19 |
20 | ### **2. Install & Authorize the Uffizzi GitHub App**
21 | After selecting **Configure GitHub**, you will be redirected to a GitHub login page to install and authorize the Uffizzi Cloud [GitHub App](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps). If you have more than one GitHub account, be sure to install the GitHub App on the same account that you used to create your Uffizzi account. To install the Uffizzi Cloud GitHub App on an organizational account, you must have Owner permissions for your GitHub Organization.
22 |
23 | Click to expand (Screenshots)
24 |
Install Uffizzi Cloud on your GitHub account
25 |
26 |
27 |
28 |
29 |
30 | Next, choose which repositories you wish to preview, then select **Install & Authorize**. Uffizzi requests only the minimum permissions it needs, which includes read access to your code and write access to pull request issues for posting comments. You can manage the GitHub App permissions from the **Developer Settings** page in GitHub.
31 |
32 | ### **3. Add a Compose file in project settings**
33 |
34 | After installing and authorizing the GitHub App, you will be redirected back to the Uffizzi Dashboard. From there you can select a repository to complete project set up.
35 |
36 | 1. Select **Set up project** for your desired repository
37 | 2. Add your [`docker-compose.uffizzi.yml`](../references/compose-spec.md) file in **Project** > **Settings** > **Compose file**. Be sure to choose the branch that you merge into, i.e. your target base branch. For example, if your team opens pull requests against `main`, select this branch.
38 | 3. Save and validate your Compose; resolve any errors
39 | 4. Check your configuration with a test deployment
40 |
41 | Click to expand (Screenshots)
42 |
1. Select Set up project for the repository you just forked
43 |
44 |
2. Add your `docker-compose.uffizzi.yml` file in Project > Settings > Compose. Be sure to choose the branch that you merge into, i.e. your target base branch.
45 |
46 |
3. Save and validate your Compose; resolve any errors
47 |
48 |
4. Check your configuration with a test deployment
49 |
50 |
51 |
52 |
53 | ## How to use Uffizzi CI
54 | Once everything is configured on both GitHub and Uffizzi, you don't need to do anything special to get Uffizzi CI working. Open pull requests as you normally do. Uffizzi CI will work in the background to build your application every time a PR is opened, closed, reopened, or synchronized (i.e. new commits). Uffizzi will post a comment to your pull request issue with a link to your Preview Environment. You can also login to the Uffizzi Dashboard to see a list of all your previews and your application logs.
55 |
56 | Click to expand (Screenshots)
57 |
Open a pull request on GitHub:
58 |
59 |
60 |
Uffizzi CI will post a comment to your pull request issue:
61 |
62 |
63 |
Log in to the Uffizzi Dashboard to see a list of Preview Environments and your application logs:
64 |
65 |
66 |
67 | ### When are previews triggered?
68 |
69 | Currently Uffizzi CI will only create previews for pull requests that target the branch you configure in the Uffizzi Dashboard (**Project** > **Settings** > **Compose file** > **Branch** > **Path to Compose**).
70 |
71 | Click to expand (Screenshots)
72 |
Open a pull request on GitHub:
73 |
74 |
75 |
76 | For example, if you configure Uffizzi CI with a Compose file from your main branch, Uffizzi will apply the following logic:
77 |
78 | **Previews will be triggered for pull requests matching**:
79 |
80 | - `main` ← `{topic_branch}`
81 |
82 | **Previews _will not_ be triggered for pull requests matching**:
83 |
84 | - `{topic_branch}` ← `main` or
85 | - `{topic_branch}` ← `{topic_branch}`
86 |
87 | Note that this design may change in a future release of Uffizzi CI, such that all pull requests will be previewed for a given project.
88 |
89 | !!! Important
90 | If the Compose file in a base and head branches do not match for a given pull request, Uffizzi will use the Compose file in the head branch (i.e. the merging branch) as the preview configuration.
91 |
92 | For example, if a pull request is opened for `main` ← `my-feature` and the Compose files do not match, Uffizzi will use the Compose file from `my-feature`,
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/docs/references/uffizzi-environment-variables.md:
--------------------------------------------------------------------------------
1 | # `UFFIZZI_URL` environment variable
2 |
3 | Each Uffizzi environment is assigned a unique, public URL that exists for the lifetime of the environment. This URL is accessible to all containers of your deployment via the environment variable `UFFIZZI_URL`.
4 |
5 | ### Uses
6 |
7 | It is often the case that components of an application need to know the endpoint of their host environment. For example, you may want your API to provide its own documentation using a tool like Swagger. Since Uffizzi URLs are dynamically generated when your application is deployed, you cannot preconfigure Swagger with the host URL. However, you can use `UFFIZZI_URL` to dynamically set the value of your API endpoint when it is generated by Uffizzi.
8 |
--------------------------------------------------------------------------------
/docs/stylesheets/extra.css:
--------------------------------------------------------------------------------
1 | :root {
2 |
3 | /* Primary color shades */
4 | --md-primary-fg-color: black;
5 | --md-primary-bg-color: hsla(0, 0%, 100%, 1);
6 | --md-primary-bg-color--light: hsla(0, 0%, 100%, 0.7);
7 | --md-primary-fg-color--dark: rgb(253, 216, 48);
8 | --md-text-link-color: hsla(231, 48%, 48%, 1);
9 |
10 | /* Accent color shades */
11 | --md-accent-sh-color: rgb(67, 67, 67);
12 | --md-accent-fg-color: rgb(100, 100, 100);
13 | --md-accent-fg-color--transparent: hsla(189, 100%, 37%, 0.1);
14 | --md-accent-bg-color: hsla(0, 0%, 100%, 1);
15 | --md-accent-bg-color--light: hsla(0, 0%, 100%, 0.7);
16 |
17 | }
18 |
19 | :root>* {
20 |
21 | /* Code block color shades */
22 | --md-code-bg-color: hsla(0, 0%, 96%, 1);
23 | --md-code-fg-color: hsla(200, 18%, 26%, 1);
24 |
25 | /* Footer */
26 | --md-footer-bg-color: black;
27 | --md-footer-bg-color--dark: hsla(0, 0%, 0%, 0.32);
28 | --md-footer-fg-color: hsla(0, 0%, 100%, 1);
29 | --md-footer-fg-color--light: hsla(0, 0%, 100%, 0.7);
30 | --md-footer-fg-color--lighter: hsla(0, 0%, 100%, 0.3);
31 |
32 | /* Link color */
33 | --md-typeset-a-color: rgb(92, 127, 209);
34 | }
35 |
36 | /* Optionally remove the copy code button from code block */
37 | .highlight.no-copy .md-clipboard {
38 | display: none;
39 | }
40 |
41 |
42 | /* H1 and H2 tags */
43 | .md-typeset h1 {
44 | font-weight: bold;
45 | color: var(--md-primary-fg-color);
46 | }
47 |
48 | .md-typeset h2,
49 | .md-typeset h3 {
50 | font-weight: bold;
51 | color: var(--md-accent-sh-color);
52 | }
53 |
54 | /* Full-width tables */
55 | .md-typeset__table {
56 | min-width: 100%;
57 | }
58 |
59 | .md-typeset table:not([class]) {
60 | display: table;
61 | }
--------------------------------------------------------------------------------
/docs/topics/ci-cd-registry.md:
--------------------------------------------------------------------------------
1 | # Add Continuous Previews (CP) to your CI/CD
2 |
3 | This blog provides an example of how to integrate Uffizzi with an existing CI/CD solution to enable tag-initiated previews, also known as [Continuous Previews](continuous-previews.md). This guide walks you through setting up webhooks on the registry and using the Uffizzi image tagging convention `uffizzi_request_*` to trigger automated previews of new pull requests.
4 |
5 | We'll use GitLab CI/CD for builds and the Azure Container Registry (ACR) to store images, but the general method discussed here applies to any CI/CD and registry combination. For the application, we'll use [an example Python application that fetches and renders weather forecasts from NOAA](https://gitlab.com/adam.d.vollrath/noaafetch/).
6 |
7 | ## Azure Container Registry
8 |
9 | If you haven't yet, integrate your Azure Container Registry by following our [ACR integration documentation](../guides/container-registry-integrations.md#azure-container-registry-acr). You'll need the registry domain, Application (client) ID, and Secret or Password value for the next steps.
10 |
11 | ## GitLab CI/CD
12 |
13 | You can see my example [GitLab CI/CD](https://docs.gitlab.com/ee/ci/) configuration file here:
14 |
15 | Most of this is very standard. The `before_script` logs into Azure as a [Service Principal](https://docs.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals) before each Job. The `build` Job just builds a container image per a `Dockerfile` and pushes it to your ACR registry.
16 |
17 | To integrate with Azure, you'll need to [define some CI/CD variables in your GitLab Project](https://docs.gitlab.com/ee/ci/variables/#add-a-cicd-variable-to-a-project). I used these:
18 |
19 | - `AZURE_REGISTRY` - hostname of the Azure Container Registry, like `example.azurecr.io`
20 | - `AZURE_SP` - UUID of an Azure Application (client) ID
21 | - `AZURE_SP_PASSWORD` - secret value for the above Application
22 |
23 | It is **critical** that these variables not be "Protected" in GitLab because they must be used by Merge Request branches that are not Protected.
24 |
25 | Let's look at the last part of this file, the `Push merge_request` Job:
26 |
27 | ``` yaml title=".gitlab-ci.yml" hl_lines="10 11"
28 | Push merge_request:
29 | variables:
30 | GIT_STRATEGY: none
31 | stage: push
32 | only:
33 | # We want this job to be run on Merge Requests only.
34 | - merge_requests
35 | script:
36 | - docker pull $AZURE_REGISTRY/$CI_PROJECT_NAME:$CI_COMMIT_SHA
37 | - docker tag $AZURE_REGISTRY/$CI_PROJECT_NAME:$CI_COMMIT_SHA $AZURE_REGISTRY/$CI_PROJECT_NAME:uffizzi_request_$CI_MERGE_REQUEST_IID
38 | - docker push $AZURE_REGISTRY/$CI_PROJECT_NAME:uffizzi_request_$CI_MERGE_REQUEST_IID
39 | ```
40 |
41 | Notice the last two lines tag and push an image whose tag begins with `uffizzi_request_`. This is so Uffizzi can identify the new image is associated with a Merge Request.
42 |
43 | ## Uffizzi Compose File
44 |
45 | Next we'll add a `docker-compose.uffizzi.yml` file to our repository and configure Uffizzi to use it. At the moment, Uffizzi only reads Compose files from GitHub, so I've [cloned my example repository over there](https://gitlab.com/adam.d.vollrath/noaafetch). (Compose files on GitLab will be supported soon™.) Here's my example Compose file:
46 |
47 | This file tells Uffizzi where to fetch the container image, what memory resources it requires, which container receives traffic from the load balancer, and how to create new Previews when new images are pushed. You can read more in [Uffizzi's Compose Reference Guide](../references/compose-spec.md).
48 |
49 | ## Uffizzi Continuous Previews
50 |
51 | Lastly we'll configure Uffizzi to use our Compose file. Within your Uffizzi Project, select Specs on the left side and then click the yellow "New Compose" button.
52 | 
53 |
54 | Select your GitHub repository and branch and then enter the filename of your Uffizzi Compose file. I used `docker-compose.uffizzi.yml`.
55 | 
56 |
57 | Validate and save this Compose spec. Now Uffizzi should be ready to deploy a new Preview whenever you open a GitLab Merge Request!
58 |
59 | ## Smoke Test
60 |
61 | Now let's tie it all together. Push a new commit on a new branch to your GitLab repository and then open a new Merge Request. GitLab's CI/CD will build a new image and push it to your Azure Container Registry. Uffizzi will recognize the new image and deploy it automatically.
62 |
63 | 
64 |
--------------------------------------------------------------------------------
/docs/topics/continuous-previews.md:
--------------------------------------------------------------------------------
1 | # Continuous Previews: A Best Practice for Agile Teams
2 | Continuous Previews (CP) are an automation-enabled best practice that encourages cross-functional teams to continuously collaborate during the development process by providing feedback on features that are still in progress. With CP, git topic branches are previewed using on-demand test environments before they are merged into a downstream branch.
3 |
4 | CP helps solve both technical challenges and collaboration challenges. From a technical standpoint CP makes it easy to test pre-merge versions of your complete application with all of its services while at the same time working to eliminate barriers to team collaboration - particularly in a primarily remote work environment.
5 |
6 | This modern approach to agile enables teams to catch issues early, iterate quickly, and avoid the inefficiencies inherent in merging broken features or "dirty code". The following diagram illustrates how CP improves the standard agile development process:
7 |
8 | 
9 |
10 | **CP is not a replacement for Continuous Integration / Continuous Delivery (CI/CD). CP is designed to work in conjunction with CI/CD pipelines. You can think of CP as a preprocessing step that occurs before the merge, such that once you merge, your existing CI/CD pipeline takes over.**
11 |
12 | ## Previews vs. Standard Deployments
13 |
14 | | Previews | Standard Deployments |
15 | | --------------------------------------- | -------------------------- |
16 | | Ephemeral / purpose-driven lifecycle | Persistent / long-running |
17 | | Topic branches (features and bug fixes) | Production, Staging, QA |
18 | | Pre-merge | Post-merge |
19 | | Preview URL | Static URL |
20 |
21 |
22 | ## Previews vs. Continuous Previews
23 |
24 | | Previews | Continuous Previews |
25 | | --------------------------------------- | ------------------------------------------ |
26 | | Initiated and deleted ad hoc (e.g. docker-compose up/down) | Initiated and deleted via event webhooks (open/close PR, new/updated image tags) |
27 | | Typically for individual developer / local testing | Intended for sharing with team for feedback and approval |
28 | | | Team-focused System for Previewing |
29 |
30 | ## Benefits of Continuous Previews
31 |
32 | Teams incorporating Continuous Previews into their workflow often see the following benefits:
33 |
34 | * **Catch issues earlier in the Development Cycle where they are easier to Find and Fix**
35 | * **Improve Collaboration Across Dev and Product Teams to Iterate Faster**
36 | * **Reduce how often Test/QA environment breaks; ability to resolve breakage more quickly**
37 | * **Increase development velocity by reducing returned tickets**
38 | * **Reduce costs by replacing your static QA environment with dynamic preview environments**
39 | * **Eliminate the bottlenecks of shared Dev Environments - Deploy git branches without having to wait until they’re merged**
40 | * **Merge with confidence knowing a feature works as intended**
41 | * **Works with your existing CI/CD pipeline**
42 |
43 | A common bottleneck for software development teams is tracing the root cause of bugs in QA/Test. When multiple developers are pushing commits to a shared development branch, it’s difficult to know if a problem originated as a result of the integration step or if there was a problem with the feature itself.
44 |
45 | By testing the functionality of a topic branch before it’s merged into QA/Test, your team can be sure that any problems that occur after the merge are the result of an integration issue, not a functionality issue. That is, you can verify that a feature works as intended before it’s merged with everyone else’s code.
46 |
47 | By deploying your feature(s) to a publicly accessible endpoint - like the shareable preview URLs that Uffizzi provides - your teammates can view your work and provide timely feedback that reduces the number of returned tickets and ultimately improves development velocity.
48 |
49 | Continuous Previews can lead not only to time savings, but also cost savings. Teams employing an Agile + Continuous Previews strategy can often replace their single, static QA/Test environment with a dynamic set of test environments for each new topic branch. These dynamic test environments can share the same lifecycle as the topic branch itself—i.e., when a branch is created or deleted, a corresponding environment is stood up or torn down. This enables you to effectively "rent" your QA environment(s) - there's no reason to run QA environments in off hours, over the weekend, or during holidays - you can run these for a fraction of the time and have as many environments as you need for as long as you need them and no longer.
50 |
51 | To learn more see the [CP Manifesto](https://www.continuous-previews.org).
52 |
53 |
--------------------------------------------------------------------------------
/docs/topics/docker-extension-partner.md:
--------------------------------------------------------------------------------
1 | # Announcing the Uffizzi Docker Desktop Extension: Test Your Compose Stack In An On-Demand Cloud Environment
2 |
3 | May 10th, 2022 – by [Josh Thurman](https://twitter.com/joshthurman19)
4 |
5 | Today we are thrilled to announce that Uffizzi is one of the first Extensions live on the Docker Desktop marketplace. Through the Docker Extensions Program we are making Uffizzi’s on-demand full-stack preview environments accessible within the Docker Desktop interface.
6 |
7 | This means Developers can streamline their workflows and reduce context switching to do their best work. Through Desktop and the Uffizzi Extension Developers now have the ability to manage their compose stack both locally and in an on-demand cloud environment.
8 |
9 | 
10 |
11 | Uffizzi extends Docker and Docker Desktop‘s capability by taking the popular Docker Compose configuration and applying it to on-demand cloud environments. This means that the millions of developers who use the compose stack for testing their application locally can now use that same configuration to define production-like test environments that are accessible at a secure, shareable URL.
12 |
13 | Teams using Uffizzi are transforming how they test new features with clean, production-like preview environments for every feature. The Continuous Previews capability that Uffizzi provides empowers teams to iterate faster and improve their overall development velocity. With our commitment to Docker Compose as a configuration, the Docker Extensions Partnership is a natural fit and is a big win for Developers.
14 |
15 | Series A Fintech [Tilled.com](https://tilled.com/)’s Head of DevOps and Quality Butch Mayhew noted regarding the Extension, “Uffizzi is super valuable to me, I don’t have to worry about the infrastructure, I just have to have a docker compose file and let Uffizzi do the hard work . . . it allows us to get feedback quickly in an automated fashion and also gives us a place to do some exploratory testing so as we get that merge to develop we’ll have high confidence in our releases.”
16 |
17 | The real power of Uffizzi’s on-demand environments is that they enable Developers and their teams to test new features in isolation and with all their dependencies. This eliminates the variables of commingled code being simultaneously introduced into what we would call a dirty environment. Introducing new features into an existing code base is hard enough, and when you can eliminate variables it’s a game-changer for how efficiently your team can release new features.
18 |
19 | Historically Docker Desktop has been an inner loop tool that organizes individual Developer workflows as they iterate. With the Uffizzi Extension, Desktop becomes a powerful outer loop tool that enables key stakeholders on your cross-functional team – whether it be peer review, QA, or product– to shift left and provide feedback on in-progress development.
20 |
21 | If you'd like to try Uffizzi you can start with a [Live Demo](https://uffizzi.com) on our main site or jump right into the [Docker Desktop Extensions Marketplace](https://www.docker.com/blog/
22 | docker-extensions-discover-build-integrate-new-tools-into-docker-desktop).
23 |
24 | ## Relevant Resources
25 |
26 | -[Uffizzi Testimonials – How Series A Fintech tilled.com uses Uffizzi to achieve “high confidence releases”](https://www.youtube.com/watch?v=vPVBcq8qzj4&t=2s)
27 |
28 | -Download [Docker Desktop](https://www.docker.com/products/docker-desktop)
29 |
30 | -Github @UffizziCloud
31 |
32 | -Twitter [@Uffizzi_](https://twitter.com/Uffizzi_)
33 |
34 | ## Screenshots
35 |
36 | 
37 | 
38 | 
39 | 
40 | 
--------------------------------------------------------------------------------
/docs/topics/networking.md:
--------------------------------------------------------------------------------
1 | # Networking architecture
2 |
3 | All of a preview environment's containers are deployed within a single Kubernetes Pod. Containers within this Pod share their network namespaces—including their IP address. This means that containers within an environment can all reach each other on `localhost`. This is similar to using Docker's `host` network.
4 |
5 | This also means that containers must coordinate port usage, but this is no different from processes on a workstation or virtual machine. Be careful not to configure two or more containers to bind to the same TCP port.
6 |
7 | ## Load Balancing Incoming Traffic
8 |
9 | Every preview environment includes a load balancer that receives incoming HTTPS requests and routes them to the [HTTP port specified](https://docs.uffizzi.com/references/compose-spec/#ingress-required) for the container which receives incoming requests. Preview load balancers are set up and managed automatically, so you don't need to enable or configure them. The load balancer also handles HTTPS certificates for you; the certificate authority is trusted by all popular web browsers and devices.
10 |
11 | The load balancer will also set up an external IP address and DNS record, so you and your stakeholders can access it from anywhere via a public HTTPS URL.
12 |
13 | Separate preview environments do not share an internal network, so they may only communicate over the public Internet.
14 |
15 | ## Limitations
16 |
17 | - Only HTTP traffic is forwarded by the load balancer, and only to one container within each preview. If your application needs external traffic that is not HTTP, and/or needs to route external traffic to more than one container, please [let us know on Slack](https://join.slack.com/t/uffizzi/shared_invite/zt-ffr4o3x0-J~0yVT6qgFV~wmGm19Ux9A)!
18 |
19 | - Since all containers in a preview deployment exist within a Kubernetes Pod, they necessarily share the same lifecycle. By default, Uffizzi monitors the health of a Pod and will restart containers that fail or otherwise exit. While this design simplifies networking, scaling and other factors, it can lead to unexpected behavior when some of your containers are intended to persist while others terminate by design (such as a migration process). As a workaround, you may need to wrap your process in a command loop to keep it from terminiating. One-time jobs are on the Uffizzi roadmap to support this usecase.
20 |
--------------------------------------------------------------------------------
/docs/topics/oidc.md:
--------------------------------------------------------------------------------
1 | # Authenticating via OpenID Connect
2 |
3 | _This article is relevant for [GitHub Actions](https://github.com/features/actions) users._
4 |
5 | Using the official Uffizzi [preview action](https://github.com/marketplace/actions/preview-environments), GitHub Actions workflows authenticate with Uffizzi Cloud via OpenID Connect (OIDC) JSON Web Tokens (JWT). Every time a job runs, GitHub's OIDC Provider automatically generates an OIDC token, which is signed by GitHub to verify the workflow runner's identity. When this token is passed to the preview action, Uffizzi verifies the signature on the token to confirm that the request came from GitHub and the identity of the requester (i.e., the GitHub username). No other credentials are needed by Uffizzi to authenticate a request. This point is worth emphasizing: you do not need a password to authenticate with Uffizzi. In fact, **when the preview workflow runs for the first time, Uffizzi will automatically create an account from the metadata of the OIDC JWT**, so it's not even necessary to first create an account at _uffizzi.com_ before seeing your previews.
--------------------------------------------------------------------------------
/docs/topics/rbac.md:
--------------------------------------------------------------------------------
1 | # Role-based access control
2 |
3 | Uffizzi provides role-based access to limit user privileges across your organization's account, projects and previews. The following list provides a summary Uffizzi RBAC roles and objects that may be restricted with RBAC.
4 |
5 | ## Accounts
6 |
7 | Accounts are associated with a customer billing account, typically the customer's company or organization. Accounts are at the top of the RBAC hierarchy. Currently, users may belong to only one organization (Support for membership in multiple organizational accounts is coming soon. As a temporary workaround, a user can be a member of multiple accounts by using different email logins.)
8 |
9 | ## Projects
10 |
11 | Projects fall within accounts and represent a development effort such as an application. Projects can be created and edited by [Owners](#owner) and [Developers](#developer).
12 |
13 | ## Team Members
14 |
15 | Members are individual users that are associated with an Account and have an assigned access role of [Owner](#owner), [Developer](#developer), or [View Only](#view-only). The Member who creates an Account is by default the Admin of that account. An account must always have at least one Admin.
16 |
17 | ## Single Sign-On (SSO)
18 |
19 | If a Member's Organization has enabled SSO for their account, then a Member must utilize the SSO function to log in to their account. Admins are still able to login in via email/password to administer SSO configuration. See [Single Sign-on](../guides/single-sign-on.md) for more details.
20 |
21 | ## Roles
22 |
23 | ### Owner
24 | Owners can do all and see all within an Account. Owners can view and edit every Project and previews. This is the highest level of permission for an account. Uniquely, Owners control the RBAC, Team creation/deletion, adding Team Members, Projects, integrations, settings and billing. An Account must have at least one Owner.
25 |
26 | ### Developer
27 | Developers can view, create, and edit Projects. They cannot edit Account-level settings like Billing, SSO, Team Members or integrations. A Developer can create Projects and be invited to Projects.
28 |
29 | ### View Only
30 | View Only users can see every Project and Owner Settings but cannot edit anything within Uffizzi.
31 |
--------------------------------------------------------------------------------
/docs/topics/single-page-applications.md:
--------------------------------------------------------------------------------
1 | # Configure `API_BASE_URL` for React Apps and Other Single-Page Applications (SPA)
2 |
3 | In a typical single-page application (SPA) frontend + REST API backend example, the frontend service would have an `API_BASE_URL` or similar `ENV` `var` which points to the backend service. How would we set something like this up with Uffizzi’s preview environments?
4 |
5 | Each Uffizzi environment includes an environment variable [`UFFIZZI_URL`](../references/uffizzi-environment-variables.md) which is available to all containers in the environment. It’s value is the public endpoint of the environment, so if you just have a backend API deployed there, that’s what you’d need to provide to your frontend. Note that this URL is dynamically created when the ephemeral environment is created.
6 |
--------------------------------------------------------------------------------
/docs/topics/teams-and-accounts.md:
--------------------------------------------------------------------------------
1 | # Teams and Accounts on Uffizzi Cloud
2 |
3 | The Uffizzi Team and Account model is tightly coupled with the GitHub and GitLab account models. For example...
4 |
5 | Uffizzi Cloud requires that you sign up for an account using either GitHub or GitLab OAuth. When you create a new account with Uffizzi, you are creating a personal account from your [GitHub Personal Account](https://docs.github.com/en/get-started/learning-about-github/types-of-github-accounts#personal-accounts) or [GitLab User Account](https://docs.gitlab.com/ee/user/profile/), depending on which provider you selected. Your Uffizzi personal account is always named after your personal GitHub/GitLab account. You cannot disassociate your Uffizzi personal account from your GitHub/GitLab personal account. If you sign in to Uffizzi with different GitHub/GitLab personal accounts, they will not be merged, i.e. you will have two separate Uffizzi personal accounts.
6 |
7 | A Uffizzi personal account may also be a Member of one or more Team accounts.
8 |
9 | When you create a Team on Uffizzi, you are creating it from a [GitHub Organizational Account](https://docs.github.com/en/get-started/learning-about-github/types-of-github-accounts#organization-accounts) or a [GitLab Group](https://docs.gitlab.com/ee/user/group/). Your Team is always named after your GitHub Organization or GitLab Group. You cannot disassociate your Team account from your GitHub Organization or GitLab Group. Projects created within the context of a Team account are only visible from your Team account. Similarly, projects within the context of your pesonal account, are only visible from your personal account, not your Team account.
10 |
11 | ## **`Accounts do not match` error**
12 |
13 | !!! Important
14 | You cannot attach GitHub Organization or GitLab Group credentials to a Uffizzi personal account. You must first create a Uffizzi Team for your GitHub Organization or GitLab Group, then configure credentials. Otherwise, you will see the error below.
15 |
16 | Click to expand (Error message)
17 |
This error occurs when, for example, a personal account tries to configure credentials for a GitHub Organizational Account. You should first create a Uffizzi Team to conenct to a GitHub Organization / GitLab Group.
18 |
19 |
20 |
21 | ## **Create a Team**
22 | When you login to Uffizzi, you login to your personal account. You can switch to a Team account or create a new Team from the account dropdown. If you choose **Create team**, you will be asked to install the Uffizzi GitHub/GitLab App and select the repositories you want to configure.
23 |
24 | Click to expand (Screenshots)
25 |
Account dropdown
26 |
27 |
Create a team
28 |
29 |
Choose an Organization to create a Team. If you choose a personal account in this step you will get an error in Uffizzi.
30 |
31 |
Select the repositories you want to configure with Uffizzi.