I'm trying to use traefik with docker compose.
According to the threads I've seen on their site, you could use something like this :
mytest-steph:
image: myimage
ports:
- "45001:45001"
labels:
- "traefik.backend=test_steph"
- "traefik.frontend.rule=Host:test.mydomain.com;PathPrefix:/myprefix"
- "traefik.backend.port=8080"
- "traefik.frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
But when I launch docker-compose up, I get :
WARNING: The apr1 variable is not set. Defaulting to a blank string.
WARNING: The H6uskkkW variable is not set. Defaulting to a blank string.
WARNING: The IgXLP6ewTrSuBkTrqE8wj variable is not set. Defaulting to a blank string.
Does anyone achieve to use basic auth like that ?
I've found the answer. You have to double every "$" character.
For example:
"traefik.frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
will become:
"traefik.frontend.auth.basic=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/"
Reformat your labels :
labels:
- traefik.backend="test_steph"
- traefik.frontend.rule="Host:test.mydomain.com;PathPrefix:/myprefix"
- traefik.backend.port="8080"
- traefik.frontend.auth.basic="test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
Related
For my deployment I would like to be able to set the container tag at runtime. For example.
I have 2 containers:
container-1:1.0.2
container-2:0.1.0
I have a manually triggered deployment step. I would like to be able to do something like this in my code:
- helm install ${container_name}_chart --version=${helm_version} --set cotainer_version=${container_version}
Where container_name, helm_version, and container_version are set by the user at runtime.
At runtime the user can enter (or even better, if possible select from a list) the container/app name and version.
Is this possible?
Turns out you can use runtime parameters with custom pipelines only.
https://support.atlassian.com/bitbucket-cloud/docs/pipeline-triggers/
pipelines:
custom:
custom-name-and-region: #name of this pipeline
- variables: #list variable names under here
- name: Username
- name: Region
- step:
script:
- echo "User name is $Username"
- echo "and they are in $Region"
Also, there is no drop down functionality.
So I have a env.yml file which lets me have a different variables for each stage:
provider:
name: aws
environment: ${file(env.yml):${opt:stage}}
I also need to share some output variables to Lambda which are declared like so:
Outputs:
UserPoolId:
Value:
Ref: QNABUserPool
Export:
Name: ${self:provider.stage}-UserPoolId
UserPoolClientId:
Value:
Ref: QNABUserPoolClient
Export:
Name: ${self:provider.stage}-UserPoolClientId
I've seen I can do this by adding this to my provider but this conflicts with my env.yml
environment:
COGNITO_USER_POOL_ID: ${cf:${self:service}-${self:provider.stage}.UserPoolId}
COGNITO_USER_POOL_CLIENT_ID: ${cf:${self:service}-${self:provider.stage}.UserPoolClientId}
I tried putting these into the env.yml but that didn't work:
Trying to request a non exported variable from CloudFormation. Stack name: "XXXX-alpha" Requested variable: "UserPoolId".
I tried using custom instead of environment and it deployed but the Lambda functions no longer had access to the variables.
So how can I mix these two together?
Thank you so much!
You can reference the Output values from your current service using the Fn::ImportValue function.
The serverless system adds sls-[service_name] to the variable but you can find them in the Outputs area of the CloudFormation Stack.
Navigate to CloudFormation --> Stacks --> [select your service] --> Outputs (tab). From there you'll see a column called Exports name.
Use that Exports name and use that for the import.
e.g. you have a WebSocket service and you need the service endpoint. If you look in the tab it will have an export ~ sls-wss-[your_service_name]-[stage]-ServiceEndpointWebsocket. Thus, you can import that into an environment variable:
Environment:
Variables:
ENDPOINT:
Fn::ImportValue: sls-wss-[your_service_name]-${opt:stage}-ServiceEndpointWebsocket
I'm trying to password protect a specific path for an app, but it seems I am missing something and the traefik documentation is not helpful:
Paste from docker-compose:
traefik:
command:
- "--log.level=INFO"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.letsencrypt.acme.email=email#email.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/etc/traefik/acme.json"
service:
labels:
- "traefik.enable=true"
- "traefik.http.routers.service.middlewares=service"
- "traefik.http.routers.service.rule=Host(`domain.example.com`)"
- "traefik.http.middlewares.service.headers.stsSeconds=31536000"
- "traefik.http.middlewares.service.headers.forceSTSHeader=true"
- "traefik.http.middlewares.service.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.service.headers.stsPreload=true"
- "traefik.http.middlewares.service.headers.referrerPolicy=no-referrer"
- "traefik.http.middlewares.service.headers.browserXssFilter=true"
- "traefik.http.middlewares.service.headers.customRequestHeaders.X-Forwarded-Proto=https"
- "traefik.http.routers.service.tls.certresolver=letsencrypt"
If I add the following labels basic auth is working but it's enabled on the whole website:
"traefik.http.middlewares.service-auth.basicauth.usersfile=/etc/traefik/auth"
"traefik.http.routers.service.middlewares=service,service-auth"
I played around with adding a second router like so, but that doesn't seem to work:
"traefik.http.routers.service-admin.rule=Host(domain.example.com) && PathPrefix(/somepath)"
"traefik.http.middlewares.service-auth.basicauth.usersfile=/etc/traefik/auth"
"traefik.http.routers.service-admin.middlewares=service-auth"
What am I missing?
I managed to figure it out with some "educated" guesses. It seems the order of the labels and the spacing between them plays a vital role. Adding a second router (without a service) was indeed the correct way of accomplishing this but separating the routers and middlewares code blocks was important:
- "traefik.enable=true"
- "traefik.http.routers.service.rule=Host(`example.example.com`)"
- "traefik.http.routers.service-admin.rule=Host(`example.example.com`) && PathPrefix(`/somepath`)"
- "traefik.http.routers.service.tls.certresolver=letsencrypt"
- "traefik.http.routers.service-admin.tls.certresolver=letsencrypt"
- "traefik.http.routers.service.middlewares=service"
- "traefik.http.routers.service-admin.middlewares=service-admin"
- "traefik.http.middlewares.service.headers.stsSeconds=31536000"
- "traefik.http.middlewares.service.headers.forceSTSHeader=true"
- "traefik.http.middlewares.service.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.service.headers.stsPreload=true"
- "traefik.http.middlewares.service.headers.referrerPolicy=no-referrer"
- "traefik.http.middlewares.service.headers.browserXssFilter=true"
- "traefik.http.middlewares.service.headers.customRequestHeaders.X-Forwarded-Proto=https"
- "traefik.http.middlewares.service-admin.basicauth.usersfile=/etc/traefik/auth"
Note: traefik version used is 2.2.1
I think that you are misconfiguring the second router, try to do it like this
"traefik.http.routers.service-admin.rule=Host(domain.example.com) && PathPrefix(/somepath)"
"traefik.http.middlewares.service-admin.basicauth.usersfile=/etc/traefik/auth"
"traefik.http.routers.service-admin.middlewares=service-admin"
"traefik.http.routers.service-admin.service=$yourservice"
I just had the same problem and the solution seems to be related to the priority given for a route, see https://doc.traefik.io/traefik/routing/routers/#priority.
The routes to consider are ordered by priority by traefik. The priority is, by default, determined by the length of the rule of the route. That is the reason why the accepted answer was working. The rule for the admin route is longer.
I would suggest to set a very high priority for such cases manually, because if you add more hosts or other expressions to your original route, traefik would basically ignore the admin route as it has a short rule.
I'm having trouble pushing to gcr with the following
gcr:
image: plugins/gcr
registry: us.gcr.io
repo: dev-221608/api
tags:
- ${DRONE_BRANCH}
- ${DRONE_COMMIT_SHA}
- ${DRONE_BUILD_NUMBER}
dockerfile: src/main/docker/Dockerfile
secrets: [GOOGLE_CREDENTIALS]
when:
branch: [prod]
...Where GOOGLE_CREDENTIALS will work, but if named say GOOGLE_CREDENTIALS_DEV it will not be properly picked up. GCR_JSON_KEY works fine. I recall reading legacy documentation that spelled out the acceptable variable names, of which GOOGLE_CREDENTIALS and GCR_JSON_KEY were listed among other variants but as of version 1 they've done some updates omitting that info.
So, question is, is the plugin capable of accepting whatever variable name or is it expecting specific variable names and if so what are they?
The Drone GCR plugin accepts the credentials in a secret named PLUGIN_JSON_KEY, GCR_JSON_KEY, GOOGLE_CREDENTIALS, or TOKEN (see code here)
If you stored the credentials in drone as GOOGLE_CREDENTIALS_DEV then you can rename it in the .drone.yml file like this:
...
secrets:
- source: GOOGLE_CREDENTIALS_DEV
target: GOOGLE_CREDENTIALS
...
On line 19 of this serverless.yml example, the following appears:
Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
1) Is the syntax ${...} an instance of bash parameter expansion, like the expansion covered by this guide
2) In any case, what does the line above do?
Those are variable definitions. They can be defined somewhere else. Example
custom: ${file(env.yml)}
environment: ${self:custom.environment}
Then I define my variables in my env.yml as such
environment: dev
Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
that resource is the resource arn for an example DYANMODB_TABLE
You would preform something like this
- Sid: "LogsAccess"
Effect: "Allow"
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
- "logs:DescribeLogStreams"
Resource: "arn:aws:logs:*:*:*"
But in this case your block would relate to dynamodb.