Golang Server 404 on Static Pages - go

I am working on a compiled Golang server that displays a home page, and upload page, and a file repository. It can also upload a file to its backend. The goal is to put this into a container and use it.
Code: https://github.com/thatMacAdmin/go-webserver
If I do the following on my local machine:
go run webserver.go
Then it works as expected. The page in /static/index.html loads. I can upload files etc (as long as the repo exists in the right location). However when I build this and put it in a docker container, the repo file list works, and the upload endpoint exists, however the two static html pages get 404 errors.
What am I doing wrong? Why doesn't http://localhost:8080 work to display my home page in the container but it does work with the go run method?
Thanks,
Ed

The issue here was that Docker uses / as its relative path unless you tell it otherwise. In this instance my code expected the relative path to be where my server binary was located. In my case:
/server
Setting the WORKDIR option correctly in my Dockerfile fixed this.
Example:
FROM alpine:latest
RUN mkdir -p /server/static
COPY webserver /server
COPY static /server/static
WORKDIR /server
ENTRYPOINT ["/server/webserver"]
EXPOSE 8080

The static files are not automatically included in your binary. So you need to make sure that the running application working directory (even if it is running within a docker container) contains the folder "static" and its files. Otherwise the file is not found and you get an 404.
One alternative to this is to compile the static files into your binary. You can use gofiles for this.

Related

CLI Go Config.toml file location

I am attempting to test a Golang application hauser locally on via -bash CLI before deploying on a VM.
Per the documentation, I compiled locally and copied the example-config.toml file. I then mapped to the GOPATH and opened hauser.exe to open config.toml file. However, when I execute, it returns open config.toml: no such file or directory
C02Z30ANLVDV:~ pmcgin2$ $GOPATH/bin/hauser -c Documents/go/bin/config.toml
2020/08/14 18:05:23 Cannot find folder , make sure it exists
C02Z30ANLVDV:~ pmcgin2$ open Documents/go/bin/config.toml
No application knows how to open /Users/pmcgin2/Documents/go/bin/config.toml.
Is there an alternative command I can execute to override the default config.toml location for an application like this?
There are two possibilities to solve your issue:
give an absolute path as argument:
$GOPATH/bin/hauser -c /Users/pmcgin2/Documents/go/bin/config.toml
give a relative path from the binary location:
$GOPATH/bin/hauser -c config.toml
Generally, it is easier to use absolute paths.

Site can't be reached when running IIS in Docker

I followed the instructions on the official Dockerhub repo for IIS (https://hub.docker.com/_/microsoft-windows-servercore-iis), but running into "Site can't be reached" when trying to access via the IP of the container.
I get 403 forbidden when I try htp://localhost:8000.
I copied a test.html page into C:/inetpub/wwwroot and verified by logging into the container as well.
The results of appcmd list site is as follows:
SITE "Default Web Site" (id:1,bindings:http/*:80:,state:Started)
403 typically indicates that the web address we are trying to access is not the root directory of the website.
I doubt if there exist any files, which have been copied to the remote docker container.
Please make sure that the directory where the dockerfile is located contains the content folder and contains all site files.
WORKDIR /inetpub/wwwroot
COPY content/ .
Feel free to let me know if the problem persists.
You are right in your analysis. What i didn't realize is IIS perhaps serves index.html as default and my file was called helloworld.html which obviously wasn't going to be to served when i access localhost:8000; it works when i try localhost:8000/helloworld.html.

Is there a way to automate the creation of Docker Image?

I needed to create a Docker image of a Springboot application and I achieved that by creating a Dockerfile and building it into an image. Then, I used "docker run" to bring up a container. This container is used for all the activities for which my application was written.
My problem, however, is that the JAR file that I have used needs constant changes and that requires me to rebuild the Docker image everytime. Furthermore, I need to take the contents of the earlier running Docker container and transfer it into a container created from the newly built image.
I know this whole process can be written as a Shell script and exected every time I have changes on my JAR file. But, is there any tool I can use to somehow automate it in a simple manner?
Here is my Dockerfile:
FROM java:8
WORKDIR /app
ADD ./SuperApi ./SuperApi
ADD ./config ./config
ADD ./Resources ./Resources
EXPOSE 8000
CMD java -jar SuperApi/SomeName.jar --spring.config.location=SuperApi/application.properties
If you have a JAR file that you need to copy into an otherwise static Docker image, you can use a bind mount to save needing to rebuild repeatedly. This allows for directories to be shared from the host into the container.
Say your project directory (the build location where the JAR file is located) on the host machine is /home/vishwas/projects/my_project, and you need to have the contents placed at /opt/my_project inside the container. When starting the container from the command line, use the -v flag:
docker run -v /home/vishwas/projects/my_project:/opt/my_project [...]
Changes made to files under /home/vishwas/projects/my_project locally will be visible immediately inside the container1, so no need to rebuild (and probably no need to restart) the container.
If using docker-compose, this can be expressed using a volumes stanza under the services listing for that container:
volumes:
- type: bind
source: /home/vishwas/projects/my_project
target: /opt/my_project
This works for development, but later on, it's likely you'll want to bundle the JAR file into the image instead of sharing from the host system (so it can be placed into production). When that time comes, just re-build the image and add a COPY directive to the Dockerfile:
COPY /home/vishwas/projects/my_project /opt/my_project
1: Worth noting that it will default to read/write, so the container will also be able to modify your project files. To mount as read-only, use: docker run -v /home/vishwas/projects/my_project:/opt/my_project:ro
You are looking for docker compose
You can build and start containers with a single command using compose.

docker build hangs in directory with many files

Windows 10. I have in folder just:
app (directory with many files)
Dockerfile (simpliest docker file)
I run "docker build ." and it just hangs.
If I remove "app" directory. Build runs ok.
In docker file just one line:
FROM node
Didn't find any issues like that. It fills like it tries to scan the directory or something.
Any advice?
UPD: It seems that I should use .dockerignore https://docs.docker.com/engine/reference/builder/#/dockerignore-file
When you run docker build ... the Docker client sends the context (recursive contents of the directory) via REST to the Docker daemon for building. If that context is large, this could take some time (depending on a variety of factors, if your daemon is local / remote, platform maybe, etc...).
How long are you giving it to hang before giving up? Could be that it's still just working? Or could be that the context was so large maybe the client / daemon experienced an issue. Checking the (client / daemon) logs would help debug that.
And yes, a .dockerignore file (basically a .gitignore but for Docker context) is probably what you're looking for, unless you need the contents of the app directory during your build.
Your Dockerfile should be put in the directory that only includes it's build context. For example, if you are building a spring-boot app, you can put the Dockerfile right under /app, as shown in this official docker sample.
Docker's documentation:
In most cases, it’s best to start with an empty directory as context and keep your Dockerfile in that directory. Add only the files needed for building the Dockerfile.
Warning: Do not use your root directory, /, as the PATH as it causes the build to transfer the entire contents of your hard drive to the Docker daemon.
I've seen that simple docker examples put dockerfile in the root directory, but for complicated examples like the one I posted above, the dockerfile is put only in it's relevant directory. You can dig through the dockersamples repository and find your case.

Running goconvey http server from within a docker container

I'm using docker containers for some of my golang web service projects and part of the development workflow is using goconvey for some fast tdd feedback. I'd like to spin this up within a docker container and expose the port to the host machine so I can point my web browser to it and get coding.
We have compiled the goconvey binary and have popped it in /usr/local/bin
The problem is that whenever I connect to the port exposed form the docker container I only get "404 Page not found" errors.
There are a few tweaks we have with out GOPATH specifically I'm vendoring my libs eg GOPATH=/proj-dir/vendor and code dev is happening in /src
I can get goconvey working nicely on my host but in the docker i'm stumped.
The 404 suggest that I'm hitting the goconvey server but it does not serve up anything?
Any assistance appreciated.
The goconvey server returns 404 when it cannot find the directory that contains the static resources.
The location of this directory depends on where go get stored the goconvey files, usually in
$GOPATH/src/github.com/smartystreets/goconvey
So in your docker container, ensure that goconvey is installed using the current $GOPATH value, and also verify that the /goconvey dir contains /web/client/... subdirectories, which is where the html, css, and js files for the Web UI reside.
(To test this, I renamed the client dir, which caused goconvey to return a plain 404 message.)

Resources