Introduction
Grafana Loki is a horizontally scalable, highly available, multi-tenant log aggregation system inspired by Prometheus. It is designed to be very cost-effective and easy to operate. Unlike other logging systems, Loki does not index the content of the logs, but rather a set of labels for each log stream.
In this lab, you will perform a basic installation of Grafana Loki using its official Docker image. You will learn how to create a minimal configuration file and launch the Loki service as a container. This is the first fundamental step in building a complete logging stack with Loki.
Pull Loki Docker Image
In this step, you will download the official Grafana Loki Docker image from Docker Hub. The docker pull command fetches an image or a repository from a registry. Your lab environment already has Docker installed and configured.
Execute the following command in the terminal to pull the latest Loki image:
docker pull grafana/loki
You will see output indicating the download progress. Docker will pull the image with the latest tag by default.
Expected output (version numbers may vary):
latest: Pulling from grafana/loki
a48641c1b8a9: Pull complete
...
Digest: sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Status: Downloaded newer image for grafana/loki
docker.io/grafana/loki
Create Basic loki-config.yaml File
In this step, you will create a minimal configuration file for Loki. This file, loki-config.yaml, tells Loki how to run, where to store data, and what schema to use. For this lab, we will configure Loki to use the local filesystem for storage.
We will use the nano text editor to create the file. Run the following command to open a new file named loki-config.yaml:
nano loki-config.yaml
Now, copy and paste the following YAML content into the nano editor:
auth_enabled: false
server:
http_listen_port: 3100
common:
path_prefix: /tmp/loki
storage:
filesystem:
chunks_directory: /tmp/loki/chunks
rules_directory: /tmp/loki/rules
ring:
kvstore:
store: inmemory
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
storage_config:
boltdb_shipper:
active_index_directory: /tmp/loki/index
cache_location: /tmp/loki/cache
filesystem:
directory: /tmp/loki/chunks
ruler:
alertmanager_url: http://localhost:9093
limits_config:
allow_structured_metadata: false
This configuration keeps everything Loki needs under /tmp/loki inside the container, which avoids permission issues and keeps the setup easy to understand. It disables authentication, enables an in-memory ring for single-node use, and stores blocks and indexes on the local filesystem.
Here is what each section in the file does:
auth_enabled: false: Turns off authentication so you can talk to Loki without extra credentials. This makes local testing simple; you would enable authentication in production.server.http_listen_port: 3100: Tells Loki to listen for HTTP requests on port 3100. When you curllocalhost:3100, you are hitting this port.common.path_prefix: Sets the base folder where Loki stores temporary data inside the container. Every other path in this file is built from/tmp/lokiso everything stays in one place.common.storage.filesystem: Points Loki to two folders for storing chunks of log data and rule files. Because we mount nothing special into the container, using/tmp/lokiavoids permission headaches.common.ring.kvstore.store: inmemory: Keeps membership information in memory. For a single-node lab this is perfect; a real cluster would use a shared store like Consul or etcd.schema_config: Defines how Loki should lay out the index for log data. We set a start date, choose theboltdb-shipperstore, and keep the index on the filesystem. Theprefixandperiodcontrol how files are named and how often a new index file is created (every 24 hours).storage_config: Provides the exact folders for theboltdb-shipperindex (active_index_directoryandcache_location) and for raw chunk storage. All paths again live under/tmp/lokito keep things tidy.ruler.alertmanager_url: Prepares Loki’s ruler component to send alerts to an Alertmanager athttp://localhost:9093. Nothing will break if Alertmanager is not running; Loki will simply log a warning when it tries to send an alert.limits_config.allow_structured_metadata: false: Disables an advanced feature so Loki sticks to the simpler, plain-text log metadata that beginners expect.
Press Ctrl+X to exit, then Y to confirm saving, and finally Enter to save the file with the name loki-config.yaml.
Run Loki Container on Port 3100 with Config
Now that you have the Loki image and a configuration file, you will run Loki as a Docker container. You will use the docker run command to start the container, mount your configuration file, and expose the necessary port.
Execute the following command:
docker run -d --name loki -v $(pwd)/loki-config.yaml:/etc/loki/config.yml -p 3100:3100 grafana/loki -config.file=/etc/loki/config.yml
Let's break down this command:
-d: Runs the container in detached mode (in the background).--name loki: Assigns the namelokito the container for easy reference.-v $(pwd)/loki-config.yaml:/etc/loki/config.yml: Mounts your localloki-config.yamlfile into the container at/etc/loki/config.yml. Loki will read its configuration from this file.-p 3100:3100: Maps port3100of the host machine to port3100inside the container, allowing you to access the Loki API.grafana/loki: The image to use for the container.-config.file=/etc/loki/config.yml: A command-line argument passed to the Loki process, telling it where to find the configuration file.
After running the command, Docker will print the unique ID of the newly created container.
e8a9f2b1c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0
Verify Loki Ready Endpoint at localhost:3100/ready
In this step, you will perform a health check to confirm that the Loki server is up and running correctly. Loki exposes a /ready HTTP endpoint that can be used for this purpose. A successful response indicates that the server is ready to receive requests.
Use the curl command to send a request to this endpoint. Since we mapped port 3100 in the previous step, you can access it via localhost:3100.
curl http://localhost:3100/ready
If Loki has started successfully, it will respond with the text ready and an HTTP 200 OK status code.
Expected output:
ready
Check Loki Logs for Startup Confirmation
Another way to verify that Loki started successfully is by inspecting its container logs. This is useful for debugging configuration issues or other startup problems. The docker logs command fetches the logs of a container.
Use the following command to view the logs for your loki container:
docker logs loki
You should see output detailing the startup process. Look for a line confirming that the server is listening for connections. This confirms that the service initialized without any critical errors.
Expected output snippet (log details may vary):
level=info ts=... caller=server.go:299 http=[::]:3100 grpc=[::]:9096 msg="server listening on addresses"
level=info ts=... caller=loki.go:372 msg="Loki started"
Summary
Congratulations! You have successfully completed this lab.
In this lab, you have learned the fundamental steps to get a Grafana Loki instance up and running. You have:
- Pulled the official Loki Docker image from Docker Hub.
- Created a basic
loki-config.yamlfile to define server and storage settings. - Launched Loki in a Docker container, mounting the configuration and exposing the API port.
- Verified that the Loki instance is running and healthy using its
/readyendpoint and by checking its container logs.
This basic setup is the foundation for building a more complex and robust logging architecture. From here, you could proceed to configure a log shipping agent like Promtail to send logs to Loki and use Grafana to query and visualize them.



