Docker ialah platform kontena yang memudahkan pembungkusan, pengedaran dan penggunaan aplikasi. Anda boleh memanfaatkan faedah Go dan Docker untuk meningkatkan kecekapan, mudah alih dan keselamatan aplikasi anda.
Tutorial ini dilaburkan dalam mengajar anda cara anda boleh membina dan menggunakan aplikasi Go anda dengan Docker. Anda akan belajar dengan membina API RESTful dengan pakej Gorilla Mux dan GORM yang akan anda simpan dan gunakan.
Anda perlu memasang Go dan Docker pada komputer anda untuk membina dan menyimpan apl Go anda dengan Docker.
Pastikan anda telah memasang Go dan Docker pada sistem anda. Anda boleh memuat turun Go dari tapak web muat turun rasmi Go dan Docker dari Docker Hub. Lawati halaman web jika anda belum melakukannya dan ikut arahan pemasangan untuk sistem pengendalian khusus anda.
Artikel ini mengajar cara untuk menggunakan apl Go dengan Docker dan mengajar anda lebih lanjut tentang memasang dan menyediakan pangkalan data Docker dan Postgres, termasuk menyimpan aplikasi Go anda.
Selepas pemasangan, konfigurasikan persekitaran pembangunan Go anda dengan menetapkan pembolehubah persekitaran dan laluan mengikut keperluan. Pastikan anda mempunyai ruang kerja Go yang berfungsi dengan struktur direktori yang diperlukan.
Selain itu, anda boleh membiasakan diri dengan antara muka baris arahan (CLI) Docker dan konsep asas Docker.
Buat direktori baharu untuk projek ini dan jalankan arahan go mod init untuk memulakan direktori sebagai projek Go.
go mod init
Selepas memulakan projek Go, jalankan arahan ini untuk menambah pakej GORM dan Gorilla Mux sebagai kebergantungan pada projek anda.
go get github.com/gorilla/mux go get gorm.io/gorm go get gorm.io/driver/postgres
Anda akan menggunakan pakej Gorilla Mux untuk penghalaan. Pakej GORM menyediakan antara muka untuk anda menggunakan jenis Go untuk operasi pangkalan data SQL bersama-sama dengan pakej pemacu yang anda pasang (dalam kes ini, Postgres).
Dalam tutorial ini, anda akan menggunakan gaya seni bina berlapis Go yang popular dan menggunakan antara muka untuk berinteraksi dengan pelbagai komponen apl kami.
Berikut ialah struktur direktori aplikasi.
go mod init
Struktur projek ini kelihatan teratur, dengan jelas memisahkan kebimbangan antara komponen yang berbeza. Organisasi ini memudahkan untuk menyelenggara dan menskalakan API Go anda semasa ia berkembang.
Ini bukan standard Go. Walau bagaimanapun, banyak pembangun Go dan projek sumber terbuka menggunakan struktur ini untuk aplikasi anda.
Anda akan menyediakan kefungsian pangkalan data untuk aplikasi anda. Anda perlu menentukan model menggunakan struct, menyambung ke pangkalan data dan menyediakan migrasi untuk operasi sisipan anda pada pangkalan data anda.
Berikut ialah senarai import yang anda perlukan untuk pelaksanaan pangkalan data.
go get github.com/gorilla/mux go get gorm.io/gorm go get gorm.io/driver/postgres
Tugas pertama ialah mentakrifkan topang yang sepadan dengan skema pangkalan data anda untuk apl anda. GORM menyediakan teg untuk menentukan pilihan tambahan dan kekangan pada medan.
. ├── Dockerfile ├── cmd │ └── server │ └── main.go └── internal ├── http │ ├── handlers.go │ └── users.go ├── models │ ├── database.go │ ├── migrations.go │ └── users.go └── users └── user.go 6 directories, 11 files
Struktur Pengguna mewakili model untuk bekerja dengan data pengguna dalam pangkalan data.
Dalam fail database.go anda, isytiharkan struct untuk merangkum contoh sambungan pangkalan data. Anda akan menggunakan struct untuk menyambung ke pangkalan data anda daripada bahagian lain pakej pelaksanaan pangkalan data.
go mod init
Seterusnya, buat fungsi sambungan pangkalan data yang menghubungkan pelaksanaan pangkalan data ke program pangkalan data ke pangkalan data:
go get github.com/gorilla/mux go get gorm.io/gorm go get gorm.io/driver/postgres
Fungsi NewDatabase mencipta contoh Pangkalan Data baharu dan mewujudkan sambungan ke pangkalan data. Ia mengembalikan penunjuk kepada contoh Pangkalan Data dan ralat, jika ada, berlaku semasa proses.
Selepas sambungan pangkalan data berjaya, anda boleh menyediakan kefungsian migrasi untuk pelaksanaan pangkalan data anda dengan fungsi seperti berikut:
. ├── Dockerfile ├── cmd │ └── server │ └── main.go └── internal ├── http │ ├── handlers.go │ └── users.go ├── models │ ├── database.go │ ├── migrations.go │ └── users.go └── users └── user.go 6 directories, 11 files
Fungsi MgrateDB menyediakan migrasi automatik untuk struktur Pengguna dengan fungsi AutoMigrate klien pangkalan data dan mengembalikan ralat jika terdapat apa-apa yang ditemui semasa proses.
Dalam fail users.go di mana anda mentakrifkan struct untuk skema pangkalan data anda, anda boleh meneruskan untuk mentakrifkan fungsi untuk pelaksanaan pangkalan data.
Berikut ialah fungsi CreateUser, GetUserByID, UpdateUser dan DeleteUser yang bertanggungjawab untuk operasi CRUD pada pangkalan data.
package models import ( // imports from the user implementation "BetterApp/internal/users" "context" "gorm.io/gorm" "fmt" "gorm.io/driver/postgres" "gorm.io/gorm/schema" "os" )
Pelaksanaan pengguna anda akan memanggil fungsi ini untuk mengakses kefungsian pangkalan data.
Pelaksanaan pengguna anda memainkan peranan penting dalam menyampaikan data daripada pangkalan data kepada pelaksanaan HTTP.
Anda akan mentakrifkan struct yang sepadan dengan struct dalam pelaksanaan pangkalan data dan menambah tag JSON pada medan untuk kegunaan; kemudian, anda akan menentukan fungsi yang memanggil fungsi pangkalan data dengan data daripada pelaksanaan HTTP.
Berikut ialah import yang anda perlukan untuk pelaksanaan pengguna anda:
// internal/models/users.go type User struct { gorm.Model Username string `gorm:"unique;not null"` Email string `gorm:"unique;not null"` IsActive bool `gorm:"not null"` }
Berikut ialah struktur dengan tag JSON. Json:"-" dalam medan gorm.Model menentukan bahawa anda ingin mengecualikan medan daripada operasi JSON.
// internal/models/database.go type Database struct { Client *gorm.DB }
Seterusnya, anda akan mengisytiharkan antara muka dengan kaedah untuk fungsi pelaksanaan pengguna, struktur perkhidmatan untuk pelaksanaan pengguna dan fungsi yang memulakan pelaksanaan perkhidmatan.
// internal/models/database.go func NewDatabase() (*Database, error) { // Construct a connection string using environment variables for database configuration. configurations := fmt.Sprintf("host=%v port=%v user=%v password=%v dbname=%v sslmode=%v", os.Getenv("DB_HOST"), os.Getenv("DB_PORT"), os.Getenv("DB_USERNAME"), os.Getenv("DB_PASSWORD"), os.Getenv("DB_NAME"), os.Getenv("SSL_MODE")) // Open a connection to the database using GORM and PostgreSQL driver. db, err := gorm.Open(postgres.New(postgres.Config{ DSN: configurations, PreferSimpleProtocol: true, }), &gorm.Config{NamingStrategy: schema.NamingStrategy{ SingularTable: true, }}) if err != nil { return nil, err } // Enable connection pooling by configuring maximum idle and open connections. sqlDB, err := db.DB() if err != nil { return nil, err } sqlDB.SetMaxIdleConns(10) sqlDB.SetMaxOpenConns(100) // Return the Database instance with the established database connection. return &Database{ Client: db, }, nil }
Antara muka dan perkhidmatan akan membantu mengurus operasi berkaitan pengguna di luar pelaksanaan pengguna.
Seterusnya, anda boleh menentukan kaedah pelaksanaan struktur UserService yang memanggil pelaksanaan pangkalan data.
// internal/models/migrations.go func (d *Database) MigrateDB() error { log.Println("Database Migration in Process...") // Use GORM AutoMigrate to migrate all the database schemas. err := d.Client.AutoMigrate(&User{}) if err != nil { return err } log.Println("Database Migration Complete!") return nil }
Fungsi CreateUser, GetUserByID, UpdateUser dan DeleteUser bertanggungjawab untuk memanggil operasi CRUD pada pelaksanaan pangkalan data. Pelaksanaan HTTP akan memanggil fungsi ini untuk mengakses pangkalan data.
Pelaksanaan HTTP adalah sebahagian daripada aplikasi anda yang menerima dan berinteraksi dengan permintaan masuk.
Berikut ialah senarai import yang anda perlukan merentas pelaksanaan HTTP anda:
go mod init
Mula-mula, isytiharkan struct dan sertakan tika Router, tika HTTP dan tika perkhidmatan pengguna.
go get github.com/gorilla/mux go get gorm.io/gorm go get gorm.io/driver/postgres
Kemudian buat fungsi yang mengembalikan penunjuk kepada struct Pengendali, di mana anda boleh mengkonfigurasi pelayan dan pengendali.
. ├── Dockerfile ├── cmd │ └── server │ └── main.go └── internal ├── http │ ├── handlers.go │ └── users.go ├── models │ ├── database.go │ ├── migrations.go │ └── users.go └── users └── user.go 6 directories, 11 files
Fungsi NewHandler menyediakan dan mengkonfigurasi pengendali permintaan HTTP, menjadikannya bersedia untuk mengendalikan permintaan HTTP masuk untuk perkhidmatan tertentu sambil turut menentukan tetapan dan laluan pelayan.
Fungsi mapRoutes yang anda panggil dalam fungsi NewHandler menyediakan laluan dengan memetakannya ke fungsi pengendali masing-masing.
package models import ( // imports from the user implementation "BetterApp/internal/users" "context" "gorm.io/gorm" "fmt" "gorm.io/driver/postgres" "gorm.io/gorm/schema" "os" )
Seterusnya, tentukan fungsi pengendali dan fungsinya. Berikut ialah fungsi CreateUser, GetUserByID, UpdateUser dan DeleteUser yang bertanggungjawab untuk memintas permintaan HTTP dan bertindak balas berdasarkan operasi.
// internal/models/users.go type User struct { gorm.Model Username string `gorm:"unique;not null"` Email string `gorm:"unique;not null"` IsActive bool `gorm:"not null"` }
Kini, anda boleh menulis fungsi untuk memulakan pelayan.
// internal/models/database.go type Database struct { Client *gorm.DB }
Fungsi Serve memulakan pelayan pada port yang ditentukan dan mengembalikan ralat jika ada semasa proses.
Import pelaksanaan dalam fail main.go anda untuk menggandingkan pelaksanaan dan jalankan apl anda.
// internal/models/database.go func NewDatabase() (*Database, error) { // Construct a connection string using environment variables for database configuration. configurations := fmt.Sprintf("host=%v port=%v user=%v password=%v dbname=%v sslmode=%v", os.Getenv("DB_HOST"), os.Getenv("DB_PORT"), os.Getenv("DB_USERNAME"), os.Getenv("DB_PASSWORD"), os.Getenv("DB_NAME"), os.Getenv("SSL_MODE")) // Open a connection to the database using GORM and PostgreSQL driver. db, err := gorm.Open(postgres.New(postgres.Config{ DSN: configurations, PreferSimpleProtocol: true, }), &gorm.Config{NamingStrategy: schema.NamingStrategy{ SingularTable: true, }}) if err != nil { return nil, err } // Enable connection pooling by configuring maximum idle and open connections. sqlDB, err := db.DB() if err != nil { return nil, err } sqlDB.SetMaxIdleConns(10) sqlDB.SetMaxOpenConns(100) // Return the Database instance with the established database connection. return &Database{ Client: db, }, nil }
Anda boleh mengisytiharkan fungsi Run yang memulakan permulaan apl anda dalam fail main.go dan kemudian memanggil fungsi dalam fungsi utama.
// internal/models/migrations.go func (d *Database) MigrateDB() error { log.Println("Database Migration in Process...") // Use GORM AutoMigrate to migrate all the database schemas. err := d.Client.AutoMigrate(&User{}) if err != nil { return err } log.Println("Database Migration Complete!") return nil }
Fungsi Run mencipta contoh pangkalan data, memulakan fungsi migrasi, memulakan HTTP dan pelaksanaan Pengguna dan memulakan pelayan.
Anda boleh memanggil fungsi Run dalam fungsi utama untuk melancarkan aplikasi anda.
// internal/models/users.go func (d *Database) CreateUser(ctx context.Context, user *users.User) error { newUser := &User{ Username: user.Username, Email: user.Email, IsActive: false, } if err := d.Client.WithContext(ctx).Create(newUser).Error; err != nil { return err } return nil } // GetUserByID returns the user with a specified id func (d *Database) GetUserByID(ctx context.Context, id int64) (users.User, error) { user := users.User{} if err := d.Client.WithContext(ctx).Where("id = ?", id).First(&user).Error; err != nil { return users.User(User{}), err } return users.User(User{ Username: user.Username, Email: user.Email, IsActive: user.IsActive, }), nil } // UpdateUser updates an existing user in the database func (d *Database) UpdateUser(ctx context.Context, updatedUser users.User, id uint) error { // Check if the user with the specified ID exists var existingUser User if err := d.Client.WithContext(ctx).Where("id = ?", id).First(&existingUser).Error; err != nil { return err } // Update the fields of the existing user with the new values existingUser.Username = updatedUser.Username existingUser.Email = updatedUser.Email existingUser.IsActive = updatedUser.IsActive // Save the updated user back to the database if err := d.Client.WithContext(ctx).Save(&existingUser).Error; err != nil { return err } return nil } // DeleteUser deletes a user from the database by their ID func (d *Database) DeleteUser(ctx context.Context, id uint) error { // Check if the user with the specified ID exists var existingUser User if err := d.Client.WithContext(ctx).Where("id = ?", id).First(&existingUser).Error; err != nil { return err } // Delete the user from the database if err := d.Client.WithContext(ctx).Delete(&existingUser).Error; err != nil { return err } return nil }
Aplikasi harus berjalan dengan baik sebelum anda mempertimbangkan untuk menyimpannya dengan Docker.
Sekarang anda telah berjaya membina dan menjalankan program, anda boleh meneruskan untuk menyimpannya dengan Docker.
Fail Docker anda akan mempunyai dua peringkat, peringkat binaan dan akhir. Pendekatan ini mengurangkan saiz imej, meminimumkan risiko keselamatan dengan mengurangkan permukaan serangan, memastikan prestasi masa jalan yang cekap dan memudahkan kebolehulangan merentas peringkat pembangunan dan penggunaan yang berbeza.
Anda juga akan menggunakan Alpine Linux sebagai imej asas imej Docker anda kerana ia lebih cekap dan selamat dengan reka bentuk minimalis menghasilkan saiz imej yang lebih kecil, binaan yang lebih pantas dan permukaan serangan yang berkurangan.
Menggunakan peringkat binaan dan akhir dalam Dockerfile membolehkan penciptaan imej Docker yang cekap. Peringkat binaan bermula dengan imej asas yang mengandungi alatan binaan dan kebergantungan, menyusun artifak aplikasi dan menjana imej perantaraan yang berpotensi besar.
Berikut ialah kandungan Dockerfile untuk Peringkat Binaan:
go mod init
Peringkat akhir menggunakan imej asas yang lebih kecil, hanya menyalin komponen masa jalan yang diperlukan dan menghasilkan imej padat yang dioptimumkan untuk pengeluaran.
Berikut ialah kandungan Dockerfile anda untuk peringkat akhir:
go mod init
Selepas Menulis Fail Docker, anda boleh meneruskan untuk membina dan menjalankan fail tersebut.
Jalankan arahan ini untuk membina imej Docker daripada fail dengan arahan bina.
go get github.com/gorilla/mux go get gorm.io/gorm go get gorm.io/driver/postgres
Bendera -t menentukan teg untuk imej Docker sebagai aplikasi yang lebih baik dan titik berikut (.) menyatakan bahawa anda ingin membina Fail Docker dalam direktori semasa.
Anda boleh menjalankan imej dengan arahan run dan menentukan pemetaan port daripada bekas ke mesin hos anda dengan bendera -p.
. ├── Dockerfile ├── cmd │ └── server │ └── main.go └── internal ├── http │ ├── handlers.go │ └── users.go ├── models │ ├── database.go │ ├── migrations.go │ └── users.go └── users └── user.go 6 directories, 11 files
Bendera -e berikutnya adalah untuk menentukan pembolehubah persekitaran sejak untuk aplikasi anda.
Docker Compose ialah alat orkestrasi kontena yang memudahkan kerja dengan berbilang bekas Docker. Anda boleh menggunakan Docker compose untuk mengatur apl Go anda dan komponennya.
Anda akan menggunakan fail YAML untuk menentukan arahan dan karang Docker akan menyediakan aplikasi anda untuk menjimatkan masa dan kerumitan anda.
Mula-mula, buat fail Docker Compose YAML dengan arahan di bawah dan buka fail dalam editor anda:
package models import ( // imports from the user implementation "BetterApp/internal/users" "context" "gorm.io/gorm" "fmt" "gorm.io/driver/postgres" "gorm.io/gorm/schema" "os" )
Selepas mencipta Dockerfile, anda boleh mula menulis arahan dan arahan untuk menggunakan apl anda:
// internal/models/users.go type User struct { gorm.Model Username string `gorm:"unique;not null"` Email string `gorm:"unique;not null"` IsActive bool `gorm:"not null"` }
Fail YAML mentakrifkan dua perkhidmatan: my-postgres iaitu contoh bekas pangkalan data dan perkhidmatan web, iaitu aplikasi Go anda sebelum mengkonfigurasi pembolehubah persekitaran, port dan kebergantungan mereka.
Kini, anda boleh meneruskan untuk membina imej dengan arahan bina docker-compose.
// internal/models/database.go type Database struct { Client *gorm.DB }
Keluaran anda sepatutnya serupa dengan ini:
Akhir sekali, anda boleh menjalankan bekas anda dengan arahan docker-compose up.
go mod init
Bendera -d menjalankan bekas dalam mod tertanggal yang menjadikannya agnostik sesi terminal.
Inilah hasil daripada menjalankan arahan:
Anda boleh menutup terminal anda dan bekas harus terus berjalan.
Anda boleh menjalankan permintaan CURL untuk menguji API anda sebaik sahaja bekas siap:
go get github.com/gorilla/mux go get gorm.io/gorm go get gorm.io/driver/postgres
Tahniah, anda telah berjaya mengatur dan menjalankan aplikasi Go yang berfungsi dengan Docker dan Docker Compose.
Anda telah mempelajari cara membina dan memudahkan penggunaan apl Go anda dengan Docker dan Docker Compose. Semasa anda meneruskan perjalanan pembangunan anda, kemahiran dan pemahaman yang anda perolehi di sini akan terbukti menjadi aset penting dalam memastikan penggunaan lancar dan kecemerlangan operasi.
Pertimbangkan untuk meneroka ciri Docker lanjutan seperti mengoptimumkan binaan Dockerfile atau melaksanakan Docker Swarm untuk aplikasi yang lebih besar.
Atas ialah kandungan terperinci Cara Menggunakan Aplikasi Go Dengan Docker. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!