AWS EC2 Instance can't be reached even though docker containers running - amazon-web-services

i'm trying to get my laravel app running in ec2 with docker containers. I have two containers one of the app and then one for nginx. I have created the ec2 instance with docker-machine and i've also built the docker images successfully.
Running docker-compose up also runs successfully. If I run docker ps I see the two containers running.
So I have two containers running I would expect to go to the http://ec2-ip-addy-here.compute-1.amazonaws.com/ and see the app. My hunch is that something isn't setup on AWS side correctly, maybe the VPC? I'm a novice with AWS so I don't know what to look for. Any ideas?
I'm following this guide https://hackernoon.com/stop-deploying-laravel-manually-steal-this-docker-configuration-instead-da9ecf24cd2e
I'm also using the laradock nginx dockerfile and my own dockerfile for the app
EDIT:
It could be the networks that are created with docker-compose. I say that because I just checked and the network is being prepended with the service name. When I run docker network ls I see a network called php-fpm_backend. Here's my docker-compose.yml file
version: '3'
networks:
backend:
driver: bridge
services:
### PHP-FPM ##############################################
php-fpm:
image: php-fpm
container_name: php-fpm
build:
context: ../
dockerfile: ./laradock/php-fpm/Dockerfile-Prod
args:
- LARADOCK_PHP_VERSION=7.2
- INSTALL_PGSQL=true
- INSTALL_PG_CLIENT=true
- INSTALL_POSTGIS=true
expose:
- "9000"
networks:
- backend
### NGINX Server #########################################
nginx:
image: nginx
container_name: nginx
build:
context: ../
dockerfile: ./laradock/nginx/Dockerfile-Prod
args:
- http_proxy
- https_proxy
- no_proxy
ports:
- "80:80"
- "443:443"
depends_on:
- php-fpm
networks:
- backend

I figured this out. It was as I thought, I had to add a new security group with port 80/443 access for HTTP and HTTPS.

Related

Set ports on a Docker compose file for Amazon ECS

I am following this tutorial to deploy my app to AWS using docker compose.
If I use docker compose up I get this error:
published port can't be set to a distinct value than container port: incompatible attribute
This is the docker-compose.yml:
version: "3"
services:
www:
image: my_image_path:latest
ports:
- "8001:80"
volumes:
- ./www:/var/www/html/
links:
- db
networks:
- default
phpmyadmin:
image: phpmyadmin/phpmyadmin:4.8
links:
- db:db
ports:
- 8000:80
environment:
MYSQL_USER: user
MYSQL_PASSWORD: test
MYSQL_ROOT_PASSWORD: test
I have two services listening to port 80 in the container, so I cannot just use 80:80 in both of them.
Any ideas?
You need to change one of your docker images to listen on another port. Docker-compose deploys to AWS Fargate, and there are some restrictions in Fargate that are preventing your configuration from working:
Multiple containers in a single Fargate task have to listen on distinct ports.
The published port can't be different from the port the container is listening on. If you needed to change the port clients connect to, that can be done in the ALB/Target Group settings, instead of the container settings.
Since one of your images is phpmyadmin I suggest simply adding an environment variable to that image APACHE_PORT: 8000 which will change the port the Apache web server in that container listens on to port 8000. Then you can set the port mapping on that container to 8000:8000 and set the port mapping on your www container to 80:80

Docker compose ECS integration: load balancer is of type application, project require a network

I have a docker-compose.yml file as follows:
version: "3.8"
x-aws-loadbalancer: "arn:aws:elasticloadbalancing:my-load-balancer"
services:
fastapi:
image: username/auth:FastAPI
x-aws-pull_credentials: "arn:aws:secretsmanager:us-west-2:creds"
build: FastAPI
ports:
- "5555:5555"
nginx:
image: username/auth:nginx
x-aws-pull_credentials: "arn:aws:secretsmanager:us-west-2:creds"
build: nginx
ports:
- "80:80"
depends_on:
- fastapi
networks:
default:
external: true
name: my-sg
But when attempting to integrate this with ECS using docker compose up I receive the error:
load balancer "arn:aws:elasticloadbalancing:my-load-balancer" is of type application, project require a network
I have also tried providing a vpc using the top-level x-aws-vpc property and received the same error.
What
It's because you are using port 5555, which docker-compose can't know is being uses for HTTP, so it makes the assumption that you need a network load balancer since Application Load Balancers only support HTTP.
Per the documentation for ECS docker-compose integration:
If services in the Compose file only expose ports 80 or 443, an
Application Load Balancer is created, otherwise ECS integration will
provision a Network Load Balancer. HTTP services using distinct ports
can force use of an ALB by claiming the http protocol with
x-aws-protocol custom extension within the port declaration:
So, just going by that example at the documentation I linked, I would try changing your FastAPI service declaration to the following:
fastapi:
image: username/auth:FastAPI
x-aws-pull_credentials: "arn:aws:secretsmanager:us-west-2:creds"
build: FastAPI
ports:
- "5555:5555"
x-aws-protocol: http
Or maybe change it to the following, to more closely match the example in the documentation:
ports:
- target: 5555
x-aws-protocol: http

Cannot connect to docker-compose services in AWS CodeBuild

I am trying to run Cypress e2e tests by spinning up docker-compose services and checking them with Cypress. What ever I do, I am not able to connect to another service either outside of the service or inside of one.
I tried adding running curl 127.0.0.1 to check if service is reachable, but it returns "Failed to connect to 127.0.0.1 port 80: Connection refused"
My CodeBuild environment has privileged set to true.
This is my buildspec:
version: 0.2
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
build:
commands:
- echo Test Execution starting...
- AWS_ACCOUNT_ID=$AWS_ACCOUNT_ID
- AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION
- docker-compose --file=deployment/docker.yml up -d main webserver
- docker-compose --file=deployment/docker.yml run cypress
post_build:
commands:
- docker-compose --file=deployment/docker.yml down
My docker-compose file is very simple. It get's images that have already been built.
version: '3'
services:
main:
image: ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/main:${ENVIRONMENT}
build:
context: ../main
container_name: main
ports:
- "3000:3000"
networks:
- network
webserver:
image: ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/webserver:${ENVIRONMENT}
build:
context: ../frontend
container_name: webserver
ports:
- "80:80"
depends_on:
- main
networks:
- network
cypress:
image: ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/cypress:${ENVIRONMENT}
build:
context: ../cypress
command: "--browser chrome"
depends_on:
- webserver
- main
environment:
- CYPRESS_baseUrl=http://webserver:80
networks:
- network
networks:
network:
driver: bridge
I had a similar issue. My cypress instance wasn´t able to connect with the service to test.
I solved it setting "network_mode" to "host" and the base url to "localhost" in the cypress service.
In your case, it would be something similar to this:
cypress:
image: ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/cypress:${ENVIRONMENT}
build:
context: ../cypress
command: "--browser chrome"
depends_on:
- webserver
- main
environment:
- CYPRESS_baseUrl=http://localhost:80
network_mode: "host"

Service to service Name does not resolve ECS Fargate

I tried to deploy the following project to AWS Fargate by docker compose CLI.
docker-compose.yml
version: "3"
x-aws-vpc: vpc-04db4c9a69a101123
services:
redis:
image: redis:alpine
container_name: redis
networks:
- default
nettool:
image: praqma/network-multitool:latest
container_name: nettool
depends_on:
- redis
command: >
/bin/bash -c "sleep 30 && ping redis"
networks:
- default
networks:
default:
external: true
name: sg-076b1c7d0cfaac123
AWS Context as administrator permission. I deploy the project by docker compose up. It deploys with load balancer being used and required 2 subnet masks, I fulfilled it.
ping redis at nettool service got Name does not resolve
I hope here is somebody who can help me!

Can't connect to elasticache redis from docker container running in EC2

As a part of my CI process, I am creating a docker-machine EC2 instance and running 2 docker containers inside of it via docker-compose. The server container test script attempts to connect to an AWS elasticache redis instance within the same VPC as the EC2. When the test script is run I get the following error:
1) Storage
check cache connection
should return seeded value in redis:
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (/usr/src/app/test/scripts/test.js)
at listOnTimeout (internal/timers.js:549:17)
at processTimers (internal/timers.js:492:7)
Update: I can connect via redis-cli from the EC2 itself:
redis-cli -c -h ***.cache.amazonaws.com -p 6379 ping
> PONG
It looks like I cant connect to my redis instance because my docker container is using an IP that is not within the same VPC as my elasticache instance. How can I setup my docker config to use the same IP as the host machine while building my containers from remote images? Any help would be appreciated.
Relevant section of my docker-compose.yml:
version: '3.8'
services:
server:
build:
context: ./
dockerfile: Dockerfile
image: docker.pkg.github.com/$GITHUB_REPOSITORY/$REPOSITORY_NAME-server:github_ci_$GITHUB_RUN_NUMBER
container_name: $REPOSITORY_NAME-server
command: npm run dev
ports:
- "8080:8080"
- "6379:6379"
env_file: ./.env
Server container Dockerfile:
FROM node:12-alpine
# create app dir
WORKDIR /usr/src/app
# install dependencies
COPY package*.json ./
RUN npm install
# bundle app source
COPY . .
EXPOSE 8080 6379
CMD ["npm", "run", "dev"]
Elasticache redis SG inbound rules:
EC2 SG inbound rules:
I solved the problem through extensive trial and error. The major hint that pointed me in the right direction was found in the Docker docs:
By default, the container is assigned an IP address for every Docker network it connects to. The IP address is assigned from the pool assigned to the network...
Elasticache instances are only accessible internally from their respective VPC. Based on my config, the docker container and the ec2 instance were running on 2 different IP addresses but only the EC2 IP was whitelisted to connect to Elasticache.
I had to bind the docker container IP to the host EC2 IP in my docker.compose.yml by setting the container network_mode to "host":
version: '3.8'
services:
server:
image: docker.pkg.github.com/$GITHUB_REPOSITORY/$REPOSITORY_NAME-server:github_ci_$GITHUB_RUN_NUMBER
container_name: $REPOSITORY_NAME-server
command: npm run dev
ports:
- "8080:8080"
- "6379:6379"
network_mode: "host"
env_file: ./.env
...