Membangun dan menguji API yang disambungkan secara setempat ke pangkalan data bukanlah jenaka. Pangkalan data sering menjadi titik kesakitan. Walau bagaimanapun, menggunakan Docker, proses menjadi lebih mudah dan lebih mudah, menjadikan replikasi mudah. Dalam blog ini, kita akan melihat bagaimana kita boleh Dockerize API Golang dengan Pangkalan Data MySQL, juga menjadikannya Docker Compose bersedia
Untuk demo, saya mencipta RESTful Golang API ini. Kami boleh melakukan operasi CRUD seperti, mencipta, memadam dan mengedit jadual ke Pangkalan Data MySQL. Kita boleh mengetahui lebih lanjut tentang titik akhir, kaedah, dsb., dalam projek README. Kami tidak akan mendalami cara API berfungsi, kerana matlamat utama kami adalah untuk menumpukan pada bahagian Dockerization.
Untuk Dockerzing apl kita perlu mencipta Dockerfile. Biar saya beritahu anda terdapat 100-an cara untuk menulis Dockerfile, dan tidak ada yang salah atau betul, setiap individu/syarikat mempunyai set amalan dan cara penulisannya sendiri. Dalam kes kami, kami akan mengikuti empat amalan terbaik dalam Dockerfile kami untuk mendapatkan imej yang lebih baik dan dioptimumkan yang lebih kecil dan lebih selamat. Mari fahami kesemua 4 amalan dan sebab kami melaksanakannya sebelum memulakan penulisan Dockerfile.
Menggunakan imej asas yang lebih ringan: Untuk hampir setiap bahasa terdapat versi imej yang lebih ringan. Dengan lebih ringan saya tidak bermaksud beberapa Megabait lebih kecil, ia boleh menjadi 10x lebih kecil, sebabnya lebih ringan ialah ia tidak mengandungi kebergantungan yang tidak perlu yang menjadikannya lebih kecil dan lebih selamat. Ya, lebih banyak kebergantungan datang dengan lebih banyak risiko keselamatan. kami akan mempunyai versi bullseye dan alpine untuk nod, Golang, dsb.
Binaan Berbilang Peringkat: Mereka adalah salah satu kuasa besar Docker, mereka membenarkan kami menjalankan langkah binaan secara selari dan juga membenarkan kami mencipta imej akhir dengan menyalin fail dan perkara yang diperlukan daripada langkah lain dan hanya mempunyai item yang diperlukan untuk menjalankan program kami.
Buat Perduaan: Banyak bahasa menyokong penciptaan binari daripada kod sumber, menjadikannya kecil dan lebih mudah untuk dijalankan kerana kita tidak perlu mengendalikan kod sumber yang lengkap. Selain itu, kami boleh berjalan dalam mana-mana persekitaran tanpa mengira halangan bahasa.
Memecahkan lapisan: Seperti yang kita tahu setiap arahan dalam Dockerfile ialah lapisan, dan memecahkan lapisan ialah cara yang baik untuk menjadikan binaan kita lebih pantas. Contohnya, jika kami menyalin semua fail (bersama-sama dengan fail dependensi untuk dipasang) daripada sumber dan kemudian memasang dependencies, walaupun kami tidak membuat sebarang perubahan pada dependencies, setiap kali kami membina semula imej, ia akan salin semua fail dan pasang kebergantungan. Untuk mengatasinya, kami memecahkannya kepada beberapa lapisan dan boleh menyalin fail kebergantungan dalam satu langkah dan memasangnya. Dan dalam langkah seterusnya, kita boleh menyalin semua fail. Sekarang, apabila kita membuat perubahan pada kod, dan membina semula kali ini hanya lapisan di mana kita menyalin semua fail akan dibina semula, meninggalkan langkah pergantungan (yang dicache kerana tiada perubahan). Kita boleh melihat contoh dalam Dockerfile di bawah juga. Kami menulis Dockerfile sedemikian rupa sehingga perkara yang kurang berubah, seperti imej asas, kebergantungan, dll., akan berada pada pendekatan atas ke bawah.
Jadi, berikut ialah Fail Docker yang kami buat untuk API Go kami.
# Build Stage FROM golang:alpine3.20 AS builder WORKDIR /build COPY go.mod go.sum ./ RUN go mod download COPY . . RUN go build -o /app . # Final Stage FROM alpine:3.20 COPY --from=builder /app /app CMD ["/app"]
Dalam FROM kita boleh lihat kita menggunakan versi golang:alpine sebagai imej asas dan bukannya menggunakan golang penuh dan menamakan pembina langkah, nama/label akan membantu kita menyalin fail dari satu peringkat ke yang lain. Selepas itu, kami mencipta direktori kerja. Kemudian daripada menyalin semua fail bersama-sama, kami hanya menyalin go.mod dan go.sum dan memasang kebergantungan (saya telah menerangkan sebab di atas dalam titik Memecah lapisan).
Sekarang setelah kebergantungan dipasang, kami menyalin fail yang tinggal. Kemudian kami mencipta binari daripada kod sumber kami dengan menjalankan go build dan menamakan binari dengan bendera output -o ke lokasi semasa.
Sekarang, di sini perkara menjadi menarik, pada peringkat akhir kita tidak memerlukan imej golang atau sebagainya, kita boleh menggunakan imej asas Alpine kerana kita kini mempunyai binari, dan kita boleh berjalan pada mana-mana sistem Linux tanpa mengira pengaturcaraan spesifik bahasa. Dalam langkah seterusnya, kita boleh menyalin binari daripada langkah pembina ke peringkat akhir dan menjalankan binari.
Itu sahaja. Begitulah cara Dockerzie aplikasi kami dan kami boleh menambah baik lagi Dockerfile dengan memperkenalkan amalan terbaik seperti, mencipta pengguna dan berjalan sebagai bukan root, dsb. Kini kami boleh membina imej dengan Dockerfile dan jalankan dan kemudian menyambung ke alat kawalan jauh atau pelayan MySQL tempatan dengan menyediakan bukti kelayakan yang diperlukan dan kemudian tekan titik akhir API tersebut.
But, we will not stop here we will take a step further, and we will also run a MySQL server in a container and connect with our app. But, one point to note here is we can run a spin of a MySQL container and connect our API container to that, but there is so much manual work and long commands to type in the terminal, and things can go wrong. To overcome this we will use Docker Compose instead to make our life easier.
Let's create a file called compose.yml and use the blow config.
services: app: container_name: go-api build: context: . dockerfile: Dockerfile image: go-api ports: - 8080:8080 environment: - DB_HOST=mysql - DB_PORT=3306 - DB_USER=user - DB_PASSWORD=password - DB_NAME=my-database depends_on: mysql: condition: service_healthy networks: - go-network mysql: container_name: go-mysql image: mysql:9.0 environment: - MYSQL_ROOT_PASSWORD=password - MYSQL_USER=user - MYSQL_PASSWORD=password volumes: - dbdata:/var/lib/mysql networks: - go-network healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s timeout: 5s retries: 3 volumes: dbdata: networks: go-network: driver: bridge
It's a pretty basic configuration, but a couple of key things I want to mention is that if we see DB_HOST is mysql, there is no localhost or ip because in compose services communicate with other services by the service name. This is out-of-the-box networking provided by Docker Compose.
Another point, it often happens when working with Docker Compose where we have two services: an app and a database, and the app service starts first and crashes because the database isn't ready when the app tries to connect. To overcome this, we set up a healthcheck for the database to confirm its readiness. Then, in our app service, we can use depends_on with a condition to ensure the app only starts when the database service is healthy.
Now when we do Docker compose for 1st time, we might encounter an error saying permission denied because it doesn't have permission as well as a database with the name my_database, so we need to both by execing into the container.
Even though our app has crashed the DB is still up and running. We can check by doing docker ps.
Now exec into the container by doing docker exec -it
mysql -u root -p
It will ask for the password, enter the password you mentioned in the compose.yml file. Once we log in, we can create a database. Create a database with the same name specified in the compose file. In my case, it's my_database. Execute the below command:
CREATE DATABASE my_database;
Now to give the right privileges and flush it execute the below command.
GRANT ALL PRIVILEGES ON my_database.* TO 'user'@'%'; FLUSH PRIVILEGES;
Once we are done, we need to stop the running compose service and restart again by doing docker compose up
That's it for this blog. I'm glad you're still reading and made it to the end—thank you so much for your support and reading. I sometimes share tips on Golang on Twitter. You can connect with me there.
Atas ialah kandungan terperinci Melabuhkan API Golang dengan MySQL dan menambah Sokongan Karang Docker. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!