Project
Remember our database info in the previous part? We will use them here.
- Database: bootcamp
- Username: dbadmin
- Password: Password
Configurations
CLI tool
Configuration file for CLI tool is located in hack
folder. There is a config for gf docker
as initial, we could add more to it. This file is used to add some default settings for gf
related commands. Details for all commands settings could be found here.
Hot reload
Go is a compiled language, so we need to use hot reload after we change any code. There is a useful command called gf run
, add this command settings bellow gfcli
:
gfcli:
run:
path: "bin"
args: ""
- path: Set output directory path for built binary file. it’s
./
in default - args: Custom arguments for
gf run
Additional config for gf run
gfcli:
run:
path: "bin"
extra: ""
args: ""
watchPaths:
- api/*.go
- internal/controller/*.go
- extra: The same options as “go run”/“go build” except some options as follows defined
- watchPaths: Watch paths for hot reload
Code generation
There are several command for code generation that would be used in our bootcamp, they are:
gf gen ctrl
: Generate controllergf gen service
: Generate service interfacegf gen dao
: Generate database related code
Typically, we only need to add dao
related code configurations, since it requires link to the database.
gfcli:
gen:
dao:
- link: "mariadb:dbadmin:Password@tcp(database:3306)/bootcamp"
gf
in container, host would be database
rather than localhost
. Or if you want to use gf gen dao
out of the container, you could keep it to localhost
.The format for the link is:
type:username:password@protocol(address)[/dbname][?param1=value1&...¶mN=valueN]
You could use other supported database similar to this link.
Build project
As we mentioned before, Go is a compiled language. So we need to build our project after we finish all the development. The command for this is gf build
:
gfcli:
build:
arch: "amd64"
system: "linux"
output: "./tmp/bootcamp"
dumpEnv: true
- arch: Set the target architecture
- system: Set the target system
- output: Set the output path for built binary file
- dumpEnv: Display environment variables when building
Full config for CLI
gfcli:
docker:
build: "-a amd64 -s linux -p temp -ew"
tagPrefixes:
- my.image.pub/my-app
run:
path: "bin"
args: ""
gen:
dao:
- link: "mariadb:dbadmin:Password@tcp(database:3306)/bootcamp"
build:
arch: "amd64"
system: "linux"
output: "./tmp/bootcamp"
dumpEnv: true
Project
Similar to CLI tool configuration, our project also have its own configuration file in manifest/config
folder by default. It contains some initial settings for our application:
server:
address: ":8000"
openapiPath: "/api.json"
swaggerPath: "/swagger"
logger:
level: "all"
stdout: true
We still need to modify server
and logger
configurations and add database
configuration.
Server
For now, the configuration file has declared the address
, which is used to set listening port. You could change it to :8080
or any other port with no conflict.
The openapiPath
and swaggerPath
are used to set the URI of OpenAPI and Swagger, you may find it useful to check the auto-generated API documentation.
Besides these, we could still add some configurations for the server:
server:
address: ":8000"
openapiPath: "/api.json"
swaggerPath: "/swagger"
graceful: true
gracefulTimeout: 10
errorLogEnabled: true
errorLogPattern: "error-{Y-m-d}.log"
- graceful: Whether to enable graceful functions.
- gracefulTimeout: The timeout for request using graceful functions.
- errorLogEnabled: Whether to enable error log, default to
true
. - errorLogPattern: The pattern of error log.
Logger
For logger
, we could add a path to output log file:
logger:
path: "/var/log/ServerLog"
level: "all"
stdout: true
If path
is not set, the log will only be output to stdout.
Database
Before we add connection to database, a logger would be good for debugging:
database:
logger:
path: "/var/log/ServerLog"
file: "database-{Y-m-d}.log"
level: "all"
stdout: false
Then we could add default database configurations:
database:
default:
host: "database"
port: "3306"
user: "dbadmin"
pass: "Password"
name: "bootcamp"
type: "mariadb"
timezone: "Asia/Shanghai"
extra: "parseTime=true"
role: "master"
debug: "true"
dryrun: 0
charset: "utf8mb4"
maxLifetime: "10s"
database
rather than localhost
as the host.Full config for project
server:
address: ":8000"
openapiPath: "/api.json"
swaggerPath: "/swagger"
graceful: true
gracefulTimeout: 10
errorLogEnabled: true
errorLogPattern: "error-{Y-m-d}.log"
logger:
path: "/var/log/ServerLog"
level: "all"
stdout: true
database:
logger:
path: "/var/log/ServerLog"
file: "database-{Y-m-d}.log"
level: "all"
stdout: false
default:
host: "database"
port: "3306"
user: "dbadmin"
pass: "Password"
name: "bootcamp"
type: "mariadb"
timezone: "Asia/Shanghai"
extra: "parseTime=true"
role: "master"
debug: "true"
dryrun: 0
charset: "utf8mb4"
maxLifetime: "10s"
For simplicity, we only use part of the config settings for CLI tools and project, you could find more details here:
Run with docker
- In the following steps, we are mounting folders from our local machine to the container, there are some cases that the hot reload would not be triggered due to the WSL problem. Make sure to modify code under WSL when you are using Windows, or to be simple, just put all you need into WSL and use your IDE to connect to it.
- Or you could write your own config to only use built file in the container. Which means the hot reload would be finished by your local machine.
After finishing all the configurations, finally we could start setting the container.
Create a Dockerfile
in your project folder:
FROM golang:1.22-alpine as builder
WORKDIR /tmp
RUN wget -O gf "https://github.com/gogf/gf/releases/latest/download/gf_$(go env GOOS)_$(go env GOARCH)" && \
chmod +x gf && \
./gf install -y && \
rm ./gf
FROM golang:1.22-alpine as dev
WORKDIR /var/www
COPY --from=builder /go/bin/gf /go/bin/gf
CMD gf run main.go
ENV DEBIAN_FRONTEND noninteractive
RUN apk add --no-cache tzdata
ENV TZ=Asia/Shanghai
Then add the following settings to your services
in docker-compose.yaml
file:
web:
build:
dockerfile: Dockerfile
context: .
target: dev
depends_on:
database:
condition: service_healthy
volumes:
- ./:/var/www
- ./storage:/var/www/storage
environment: &bootcamp-environment
CONTAINER_ROLE: web
DB_HOST: database
DB_PORT: 3306
DB_DATABASE: bootcamp
DB_USERNAME: dbadmin
DB_ROOT_PASSWORD: R0OTp@ssword
DB_PASSWORD: Password
DB_DRIVER: mysql
ports:
- "8000:8000"
Full docker-compose.yaml
file
version: "3"
services:
database:
image: mariadb:10.3
environment:
MYSQL_ROOT_PASSWORD: R0OTp@ssword
MYSQL_DATABASE: bootcamp
MYSQL_USER: dbadmin
MYSQL_PASSWORD: Password
TZ: Asia/Shanghai
healthcheck:
test: mysqladmin ping -u dbadmin -pPassword
volumes:
- ./manifest/database/:/var/database
- database:/var/lib/mysql
command:
mysqld --default-time-zone=Asia/Shanghai --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
ports:
- "3306:3306"
web:
build:
dockerfile: Dockerfile
context: .
target: dev
depends_on:
database:
condition: service_healthy
volumes:
- ./:/var/www
- ./storage:/var/www/storage
environment: &bootcamp-environment
CONTAINER_ROLE: web
DB_HOST: database
DB_PORT: 3306
DB_DATABASE: bootcamp
DB_USERNAME: dbadmin
DB_ROOT_PASSWORD: R0OTp@ssword
DB_PASSWORD: Password
DB_DRIVER: mysql
ports:
- "8000:8000"
volumes:
database:
Now use docker-compose up -d --build
again to start all the containers and wait for a moment, you will see the project is running now.
Check the hello page and Swagger page auto-generated by GoFrame
gf
as a virus since we are mounting folders to our local machine, you can just allow it.