Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Linux & Mac & Bash Command Dictionary

  1. Home
  2. Linux & Mac & Bash Command Dictionary
  3. Deploying Go Apps (Single Binary + Nginx)

Deploying Go Apps (Single Binary + Nginx)

Go compiles to a single binary, so you can deploy simply by copying it to a server — no runtime or dependency installation required. The typical deployment flow is: cross-compile a Linux binary locally, transfer it to the server with scp or rsync, register it as a systemd service, and configure Nginx as a reverse proxy.

Syntax

# -----------------------------------------------
#  Building locally (Mac/Linux)
# -----------------------------------------------

# go build -o {output binary name} {package path}
#   → Builds the Go app in the current directory
#   Example: go build -o kiryu-api .

# GOOS=linux GOARCH=amd64 go build -o {output binary name} {package path}
#   → Cross-compiles for Linux AMD64
#   → Generates a Linux server binary from a macOS or Windows development machine
#   Example: GOOS=linux GOARCH=amd64 go build -o kiryu-api .

# -----------------------------------------------
#  Transferring and placing the binary on the server
# -----------------------------------------------

# scp {binary} {user}@{server}:{destination path}
#   → Transfers the local binary to the server
#   Example: scp kiryu-api kiryu@192.168.1.10:/usr/local/bin/kiryu-api

# chmod {permissions} {binary path}
#   → Grants execute permission to the binary
#   Example: sudo chmod 755 /usr/local/bin/kiryu-api

# -----------------------------------------------
#  Registering and managing the systemd service
# -----------------------------------------------

# systemctl daemon-reload
#   → Reloads the systemd configuration
#   → Must be run after creating or modifying a service file

# systemctl enable {service name}
#   → Configures the service to start automatically on server boot
#   Example: sudo systemctl enable kiryu-api

# systemctl start {service name}
#   → Starts the service immediately
#   Example: sudo systemctl start kiryu-api

# systemctl restart {service name}
#   → Restarts the service (use after updating the binary)
#   Example: sudo systemctl restart kiryu-api

# systemctl status {service name}
#   → Checks the running status and logs of the service
#   Example: sudo systemctl status kiryu-api

# -----------------------------------------------
#  Applying the Nginx reverse proxy configuration
# -----------------------------------------------

# nginx -t
#   → Checks the syntax of the configuration file
#   → Always run this before reloading to catch any errors

# systemctl reload nginx
#   → Reloads the Nginx configuration without downtime
#   → Use restart if reload is unavailable

Syntax Reference

StepDescription
Local buildGenerate a binary with go build -o kiryu-api .. It compiles for the same OS and architecture as the build environment.
Cross-compilationGenerate a Linux AMD64 binary with GOOS=linux GOARCH=amd64 go build -o kiryu-api .. You can create a Linux binary directly from a Mac or Windows development machine.
Binary transferCopy the binary to the server with scp kiryu-api kiryu@server-ip:/usr/local/bin/kiryu-api. Using rsync allows incremental transfers.
Granting execute permissionGrant execute permission to the binary with sudo chmod 755 /usr/local/bin/kiryu-api.
Creating the systemd service fileWrite the service definition in /etc/systemd/system/kiryu-api.service. Use Restart=always to configure automatic restart on crash.
Reloading the configurationRun sudo systemctl daemon-reload to make systemd recognize changes to the service file.
Enabling auto-startRegister the service to start automatically after a server reboot with sudo systemctl enable kiryu-api.
Starting the serviceStart the service with sudo systemctl start kiryu-api.
Creating the Nginx configurationWrite the reverse proxy configuration in /etc/nginx/sites-available/kiryu-go.conf and create a symbolic link in sites-enabled.
Nginx syntax checkVerify the configuration file syntax with sudo nginx -t. Always run this before reloading.
Reloading NginxApply the configuration without downtime using sudo systemctl reload nginx.
Verifying operationCheck the service state and logs with sudo systemctl status kiryu-api. You can also verify the app responds with curl http://localhost:8080/health.

Examples

/etc/systemd/system/kiryu-api.service
# -----------------------------------------------
#  systemd service file for Kiryu Kazuma's Go API server
# -----------------------------------------------

[Unit]
# Describes the service
Description=Kiryu API Server (Go)
# Starts after the network becomes available
After=network.target

[Service]
# Specifies the user and group to run the service as
# Avoid running as root — create a dedicated user instead
User=kiryu
Group=kiryu

# Specifies the absolute path to the binary
ExecStart=/usr/local/bin/kiryu-api

# Passes configuration such as port number and database connection via environment variables
Environment=PORT=8080
Environment=APP_ENV=production
Environment=DB_PATH=/var/lib/kiryu-api/kiryu.db

# Automatically restarts on crash
Restart=always
# Sets the wait time before restarting (in seconds)
RestartSec=5

# Sends stdout and stderr to the journal
StandardOutput=journal
StandardError=journal

# Specifies the working directory (used to resolve relative paths in config files)
WorkingDirectory=/var/lib/kiryu-api

[Install]
# Starts automatically under multi-user.target (the normal boot target)
WantedBy=multi-user.target
/etc/nginx/sites-available/kiryu-go.conf
# -----------------------------------------------
#  Nginx reverse proxy configuration for the Kiryu Go API server
# -----------------------------------------------

server {
    listen 80;
    # Specifies the domain name to serve
    server_name kiryu-api.example.com;

    # Outputs access and error logs to app-specific files
    access_log /var/log/nginx/kiryu-api.access.log;
    error_log /var/log/nginx/kiryu-api.error.log;

    location / {
        # Forwards requests to the address where the Go app is listening
        proxy_pass http://127.0.0.1:8080;

        # Passes real client information to the Go app even through the proxy
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Sets timeouts (adjust if your app has requests that take longer than 60 seconds)
        proxy_connect_timeout 10s;
        proxy_send_timeout    60s;
        proxy_read_timeout    60s;
    }

    # Disables access logging for the health check endpoint to reduce log volume
    location /health {
        proxy_pass http://127.0.0.1:8080/health;
        access_log off;
    }
}

Run the following command:

$ # Cross-compile locally and transfer to the server
$ GOOS=linux GOARCH=amd64 go build -o kiryu-api .
$ scp kiryu-api kiryu@192.168.1.10:/usr/local/bin/kiryu-api

$ # Perform deployment tasks on the server (all commands below run on the server)
$ sudo chmod 755 /usr/local/bin/kiryu-api

$ # Place the systemd service file and reload the configuration
$ sudo cp kiryu-api.service /etc/systemd/system/kiryu-api.service
$ sudo systemctl daemon-reload

$ # Enable auto-start and launch the service
$ sudo systemctl enable kiryu-api
Created symlink /etc/systemd/system/multi-user.target.wants/kiryu-api.service → /etc/systemd/system/kiryu-api.service.
$ sudo systemctl start kiryu-api

$ # Check the service status
$ sudo systemctl status kiryu-api
● kiryu-api.service - Kiryu API Server (Go)
     Loaded: loaded (/etc/systemd/system/kiryu-api.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2026-03-25 10:42:17 JST; 3s ago
   Main PID: 12847 (kiryu-api)
      Tasks: 5 (limit: 2308)
     Memory: 8.2M
        CPU: 12ms
     CGroup: /system.slice/kiryu-api.service
             └─12847 /usr/local/bin/kiryu-api

$ # Verify that the Go app responds correctly
$ curl http://localhost:8080/health
{"status":"ok","server":"Kiryu API","version":"1.0.0"}

$ # Apply the Nginx configuration
$ sudo ln -s /etc/nginx/sites-available/kiryu-go.conf /etc/nginx/sites-enabled/
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ sudo systemctl reload nginx

$ # Verify that external access through Nginx works
$ curl http://kiryu-api.example.com/health
{"status":"ok","server":"Kiryu API","version":"1.0.0"}

Overview

Deploying a Go app takes advantage of its single-binary nature and can be completed in four steps: build, transfer, register with systemd, and configure Nginx. Cross-compilation lets you generate a Linux binary regardless of your development machine's OS, so you can achieve a straightforward deployment without setting up a container environment like Docker. For process management with systemd, Restart=always is recommended to enable automatic recovery from unexpected crashes, and specifying a dedicated user with User= keeps the process from running with unnecessary privileges. By placing Nginx in front as a reverse proxy, SSL termination, log aggregation, and load balancing are handled by Nginx, allowing the Go app to focus on business logic. For more details on systemd service files, see the systemd unit file page, and for Nginx reverse proxy configuration, see the Nginx reverse proxy page.

If you find any errors or copyright issues, please .