Access Swagger UI trough AWS ALB without trailing slash - swagger-ui

I have a swagger-ui docker container running in its own service in AWS, which is meant to be accessed trough /swagger. To achieve this, I have set up the docker container to serve swagger on /swagger and set the ALB to forward /swagger* to the swagger service.
This works perfectly when going to /swagger/, but /swagger falls trough to our final "not found" rule.
I've tried adding a additional forwards for /swagger/* and just /swagger as well as setting up a redirect from /swagger to /swagger/ in various combinations and orders, but none of it is working.
Just /swagger without trailing slash works perfectly when accessing the swagger service directly, both on AWS and locally, so I don't think that's the issue, but just in case, I got it to serve the content on /swagger by overwriting 40-swagger-ui.sh in docker/docker-entrypoint.d with the following:
FROM swaggerapi/swagger-ui:v4.15.5 as build
COPY ./doc/openapi.yaml /usr/share/nginx/html/openapi.yaml
RUN mkdir /tmp2
RUN cp /usr/share/nginx/html/* /tmp2
RUN rm /usr/share/nginx/html/*
RUN mkdir /usr/share/nginx/html/swagger
RUN cp /tmp2/* /usr/share/nginx/html/swagger
RUN echo "moved to /swagger" >> /usr/share/nginx/html/index.html
COPY --chmod=0555 ./docker/docker-entrypoint.d/ /docker-entrypoint.d/
ENV API_URL "openapi.yaml"
ENV PORT 80
RUN chmod 777 /usr/share/nginx/html/ /usr/share/nginx/html/swagger/ /etc/nginx/ /var/cache/nginx/ /var/run/
EXPOSE 80

Related

Docker Port mapping resulting in ERR_EMPTY_RESPONSE [duplicate]

I've been trying to figure this out in the last hours but I'm stuck.
I have a very simple Dockerfile which looks like this:
FROM alpine:3.6
COPY gempbotgo /
COPY configs /configs
CMD ["/gempbotgo"]
EXPOSE 8025
gempbotgo is just an go binary which runs a webserver and some other stuff.
The webserver is running on 8025 and should answer with an hello world.
My issue is with exposing ports. I ran my container like this (after building it)
docker run --rm -it -p 8025:8025 asd
Everything seems fine but when I try to open 127.0.0.1:8025 in the browser or try a wget i just get an empty response.
Chrome: ERR_EMPTY_RESPONSE
The port is used and not restricted by the firewall on my Windows 10 system.
Running the go binary without container just on my "Bash on Ubuntu on Windows" terminal and then browsing to 127.0.0.1:8025 works without a hitch.
Other addresses returned a "ERR_CONNECTION_REFUSED" like 127.0.0.1:8030 so there definetly is something active on the port.
I then went into the conatiner with
docker exec -it e1cc6daae4cf /bin/sh
and checked in there with a wget what happens. Also there no issues. index.html file gets downloaded with a "Hello World"
Any ideas why docker is not sending any data? I've also ran my container with docker-compose but no difference there.
I also ran the container on my VPS hosted externally. Same issue there... (Debian)
My code: (note the Makefile)
https://github.com/gempir/gempbotgo/tree/docker
Edit:
After getting some comments I changed my Dockerfile to a multi-stage build. This is my Dockerfile now:
FROM golang:latest
WORKDIR /go/src/github.com/gempir/gempbotgo
RUN go get github.com/gempir/go-twitch-irc \
&& go get github.com/stretchr/testify/assert \
&& go get github.com/labstack/echo \
&& go get github.com/op/go-logging
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY configs ./configs
COPY --from=0 /go/src/github.com/gempir/gempbotgo/app .
CMD ["./app"]
EXPOSE 8025
Sadly this did not change anything, I kept everything as close as possbile to the guide here: https://docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds
I have also tried the minimalist Dockerfile from golang.org which looks like this:
FROM golang:onbuild
EXPOSE 8025
But no success either with that.
Your issue is that you are binding to the 127.0.0.1:8025 inside your code. This makes the code work from inside the container but not outside.
You need to bind to 0.0.0.0:8025 to bind to all interfaces inside the container. So traffic coming from outside of the container is also accepted by your Go app
Adding to the accepted answer: I had the same error message trying to run docker/getting-started.
The problem was that "getting-started" is using port 80 and this was
"occupied" (netsh http show urlacl) on my machine.
I had to use docker run -d -p 8888:80 docker/getting-started where
8888 was an unused port. And then open "http://localhost:8888/tutorial/".
I have the same problem using Dockerize GatsbyJS. As Tarun Lalwani's comment above, I resolved the problem by binding or using 0.0.0.0 as hostname
yarn develop -P 0.0.0.0 -p 8000
For me this was a problem with the docker swarm mode ingress network. I had to recreate it. https://docs.docker.com/network/overlay/#customize-the-default-ingress-network
Another possibility why you are getting that error is that the docker run command is run through a normal cmd prompt and not the admin command prompt. Make sure you run as an admin!

How to add Nginx reverse proxy to existing image

How would I add an nginx reverse proxy to an existing image?
For example I use https://github.com/Koenkk/zigbee2mqtt and this exposes a front end that only works over http.
I want to use the image but have the front end accessible only over https. Adding a Nginx reverse proxy is quite simple but what is the best method?
Do I fork the repository and add Nginx and config into the build or do I create a new image based on the existing one?
Presumably if I create a new image based on the existing one the entrypoint is essentially lost so any setup done in that script would need to be replicated in my image?
Edit: I need to run this container on a macvlan network but I do not want the insecure http access available to other devices on that network.
In this particular image there was an entrypoint and the best way I have found of doing this to override the entrypoint when running it.
The original entrypoint was /usr/local/bin/docker-entrypoint.sh and there was a CMD of npm start
After some hacking around (As I still cannot quite get my head around the combination of entry point and CMD) I created the following script which installs nginx if it insn't already installed as well as running the original entrypoint and CMD
The script and the config is on a volume so this persists across different instances of the image.
#!/bin/sh
echo "Hello"
. /usr/local/bin/docker-entrypoint.sh
if [[ `apk -e info nginx | wc -l ` -eq 0 ]]
then
apk add nginx
cd /etc/nginx/conf.d
mv default.conf default.conf.disabled
ln -s /app/data/nginx.conf nginx.conf
mkdir /run/nginx
echo "Installed Nginx"
fi
echo "Starting Nginx"
nginx &
npm init -y
echo "Starting Node"
npm start
Not sure if this is advisable or the best way of doing this but it seems to work reasonably well.

Google Cloud Run fails to listen even after changing port to 8080

I am having some issues deploying to Cloud Run lately. When I am trying to deploy the below Dockerfile to Cloud Run, it ends up with the error Failed to start and then listen on the port defined by the PORT environment variable.:
FROM phpmyadmin/phpmyadmin:latest
EXPOSE 8080
RUN sed -i 's/80/${PORT}/g' /etc/apache2/sites-available/000-default.conf /etc/apache2/ports.conf
ENTRYPOINT [ "/docker-entrypoint.sh" ]
CMD [ "apache2-foreground" ]
The ENTRYPOINT and CMD were added separately even though the phpmyadmin/phpmyadmin:latest uses this same ENTRYPOINT and CMD to see if that would solve it, though it is not required. The same Docker image when deployed using docker run runs properly and listens on port 8080. Is there something I am doing wrong?
This is the command I use to deploy:
gcloud run deploy phpmyadmin --memory=1Gi --platform=managed \
--allow-unauthenticated --add-cloudsql-instances project_id:us-central1:db-name \
--region=us-central1 --image gcr.io/project_id/phpmyadmin:1.3 \
--update-env-vars PMA_HOST=localhost,PMA_SOCKET="/cloudsql/project_id:us-central1:db-name",PMA_ABSOLUTE_URI=phpmyadmin.domain.com
This is all I can find in the logs. (Have redacted some data):
https://gist.github.com/shanukk27/9dd4b3076c55307bd6e853a76e7a34e0
Cloud Run runtime environment seems to be slightly different than Docker run command. You can't use ENTRYPOINT and CMD in the same time
ENTRYPOINT [ "/docker-entrypoint.sh" ]
CMD [ "apache2-foreground" ]
It works with Docker Run (Why? Docker issue? Docker feature?) and not on Cloud Run (missing feature? bug?).
Use only one of them, for example:
ENTRYPOINT /docker-entrypoint.sh && apache2-foreground
EDIT
A strange remark shared by Shanu is the 2 command works with Wordpress deployment, and doesn't work here.
FROM wordpress:5.3.2-php7.3-apache
EXPOSE 8080
# Copy custom entrypoint from repo
COPY cloud-run-entrypoint.sh /usr/local/bin/
# Change apache listening port and set permission for docker entrypoint
RUN sed -i 's/80/${PORT}/g' /etc/apache2/sites-available/000-default.conf /etc/apache2/ports.conf && \
chmod +x /usr/local/bin/cloud-run-entrypoint.sh
# Wordpress conf
COPY wordpress/. /var/www/html/
# Custom entrypoint
ENTRYPOINT ["cloud-run-entrypoint.sh","docker-entrypoint.sh"]
# Start apache when docker container starts
CMD ["apache2-foreground"]
The problem is solved here, but the reason is not clear
Note to Googler (Steren? Ahmet?): Can you share more details on this behavior?

Expose Both Ports 8080 and 3000 For Cloud Run Deployment

TL:DR - I am trying to deploy my MERN stack application to GCP's Cloud Run. Struggling with what I believe is a port issue.
My React application is in a client folder inside of my Node.js application.
Here is my one Dockerfile to run both the front-end and back-end:
FROM node:13.12.0-alpine
WORKDIR /app
COPY . ./
# Installing components for be connector
RUN npm install --silent
WORKDIR /app/client
RUN npm install --silent
WORKDIR /app
RUN chmod +x /app/entrypoint.sh
ENTRYPOINT [ "/app/entrypoint.sh" ]
... and here is my entrypoint.sh file:
#!/bin/sh
node /app/index.js &
cd /app/client
npm start
docker-compose up works locally, and docker run -p 8080:8080 -p 3000:3000 <image_id> runs the image I built. Port 8080 is for Node and port 3000 for the React app. However, on Cloud Run, the app does not work. When I visit the app deployed to Cloud Run, the frontend initially loads for a split second, but then the app crashes as it attempts to make requests to the API.
In the Advanced Settings, there is a container port which defaults to 8080. I've tried changing this to 3000, but neither works. I cannot enter 8080,3000, as the field takes valid integers only for the port. Is it possible to deploy React + Node at the same time to Cloud Run like this? How can I have Cloud Run listen on both 8080 and 3000, as opposed to just 1 of the 2?
Thanks!
It's not currently possible.
Instead, you can run multiple processes inside Cloud Run, but instead use nginx to proxy requests between them depending on the URL, similar to what's recommended in this answer.

Running Vue.js App on a different port with docker

I created a simple VueJS app with a very basic configuration. I used the webpack configuration to do this.
vue init webpack app
I build this simple Dockerfile
FROM node:lts-alpine
# install simple http server for serving static content
RUN npm install -g http-server
# make the 'app' folder the current working directory
WORKDIR /app
# copy both 'package.json' and 'package-lock.json' (if available)
COPY package*.json ./
# install project dependencies
RUN npm install
# copy project files and folders to the current working directory (i.e. 'app' folder)
COPY . .
# build app for production with minification
RUN npm run build
EXPOSE 3838
CMD [ "http-server", "dist" ]
This app should run of a plattform which only listens to port 3838. Changing the Dockerfile to EXPOSE 3838 did not work unfortunately.
sudo docker run -it -p 3838:3838 vuetest
Starting up http-server, serving dist
Available on:
http://127.0.0.1:8080
The container runs, but stil on 8080.
I´m quite unfamiliar with both VueJS and deploying, so can anyone help me? I guess the configuration to listen to 8080 might be set in a different file and the Dockerfile ignores it.
Your application server runs by default on 8080
https://www.npmjs.com/package/http-server
Use flag -p 3838 to serve on that port.
Docker is doing its job correctly, adjust in your CMD
CMD [ "http-server", "-p 3838", "dist" ]
You can try just use the port 8080 of the continer and map it to port 3838 of your host.
#Dockerfile: delete the line -> Expose 3838
#Command line : $ sudo docker run -it -p 3838:8080 vuetest
This is an option not to add more lines to the Dockerfile.
Bye

Resources