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,
};
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
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;"]
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;'
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;'
and you can start the container with Docker run command
docker run -p 4000:80 -e CONFIGURATION=test <IMAGE_ID>
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;'
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"]
and start the container with Docker run command
docker run -p 4000:80 -e CONFIGURATION=test <IMAGE_ID>
If you are not using Docker you can also same approach, since sed
is simple UNIX command
Top comments (0)