Deploy a Go App
How to Deploy a Go App on a VPS, Cloud Server, or Dedicated Server
In this guide, we will walk through the process of deploying a Go application on a VPS, cloud, or dedicated server using Docker and Caddy as your web server and reverse proxy. Whether you’re running your application on AWS, DigitalOcean, Hetzner, Scaleway or a dedicated physical server, the steps remain largely the same.
Setting Up the Server
Create a new server on your cloud provider or local machine with a public IP address, SSH access from your development machine, and a fresh Ubuntu 22.04 installation. Ensure that ports 22, 80, and 443 are open. (Some cloud providers, like AWS, close ports by default; you’ll need to open them before deployment.)
If you’re looking for a new cloud provider, consider Hetzner, DigitalOcean, or OVH. These providers typically have ports open by default. OVH also offers affordable domain registration and free DNS management via API.
Deploy with One Command
If you don’t want to deploy manually or don’t have time to set up a deployment pipeline, you can deploy your Go application to any cloud provider or private server with a single command from your local repository using TurboCloud. (No need for GitHub, Bitbucket, or even Git!) You can also deploy directly from GitHub or Bitbucket repositories.
Prepare Your Go App for Deployment
If you deploy with TurboCloud, it will check for the presence of a Dockerfile in the project's root directory. If no Dockerfile is found, TurboCloud will attempt to generate one automatically using Nixpacks. (See here for details on how Nixpacks generates Dockerfiles for Go apps.) However, we recommend creating a Dockerfile manually and placing it in the project's root folder for better control:
- Create a file named
Dockerfile
in your project’s root directory. - Add the following content:
FROM golang:1.23
WORKDIR /usr/src/app
# Pre-copy/cache go.mod to pre-download dependencies, only re-downloading them in subsequent builds if they change
COPY go.mod go.sum ./
RUN go mod download && go mod verify
# Copy the application source code
COPY . .
# Build the application
RUN go build -v -o /usr/local/bin/app ./...
# Define the command to run the application
CMD ["app"]
Deploy from the Local Repository
- On your development machine, navigate to the folder containing the project's code and run the deployment command (replace
server_ip
with the actual public IP of your server andservice_port
with the port number your app uses):
cd my_project
curl https://turbocloud.dev/deploy | bash -s -- -i server_ip -p service_port
- Wait until the deployment script displays the URL of the deployed Go application.
- Full documentation for all available parameters and detailed instructions can be found at turbocloud.dev/docs.
Deploy from GitHub or Bitbucket
- SSH into your server (replace
server_ip
with the actual public IP of your server):
ssh root@server_ip
- Run the setup command:
curl https://turbocloud.dev/setup | bash -s
- Once installation is complete, start the TurboCloud TUI (Terminal User Interface), which functions similarly to standard applications on macOS, Linux, and other operating systems but can operate on servers without displays. Use the TUI to set up deployments with interactive guides:
turbocloud
Step-by-Step guide
Step 1: Setting Up Your Server
To begin, ensure your Ubuntu 22.04 server is set up properly.
- Create a new Ubuntu 22.04 instance on your cloud provider or local machine.
- SSH into your server:
ssh user@your_server_ip
- Update your server’s packages:
sudo apt update
sudo apt upgrade -y
- Install Docker:
sudo apt install docker.io -y
- Install Docker Compose:
sudo apt install docker-compose -y
- Start Docker service:
sudo systemctl enable docker
sudo systemctl start docker
- Check Docker version:
docker --version
Now that Docker is installed and running on your server, proceed to the next step of creating your Go application.
Step 2: Creating the Go Application
If you don't already have a Go application, you can easily create a simple one. This example will use a basic Go HTTP server that responds with "Hello, World!" when accessed.
- Create a new project directory:
mkdir go-app
cd go-app
- Create a file named
main.go
and add the following code:
package main
import (
"fmt"
"log"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
}
func main() {
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
- Run the application locally:
go run main.go
Your Go application will be accessible at http://localhost:8080
.
Step 3: Dockerizing the Go Application
Now that the Go application is ready, the next step is to containerize it with Docker.
- Create a
Dockerfile
in your project’s root directory:
FROM golang:1.23
WORKDIR /usr/src/app
# Pre-copy/cache go.mod to pre-download dependencies, only re-downloading them in subsequent builds if they change
COPY go.mod go.sum ./
RUN go mod download && go mod verify
# Copy the application source code
COPY . .
# Build the application
RUN go build -v -o /usr/local/bin/app ./...
# Define the command to run the application
CMD ["app"]
- Build the Docker image (Optional, Docker should be installed on your local machine):
docker build -t go-app .
- Run the Docker container (Optional, Docker should be installed on your local machine):
docker run -p 8080:8080 go-app
At this point, your Go application is running inside a Docker container and accessible at http://localhost:8080
.
Step 4: Configuring Caddy
Caddy is a simple and powerful web server that automatically handles HTTPS certificates via Let's Encrypt. We will use Caddy as a reverse proxy for the Go application.
- Create a
Caddyfile
in the root directory of your project:
yourdomain.com {
reverse_proxy localhost:8080
}
Replace yourdomain.com
with your actual domain or server IP address. Caddy will forward HTTP requests to your Go application running on port 8080. Replace "8080" with the port you use in the Go application.
- Create a
docker-compose.yml
file to manage both Caddy and the Go application containers:
version: "3.8"
services:
app:
build: .
container_name: go-app
ports:
- "8080:8080"
caddy:
image: caddy:latest
container_name: caddy
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
depends_on:
- app
Explanation:
- The app
service builds the Go application and exposes port 8080.
- The caddy
service uses the official Caddy image, exposing ports 80 and 443 for HTTP and HTTPS.
- The depends_on
directive ensures Caddy waits for the Go application to be up before starting.
- Run both services with Docker Compose:
docker-compose up --build -d
This command will build the images for your Go application and Caddy, and run both containers in detached mode. Caddy will reverse proxy traffic to your Go application, and SSL certificates will be automatically managed if you use a valid domain.
Step 5: Pushing Code to GitHub
Now that your Go application is set up locally, let's push it to GitHub so you can easily clone it on your server.
- Initialize Git in your project directory (if not already done):
git init
- Create a
.gitignore
file to exclude unnecessary files:
# Ignore the binary files
main
# Ignore the Docker image files
.docker
# Ignore Go dependencies (if using Go modules)
/vendor/
- Commit your changes:
git add .
git commit -m "Initial commit of Go application"
-
Create a repository on GitHub: Go to GitHub and create a new repository. Copy the repository Git URL.
-
Add the remote repository:
git remote add origin https://github.com/yourusername/go-app.git
- Push your code to GitHub:
git push -u origin master
Step 6: Cloning the Repository on Your Server
Now that your code is on GitHub, you can easily clone it onto your server.
- SSH into your server:
ssh user@your_server_ip
- Install Git on your server (if not already installed):
sudo apt install git -y
- Clone the repository to your desired directory (if you clone over SSH (git@...) you should add a server public SSH key to GitHub deployment keys ):
cd /path/to/your/projects
git clone https://github.com/yourusername/go-app.git
- Navigate to the project directory:
cd go-app
- Run both services with Docker Compose:
docker-compose up --build -d
After around a few minutes your Go application should be online and accessible at https://your_domain.com
Conclusion
In this guide, we’ve covered two options for deploying Go applications:
- Using the TurboCloud deployment toolkit with a single command. This option also includes CI/CD, multiple environments, a Web Application Firewall (WAF), a Rate Limiter, and VPN functionality across servers and local machines.
- Deploying manually with Docker, Docker Compose, and Caddy. To prepare your server for production, we recommend adding a Web Application Firewall (WAF) and a Rate Limiter.