Go Runtime
Build and run Go applications on Witchly.host. Compile from source on deploy, run the executable with dedicated resources.
languages (12 articles)
On This Page
Go Runtime
The Go egg compiles your Go source into a binary at install time, then runs that binary. Perfect for Discord bots, HTTP services, CLI daemons, and anything else where you want a compiled, fast, single-binary deployable.
Quick deploy
- dash.witchly.host → Deploy → Languages → golang generic.
- On the Startup tab:
Go Package— your Go import path (e.g.,github.com/user/mybot)Executable— name of the compiled binary (e.g.,mybot)
- Start.
Startup flow
./${EXECUTABLE}
The startup is minimal — just runs your compiled binary. The install script handles the actual compile step:
# Pseudocode of the install step
go install ${GO_PACKAGE}@latest
mv $GOPATH/bin/<binary> /home/container/${EXECUTABLE}
Variables reference
| Variable | Purpose |
|---|---|
GO_PACKAGE | Go module path to install (e.g., github.com/user/tool) |
EXECUTABLE | Name of the resulting binary (typically the repo name) |
Workflow: Git repo → running service
Option A: public Go package. Set GO_PACKAGE = github.com/you/yourapp. Reinstall to recompile.
Option B: upload source manually. Upload your .go files + go.mod via SFTP to /home/container/src/, then on the Console tab:
cd src
go build -o ../myapp .
cd ..
chmod +x myapp
Set EXECUTABLE = myapp and start.
HTTP server example
// main.go
package main
import (
"fmt"
"log"
"net/http"
"os"
)
func main() {
port := os.Getenv("SERVER_PORT")
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello from Go on Witchly!")
})
log.Println("Listening on :" + port)
http.ListenAndServe(":"+port, nil)
}
Discord bot with discordgo
package main
import (
"os"
"os/signal"
"syscall"
"github.com/bwmarrin/discordgo"
)
func main() {
dg, _ := discordgo.New("Bot " + os.Getenv("DISCORD_TOKEN"))
dg.Identify.Intents = discordgo.IntentsGuildMessages | discordgo.IntentMessageContent
dg.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) {
if m.Content == "!ping" {
s.ChannelMessageSend(m.ChannelID, "pong")
}
})
dg.Open()
defer dg.Close()
stop := make(chan os.Signal, 1)
signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)
<-stop
}
Cross-compiling locally
If you want to skip the in-container compile and upload a ready binary:
# Build a Linux/amd64 binary from macOS or Windows
GOOS=linux GOARCH=amd64 go build -o myapp
# Upload myapp to /home/container/ via SFTP
chmod +x myapp
Faster deploys, and your server uses 0 resources at install time.
Troubleshooting
- “exec format error” — binary was built for the wrong architecture. Use
GOOS=linux GOARCH=amd64when cross-compiling. - “permission denied” — chmod +x the binary after upload.
- Listener fails — always bind to
0.0.0.0, never127.0.0.1orlocalhost, and useos.Getenv("SERVER_PORT").
Next steps
- Pair with Redis for caching
- Rust runtime if you want similar performance with stricter safety