DEV Community

Pavan K Jadda for This is Angular

Posted on

Dynamically Update Angular BASE URL Using Docker Env Variables

In Angular the BASE/API URLs are be stored environment files which are present under src/environments directory. Usually we can create new file for each environment.

  • environment.ts
  • environment.dev.ts
  • environment.test.ts
  • environment.stage.ts
  • environment.prod.ts

environment.ts

import packageInfo from '../../package.json';

export const environment = {
    production: false,
    BASE_URL: '//localhost:4200',
    VERSION: packageInfo.version,
};
Enter fullscreen mode Exit fullscreen mode

During the build, a configuration flag is provided to swap the default environment.ts file with environment.<CONFIGURATION>.ts based on the flag

npm run build -- --configuration=stage
Enter fullscreen mode Exit fullscreen mode

The problem with this approach is you can't reuse same build for multiple environments and promote DEV to TEST then to STAGE eventually to PROD since BASE_URL is hard coded during build. To prevent this we need to replace the BASE_URL in main.*.js file generated by Angular during the Docker container start up.

First lets look at standard Dockerfile that follows multi stage Dockerfile. To better understand this, refer my other post.

Dockerfile

// See my other post for Build stage, so skipping it here

############  User Nginx alpine image  ############
FROM nginx:stable-alpine

# Remove default nginx website
RUN rm -rf /usr/share/nginx/html/*

# Copy nginx config file
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf

# Copy dist folder fro build stage to nginx public folder
COPY --from=builder /app/dist /usr/share/nginx/html

# Start NgInx services
CMD ["nginx", "-g", "daemon off;"]

Enter fullscreen mode Exit fullscreen mode

In this we can add single that will update the BASE_URL during Docker container/service. Let's say out BASE_URL/API_URL is employee-dev.example.com, then it can be replaced with UNIX sed command as shown below

CMD sed -i "s/employee-dev.example.com/employee-$CONFIGURATION.example.com/g" /usr/share/nginx/html/main.*.js && nginx -g 'daemon off;'
Enter fullscreen mode Exit fullscreen mode

So the updated Dockerfile looks as below
Dockerfile (Updated)

// See my other post for Build stage, so skipping it here

############  User Nginx alpine image  ############
FROM nginx:stable-alpine

# Remove default nginx website
RUN rm -rf /usr/share/nginx/html/*

# Copy nginx config file
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf

# Copy dist folder fro build stage to nginx public folder
COPY --from=builder /app/dist /usr/share/nginx/html

# Start NgInx services
CMD sed -i "s/employee-dev.example.com/employee-$CONFIGURATION.example.com/g" /usr/share/nginx/html/main.*.js && nginx -g 'daemon off;'

Enter fullscreen mode Exit fullscreen mode

and you can start the container with Docker run command

docker run -p 4000:80 -e CONFIGURATION=test <IMAGE_ID>
Enter fullscreen mode Exit fullscreen mode

You can also use Docker ENTRYPOINT to achieve the same result. To do this using ENTRYPOINT, create new start.sh script file and copy the command.

start.sh

#!/bin/sh
sed -i "s/employee-dev.example.com/employee-$CONFIGURATION.example.com/g" /usr/share/nginx/html/main.*.js
nginx -g 'daemon off;'
Enter fullscreen mode Exit fullscreen mode

and make sure to copy this file, make it executable and refer in ENTRYPOINT

Dockerfile (Updated with ENTRYPOINT)

######  User Nginx alpine image  ######
FROM nginx:stable-alpine
ENV CONFIGURATION='dev'
# Remove default nginx website
RUN rm -rf /usr/share/nginx/html/*

# Copy nginx config file
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf

# Copy dist folder fro build stage to nginx public folder
COPY /dist /usr/share/nginx/html
COPY start.sh /usr/share/nginx/html
RUN chmod +x /usr/share/nginx/html/start.sh

# Start NgInx service
ENTRYPOINT ["./usr/share/nginx/html/start.sh", "$CONFIGURATION"]

Enter fullscreen mode Exit fullscreen mode

and start the container with Docker run command

docker run -p 4000:80 -e CONFIGURATION=test <IMAGE_ID>
Enter fullscreen mode Exit fullscreen mode

If you are not using Docker you can also same approach, since sed is simple UNIX command

Top comments (0)