Deploying Go App with Heroku - heroku

I'm using this guide to build a small Go app:
https://codegangsta.gitbooks.io/building-web-apps-with-go/index.html
Folder structure looks like this:
go/src/fileserver/
main.go
fileserver.exe
public/
index.html
css/
bootstrap.min.css
The deployment instructions mention a "procfile" and a ".godir" file but it's a bit unclear what these are supposed to contain or where they are to be implemented. I'm not quite sure if my folder structure is correct either.
The error I'm getting is:
Failed to detect set buildpack https://github.com/kr/heroku-buildpack-go.git

Am going to be quoting the heroku documentation a lot.
Procfile
Define a Procfile
Use a Procfile, a text file in the root directory of your application, to explicitly declare what command should be executed to start your app.
The Procfile in the example app you deployed looks like this:
web: go-getting-started
This declares a single process type, web, and the command needed to run it. The name web is important here. It declares that this process type will be attached to the HTTP routing stack of Heroku, and receive web traffic when deployed. The command used here, go-getting-started is the compiled binary of the getting started app.
Procfiles can contain additional process types. For example, you might declare one for a background worker process that processes items off of a queue.
Define a Procfile
So in your example you would have a file named 'Procfile' in your root directory with contents being:
web: fileserver
.godir
The .godir file is simply a file that simply specifies the root directory of your go project. This is useful when you say have a number of modules for a web app in different languages. So for example given a repo with the following tree.
github.com
└──someuser
└── somerepo
├── .godir
├── go_module
└── node_module
Where the contents of your .godir file would be:
github.com/someuser/somerepo/go_module
A more verbose explanation of what .godir is for and when it is used can be found here.

Related

Procfile declared none

I am trying to deploy to Heroku. I keep getting an application error.
I created a ProcFile file without any extension, but Heroku doesn't seem to recognize it.
You're correct that the file doesn't have an extension, but it needs to be called Procfile, exactly. Your file is called ProcFile with a capital F.
Rename it to Procfile, commit, and redeploy.
The problem was solved by changing the ProcFile file to Procfile and there was more than one requirements.txt file It has been erased and create one requirements.txt file for all downloaded

VSCode terminal settings

There is a directory structure something like given below-
Demo/
└── Project
└── sample.py
I opened Project/ directory in the VS Code but the path shown in the terminal is from its root directory i.e., shubhanshusingh#shubhanshusingh:~/Demo/Project$ that I don't want.
I want it to be like this shubhanshusingh#shubhanshusingh:~/Project$, that is, show only the name of the last directory. Is there any configuration that I can set for the VS Code terminal? Please let me know.
I am using WSL:Ubuntu

Building Go module without main file

I have a small module that contains some shared code. The module looks like the following :
Shared
├── go.mod
├── go.sum
├── logging
│ └── logger.go
└── db-utils
├── db.go
If I'll try to build the Shared module from inside the directory I'm getting an error that no go file available under this module.
bash-3.2$ go build .
no Go files in /Users/xxxx/go/src/Shared
Is there a way to build a Go module that only has packages inside and doesn't have a main.go file? The motivation here is to use those packages in other go modules that can't access the internet or private repo in order to retrieve the packages.
The go command stores downloaded modules in the module cache as source code, not compiled object files. go build rebuilds the object files on demand and stores them in a separate build cache.
If you want to distribute a non-public module for use with other modules, you have a few options:
You can publish the module to a private repository — typically accessed with credentials stored in a .netrc file — and use the GOPRIVATE environment variable to tell the go command not to try to fetch it from the public proxy and checksum servers.
You can provide a private GOPROXY server or directory containing the source code, and use the GOPROXY environment variable to instruct the go command to use that proxy.
You can publish the source code as a directory tree and use a replace directive in the consumer's go.mod file to slot it into the module graph.
If you only needed to build files in either the logging or db-utils directory, then you could executing the following from the root directory Shared:
go build <INSERT_MODULE_NAME_FROM_GO_MOD>/logging
go build <INSERT_MODULE_NAME_FROM_GO_MOD>/db-utils
I'm not certain if those commands will work if one of the files has a dependency on a file from the other directory.
Another command that will probably build the entire project is this:
go build ./...
Is there a way to build a go module that only has packages inside and doesn't have a main.go file?
No. The input for the build process is a package, not a module. Note how it says [packages] in the CLI documentation of go build.
When building a package leads to multiple packages being compiled, that is merely a consequence of direct and indirect import statements coming from .go-files located in the package you are building.
Note that Go does not support compiling packages to binaries to distribute closed-source libraries or such. This was not always the case, though. See #28152 and Binary-Only packages. The closest which exists to supporting that are plugins, but they are a work in progress and require resolution of symbols at runtime.

How can I use a local repository in the vendor in Google Cloud Functions with Go

I'm trying to deploy a Google Cloud Function written in Go.
By doing some research I found out that vendor files are prefered over go.mod so I'm vendoring everything I use (which includes some local dependencies) and ignoring the go.mod/sum files in the .gcloudignore file.
The problem is that after trying to deploy, I get the following error:
go: nimbus#v0.0.0-00010101000000-000000000000: parsing /nimbus/go.mod: open /nimbus/go.mod: no such file or directory; Error ID: 03a1e2f7
nimbus is my local dependency and it has the following structure:
My Function repository has the following structrure:
and my go.mod file is:
module my_function
go 1.13
require nimbus v0.0.0-00010101000000-000000000000
replace nimbus => ../../../nimbus
I've tried this solution https://stackoverflow.com/questions/5441096 already. But it did not fix my issue.
I've tried everything to solve this issue, but nothing seems to work.
If you have a go.mod file and a vendor directory, the vendor directory will be ignored when you deploy your function.
https://cloud.google.com/functions/docs/writing/specifying-dependencies-go
I have used modules when deploying GCP functions in Go. Haven't had any problems. But I can't speak to the preference of using vendor/ instead. It should work, just without the go.mod file.
Turns out the problem was very complicated and I hope Google finds a solution for it asp.
By deploying my function using Cloud Build, It would read from my repository on Google Source, but, by reading from there it would bypass the .gcloudignore file and deploy both the go.mod/sum files and the vendor directory with my local code.
As said in https://stackoverflow.com/a/62050872/10316247:
If you have a go.mod file and a vendor directory, the vendor directory will be ignored when you deploy your function.
So the error would occur because of my go.mod not being able to find local repository.
My solution was to rename my go.mod/sum files so it would not be considered:
When you use golang 1.16 and specify golang 1.16 in the go.mod folder it will instead default to using the vendor files with the --mod=vendor flag set, which will solve this issue.
You'll just need to ensure your module name is formatted correctly (something like example.com/module).

How to use modules replace functionality in cloud functions

I have a google cloud function that is a subdirectory in a repository. It uses the "Directory with source code" option in the settings menu. I keep getting this error on deploy:
Deployment failure:
Build failed: go: parsing /utils/pubsub/go.mod: open /utils/pubsub/go.mod: no such file or directory
go: error loading module requirements
I'm assuming that GCF does not upload the entire directory to the instance, but instead only the folder? This breaks the replace functionality of Go modules. Is there something I am doing wrong?
Link to the repo: https://github.com/FreekingDean/jeffbotgo/tree/5d735cc/slackevent
I work at Google and on this product.
Only the directory where you run gcloud is uploaded. There is no staging step beyond zipping the current directory and uploading it.
Notably, modules are preferred by the builder over vendor. If there is a go.mod, modules will be used. When you upload your function, it only includes the directory with your function at the root, not any directories one level up. So, when there is a go.mod and you have a replace directive pointing one level up, it will not work.
The solution for now with this layout is to vendor and not upload the go.mod/go.sum files. When using gcloud, you can create a .gcloudignore file to do this for you. See https://cloud.google.com/functions/docs/concepts/go-runtime#specifying_dependencies for more detail. Alternatively, modify your project to include any necessary helper packages in subdirectories.
I had the same issue today.
When reading thru the documentation for the 8th time i came across a warning box bellow the "Vendor directory" headline.
Warning: If your project has both a go.mod file and a vendor directory
at the root of your project, the vendor directory will be ignored
during deployment. You must use a .gcloudignore file to ignore the
go.mod file in order to ensure that your vendor directory is used
during deployment.
So basically once i added a .gcloudignore file with go.mod (will add go.sum as well) everything worked. So i guess if you have a go.mod file the cloud function will try to fetch dependencies instead of using the ones uploaded in the vendor folder.
I'm just guessing here tough.

Resources