Did you restart your docker host? Update your portainer docker container? Or did your Swarm change? Then you want to recover your “lost” docker stacks in portainer. This post is about how to recover them, if possible.
As tool for the requests I use Postman (https://www.getpostman.com/) and I will provide curl (https://curl.haxx.se/) cli examples too
- Authenticate
- Get stacks array
- Migrate stack
- Update the stack
1.Authenticate
To authenticate you need to send the username and password to your portainer instance ($PortainerUrl e.g. http://localhost:9000)
For Postman:
Use a POST request to $PortainerUrl/api/auth, set Body to raw and send the following json:
{ "Username": $PortainerUsername, "Password": $PortainerPassword }
For curl use:
curl -X POST \ -H Content-Type:application/json \ -d '{"Username": $PortainerUsername,"Password":$PortainerPassword}' \ $PortainerUrl/api/auth
The result for both should look like this:
{ "jwt": "tester1234JIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJhZG1pbiIsInJvbGUiOjEsImV4cCI6MTU5Njk5NzAyOH0.t3lW6bRy0muT8AV3V1sfDfI_URaQ6AA270nZRSfbH3w" }
This JWT (JSON Web Token) is required for all following calls.
2. Get Stacks Array
Next step is to retrieve the array of stacks that´s available (but might not be display on the web interface).
With Postman use a GET request to $PortainerUrl/api/stacks, go to Authorization, select Type Bearer token and input the JWT into the token field.
For curl use:
curl \ -H "Authorization: Bearer token" \ $PortainerUrl/api/stacks
As a result you should get something like this:
[ { "Id": 1, "Name": "Stack 1", "Type": 1, "EndpointId": 1, "SwarmId": "7jqtnwy7v7iskuwnj03eedftn", "EntryPoint": "docker-compose.yml", "Env": [], "ResourceControl": null, "ProjectPath": "/data/compose/6" }, { "Id": 1, "Name": "Stack 2", "Type": 1, "EndpointId": 1, "SwarmId": "7jqtnwy7v7iskuwnj03eedftn", "EntryPoint": "docker-compose.yml", "Env": [], "ResourceControl": null, "ProjectPath": "/data/compose/11" }, { "Id": 3, "Name": "Stack 3", "Type": 1, "EndpointId": 1, "SwarmId": "7jqtnwy7v7iskuwnj03eedftn", "EntryPoint": "docker-compose.yml", "Env": [], "ResourceControl": null, "ProjectPath": "/data/compose/15" }]
3. Migrate Stack
This is the tricky part. You need to verify the Stack reference and change the wrong/corrupted data.
To do this in Postman:
Use a POST request to $PortainerUrl/api/stacks/$stackId/migrate, set the body to raw, use this json format:
{ "EndpointId": 1, "$FieldToFix": $newFieldValue }
For curl use this:
curl -X POST \ -H "Authorization: Bearer token" \ -H Content-Type:application/json \ $PortainerUrl/api/stacks/$stackId/migrate \ -d '{"EndpointId":1,"$FieldToFix": $newFieldValue}'
As the result you should get a confirmation that all went well.
4. Update Stack
Potentially you need to update the stack, even when you didn´t change the stack config. To do that just open the stack in the portainer web ui, click on Editor, scroll to “Update stack”. This applies the stack again and makes therefore sure that everything is up-to-date.
As result the stacks will be recovered in portainer, they will have their data refreshed and they will be freshly deployed. They are ready to use.
Let me know when this helped you to recover your stacks after a problem with portainer.
Best,
Frank