Build with Environment variables with caddy and docker that can access with reactJs app

1. The problem I’m having:

Hi Caddy,

First of all I do not sure this issue is related to caddy. Please ignore or delete this post if it is not related to caddy.

I am trying to access multiple env variables using process.env.VAL_NAME1 process.env.VAL_NAME2 on my frontend react app. But I am always getting undefined as a value of those env variables

I tried many ways to set ENV variables but nothing works. So I thought this need to be set on the build time on the caddy server. Even for that I tried many ways but still I couldn’t able to access my ENV variables. Could you please help me to get this resolved.

2. Error messages and/or full log output:

No any error messages

3. Caddy version:

2.7.4

4. How I installed and ran Caddy:

I am using docker and docker-compose to build and run the caddy server and react app. Docker file build inside the github action.

a. System environment:

Linux
Docker
docker-compose

b. Command:

ENV=prod  docker-compose -f <DOCKER_COMPOSE_FILE_PATH>/docker-compose-prod.yml up -d

c. Service/unit/compose file:

Dockerfile

### first Stage

FROM node:16 AS builder

WORKDIR /usr/src/app

COPY ./package.json ./
COPY ./yarn.lock ./

RUN npm install

COPY . .

ARG BASE_URL=https://www.mydomail.com
ARG CURRENCY_EXCHANGE_API_KEY=1234567
ENV REACT_APP_BASE_URL=${BASE_URL} NODE_ENV=${NODE_ENV} CURRENCY_EXCHANGE_API_KEY=${CURRENCY_EXCHANGE_API_KEY}

RUN yarn build

### second stage

FROM caddy:2.7.4

ARG CADDYFILE
COPY ${CADDYFILE} /etc/caddy/Caddyfile

COPY --from=builder /usr/src/app/build/ /srv

EXPOSE 80

EXPOSE 443

Docker Compose file

version: "3"
services:
  image-name-frontend-admin:
    container_name: image-name-frontend-admin
    image: dockerhub/image-name-frontend-admin:${ENV}
    restart: unless-stopped
    ports:
      - "7080:80"
      - "7443:443"
    networks:
      - caddy-network
    volumes:
      - caddy-data:/data
      - caddy-config:/config
      - /root/treble/uploads/chemmyfashionvpadminuploads/:/srv/chemmyfashionvpadminuploads
      - /var/caddy-logs:/var/log/caddy
  image-name-frontend:
    container_name: image-name-frontend
    image: dockerhub/image-name-frontend:${ENV}
    restart: unless-stopped
    env_file: ./${ENV}.env
    environment:
      - BASE_URL=https://www.mydomail.com
      - CURRENCY_EXCHANGE_API_KEY=1234567
    ports:
      - "7090:80"
      - "7543:443"
    networks:
      - caddy-network
    volumes:
      - caddy-data:/data
      - caddy-config:/config
      - /root/treble/uploads/chemmyfashionvpuploads/:/srv/chemmyfashionvpuploads
      - /var/caddy-logs:/var/log/caddy
  image-name-backend-admin:
    container_name: image-name-backend-admin
    image: dockerhub/image-name-backend-admin
    restart: unless-stopped
    env_file: ./${ENV}.env
    ports:
      - "5200:5000"
    networks:
      - caddy-network
    volumes:
      - /var/log/services/image-name-backend-admin/:/var/log/services/image-name-backend-admin/
      - /root/treble/uploads/chemmyfashionvpadminuploads/:/usr/src/app/chemmyfashionvpadminuploads
  image-name-backend:
    container_name: image-name-backend
    image: dockerhub/image-name-backend
    restart: unless-stopped
    env_file: ./${ENV}.env
    ports:
      - "5300:5000"
    networks:
      - caddy-network
    volumes:
      - /var/log/services/image-name-backend/:/var/log/services/image-name-backend/
      - /root/treble/uploads/chemmyfashionvpuploads/:/usr/src/app/chemmyfashionvpuploads
networks:
  caddy-network:
    external: true
volumes:
  mongo-data:
    driver: local
  caddy-data:
    driver: local
  caddy-config:
    driver: local
  caddy-logs:
    driver: local

Github action to build the docker file

    - 
        name: Build and push
        uses: docker/build-push-action@v4
        with:
          context: .
          file: Dockerfile.prod
          build-args: |
            CADDYFILE=${{ secrets.CADDYFILE_PROD }}
            BASE_URL=${{ secrets.FRONTEND_BASE_URL_PROD }}
            CURRENCY_EXCHANGE_API_KEY=${{ secrets.CURRENCY_EXCHANGE_API_KEY }}
          push: true
          tags: ${{ secrets.DOCKERHUB_USERNAME }}/image-name:prod
    - 

d. My complete Caddy config:

(cors) {

    @cors_preflight{args.0} method OPTIONS
    @cors{args.0} header Origin {args.0}

    handle @cors_preflight{args.0} {
        header {
            Access-Control-Allow-Origin "{args.0}"
            Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS"
            Access-Control-Allow-Headers *
            Access-Control-Max-Age "3600"
            defer
        }
        respond "" 204
    }

    handle @cors{args.0} {
        header {
            Access-Control-Allow-Origin "{args.0}"
            Access-Control-Expose-Headers *
            defer
        }
    }
}

:80 {

    log {
        output file /var/log/caddy/frontend.log
        format json
    }

    tls treblesolution@gmail.com

    root * /srv

    route {
        reverse_proxy /api* iamge-name-backend:5300
        try_files {path} {path}/ /index.html
        file_server
    }
}

5. Links to relevant resources:

Please use the latest version, v2.7.6

This is redundant, the Caddy image already does this.

Either way, EXPOSE doesn’t actually do anything, it’s essentially just a documentation/marker.

This doesn’t make sense. You shouldn’t configure tls for an :80 site.

I would rewrite it like this:

	handle /api* {
		reverse_proxy iamge-name-backend:5300
	}

	handle {
		root * /srv
		try_files {path} {path}/ /index.html
		file_server
	}

You’re not actually using this in your config. Snippets don’t do anything unless you import them somewhere.

Anyway, are you sure you need it?

That doesn’t have to do with Caddy, no.

Are you using Vite or something to build? If so you need to use import.meta.env.VAR I think. See the documentation for your build tool.

If you’re writing a NodeJS server app (not frontend JS), then process.env.VAR is what you’d use.

Correct, env vars are replaced at build time in your transpiled JS code. Unrelated to Caddy.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.