# Deploying a Go Application on CloudStation

### **Overview**

CloudStation simplifies the deployment process for developers, allowing you to focus on writing code without worrying about infrastructure. This guide shows how to create and deploy a simple Go application on CloudStation.

For a video walkthrough, refer to our  [Blog Post.](https://blog.cloud-station.io/how-to-create-and-deploy-a-go-application-on-cloudstation/)

### **Prerequisites**

Ensure you have a CloudStation account. Sign up [here](https://www.cloud-station.io/signup).

### **Creating the Go Application**

* **Set Up Your Project:**

```go
mkdir go-example
cd go-example
```

* **Write the Go Code:** Create a file named `main.go` and add the following code:

```go
package main

import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"runtime"
	"sync"
	"time"
)

var (
	counter int
	mu      sync.Mutex
)

// FunFact represents the structure of the fun fact fetched from the API.
type FunFact struct {
	Text string `json:"text"`
}

func main() {
	port := getPort()
	http.HandleFunc("/", helloHandler)
	http.HandleFunc("/submit", submitHandler)

	log.Printf("Listening on port %s\n", port)
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
}

func getPort() string {
	port := os.Getenv("PORT")
	if port == "" {
		port = "3000"
	}
	return port
}

func helloHandler(w http.ResponseWriter, r *http.Request) {
	mu.Lock()
	counter++
	mu.Unlock()

	currentTime := time.Now().Format("Mon Jan 2 15:04:05 MST 2006")
	hostname := getHostname()
	cpuCount, memAlloc := getSystemInfo()
	funFact := getFunFact()

	response := fmt.Sprintf(
		`<html>
			<head>
				<title>Hello from CloudStation</title>
			</head>
			<body>
				<h1>Hello from CloudStation</h1>
				<p>Current time: %s</p>
				<p>Server hostname: %s</p>
				<p>Page visits: %d</p>
				<p>CPU Count: %d</p>
				<p>Memory Alloc: %d bytes</p>
				<h2>Fun Fact:</h2>
				<p>%s</p>
				<h2>Submit a Message:</h2>
				<form action="/submit" method="post">
					<input type="text" name="message" placeholder="Enter your message">
					<button type="submit">Submit</button>
				</form>
			</body>
		</html>`,
		currentTime, hostname, counter, cpuCount, memAlloc, funFact,
	)

	w.Header().Set("Content-Type", "text/html")
	fmt.Fprint(w, response)
}

func submitHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == http.MethodPost {
		message := r.FormValue("message")
		response := fmt.Sprintf(
			`<html>
				<head>
					<title>Message Submitted</title>
				</head>
				<body>
					<h1>Thank you for your message!</h1>
					<p>Your message: %s</p>
					<a href="/">Go back</a>
				</body>
			</html>`,
			message,
		)

		w.Header().Set("Content-Type", "text/html")
		fmt.Fprint(w, response)
	} else {
		http.Redirect(w, r, "/", http.StatusSeeOther)
	}
}

func getHostname() string {
	hostname, err := os.Hostname()
	if err != nil {
		return "unknown"
	}
	return hostname
}

func getSystemInfo() (int, uint64) {
	var memStats runtime.MemStats
	runtime.ReadMemStats(&memStats)
	return runtime.NumCPU(), memStats.Alloc
}

func getFunFact() string {
	resp, err := http.Get("https://uselessfacts.jsph.pl/random.json?language=en")
	if err != nil {
		return "Could not fetch a fun fact."
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "Could not read fun fact response."
	}

	var fact FunFact
	err = json.Unmarshal(body, &fact)
	if err != nil {
		return "Could not parse fun fact response."
	}

	return fact.Text
}
```

### **Step 1: Setting Up Your Project**

Create a directory for your project and navigate into it:

```bash
mkdir go-example
cd go-example
```


**Initialize the Go Module:**

```javascript
go mod init go-example
go mod tidy
```

### **Deploying on CloudStation**


1. **Fork the** [**Repository**](https://github.com/thecloudstation/go-example)**:** Click the **Fork** button at the top-right of this repository to create your own copy.
2. **Deploy the Application:**
   * Navigate to the CloudStation [Dashboard](https://www.cloud-station.io/dashboard/project).
   * Create a new project.
   * Click on **Add New** and select **GitHub**.
   * In the repositories list, select the repository you just forked.
   * Choose a subdomain for your app, e.g., `golang-example`, and click **Deploy**.

### **Access Your Application**

Your application will be accessible at **https://golang-example.cloud-station.app**.

### **Automatic Build with Nixpacks**

CloudStation uses Nixpacks to automatically build this Go application, so no Dockerfile is needed. Nixpacks automatically detects the programming language and framework, managing the build process seamlessly.

### **Port Configuration**

This Golang application runs on port 3000. CloudStation uses port 3000 by default for deployed applications, so no changes are needed in the application configuration.

### **Customization**

To modify the application, make changes in your forked repository and push them. CloudStation will automatically rebuild and redeploy your application.

### **Conclusion**

This guide demonstrated how to create and deploy a simple Go application on CloudStation, leveraging Nixpacks for automatic builds and default port configuration.

---

**Documents**

- [Changelog](https://documentation.cloud-station.io/s/ce6e8846-8aec-4337-a850-5188b6dc6d6e/doc/changelog-r4OVtpiRA5)
- [CloudStation Tutorials](https://documentation.cloud-station.io/s/ce6e8846-8aec-4337-a850-5188b6dc6d6e/doc/cloudstation-tutorials-brnm0gaWUb)
- [Documentation](https://documentation.cloud-station.io/s/ce6e8846-8aec-4337-a850-5188b6dc6d6e/doc/documentation-4X2U9io3hK)
- [Understanding CloudStation Plans](https://documentation.cloud-station.io/s/ce6e8846-8aec-4337-a850-5188b6dc6d6e/doc/understanding-cloudstation-plans-UqY29FsY4w)