diff --git a/apps/web/README.md b/apps/web/README.md
index bf1c89bc47f765391ef1a0a0588816d91f203212..f922fe0d09f56d5637aca844736d2cff7d081e07 100644
--- a/apps/web/README.md
+++ b/apps/web/README.md
@@ -26,11 +26,13 @@ Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protrac
 
 To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
 
-## Archive Config
+## Environment Config
 
-Configuration variables can be set in the env.js file located next to the index.html file. These variables will be loaded into the angular app through the EnvService. 
+Configuration variables can be set in `src/environments` directory.
 
-The env.js file can be modified without having to rebuild the application.
+To use a configuration in a build, run `ng build --c=production` or `ng build --c=test`.
+
+To use a configuration locally, run `ng serve --c=production` or `ng serve --c=test`.
 
 ## Search Filters
 
diff --git a/apps/web/angular.json b/apps/web/angular.json
index 02d104cdbf0ebbd06ab3ad8c427f979db1feb319..6c5a0e4b1c31d4c49b4cdd22325053d9cb2fa252 100644
--- a/apps/web/angular.json
+++ b/apps/web/angular.json
@@ -59,6 +59,30 @@
                   "maximumError": "5mb"
                 }
               ]
+            },
+            "test": {
+              "fileReplacements": [
+                {
+                  "replace": "src/environments/environment.ts",
+                  "with": "src/environments/environment.test.ts"
+                }
+              ],
+              "optimization": true,
+              "outputHashing": "all",
+              "sourceMap": false,
+              "extractCss": true,
+              "namedChunks": false,
+              "aot": true,
+              "extractLicenses": true,
+              "vendorChunk": false,
+              "buildOptimizer": true,
+              "budgets": [
+                {
+                  "type": "initial",
+                  "maximumWarning": "2mb",
+                  "maximumError": "5mb"
+                }
+              ]
             }
           }
         },
@@ -70,6 +94,9 @@
           "configurations": {
             "production": {
               "browserTarget": "archive2:build:production"
+            },
+            "test": {
+              "browserTarget": "archive2:build:test"
             }
           }
         },
diff --git a/apps/web/src/app/archive-search/services/result-type.service.ts b/apps/web/src/app/archive-search/services/result-type.service.ts
index 89872f44ee26ba6278f593cb9be5e82d2d954461..fe69721b33320323a01e2e84fec96b807463487e 100644
--- a/apps/web/src/app/archive-search/services/result-type.service.ts
+++ b/apps/web/src/app/archive-search/services/result-type.service.ts
@@ -1,8 +1,6 @@
 import {Injectable} from '@angular/core';
 import {ResultType} from "../model/result-type";
 import {BehaviorSubject, Observable} from "rxjs";
-import {HttpClient} from "@angular/common/http";
-import {EnvService} from "../../env/env.service";
 
 @Injectable({
   providedIn: 'root'
@@ -13,11 +11,7 @@ export class ResultTypeService {
   private _resultType: BehaviorSubject<ResultType> = new BehaviorSubject(this.resultType);
   public readonly resultType$: Observable<ResultType> = this._resultType.asObservable();
 
-  private serverAddress: string = '';
-
-  constructor(private http: HttpClient, private env: EnvService) {
-    this.serverAddress = env.apiUrl;
-  }
+  constructor() {}
 
   updateResultType(name: string): void {
     this.resultType = ResultType.getResultType(name);
diff --git a/apps/web/src/app/archive-search/services/search-results.service.ts b/apps/web/src/app/archive-search/services/search-results.service.ts
index 528a7e7bde305bb53683b70fc935be923263e8c3..1b4d3ea61dc4d9a79f0cada2408ac014aa555c4e 100644
--- a/apps/web/src/app/archive-search/services/search-results.service.ts
+++ b/apps/web/src/app/archive-search/services/search-results.service.ts
@@ -1,9 +1,9 @@
-import { Injectable } from '@angular/core';
+import {Injectable} from '@angular/core';
 import {HttpClient, HttpParams} from "@angular/common/http";
 import {Observable, Subscription} from "rxjs";
 import {SelectedFilter} from "../model/selected-filter";
 import {SelectedFilterService} from "./selected-filter.service";
-import {EnvService } from "../../env/env.service";
+import {environment} from "../../../environments/environment";
 import {Field} from "../model/field";
 
 @Injectable({
@@ -11,13 +11,10 @@ import {Field} from "../model/field";
 })
 export class SearchResultsService {
 
-  private serverAddress: string = '';
-
   private selectedFilters: Array<SelectedFilter> = [];
   private selectedFiltersSub: Subscription;
 
-  constructor(private http: HttpClient, private selectedFilterService: SelectedFilterService, private env: EnvService) {
-    this.serverAddress = env.apiUrl;
+  constructor(private http: HttpClient, private selectedFilterService: SelectedFilterService) {
     this.selectedFiltersSub = this.selectedFilterService.selectedFilters$.subscribe(selectedFilters => {
       this.selectedFilters = selectedFilters;
     });
@@ -35,7 +32,7 @@ export class SearchResultsService {
         params = params.append(key.name, JSON.stringify(key.value));
       }
     }
-    return this.http.get(this.serverAddress + endPoint, {observe: 'response', params: params});
+    return this.http.get(environment.apiUrl + endPoint, {observe: 'response', params: params});
   }
 
   getObservationDetails(id: string): Observable<any> {
@@ -43,7 +40,7 @@ export class SearchResultsService {
     params = params.append('solr_id', id);
     console.warn('Obs Details Query');
     console.log(params);
-    return this.http.get(this.serverAddress + 'restapi_get_full_exec_block_details', {observe: "response", params: params});
+    return this.http.get(environment.apiUrl + 'restapi_get_full_exec_block_details', {observe: "response", params: params});
   }
 
   getProjectDetails(id: string): Observable<any> {
@@ -51,7 +48,7 @@ export class SearchResultsService {
     params = params.append('project_code', '"' + id + '"');
     console.warn('Project Details Query');
     console.log(params);
-    return this.http.get(this.serverAddress + 'restapi_get_paged_exec_blocks', {observe: "response", params: params});
+    return this.http.get(environment.apiUrl + 'restapi_get_paged_exec_blocks', {observe: "response", params: params});
   }
 
 }
diff --git a/apps/web/src/app/env/app-config.service.ts b/apps/web/src/app/env/app-config.service.ts
index e60d179ebdc69a1136d46ef6cded0a290a88a995..17ce837c966c7c3bb1fd3c867972d1de5ca6e724 100644
--- a/apps/web/src/app/env/app-config.service.ts
+++ b/apps/web/src/app/env/app-config.service.ts
@@ -1,6 +1,6 @@
-import { Injectable } from '@angular/core';
-import { EnvService } from "./env.service";
-import { HttpClient } from '@angular/common/http';
+import {Injectable} from '@angular/core';
+import {environment} from "../../environments/environment";
+import {HttpClient} from '@angular/common/http';
 
 @Injectable({
   providedIn: 'root'
@@ -10,14 +10,14 @@ export class AppConfigService {
   configUrl = 'restapi_get_application_parameters';
   facetUrl = 'restapi_get_execution_block_facets';
 
-  constructor(private http: HttpClient, private env: EnvService) { }
+  constructor(private http: HttpClient) { }
 
   getConfig() {
-    return this.http.get(this.env.apiUrl + this.configUrl, {responseType: "json"});
+    return this.http.get(environment.apiUrl + this.configUrl, {responseType: "json"});
   }
 
   // we want to load facets only once per session - so it feels like they are config variables.
   getFacets(){
-    return this.http.get(this.env.apiUrl + this.facetUrl, {responseType: "json"});
+    return this.http.get(environment.apiUrl + this.facetUrl, {responseType: "json"});
   }
 }
diff --git a/apps/web/src/app/env/env.service.provider.ts b/apps/web/src/app/env/env.service.provider.ts
deleted file mode 100644
index d85dd28bdcf580cc7e0e3efe007185b477895474..0000000000000000000000000000000000000000
--- a/apps/web/src/app/env/env.service.provider.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { EnvService } from './env.service';
-
-export const EnvServiceFactory = () => {
-  // Create env
-  const env = new EnvService();
-
-  // Read environment variables from browser window
-  const browserWindow = window || {};
-  const browserWindowEnv = browserWindow['__env'] || {};
-
-  // Assign environment variables from browser window to env
-  for (const key in browserWindowEnv) {
-    if (browserWindowEnv.hasOwnProperty(key)) {
-      env[key] = window['__env'][key];
-    }
-  }
-
-  return env;
-};
-
-export const EnvServiceProvider = {
-  provide: EnvService,
-  useFactory: EnvServiceFactory,
-  deps: [],
-};
diff --git a/apps/web/src/app/env/env.service.spec.ts b/apps/web/src/app/env/env.service.spec.ts
deleted file mode 100644
index d490d74c0c396d4272027bcfce652c39fae9d31e..0000000000000000000000000000000000000000
--- a/apps/web/src/app/env/env.service.spec.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { TestBed } from '@angular/core/testing';
-
-import { EnvService } from './env.service';
-
-describe('EnvService', () => {
-  beforeEach(() => TestBed.configureTestingModule({}));
-
-  it('should be created', () => {
-    const service: EnvService = TestBed.get(EnvService);
-    expect(service).toBeTruthy();
-  });
-});
diff --git a/apps/web/src/app/env/env.service.ts b/apps/web/src/app/env/env.service.ts
deleted file mode 100644
index 142adb76cc23b5a31c508bd85176f42da71875b0..0000000000000000000000000000000000000000
--- a/apps/web/src/app/env/env.service.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Injectable } from '@angular/core';
-
-@Injectable({
-  providedIn: 'root'
-})
-export class EnvService {
-
-  public apiUrl: string;
-  public workspacesUrl: string;
-
-  constructor() {
-  }
-
-
-}
diff --git a/apps/web/src/app/workspaces/services/capability-launcher.service.ts b/apps/web/src/app/workspaces/services/capability-launcher.service.ts
index 5170247d9e4bc758c617a54c4dd81a7fca6c6be6..56a3e85b7d470911ed61bf2a53ddd65c71f947a1 100644
--- a/apps/web/src/app/workspaces/services/capability-launcher.service.ts
+++ b/apps/web/src/app/workspaces/services/capability-launcher.service.ts
@@ -1,9 +1,9 @@
-import { Injectable } from "@angular/core";
-import { HttpClient, HttpParams, HttpResponse } from "@angular/common/http";
-import { EnvService } from "../../env/env.service";
-import { Observable } from "rxjs";
-import { CapabilityRequest } from "../model/capability-request";
-import { CapabilityExecution } from "../model/capability-execution";
+import {Injectable} from "@angular/core";
+import {HttpClient} from "@angular/common/http";
+import {environment} from "../../../environments/environment";
+import {Observable} from "rxjs";
+import {CapabilityRequest} from "../model/capability-request";
+import {CapabilityExecution} from "../model/capability-execution";
 
 @Injectable({
   providedIn: "root",
@@ -11,7 +11,7 @@ import { CapabilityExecution } from "../model/capability-execution";
 export class CapabilityLauncherService {
   private endpoint = "capability/request";
 
-  constructor(private httpClient: HttpClient, private env: EnvService) {}
+  constructor(private httpClient: HttpClient) {}
 
   /**
    * Create capability request and send it to capability service
@@ -22,7 +22,7 @@ export class CapabilityLauncherService {
     capabilityName: string,
     args: string
   ): Observable<CapabilityRequest> {
-    const url = this.env.workspacesUrl + this.endpoint;
+    const url = environment.workspacesUrl + this.endpoint;
     const params = JSON.stringify({ capability: capabilityName, args: args });
     return this.httpClient.post<CapabilityRequest>(url, params);
   }
@@ -32,7 +32,7 @@ export class CapabilityLauncherService {
    * @param: requestId  ID of capability request to submit
    */
   submit(requestId: string): Observable<CapabilityExecution> {
-    const url = `${this.env.workspacesUrl}${this.endpoint}/${requestId}/submit`;
+    const url = `${environment.workspacesUrl}${this.endpoint}/${requestId}/submit`;
     return this.httpClient.post<CapabilityExecution>(url, null);
   }
 }
diff --git a/apps/web/src/app/workspaces/workspaces.component.html b/apps/web/src/app/workspaces/workspaces.component.html
index 2413156fd12382903ae790f640e530083db77267..800ce5e429e69d10a5032b965a40424310cd6607 100644
--- a/apps/web/src/app/workspaces/workspaces.component.html
+++ b/apps/web/src/app/workspaces/workspaces.component.html
@@ -1,11 +1,11 @@
 <div class="container-fluid">
-  <div class="row">
+  <div class="row py-2">
     <div class="col">
       <button type="button" class="btn btn-primary" (click)="nullButtonOnClick()">Launch null capability [null -g]</button>
     </div>
   </div>
 </div>
-<div *ngFor="let request of capabilityRequests; index as i">
+<div class="p-2" *ngFor="let request of capabilityRequests; index as i">
   <code>Capability request created: {{request | json}}</code><br>
   <code *ngIf="capabilityExecutions[i]">Capability execution created: {{capabilityExecutions[i] | json}}</code>
 </div>
diff --git a/apps/web/src/app/workspaces/workspaces.component.ts b/apps/web/src/app/workspaces/workspaces.component.ts
index 6546896e4edd36baa32f0cb0c6d9328e84c50fa3..1d58b5a51373b4357be2760a9c3d5c63af9b766f 100644
--- a/apps/web/src/app/workspaces/workspaces.component.ts
+++ b/apps/web/src/app/workspaces/workspaces.component.ts
@@ -1,9 +1,7 @@
-import { Component, OnInit } from "@angular/core";
-import { CapabilityLauncherService } from "./services/capability-launcher.service";
-import { Observable } from "rxjs";
-import { CapabilityRequest } from "./model/capability-request";
-import { map } from "rxjs/operators";
-import { CapabilityExecution } from "./model/capability-execution";
+import {Component, OnInit} from "@angular/core";
+import {CapabilityLauncherService} from "./services/capability-launcher.service";
+import {CapabilityRequest} from "./model/capability-request";
+import {CapabilityExecution} from "./model/capability-execution";
 
 @Component({
   selector: "app-workspaces",
diff --git a/apps/web/src/env.js b/apps/web/src/env.js
deleted file mode 100644
index fcdfd9eb84c7d61386685924dd6cfd3945c1a4ec..0000000000000000000000000000000000000000
--- a/apps/web/src/env.js
+++ /dev/null
@@ -1,10 +0,0 @@
-(function (window) {
-  window.__env = window.__env || {};
-
-  // API url
-  window.__env.apiUrl = 'https://webtest.aoc.nrao.edu/archiveServices/';
-
-  // Workspaces capability service URL
-  window.__env.workspacesUrl = 'http://localhost:3457/'
-
-}(this));
diff --git a/apps/web/src/environments/environment.prod.ts b/apps/web/src/environments/environment.prod.ts
index 3612073bc31cd4c1f5d6cbb00318521e9a61bd8a..e849194a1269f2f2cae2b23471b30b401d0f000c 100644
--- a/apps/web/src/environments/environment.prod.ts
+++ b/apps/web/src/environments/environment.prod.ts
@@ -1,3 +1,7 @@
 export const environment = {
-  production: true
+  production: true,
+  // archive search services
+  apiUrl: 'https://webtest.aoc.nrao.edu/archiveServices/',
+  // workspace services
+  workspacesUrl: 'http://localhost:3457/'
 };
diff --git a/apps/web/src/environments/environment.test.ts b/apps/web/src/environments/environment.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e849194a1269f2f2cae2b23471b30b401d0f000c
--- /dev/null
+++ b/apps/web/src/environments/environment.test.ts
@@ -0,0 +1,7 @@
+export const environment = {
+  production: true,
+  // archive search services
+  apiUrl: 'https://webtest.aoc.nrao.edu/archiveServices/',
+  // workspace services
+  workspacesUrl: 'http://localhost:3457/'
+};
diff --git a/apps/web/src/environments/environment.ts b/apps/web/src/environments/environment.ts
index 7b4f817adb754769ca126a939d48ac4b0850489d..5dc483908976f1bc1664ed9c322d11bc608a4c24 100644
--- a/apps/web/src/environments/environment.ts
+++ b/apps/web/src/environments/environment.ts
@@ -3,7 +3,11 @@
 // The list of file replacements can be found in `angular.json`.
 
 export const environment = {
-  production: false
+  production: false,
+  // archive search services
+  apiUrl: 'https://webtest.aoc.nrao.edu/archiveServices/',
+  // workspace services
+  workspacesUrl: 'http://localhost:3457/'
 };
 
 /*
diff --git a/apps/web/src/index.html b/apps/web/src/index.html
index 8981b538c70227e6507f367de986fc7f2f9aa72d..e80d1680435d7047c940e2dec86d874080cfd069 100644
--- a/apps/web/src/index.html
+++ b/apps/web/src/index.html
@@ -9,7 +9,6 @@
   <link rel="icon" type="image/x-icon" href="favicon.ico">
   <link href='https://fonts.googleapis.com/css?family=Lato:300,400,700' rel='stylesheet' type='text/css'>
   <script src="https://kit.fontawesome.com/bd536dc06d.js"></script>
-  <script src="env.js"></script>
 </head>
 <body>
   <app-root></app-root>