Context:
I got a new computer and wanted to see if I could could setup Redwood and have a solid development environment all self-contained in docker.
Using the default Node app template in VSCode and exposing the :8910 and :8911 gets me 90% there.
Current Blocker:
The web app is unable to talk with the api, the proxy that is handled by Webpack Dev Server behind the scenes doesn’t seem to work as expected within Docker, requests to that should be forwarded to the api aren’t but both web and api are accessible individually.
I’m using localhost:8910 on my host machine to access the web frontend. It’s accessible as is localhost:8911 but when I request a page that performs a fetch to the API, it fails.
This is being served by the yarn rw dev command within a container, for reference here is the config I’m using Redwood Dev Container · GitHub
The response from the dev server is [HPM] Error occurred while trying to proxy request /graphql from localhost:8910 to http://[::1]:8911 (EADDRNOTAVAIL) (https://nodejs.org/api/errors.html#errors_common_system_errors)
The address http://[::1]:8911 is also accessible on my host.
I run RedwoodJS with Docker images in production but not for the development workflow. When it comes to the proxying part, I submitted a issue along with a PR to extend the @redwoodjs/api-server package with a routePrefix option. See the issue for the motivation behind that. After that I set the apiProxyPath to "/api" in redwood.toml. Now I proxy / to web containers and /api to the api containers.
I think you’re already set with the Dockerfiles, but here is what I do for production.
api/Dockerfile
###################################################################################################################
# Runner: node
###################################################################################################################
FROM node:12 as runner
# Node
ARG NODE_ENV
ARG RUNTIME_ENV
ENV NODE_ENV=$NODE_ENV
ENV RUNTIME_ENV=$RUNTIME_ENV
ARG DATABASE_URL
ENV DATABASE_URL=$DATABASE_URL
# Set workdir
WORKDIR /app
COPY api api
COPY .nvmrc .
COPY babel.config.js .
COPY graphql.config.js .
COPY package.json .
COPY redwood.toml .
COPY yarn.lock .
# Debug
RUN date
# Install dependencies
RUN yarn install --frozen-lockfile
# Build
RUN yarn rw build api
# Migrate database
RUN yarn rw db up --no-db-client --auto-approve
# Seed database
RUN yarn rw db seed
# Clean up
RUN rm -rf ./api/src
# Set api as workdirectory
WORKDIR /app/api
# Expose RedwoodJS api port
EXPOSE 8911
# Entrypoint to @redwoodjs/api-server binary
ENTRYPOINT [ "yarn", "api-server", "--functions", "./dist/functions", "--port", "8911", "--routePrefix", "/api" ]
web/Dockerfile
###################################################################################################################
# Builder: node
###################################################################################################################
FROM node:12 as builder
# Node
ARG NODE_ENV
ARG RUNTIME_ENV
ENV NODE_ENV=$NODE_ENV
ENV RUNTIME_ENV=$RUNTIME_ENV
# Application specific (Azure Active Directory authentication)
ARG AZURE_ACTIVE_DIRECTORY_CLIENT_ID
ARG AZURE_ACTIVE_DIRECTORY_AUTHORITY
ARG AZURE_ACTIVE_DIRECTORY_REDIRECT_URI
ARG AZURE_ACTIVE_DIRECTORY_LOGOUT_REDIRECT_URI
ENV AZURE_ACTIVE_DIRECTORY_CLIENT_ID=$AZURE_ACTIVE_DIRECTORY_CLIENT_ID
ENV AZURE_ACTIVE_DIRECTORY_AUTHORITY=$AZURE_ACTIVE_DIRECTORY_AUTHORITY
ENV AZURE_ACTIVE_DIRECTORY_REDIRECT_URI=$AZURE_ACTIVE_DIRECTORY_REDIRECT_URI
ENV AZURE_ACTIVE_DIRECTORY_LOGOUT_REDIRECT_URI=$AZURE_ACTIVE_DIRECTORY_LOGOUT_REDIRECT_URIv
# Set workdir
WORKDIR /app
#COPY api .
COPY web web
COPY .nvmrc .
COPY babel.config.js .
COPY graphql.config.js .
COPY package.json .
COPY redwood.toml .
COPY yarn.lock .
# Install dependencies
RUN yarn install --frozen-lockfile
# Build
RUN yarn rw build web
# Clean up
RUN rm -rf ./web/src
###################################################################################################################
# Runner: Nginx
###################################################################################################################
FROM nginx as runner
# Copy dist
COPY --from=builder /app/web/dist /usr/share/nginx/html
# Copy nginx configuration
COPY web/config/nginx/default.conf /etc/nginx/conf.d/default.conf
# List files
RUN ls -lA /usr/share/nginx/html
# Expose RedwoodJS web port
EXPOSE 8910
Thanks for your help @Tobbe and @jeliasson, It looks like Nginx is the only way to get this working as expected. I think I’ll sideline this for now. I may revisit this when I have a better grasp of how Nginx and dev containers work with multiple services.
I’m a little late to the party @Darth-Knoppix but I think you need to get a bit fancier with how you setup Webpack to handle ports and hosts. Something like the topics in this Issue might do the trick:
I had the same issue with the http://[::1]:8911 (EADDRNOTAVAIL) error with a clean redwood install in a devcontainer. I was able to solve it adding the following config. I think docker needs some extra config to forward ipv6.
Can confirm that configuring the web and api host to listen on 0.0.0.0 doesn’t solve the issue. Thanks for the idea though. The proxy still can’t resolve the ipv6 url inside the container. It can be enabled (Enable IPv6 support | Docker Documentation) but I’m more comfortable with the solution I understand better for now.
The RWJS_DEV_API_URL var is a configuration for the proxy, the url that the “web” service will use to make calls to the “api” service. Both of these services are inside the devcontainer so the address is local. You can still set the host to 0.0.0.0 for external access if you want to. Either way this url should still be localhost.