Publish your first app on Gyro Containers: Docker image, port, health check and replicas
1. Is your image platform-friendly?
| Rule | Why / what to do |
|---|---|
| Non-root user | Containers run as user 10001. Define USER 10001 (or another unprivileged user) and set file permissions accordingly. |
| Port 1024 or higher | An unprivileged user cannot listen on 80/443; use a port such as 8080. |
| Version tag | Use a fixed tag like 1.4.2 instead of latest; it is needed for rollback and repeatable releases. |
| Logs to standard output | Write application logs to stdout/stderr; the Logs page shows them. |
| No persistent disk | Files written are deleted when the container restarts (/tmp is temporary, 512 MiB). Write persistent data to Object Storage or a separate database. |
| Architecture | The image must be linux/amd64. |
For images whose main process needs root, the service stops with "Start-up configuration error" (CreateContainerConfigError). The fix: use a non-root image or define USER. An example of a ready-made unprivileged image: nginxinc/nginx-unprivileged.
2. Create a service in the panel
- Open your environment from My Services and go to Services.
- Press New service.
- Fill in the form:
| Field | What to write |
|---|---|
| Service name | Lowercase letters, digits, -; starts with a letter, up to 40 characters (for example api). Address: name + your code. |
| Image | user/app:1.4.2 for docker.io, ghcr.io/company/app:1.4.2 for GitHub, registry.ist.gyrohosting.com/<your-code>/app:1.4.2 for the Gyro registry. |
| Port | The port your application listens on (for example 8080). Required if it will be reachable from outside. |
| Replicas | Number of running instances. 2 or more for resilience. |
| CPU / replica, Memory / replica | Resources per replica (default 0.25 vCPU / 256 MB). |
| Health check path | An HTTP path such as /healthz. If empty, a TCP connection to the port counts as healthy. |
| Public (HTTPS address) | If ticked the service gets the address name-code.gyroapp.net. If not, it is reachable only from inside the environment at http://name. |
| Environment variables | One KEY=VALUE per line. Add values like passwords as a secret instead. |
| Command (optional) | Arguments for the image's default command. |
- Press Create and start. The status first shows Deploying, then Running.
The health check does two things: a new revision gets no traffic until its instance is ready (the basis of zero-downtime rollout), and if you give an HTTP path an instance that stops answering is restarted automatically. Define an HTTP health path when you can.
3. Pulling a private image
If your image is not public, define the registry credentials once:
- On the Node Pool page open the Private image registry section.
- Enter the Registry address (for example
ghcr.io), Username and Token / password. The token should be pull (read) only. - Press Save. One private registry is defined per environment; the token is stored encrypted and never shown again.
To keep your own images in Gyro's registry see Gyro image registry; there you do not need to define credentials separately.
4. From the command line
gyro container service create 12345 --name api \
--image ghcr.io/company/app:1.4.2 --port 8080 \
--replicas 2 --cpu-m 250 --memory-mi 256 \
--health-path /healthz --public \
--env '{"MODE":"prod"}'
To view and follow the service:
gyro container service list 12345
gyro container service get 12345 api
5. After publishing
- Address: Click the address in the service table. The first request may take a few seconds to be ready.
- Status labels: Deploying, Running, Error, Waiting for capacity, Stopped. If there is an error or waiting state, the cause and a suggested fix appear under the row (Common errors).
- Logs: Choose your service on the Logs page to see its output (Logs and graphs).
- Updating: for a new image version see Scaling, updating and rollback.
6. Frequently asked questions
Can I do the same as Docker Compose or docker run ?
Each service is created separately. The equivalents of docker run options: port → Port, -e → Environment variables, --restart → the platform restarts it itself, -v (disk) is not supported.
My image is bigger than 1 GB; is that a problem?
Pulling takes longer. Making the image smaller (multi-stage builds, alpine/distroless) speeds up deploys.
How do two services in the same environment connect?
Through the internal address: http://other-service (port 80, which forwards to the target service's port). The target service does not need to be public.
Can I rename a service later?
No. Create a new service with the new name and delete the old one.
Next step
Thanks for your feedback!