---
title: "Phase 2 GCP - core services"
description: "Install CircleCI Server 4.7 core services on GCP: create a namespace, pull images, set Helm values, deploy, and create a DNS entry."
platform: "Server"
doc_version: "Server 4.7"
last_updated: "2026-09-29"
---

> For current CircleCI product defaults, deprecated patterns, and Cloud/Server differences, see [AGENTS.md](https://circleci.com/docs/AGENTS.md).
>
> For the complete documentation index and site structure, see [llms.txt](https://circleci.com/docs/llms.txt).

# Phase 2 GCP - core services

Before you begin with the CircleCI Server v4.7 core services installation phase, ensure all prerequisites are met, as described in the following page:

*   [Phase 1 - GCP Prerequisites](https://circleci.com/docs/server-admin/latest/installation/phase-1-gcp-prerequisites/)
    

In the following sections, replace any sections indicated by `< >` with your details.

## 1\. Create a namespace

Create a namespace to install the application into.

```shell
kubectl create ns <namespace>
```

Once you have created your namespace, we recommend setting your `kubectl` context too, with the following command: `kubectl config set-context --current --namespace <namespace>`

## 2\. Pull images

Credentials to pull the images from CircleCI’s image registry will be provided to you as part of the onboarding process. A `docker-registry` Kubernetes Secret will be used to pull images from Azure Container Registry (ACR). You have two options, depending on whether your application has access to the public internet.

<Tabs>
<Tab title="Public">

**Option 1:** Your application has access to the public internet.

This example creates a Kubernetes Secret to enable deployments to pull images from CircleCI’s image registry. The `docker-registry` Kubernetes Secret takes the following form:

```shell
kubectl -n <namespace> create secret docker-registry regcred \
  --docker-server=cciserver.azurecr.io \
  --docker-username=<your-username> \
  --docker-password="<provided-token>" \
  --docker-email=<your-contact-email>
```

</Tab>
<Tab title="Private">

**Option 2:** Your application does NOT have access to the public internet.

The credentials provided to you allow you to pull and store copies of our images locally. Pull and store the images in whichever Docker repository you have available. The `docker-registry` Kubernetes Secret takes the following form:

```shell
kubectl -n <namespace> create secret docker-registry regcred \
  --docker-server=<your-docker-image-repo> \
  --docker-username=<your-username> \
  --docker-password=<your-access-token> \
  --docker-email=<your-email>
```

</Tab>
</Tabs>

## 3\. Create Helm values

Before installing CircleCI, it is recommended to create a new `values.yaml` file unique to your installation. The [Installation Reference](https://circleci.com/docs/server-admin/latest/installation/installation-reference/#example-manifests) section contains some example `values.yaml` files that are a good place to start. The following describes the minimum required values to include in `values.yaml`. Additional customizations are available, see the provided `values.yaml` for all available options.

For sensitive data there are two options:

*   Add into the `values.yaml` file.
    
*   Add them as Kubernetes Secrets directly.
    

This flexibility allows you to manage Kubernetes Secrets using whichever process you prefer. Whichever option you choose, this sensitive information is stored as a Kubernetes Secret within CircleCI.

During the installation process, you may use the following command to generate a random alphanumeric value as required: `cat /dev/urandom | LC_ALL=C tr -dc 'a-zA-Z0-9' | head -c <num-of-chars>`. This command works on any \*nix based system.

### a. API token

The application requires a Kubernetes Secret containing an API token. This API token is used to facilitate internal API communication to `api-service`. Use a random string and store it securely. CircleCI will not be able to recover this value if lost. You can create the Kubernetes Secret yourself, or CircleCI can create it for you.

<Tabs>
<Tab title="You create Secret">

**Option 1:** Create the Kubernetes Secret yourself.

```shell
kubectl -n <namespace> create secret generic api-token \
  --from-literal=api-token=<your-super-secret-random-value>

kubectl -n <namespace> annotate secret/api-token \
  meta.helm.sh/release-name=<helm-release-name> \
  meta.helm.sh/release-namespace=<namespace> \
  helm.sh/resource-policy=keep --overwrite

kubectl -n <namespace> label secret/api-token \
  app.kubernetes.io/managed-by=Helm --overwrite
```

</Tab>
<Tab title="CircleCI creates Secret">

**Option 2:** CircleCI creates the Kubernetes Secret for you.

CircleCI will create the Kubernetes Secret `api-token` automatically.

</Tab>
</Tabs>

### b. Session cookie

The application requires a session cookie key Kubernetes Secret, which CircleCI uses to sign session cookies. The Secret must be exactly 16 characters long. Use a random string and store it securely. CircleCI will not be able to recover this value if lost. You can create the Kubernetes Secret, or CircleCI can create it for you.

<Tabs>
<Tab title="You create Secret">

**Option 1:** Create the Kubernetes Secret yourself.

```shell
kubectl -n <namespace> create secret generic session-cookie \
--from-literal=session-cookie-key=<your-secret-key-16-chars>

kubectl -n <namespace> annotate secret/session-cookie \
  meta.helm.sh/release-name=<helm-release-name> \
  meta.helm.sh/release-namespace=<namespace> \
  helm.sh/resource-policy=keep --overwrite

kubectl -n <namespace> label secret/session-cookie \
  app.kubernetes.io/managed-by=Helm --overwrite
```

</Tab>
<Tab title="CircleCI creates Secret">

**Option 2:** CircleCI creates the Kubernetes Secret for you.

CircleCI will create the Kubernetes Secret "session-cookie" automatically.

</Tab>
</Tabs>

### c. Encryption

The application requires a Kubernetes Secret containing signing and encryption keysets. These keysets are used to encrypt and sign artifacts generated by CircleCI. You created these keysets during the prerequisites phase ([GCP Prerequisites](https://circleci.com/docs/server-admin/latest/installation/phase-1-gcp-prerequisites/#encryption-signing-keys), [AWS Prerequisites](https://circleci.com/docs/server-admin/latest/installation/phase-1-aws-prerequisites/#encryption-signing-keys)). CircleCI will not be able to recover the values if lost. Depending on how you prefer to manage Kubernetes Secrets, there are two options.

<Tabs>
<Tab title="You create Secret">

**Option 1:** Create the Kubernetes Secret yourself.

```shell
kubectl -n <namespace> create secret generic signing-keys \
  --from-literal=signing-key=<your-generated-signing-key> \
  --from-literal=encryption-key=<your-generated-encryption-key>
```

</Tab>
<Tab title="CircleCI creates Secret">

**Option 2:** CircleCI creates the Kubernetes Secret.

Add the value to `values.yaml`. CircleCI will create the Secret automatically.

```yaml
keyset:
  signing: '<your-generated-signing-key>'
  encryption: '<your-generated-encryption-key>'
```

</Tab>
</Tabs>

### d. PostgreSQL

#### i. Credentials

The application requires a Kubernetes Secret containing PostgreSQL credentials. This Secret is required when using either the internal (default) or an externally hosted instance of PostgreSQL. CircleCI will not be able to recover the values if lost. Based on how you prefer to manage Kubernetes Secrets there are two options.

<Tabs>
<Tab title="You create Secret">

**Option 1:** Create the Secret yourself.

```shell
kubectl -n <namespace> create secret generic postgresql \
  --from-literal=postgres-password=<postgres-password>
```

You must then provide the following to the `values.yaml` file:

```yaml
postgresql:
  auth:
    existingSecret: postgresql
```

</Tab>
<Tab title="CircleCI creates Secret">

**Option 2:** CircleCI creates the Kubernetes Secret.

Add the credentials to `values.yaml`, and CircleCI will create the Secret automatically.

```yaml
postgresql:
  auth:
    postgresPassword: "<postgres-password>"
```

</Tab>
</Tabs>

#### ii. TLS

PostgreSQL may be extended to use TLS encrypted traffic. When deployed internally, this option is disabled by default but may be enabled by adding the following to your PostgreSQL block of your `values.yaml`

```yaml
postgresql:
  ...
  tls:
    enabled: true
    autoGenerated: true # Generate automatically self-signed TLS certificates
```

Certificate files may also be provided, rather than autogenerated. In this case, create a Secret containing the TLS certs and keys needed.

```yaml
kubectl -n <namespace> create secret generic postgres-tls-secret --from-file=./cert.pem --from-file=./cert.key --from-file=./ca.pem
```

Then the PostgreSQL block in your `values.yaml` will contain the contents below.

```yaml
postgresql:
  ...
  tls:
    enabled: true
    certificatesSecret: "postgres-tls-secret" # Name of an existing secret that contains the certificates
    certFilename: "cert.pem" # Certificate filename
    certKeyFilename: "cert.key" # Certificate key filename
    certCAFilename: "ca.pem" # CA Certificate filename
```

### e. MongoDB credentials

The application requires a Kubernetes Secret containing MongoDB credentials. This Secret is required when using either the internal (default) or an externally hosted instance of MongoDB. CircleCI will not be able to recover the values if lost. Based on how you prefer to manage Kubernetes Secrets there are two options.

<Tabs>
<Tab title="You create Secret">

**Option 1:** Create the Kubernetes Secret yourself.

```shell
kubectl -n <namespace> create secret generic mongodb-credentials \
  --from-literal=mongodb-root-password=<root-password> \
  --from-literal=mongodb-password=<user-password>
```

You must then provide the following to the `values.yaml` file:

```yaml
mongodb:
  auth:
    existingSecret: mongodb-credentials
```

</Tab>
<Tab title="CircleCI creates Secret">

**Option 2:** CircleCI creates the Kubernetes Secret.

Add the credentials to `values.yaml`, and CircleCI will create the Secret automatically.

```yaml
mongodb:
  auth:
    rootPassword: "<root-password>"
    password: "<user-password>"
```

</Tab>
</Tabs>

### f. RabbitMQ configurations and auth Secrets

The RabbitMQ installation requires two random alphanumeric strings. CircleCI will not be able to recover the values if lost. Based on how you prefer to manage Kubernetes Secrets there are two options.

<Tabs>
<Tab title="You create Secret">

**Option 1:** Create the Secret yourself.

```shell
kubectl -n <namespace> create secret generic rabbitmq-key \
--from-literal=rabbitmq-password=<secret-alphanumeric-password> \
--from-literal=rabbitmq-erlang-cookie=<secret-alphanumeric-key>
```

You must then provide the following to the `values.yaml` file:

```yaml
rabbitmq:
  auth:
    existingPasswordSecret: rabbitmq-key
    existingErlangSecret: rabbitmq-key
```

</Tab>
<Tab title="CircleCI creates Secret">

**Option 2:** CircleCI creates the Kubernetes Secret.

Add the value to `values.yaml`, and CircleCI will create the Kubernetes Secret automatically.

```yaml
rabbitmq:
  auth:
    password: "<secret-alphanumeric-password>"
    erlangCookie: "<secret-alphanumeric-key>"
```

</Tab>
</Tabs>

### g. Pusher Kubernetes Secret

The application requires a Kubernetes Secret for Pusher. CircleCI will not be able to recover the values if lost. Based on how you prefer to manage Kubernetes Secrets there are 2 options:

<Tabs>
<Tab title="You create Secret">

**Option 1:** Create the Kubernetes Secret yourself.

```shell
kubectl -n <namespace> create secret generic pusher \
--from-literal=secret=<pusher-secret>

kubectl -n <namespace> annotate secret/pusher \
  meta.helm.sh/release-name=<helm-release-name> \
  meta.helm.sh/release-namespace=<namespace> \
  helm.sh/resource-policy=keep --overwrite

kubectl -n <namespace> label secret/pusher \
  app.kubernetes.io/managed-by=Helm --overwrite
```

</Tab>
<Tab title="CircleCI creates Secret">

**Option 2:** CircleCI creates the Kubernetes Secret.

CircleCI will create the Kubernetes Secret `pusher` automatically.

</Tab>
</Tabs>

### h. Global

All values in this section are children of `global` in your `values.yaml`.

#### CircleCI domain name (required)

Enter the domain name you specified when creating your Frontend TLS key and certificate ([AWS](https://circleci.com/docs/server-admin/latest/installation/phase-1-aws-prerequisites/#frontend-tls-certificates), [GCP](https://circleci.com/docs/server-admin/latest/installation/phase-1-gcp-prerequisites/#frontend-tls-certificates)).

```yaml
global:
  ...
  domainName: "<full-domain-name-of-your-install>"
```

#### License

A license will be provided by CircleCI, add it to `values.yaml`:

```yaml
global:
  ...
  license: '<license>'
```

#### Registry

The registry to pull images from will have been provided to you, or you may have added the images to your own hosted registry. Add the registry to `values.yaml`:

```yaml
global:
  ...
  container:
    registry: <registry-domain eg: cciserver.azurecr.io >
    org: <your-org-if-applicable>
```

### i. Add static IP address

If you provisioned a Static IP (GCP) in the prerequisites, you can now add the value under the nginx block.

For GCP, add the provisioned IPv4 address under the `loadBalancerIp` field in the nginx block.

```yaml
nginx:
  ...
  loadBalancerIp: "<gcp-provisioned-ipv4-address>"
```

### j. TLS

For TLS, you have a few options:

<Tabs>
<Tab title="Let’s Encrypt">

**Let’s Encrypt**

[Let’s Encrypt](https://letsencrypt.org/) will request and manage certificates for you. Let’s Encrypt is a good option when the load balancer is publicly accessible. The following snippet (using your own email) can be added to `values.yaml`:

```yaml
kong:
  acme:
    enabled: true
    email: contact@example.com
```

Let’s Encrypt may take up to 30 minutes to be reflected in your browser.

</Tab>
<Tab title="Private key & cert">

**Supply a private key and certificate**

You can supply a private key and certificate, which you may have created during the prerequisites steps. The key and certificates will need to be base64 encoded. You can retrieve and encode the values with the following commands:

```bash
cat /etc/letsencrypt/live/<CIRCLECI_SERVER_DOMAIN>/privkey.pem | base64
cat /etc/letsencrypt/live/<CIRCLECI_SERVER_DOMAIN>/fullchain.pem | base64
```

And add them to `values.yaml`:

```yaml
tls:
  certificate: '<full-chain>'
  privateKey: '<private-key>'
```

</Tab>
<Tab title="Terminate upstream">

**Disable TLS within CircleCI**

You can choose to disable TLS termination within CircleCI. The system will still need to be accessed over HTTPS, so TLS termination will be required somewhere upstream of CircleCI. Implement this by following the first option (do nothing) and forward the following ports to your CircleCI load balancer:

*   Frontend / API Gateway \[TCP 80, 443\]
    
*   Nomad server \[TCP 4647\]

</Tab>
</Tabs>

### k. GitHub integration

To configure GitHub with CircleCI, there are two options for providing credentials to the deployment. Steps for both GitHub and GitHub Enterprise (GHE) are given in the next two sections.

#### i. GitHub

These instructions are for the GitHub.com, **not** GitHub Enterprise. Use the client ID and secret you created with your GitHub OAuth application in the prerequisites phase ([AWS](https://circleci.com/docs/server-admin/latest/installation/phase-1-aws-prerequisites/#create-a-new-github-oauth-app), [GCP](https://circleci.com/docs/server-admin/latest/installation/phase-1-gcp-prerequisites/#create-a-new-github-oauth-app)).

<Tabs>
<Tab title="You create Secret">

**Option 1:** Create the Kubernetes Secret yourself.

```shell
kubectl -n <namespace> create secret generic github-secret \
  --from-literal=clientId=<client-id> \
  --from-literal=clientSecret=<client-secret>
```

</Tab>
<Tab title="CircleCI creates Secret">

**Option 2:** CircleCI creates the Kubernetes Secret.

Add the client ID and Secret to the `values.yaml` file. CircleCI will create the Kubernetes Secret automatically.

```yaml
github:
  clientId: "<client-id>"
  clientSecret: "<client-secret>"
```

</Tab>
</Tabs>

#### ii. GitHub Enterprise

The instructions for GitHub Enterprise are similar, with a few extra steps to enable Enterprise and create the required default token.

In the case of GitHub Enterprise add the `defaultToken` created in the prerequisites phase ([AWS](https://circleci.com/docs/server-admin/latest/installation/phase-1-aws-prerequisites/#create-a-new-github-oauth-app), [GCP](https://circleci.com/docs/server-admin/latest/installation/phase-1-gcp-prerequisites/#create-a-new-github-oauth-app)) to the `GitHub` section. The hostname must not include the protocol, ex: `github.exampleorg.com`.

<Tabs>
<Tab title="You create Secret">

**Option 1:** Create the Kubernetes Secret yourself.

```shell
kubectl -n <namespace> create secret generic github-secret \
  --from-literal=clientId=<client-id> \
  --from-literal=clientSecret=<client-secret> \
  --from-literal=defaultToken=<default-token>
```

You must then provide the following to the `values.yaml` file:

```yaml
github:
  enterprise: true
  hostname: "<github-enterprise-hostname>"
```

</Tab>
<Tab title="CircleCI creates Secret">

**Option 2:** CircleCI creates the Kubernetes Secret.

Add `clientID`, `clientSecret` and `defaultToken` to the `values.yaml` file. You must also set `enterprise` to `true`, and provide the `hostname` for your enterprise GitHub. CircleCI will create the Kubernetes Secret automatically.

```yaml
github:
  ...
  clientId: "<client-id>"
  clientSecret: "<client-secret>"
  enterprise: true
  hostname: "<github-enterprise-hostname>"
  defaultToken: "<token>"
```

</Tab>
</Tabs>

### l. Object storage

Regardless of your storage provider, the bucket name you created during the [Prerequisites Phase](https://circleci.com/docs/server-admin/latest/installation/phase-1-gcp-prerequisites/#object-storage-and-permissions) will need to be included.

```yaml
object_storage:
  bucketName: "<bucket-name>"
```

#### Google Cloud Storage

Under `object_storage` add the following.

```yaml
gcs:
    enabled: true
```

Under `object_storage.gcs` you may add `service_account`, `workloadIdentity`, or neither. You created these keys and roles during the prerequisites steps.

<Tabs>
<Tab title="Use service account">

**Option 1:** Use a service account.

Add a JSON format key of the Service Account to use for bucket access. Add the following to the `object_storage.gcs` section:

```yaml
service_account: "<service-account>"
```

</Tab>
<Tab title="Use Workload Identity">

**Option 2:** Use Workload Identity.

Add the Service Account Email of the Workload Identity. Add the following to the `object_storage.gcs` section:

```yaml
workloadIdentity: "<workload-identity-service-account-email>"
```

</Tab>
<Tab title="You create Secret">

**Option 3:** Create the Kubernetes Secret yourself

Instead of storing the service account in your `values.yaml` file, you may create the Kubernetes Secret yourself.

```shell
kubectl -n <namespace> create secret generic object-storage-secret \
  --from-literal=gcs_sa.json=<service-account>
```

</Tab>
</Tabs>

### m. Installing behind a proxy

Depending on your security requirements, you might want to install CircleCI Server behind a proxy. Installing behind a proxy gives you the power to monitor and control access between your installation and the broader Internet. For further information including limitations of installation behind a proxy, see the [Installing Server Behind a Proxy](https://circleci.com/docs/server-admin/latest/installation/installing-server-behind-a-proxy/) guide.

The following fields need to be configured in your `values.yaml`:

*   Toggle `proxy.enabled` to `"1"`
    
*   Enter details for `proxy.http.host` and `proxy.https.host`, along with their associated ports. These values can be the same but they both need to be configured.
    
*   For authentication you will need to configure `proxy.http.auth.enabled` and `proxy.https.auth.enabled` as `"1"`. You will also need to configure the respective username and password for both HTTP and HTTPS.
    
*   configure the `no_proxy` hosts and subnets. This will include localhost, your GitHub Enterprise host (optional), the hostname of your CircleCI installation (see [Known Limitations](https://circleci.com/docs/server-admin/latest/installation/installing-server-behind-a-proxy/#known-limitations) for an explanation), and the CIDR of Nomad.
    

```yaml
proxy:
  enabled: "1"
  http:
    host: "<proxy.example.internal>"
    port: "3128"
    auth:
      enabled: "1"
      username: "<proxy-user>"
      password: "<proxy-password>"
  https:
    host: "<proxy.example.internal>"
    port: "3128"
    auth:
      enabled: "1"
      username: "<proxy-user>"
      password: "<proxy-password>"
  no_proxy:
    - localhost
    - 127.0.0.1
    - "<github.example.internal>"
    - "<circleci.example.internal>"
    - "<nomad-subnet-cidr>"
    - "<vpc-or-subnet-cidr>"   # VPC or subnets to exclude from the proxy (optional)
```

### n. Encrypting environment variables

All environment variables stored in contexts are encrypted using either [Google Tink](https://developers.google.com/tink) or [HashiCorp Vault](https://www.vaultproject.io/). We recommend the use of Tink as Vault has been deprecated.

#### Use Tink

The following steps cover using Tink as an alternative to Vault:

1.  Enable Tink in your `values.yaml`:
    
    ```yaml
    tink:
      enabled: true
      keyset: ""
    ```
    
    When `tink.enabled` is true, Vault will not be deployed.
    
    Tink keys can be rotated after deployment. See [Rotating Tink keys in CircleCI Server](https://support.circleci.com/hc/en-us/articles/39931197265691-Rotating-Tink-keys-in-CircleCI-Server) for the procedure. To migrate from Vault to Tink (Vault is deprecated), see [Vault to Tink server script](https://github.com/CircleCI-Public/server-scripts/tree/main/vault-to-tink).
    
2.  Generate a [keyset](https://developers.google.com/tink/design/keysets), which Tink uses to manage key rotation. The easiest way to do this is to use Google’s [Tinkey](https://developers.google.com/tink/tinkey-overview) CLI utility. Once [installed](https://developers.google.com/tink/install-tinkey), use the following command:
    
    ```shell
    tinkey create-keyset --key-template XCHACHA20_POLY1305
    ```
    
3.  CircleCI Server stores your generated keyset in a Kubernetes Secret. You may generate this Secret in either of the following ways:
    
    

<Tabs>
<Tab title="You create Secret">

**Option 1:** Create the Kubernetes Secret yourself

Following the example below, create a Kubernetes Secret with the name `tink` and a key `keyset`. Apply this Secret to the namespace of your CircleCI Server installation.

```yaml
apiVersion: v1
kind: Secret
metadata:
  name: tink
data:
  keyset: <your-keyset>
```

</Tab>
<Tab title="CircleCI creates Secret">

**Option 2:** CircleCI Server will create the Kubernetes Secret

You may add the keyset to your `values.yaml` under `tink` as in the example below. CircleCI will generate the required Secret to store your keyset.

```yaml
tink:
  enabled: true
  keyset: "<your-keyset>"
```

</Tab>
</Tabs>

    

If your Tink keyset is somehow lost, you will need to generate a new keyset and then recreate your contexts and their associated Secrets.

### o. Setting up OIDC (optional)

CircleCI Server optionally supports [OpenID Connect Tokens](https://circleci.com/docs/guides/permissions-authentication/openid-connect-tokens/) (OIDC) in jobs.

This feature is not enabled by default and requires a few additional steps to set up, as follows:

1.  Generate a [JSON Web Key (JWK)](https://mkjwk.org/) using the default parameters and copy the `Public and Private Keypair Set` to a secure and convenient location (for example, `~/oidc-service-jwk.json`). This key pair will be used by `oidc-service` to sign the OIDC tokens used in jobs.
    
2.  The JWK will need to be base64 encoded without line wrapping before using it on server:
    
    *   On Linux:
        
        ```console
        $ base64 -w0 ~/oidc-service-jwk.json
        ```
        
    *   On macOS:
        
        ```console
        $ base64 -b0 -i ~/oidc-service-jwk.json
        ```
        
        Copy the output to a secure location, so it can be referenced in the next step.
        
    
3.  Finally, enable `oidc-service` and supply it the base64 encoded JWK from your server Helm values file:
    
    ```yaml
    oidc_service:
      isEnabled: true
      json_web_keys: << set your base64 encoded JWK from step 2 here >>
    ```
    

## 4\. Deploy

Once you have completed the fields detailed above, you can deploy CircleCI’s core services:

```shell
USERNAME=<provided-username>
PASSWORD=<token>
namespace=<your-namespace>
helm registry login cciserver.azurecr.io/circleci-server -u $USERNAME -p $PASSWORD
helm install circleci-server oci://cciserver.azurecr.io/circleci-server -n $namespace --version 4.7.15 -f <path-to-values.yaml>
```

## 5\. Create DNS entry

Create a DNS entry for your nginx load balancer, for example, `circleci.your.domain.com` and `app.circleci.your.domain.com`. The DNS entry must align with the DNS names used when creating your TLS certificate and GitHub OAuth app during the prerequisites steps. All traffic will be routed through this DNS record.

You need the IP address, or, if using AWS, the DNS name of the nginx load balancer. You can find this information with the following command:

```shell
kubectl get service -l app=circleci-proxy
```

## 6\. Validation

You can now navigate to your CircleCI Server installation and log in to the application successfully.

Now we will move on to build services. It may take a while for all your services to be up. You can periodically check by running the following command (you are looking for the `frontend` pod to show a status of `running` and **ready** will show `1/1` in the output):

```shell
kubectl get pods -n <YOUR_CIRCLECI_NAMESPACE>
```

Machine provisioner and Nomad server pods are expected to fail at this stage. You will set up your execution environments in the next phase of the installation.

## Next steps

*   [Phase 3 GCP: Execution Environments Installation](https://circleci.com/docs/server-admin/latest/installation/phase-3-gcp-execution-environments/)