Spin down unused Dokku containers (and spin them up upon access) - docker

Heroku spins down containers for free accounts when the app isn't accessed for a day. For our system, deployed on Dokku, we have production, staging, as well as developer containers running the same app. Today I noticed a Dokku app hang indefinitely mid-deploy on our dev VM. After investigating, I discovered that the issue was due to insufficient VM memory. After I killed a few containers, the container started successfully. For reference, there are almost 60 containers deployed on our dev box now, but only about 5 of them are being actively used. Often, our devs deploy multiple versions of the same app when testing. Sometimes these apps are no longer needed (in which case we can simply remove them), but more often than not, they'll need to be accessed again a week or two later.
To save resources on our VMs, we would like to spin down dev containers, especially since there are likely to be multiple instances of the same app.
Is this possible with Dokku? If I simply stop containers that haven't been accessed for a while (using docker stop command), then the user accessing the app later will be greeted with a 404 page. What I would like to do instead is show the loading icon to the user until the container is spun up again.

simply with dokku commands this is not posible for the moment. maybe you can use ps:stop and try something like if you find a 502 error on nginx, you then try to run a shell script that start the application, but that will of course give the 502 error to the user the first time.

Related

ERR_CONNECTION_REFUSED when trying to view software running in docker containers via url

I'm new to Docker, and have been reconstructing a test environment with instructions that were left to me by the previous developer.
We have several in-house pieces of job tracking software that both the outside clients and internal employees can access.
The job tracking software has a few dependencies that require a mailhog container to be spun up, and a second container which contains all of the other required sub software.
Despite my amateur knowledge on the subject, and the complexity of the software, I successfully installed Docker with the required Linux Kernels and Ubuntu.
I pulled the required images I needed, and successfully built the other ones.
I configured the in-house software with all of the testing settings enabled, and have it all grouped in the proper file directory.
By all intents and purposes, it should be configured fine.
The trouble starts with starting the containers.
The command line prompt "docker-compose up -d" pointed in the proper sub-directory throws this error:
Error response from daemon: Get "https://registry-1.docker.io/v2/": remote error: tls: handshake failure
I figured screw it, I'll build it right from the Docker Desktop instead of using command line, and it worked! The two containers I needed successfully built.
I even ran the docker test command to make sure they were really running.
So here's where the trouble just gets worse.
The ex-developer states the jobtracking software can then be viewed in browser using this "https://localhost/jobtracker/"
The page doesn't load, and then throws err_connection_refused error.
I am at my wits end with trouble shooting, because I quite simply don't have the networking or development knowledge to search the right things, AND to make matters even more frustrating is the remote outsourced devs have their environment up and running, despite using the exact same instructions I have.
So I'm down to two possible issues. Either somewhere in the set-up process, I messed something up, OR my office network security is breaking something. However, I was told by our lead IT specialist, I should have all of the same network permissions the outsourced guys on the vpns have.
I am here now reaching out on several docker web sources to find a solution.
I am on Windows 10.
Thankfully my employers are pretty cool about me learning as I go, and understand the technical difficulties. I just don't want to squander the opportunity, and would like to make some progress.

AWS EC2 becomes unreachable (Rails, Phusion_Passenger)

My Rails app production is running on AWS EC2 instance, on Apache through Phusion Passenger. And I am facing different problems with it.
Sometimes this instance becomes unreachable via ssh and my rails application cannot be accessed via browser. Probably some memory issues. I have created swap memory, but it is not helping.
Sometimes my Rails app gets shut down, and application/current folder gets removed.
First one can be fixed only by stopping AWS instance and starting it again, and second one by deploying application.
Any suggestions on what can be causing it? Or even more important how I can fix that once and for all?

HTTP 503 errors from Cloud Run app in one GCP projects but not the other

The issue
I am using the same container (similar resources) on 2 projects -- production and staging. Both have custom domains setup with cloud flare DNS and are on the same region. Container build is done in a completely different project and IAM is used to handle the access to these containers. Both project services have 80 concurrency and 300 seconds time out for all 5 services.
All was working good 3 days back but from yesterday almost all cloud run services on staging (thankfully) started throwing 503 randomly and for most requests. Some services were not even deployed for a week. The same containers are running fine on production project, no issues.
Ruled out causes
anything to do with Cloudflare (I tried the URL cloud run gives it has the issue of 503)
anything with build or containers (I tried the demo hello world container with go - it has the issue too)
Resources: I tried giving it 1 GB ram and 2 cpus but the problem persisted
issues on deployment (deploy multiple branches - didn't work)
issue in code (just routed traffic to old 2-3 days old revision but still issue was there)
Issue on service level ( I used the same container to create a completely new service, it also had the issue)
Possible causes
something on cloud run or cloud run load balancer
may some env vars but that also doesn't seem to be the issue
Response Codes
I just ran a quick check with vegeta (30 secs with 10 rps) same container on staging and production for a static file path and below are the responses:
Staging
Production
If anyone has any insights on this it would help greatly.
Based on your explanation, I cannot understand what's going on. You explained what doesn't work but didn't point out what works (does your app run locally? are you able to run a hello world sample application?)
So I'll recommend some debugging tips.
If you're getting a HTTP 5xx status code, first, check your application's logs. Is it printing ANY logs? Is there logs of a request? Does your application have and deployed with "verbose" logging setting?
Try hitting your *.run.app domain directly. If it's not working, then it's not a domain or dns or cloudflare issue. Try debugging and/or redeploying your app. Deploy something that works first. If *.run.app domain works, then the issue is not in Cloud Run.
Make sure you aren't using Cloudflare in proxy mode (e.g. your DNS points to Cloud Run; not Cloudflare) as there's a known issue about certificate issuance/renewals when domains are behind Cloudflare, right now.
Beyond these, if a redeploy seems to solve your problem, maybe try redeploying. It could be very likely some configuration recently became different two different projects.
See Cloud Run Troubleshooting
https://cloud.google.com/run/docs/troubleshooting
Do you see 503 errors under high load?
The Cloud Run (fully managed) load balancer strives to distribute incoming requests over the necessary amount of container instances. However, if your container instances are using a lot of CPU to process requests, the container instances will not be able to process all of the requests, and some requests will be returned with a 503 error code.
To mitigate this, try lowering the concurrency. Start from concurrency = 1 and gradually increase it to find an acceptable value. Refer to Setting concurrency for more details.

What is the benefit of dockerize the SPA web app

I dockerize my SPA web app by using nginx as base image then copy my nginx.conf and build files. As Dockerize Vue.js App mention I think many dockerizing SPA solutions are similar.
If I don't use docker I will first build SPA code then copy the build files to nginx root directory (After install/set up nginx I barely change it at all)
So what's the benefit of dockerizing SPA?
----- update -----
One answer said "If the app is dockerized each time you are releasing a new version of your app the Nginx server gets all the new updates available for it." I don't agree with that at all. I don't need the latest version of nginx, after all I only use the basic feature of nginx. Some of my team members just use the nginx version bundled with linux when doing development. If my docker image uses the latest ngixn it actually creates the different environment than the development environment.
I realize my question will be probably closed b/c it will be seen as opinion based. But I have googled it and can't find a satisfied answer.
If I don't use docker I will first build SPA code then copy the build files to nginx root directory (After install/set up nginx I barely change it at all)
This is a security concern... fire and forget is what it seems is being done here regarding the server.
If the app is dockerized each time you are releasing a new version of your app the Nginx server gets all the new updates available for it.
Bear in mind that if your App does not release new versions in a weekly bases then you need to consider to rebuild the docker images at least weekly in order to get the updates and keep everything up to date with the last security patches.
So what's the benefit of dockerizing SPA?
Same environment across development, staging and production. This is called 100% parity across all stages were you run your app, and this true for no matter what type of application you deploy.
If something doesn't work in production you can pull the docker image by the digest and run it locally to debug and try to understand where is the problem. If you need to ssh to a production server it means that you automation pipeline have failed or maybe your are not even using one...
Tools like Webpack compile Javascript applications to static files that can then be served with your choice of HTTP server. Once you’ve built your SPA, the built files are indistinguishable from pages like index.html and other assets like image files: they’re just static files that get served by some HTTP server.
A Docker container encapsulates a single running process. It doesn’t really do a good job at containing these static files per se.
You’ll frequently see “SPA Docker containers” that run a developer-oriented HTTP server. There’s no particular benefit to doing this, though. You can get an equally good developer experience just by developing your application locally, running npm run build or whatever to create a dist directory, and then publishing that the same way you’d publish other assets. An automation pipeline is helpful here, but this isn’t a task Docker makes wildly simpler.
(Also remember when you do this that the built application runs on the user’s browser. That means it can’t see any of the Docker-internal networking machinery: it can’t use the Docker-internal IP addresses and it can’t use the built-in Docker DNS service. Everything it reaches has to be on docker run -p published ports and it has to use a DNS name that reaches the host. The browser literally has no idea Docker is involved in this at all.)
There are a few benefits.
Firstly, building a Docker image means you are explicitly stating what your application's canonical run-time is - this version of nginx, with that SSL configuration, whatever. Changes to the run-time are in source control, so you can upgrade predictably and reversibly. You say you don't want "the latest version" - but what if that latest version patches a critical security vulnerability? Being able to upgrade predictably, on "disposable" containers means you upgrade when you want to.
Secondly, if the entire development team uses the same Docker image, you avoid the challenges with different configurations giving the "it works on my machine" response to bugs - in SPAs, different configurations of nginx can lead to different behaviour. New developers who join the team don't have to install or configure anything, and can use any device they want - they can be certain that what runs in Docker is the same as it is for all the other developers.
Thirdly, by having all your environments containerized (not just development, but test and production), you make it easy to move versions through the pipeline and only change the environment-specific values.
Now, for an SPA, these benefits are real, but may not outweigh the cost and effort of creating and maintaining Docker images - inevitably, the Docker image becomes a bottleneck and the first thing people blame. I'd only invest in it if you see lots of environment-specific pain (suggesting having a consistent run-time environment is necessary), or if you see lots of "it works on my machine" type of bug.

Understanding Docker in Production

I've been learning how to use Docker to setup dev environments, however, I'm
curious how these ideas translate to a production stack. As an example, I have a Laravel (Php) app, which uses MySQL, Redis, and Nginx
So in production, let's say I would normally have 2 application ec2 instances behind a load balancer on AWS. When setting up a similar production situation using Docker...
1) because I'd be using RDS and Elasticache, there would be no need for containers for those. So basically, id only need containers for PHP-Fpm and Nginx?
2) to have high availability, I would still have 2 (or least more than 1) ec2 instances behind the ELB. So I suppose each instance would run the above containers (PHP and Nginx). But that sounds no different than my previous VM setup, where each server runs what it needs to serve the application. Is that accurate?
3) with VMs, I would traditionally bake the code into an AMI and add those AMIs to a Launch Configuration and an Auto Scaling group, and that group would spin up instances as needed. So for deployment, I would tear down the old ec2 instances and spin up new ones. With Docker, Since these containers would be running on ec2 instances, wouldn't i still have to spin up / tear down the VMs, or would I just replace the containers and keep the VMs running?
Its reasonable to keep RDS, Elasticache and other fully managed services, outside of docker environment. Yes for high availability you need multiple EC2 instances having docker daemon running.
The real advantage is not coming with having two EC2 instances running two web server docker containers on each of them. Real advantages comes when you break down your application to microservices, where multiple containers in combination construct your web application providing the benefits of microservices.
Apart from that the DevOps flow would be different compared to traditional web application deployment in EC2 with autoscaling and load balancing and have many benefits. For example your source code will contain the container code as well, which will guarantee, the environment will work uniformly in your staging and production. Also you will be having images pointing to branches/tags in your source control, which allows to get new updates(delta downloads) for new releases.
If you are going to setup docker in AWS, its recommended to go with AWS ECS to reduce management overhead.
You're right, you will only need to run your code in a container and it will simply access the remote services. The only thing you'll have to consider is to ensure connectivity to them.
You're right again, you'll need to have everything you previously had in your VMs in the Docker container so that your code works as before. Anyway, with Docker containers it is possible to run multiple instances of your app on the same EC2 instance. Of course, your app will try to run on the same port, so some extra networking layer is needed for managing ports is necessary, but it's possible. All the EC2 instances needs to have is docker installed.
Instead of creating AMIs and closing and spinning up EC2 instances, you'll only have to pull the new Docker image and restart the container with the new image. This means just a few seconds compared to minutes in the EC2 instances flow. This is means you have a really quick way of reverting buggy deploys and opens the doors for a setup in which 0% downtime can be reached.

Resources