Microservices with pebl — a complete and free cloud platform: Docker Development Best Practices Guide and Checklist
Hatched by Kelvin
Jul 12, 2024
6 min read
6 views
Microservices with pebl — a complete and free cloud platform: Docker Development Best Practices Guide and Checklist
Introduction
In this article, we will explore the capabilities of pebl, a complete and free cloud platform that allows you to incorporate cloud capabilities into your application through language-specific SDKs. We will also discuss Docker development best practices and provide a checklist to ensure you are following these practices.
Getting Started with pebl
To start using pebl, you need to sign up for a free account at pebl.io. Choose your desired identity provider and follow the steps. Make sure to claim your free *.pebl.rocks subdomain, as we will be using it throughout the tutorial.
You also need to install Docker and the pebl CLI. Head over to the Docker website and follow their instructions to install Docker. For the pebl CLI, refer to the pebl setup documentation and download the correct version for your system.
Creating a Simple Service with pebl
The core building block in pebl is a service, which is similar to a serverless application. To create a simple service using pebl, we will use Python and Flask.
First, create a scratch project folder on your system. In our examples, we will be using ~/work/scratch, but you can choose a different folder. Inside the scratch folder, create a subfolder called "hello" that will contain our simple hello world service.
Inside the "hello" folder, create a main.py file with the following content:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def root():
return "hello, world!\n"
import pebl
pebl.service(app, "hey.pebl.rocks") put your own domain here
This code defines a simple Flask application with a single handler on the root path. The pebl.service function is used to declare that this Flask application should be a service hosted at your *.pebl.rocks endpoint.
To run this locally, use the pebl run command inside the hello folder:
$ cd ~/work/scratch/hello
$ pebl run
You can now send a request to your server using curl:
$ curl localhost:32807
hello, world!
Deploying to the Cloud Runtime
One of the key benefits of pebl is the ability to deploy the exact same application to different runtimes without any modifications. To deploy your application to the cloud runtime, use the pebl deploy command:
$ cd ~/work/scratch/hello
$ pebl deploy
Make sure to run pebl auth if you encounter any authentication errors during deployment.
Once the deployment is successful, you can send requests to your cloud runtime using curl:
$ curl https://hey.pebl.rocks
hello, world!
Creating Internal Services
In addition to regular services, pebl also provides the capability to create internal services. These services are only exposed to other workloads and are not configured for external traffic.
To demonstrate this, let's create an internal Go service that acts as a user service, handling user data. Create a main.go file in a subfolder called "go" inside the scratch folder:
package main
import (
"github.com/peblcloud/go"
"net/http"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("this is an internal service!\n"))
})
pebl.InternalService(mux, "go.internal")
}
In this code, we create a server object using the net/http package and pass it to pebl's SDK with the pebl.InternalService function. The endpoint for internal services can be anything, but we recommend using an easy-to-remember scheme, such as a .local or .internal TLD.
To run this locally, use the pebl run command inside the go folder:
$ cd ~/work/scratch/go
$ pebl run
You can now send requests to this internal service using curl:
$ curl localhost:32808
this is an internal service!
Using Redis with pebl
Pebl provides persistence through Redis, and you can incorporate Redis into your application using the SDK. Let's update our Go service to incorporate Redis. Update the main.go file in the go folder as follows:
package main
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/peblcloud/go"
"github.com/redis/go-redis/v9"
)
func main() {
connInfo, _ := pebl.Redis("users")
client := redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%d", connInfo.Host, connInfo.Port),
})
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
query, _ := url.ParseQuery(r.URL.RawQuery)
name := query.Get("name")
userInfo, _ := client.HGetAll(context.Background(), name).Result()
payload, _ := json.Marshal(userInfo)
w.Write(payload)
})
pebl.InternalService(mux, "go.internal")
}
In this code, we use the pebl.Redis function to get connection information for a Redis instance named "users". We then create a Redis client and use it to retrieve user data based on the request's query parameter.
To run this locally, use the pebl run command inside the go folder:
$ cd ~/work/scratch/go
$ pebl run
You can now send requests to the internal Go service with Redis using curl:
$ curl 'localhost:32808?name=alice'
{"email":"[email protected]","name":"alice"}
Proxying Requests
To utilize the internal service, we can proxy a subset of requests from the external Python service to the internal Go service. Update the main.py file in the hello folder as follows:
from flask import Flask
import requests
app = Flask(__name__)
@app.route("/")
def root():
return "hello, world!\n"
@app.route("/user/<name>")
def user_service(name):
r = requests.get(f"http://go.internal?name={name}")
return r.text, r.status_code
import pebl
pebl.service(app, "hey.pebl.rocks") put your own domain here
In this code, we use the requests library to send requests to the internal Go service at go.internal:80. Once again, pebl allows us to incorporate other Python libraries without additional configuration.
To run this locally, use the pebl run command inside the hello folder:
$ cd ~/work/scratch/hello
$ pebl run
You can now send requests to the external endpoint at the /user path to access the internal service:
$ curl localhost:32807/user/alice
{"email":"[email protected]","name":"alice"}
Deploying the Application
To deploy the changes, first deploy the internal Go service:
$ cd ~/work/scratch/go
$ pebl deploy
Then, deploy the Python subproject:
$ cd ~/work/scratch/hello
$ pebl deploy
Pebl automatically implements zero-downtime updates to services, ensuring that there are no dropped requests during the transition.
Docker Development Best Practices Checklist
Now let's discuss Docker development best practices and provide a checklist to ensure you are following these practices:
- Use a .dockerignore file to prevent unwanted files and directories from being included in the Docker image.
- Avoid using the :latest tag and instead use specific versions for your images.
- Use specific base images instead of generic ones to ensure reproducibility.
- Minimize the layer count in your Dockerfile to reduce image size and build time.
- Utilize multi-stage builds to reduce the final image size.
- Avoid running containers as root whenever possible for security reasons.
- Use linters to check your Dockerfile for common mistakes and ensure best practices.
- Order your Dockerfile instructions properly to maximize layer cache usage.
- Keep your containers ephemeral, meaning they can be stopped and replaced easily.
- Don't install unnecessary packages in your Docker images to reduce their size.
- Label your images for better organization and management.
- Scan your images for vulnerabilities using security scanning tools.
- Expose only necessary ports in your Dockerfile to minimize attack surface.
- Maintain cleanliness by regularly cleaning up unused resources like dangling images, stopped containers, unused volumes, and unused networks.
- Use Docker system prune regularly to clean up the system and free up disk space.
Conclusion
In this article, we explored the capabilities of pebl, a complete and free cloud platform that allows you to incorporate cloud capabilities into your application through language-specific SDKs. We also discussed Docker development best practices and provided a checklist to ensure you are following these practices. By following these best practices, you can ensure that your Docker development process is efficient, secure, and scalable.
Actionable Advice:
- Use pebl's SDKs to incorporate cloud capabilities directly into your application code.
- Follow Docker development best practices to ensure efficient and secure containerized deployments.
- Regularly clean up unused Docker resources to optimize system performance and disk space usage.
Sources
Hatch New Ideas with Glasp AI 🐣
Glasp AI allows you to hatch new ideas based on your curated content. Let's curate and create with Glasp AI :)
Start Hatching 🐣